1 | /* GTK - The GIMP Toolkit |
2 | * Copyright (C) 2012, One Laptop Per Child. |
3 | * Copyright (C) 2014, Red Hat, Inc. |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Lesser General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
17 | * |
18 | * Author(s): Carlos Garnacho <carlosg@gnome.org> |
19 | */ |
20 | |
21 | /** |
22 | * GtkEventController: |
23 | * |
24 | * `GtkEventController` is the base class for event controllers. |
25 | * |
26 | * These are ancillary objects associated to widgets, which react |
27 | * to `GdkEvents`, and possibly trigger actions as a consequence. |
28 | * |
29 | * Event controllers are added to a widget with |
30 | * [method@Gtk.Widget.add_controller]. It is rarely necessary to |
31 | * explicitly remove a controller with [method@Gtk.Widget.remove_controller]. |
32 | * |
33 | * See the chapter on [input handling](input-handling.html) for |
34 | * an overview of the basic concepts, such as the capture and bubble |
35 | * phases of even propagation. |
36 | */ |
37 | |
38 | #include "config.h" |
39 | #include "gtkeventcontroller.h" |
40 | #include "gtkeventcontrollerprivate.h" |
41 | |
42 | #include "gtkwidgetprivate.h" |
43 | #include "gtktypebuiltins.h" |
44 | #include "gtkmarshalers.h" |
45 | #include "gtkprivate.h" |
46 | #include "gtkintl.h" |
47 | #include "gtknative.h" |
48 | |
49 | typedef struct _GtkEventControllerPrivate GtkEventControllerPrivate; |
50 | |
51 | enum { |
52 | PROP_WIDGET = 1, |
53 | PROP_PROPAGATION_PHASE, |
54 | PROP_PROPAGATION_LIMIT, |
55 | PROP_NAME, |
56 | LAST_PROP |
57 | }; |
58 | |
59 | static GParamSpec *properties[LAST_PROP] = { NULL, }; |
60 | |
61 | struct _GtkEventControllerPrivate |
62 | { |
63 | GtkWidget *widget; |
64 | GtkPropagationPhase phase; |
65 | GtkPropagationLimit limit; |
66 | char *name; |
67 | GtkWidget *target; |
68 | GdkEvent *event; |
69 | }; |
70 | |
71 | G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkEventController, gtk_event_controller, G_TYPE_OBJECT) |
72 | |
73 | static void |
74 | gtk_event_controller_set_widget (GtkEventController *self, |
75 | GtkWidget *widget) |
76 | { |
77 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self); |
78 | |
79 | priv->widget = widget; |
80 | } |
81 | |
82 | static void |
83 | gtk_event_controller_unset_widget (GtkEventController *self) |
84 | { |
85 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self); |
86 | |
87 | priv->widget = NULL; |
88 | } |
89 | |
90 | static gboolean |
91 | gtk_event_controller_filter_event_default (GtkEventController *self, |
92 | GdkEvent *event) |
93 | { |
94 | return FALSE; |
95 | } |
96 | |
97 | static gboolean |
98 | gtk_event_controller_handle_event_default (GtkEventController *self, |
99 | GdkEvent *event, |
100 | double x, |
101 | double y) |
102 | { |
103 | return FALSE; |
104 | } |
105 | |
106 | static void |
107 | gtk_event_controller_handle_crossing_default (GtkEventController *self, |
108 | const GtkCrossingData *crossing, |
109 | double x, |
110 | double y) |
111 | { |
112 | } |
113 | |
114 | static void |
115 | gtk_event_controller_set_property (GObject *object, |
116 | guint prop_id, |
117 | const GValue *value, |
118 | GParamSpec *pspec) |
119 | { |
120 | GtkEventController *self = GTK_EVENT_CONTROLLER (object); |
121 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self); |
122 | |
123 | switch (prop_id) |
124 | { |
125 | case PROP_PROPAGATION_PHASE: |
126 | gtk_event_controller_set_propagation_phase (controller: self, |
127 | phase: g_value_get_enum (value)); |
128 | break; |
129 | case PROP_PROPAGATION_LIMIT: |
130 | gtk_event_controller_set_propagation_limit (controller: self, |
131 | limit: g_value_get_enum (value)); |
132 | break; |
133 | case PROP_NAME: |
134 | g_free (mem: priv->name); |
135 | priv->name = g_value_dup_string (value); |
136 | break; |
137 | |
138 | default: |
139 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
140 | } |
141 | } |
142 | |
143 | static void |
144 | gtk_event_controller_get_property (GObject *object, |
145 | guint prop_id, |
146 | GValue *value, |
147 | GParamSpec *pspec) |
148 | { |
149 | GtkEventController *self = GTK_EVENT_CONTROLLER (object); |
150 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self); |
151 | |
152 | switch (prop_id) |
153 | { |
154 | case PROP_WIDGET: |
155 | g_value_set_object (value, v_object: priv->widget); |
156 | break; |
157 | case PROP_PROPAGATION_PHASE: |
158 | g_value_set_enum (value, v_enum: priv->phase); |
159 | break; |
160 | case PROP_PROPAGATION_LIMIT: |
161 | g_value_set_enum (value, v_enum: priv->limit); |
162 | break; |
163 | case PROP_NAME: |
164 | g_value_set_string (value, v_string: priv->name); |
165 | break; |
166 | default: |
167 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
168 | } |
169 | } |
170 | |
171 | static void |
172 | gtk_event_controller_finalize (GObject *object) |
173 | { |
174 | GtkEventController *self = GTK_EVENT_CONTROLLER (object); |
175 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self); |
176 | |
177 | g_free (mem: priv->name); |
178 | |
179 | G_OBJECT_CLASS (gtk_event_controller_parent_class)->finalize (object); |
180 | } |
181 | |
182 | static void |
183 | gtk_event_controller_class_init (GtkEventControllerClass *klass) |
184 | { |
185 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
186 | |
187 | klass->set_widget = gtk_event_controller_set_widget; |
188 | klass->unset_widget = gtk_event_controller_unset_widget; |
189 | klass->filter_event = gtk_event_controller_filter_event_default; |
190 | klass->handle_event = gtk_event_controller_handle_event_default; |
191 | klass->handle_crossing = gtk_event_controller_handle_crossing_default; |
192 | |
193 | object_class->finalize = gtk_event_controller_finalize; |
194 | object_class->set_property = gtk_event_controller_set_property; |
195 | object_class->get_property = gtk_event_controller_get_property; |
196 | |
197 | /** |
198 | * GtkEventController:widget: (attributes org.gtk.Property.get=gtk_event_controller_get_widget) |
199 | * |
200 | * The widget receiving the `GdkEvents` that the controller will handle. |
201 | */ |
202 | properties[PROP_WIDGET] = |
203 | g_param_spec_object (name: "widget" , |
204 | P_("Widget" ), |
205 | P_("Widget the gesture relates to" ), |
206 | GTK_TYPE_WIDGET, |
207 | GTK_PARAM_READABLE); |
208 | |
209 | /** |
210 | * GtkEventController:propagation-phase: (attributes org.gtk.Property.get=gtk_event_controller_get_propagation_phase org.gtk.Property.set=gtk_event_controller_set_propagation_phase) |
211 | * |
212 | * The propagation phase at which this controller will handle events. |
213 | */ |
214 | properties[PROP_PROPAGATION_PHASE] = |
215 | g_param_spec_enum (name: "propagation-phase" , |
216 | P_("Propagation phase" ), |
217 | P_("Propagation phase at which this controller is run" ), |
218 | enum_type: GTK_TYPE_PROPAGATION_PHASE, |
219 | default_value: GTK_PHASE_BUBBLE, |
220 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); |
221 | |
222 | /** |
223 | * GtkEventController:propagation-limit: (attributes org.gtk.Property.get=gtk_event_controller_get_propagation_limit org.gtk.Property.set=gtk_event_controller_set_propagation_limit) |
224 | * |
225 | * The limit for which events this controller will handle. |
226 | */ |
227 | properties[PROP_PROPAGATION_LIMIT] = |
228 | g_param_spec_enum (name: "propagation-limit" , |
229 | P_("Propagation limit" ), |
230 | P_("Propagation limit for events handled by this controller" ), |
231 | enum_type: GTK_TYPE_PROPAGATION_LIMIT, |
232 | default_value: GTK_LIMIT_SAME_NATIVE, |
233 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); |
234 | |
235 | /** |
236 | * GtkEventController:name: (attributes org.gtk.Property.get=gtk_event_controller_get_name org.gtk.Property.set=gtk_event_controller_set_name) |
237 | * |
238 | * The name for this controller, typically used for debugging purposes. |
239 | */ |
240 | properties[PROP_NAME] = |
241 | g_param_spec_string (name: "name" , |
242 | P_("Name" ), |
243 | P_("Name for this controller" ), |
244 | NULL, |
245 | GTK_PARAM_READWRITE); |
246 | |
247 | g_object_class_install_properties (oclass: object_class, n_pspecs: LAST_PROP, pspecs: properties); |
248 | } |
249 | |
250 | static void |
251 | gtk_event_controller_init (GtkEventController *controller) |
252 | { |
253 | GtkEventControllerPrivate *priv; |
254 | |
255 | priv = gtk_event_controller_get_instance_private (self: controller); |
256 | priv->phase = GTK_PHASE_BUBBLE; |
257 | priv->limit = GTK_LIMIT_SAME_NATIVE; |
258 | } |
259 | |
260 | static gboolean |
261 | same_native (GtkWidget *widget, |
262 | GtkWidget *target) |
263 | { |
264 | GtkNative *native; |
265 | GtkNative *native2; |
266 | |
267 | if (!widget || !target) |
268 | return TRUE; |
269 | |
270 | native = gtk_widget_get_native (widget); |
271 | native2 = gtk_widget_get_native (widget: target); |
272 | |
273 | return native == native2; |
274 | } |
275 | |
276 | static gboolean |
277 | gtk_event_controller_filter_event (GtkEventController *controller, |
278 | GdkEvent *event, |
279 | GtkWidget *target) |
280 | { |
281 | GtkEventControllerPrivate *priv; |
282 | GtkEventControllerClass *controller_class; |
283 | |
284 | priv = gtk_event_controller_get_instance_private (self: controller); |
285 | |
286 | if (priv->widget && !gtk_widget_is_sensitive (widget: priv->widget)) |
287 | return TRUE; |
288 | |
289 | if (priv->limit == GTK_LIMIT_SAME_NATIVE && |
290 | !same_native (widget: priv->widget, target)) |
291 | return TRUE; |
292 | |
293 | controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); |
294 | |
295 | return controller_class->filter_event (controller, event); |
296 | } |
297 | |
298 | static gboolean |
299 | gtk_event_controller_filter_crossing (GtkEventController *controller, |
300 | const GtkCrossingData *data) |
301 | { |
302 | GtkEventControllerPrivate *priv; |
303 | GtkWidget *old_target, *new_target; |
304 | |
305 | priv = gtk_event_controller_get_instance_private (self: controller); |
306 | |
307 | if (priv->widget && !gtk_widget_is_sensitive (widget: priv->widget)) |
308 | return TRUE; |
309 | |
310 | old_target = data->old_target; |
311 | new_target = data->new_target; |
312 | |
313 | if (priv->limit == GTK_LIMIT_SAME_NATIVE) |
314 | { |
315 | /* treat out-of-scope targets like NULL */ |
316 | |
317 | if (!same_native (widget: priv->widget, target: old_target)) |
318 | old_target = NULL; |
319 | |
320 | if (!same_native (widget: priv->widget, target: new_target)) |
321 | new_target = NULL; |
322 | } |
323 | |
324 | if (old_target == NULL && new_target == NULL) |
325 | return TRUE; |
326 | |
327 | return FALSE; |
328 | } |
329 | |
330 | /*< private > |
331 | * gtk_event_controller_handle_event: |
332 | * @controller: a `GtkEventController` |
333 | * @event: a `GdkEvent` |
334 | * @target: the target widget |
335 | * @x: event position in widget coordinates, or 0 if not a pointer event |
336 | * @y: event position in widget coordinates, or 0 if not a pointer event |
337 | * |
338 | * Feeds an event into @controller, so it can be interpreted |
339 | * and the controller actions triggered. |
340 | * |
341 | * Returns: %TRUE if the event was potentially useful to trigger the |
342 | * controller action |
343 | */ |
344 | gboolean |
345 | gtk_event_controller_handle_event (GtkEventController *controller, |
346 | GdkEvent *event, |
347 | GtkWidget *target, |
348 | double x, |
349 | double y) |
350 | { |
351 | GtkEventControllerClass *controller_class; |
352 | GtkEventControllerPrivate *priv; |
353 | gboolean retval = FALSE; |
354 | |
355 | priv = gtk_event_controller_get_instance_private (self: controller); |
356 | |
357 | g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), FALSE); |
358 | g_return_val_if_fail (event != NULL, FALSE); |
359 | |
360 | if (gtk_event_controller_filter_event (controller, event, target)) |
361 | return retval; |
362 | |
363 | controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); |
364 | |
365 | priv->target = g_object_ref (target); |
366 | priv->event = gdk_event_ref (event); |
367 | |
368 | g_object_ref (controller); |
369 | retval = controller_class->handle_event (controller, event, x, y); |
370 | |
371 | g_clear_object (&priv->target); |
372 | g_clear_pointer (&priv->event, gdk_event_unref); |
373 | g_object_unref (object: controller); |
374 | |
375 | return retval; |
376 | } |
377 | |
378 | /*< private > |
379 | * gtk_event_controller_handle_crossing: |
380 | * @controller: a `GtkEventController` |
381 | * @crossing: a `GtkCrossingData` |
382 | * @x: translated event coordinates |
383 | * @y: translated event coordinates |
384 | * |
385 | * Feeds a crossing event into @controller, so it can be interpreted |
386 | * and the controller actions triggered. |
387 | */ |
388 | void |
389 | gtk_event_controller_handle_crossing (GtkEventController *controller, |
390 | const GtkCrossingData *crossing, |
391 | double x, |
392 | double y) |
393 | { |
394 | GtkEventControllerClass *controller_class; |
395 | |
396 | g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller)); |
397 | g_return_if_fail (crossing != NULL); |
398 | |
399 | if (gtk_event_controller_filter_crossing (controller, data: crossing)) |
400 | return; |
401 | |
402 | controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); |
403 | |
404 | g_object_ref (controller); |
405 | controller_class->handle_crossing (controller, crossing, x, y); |
406 | g_object_unref (object: controller); |
407 | } |
408 | |
409 | /** |
410 | * gtk_event_controller_get_widget: (attributes org.gtk.Method.get_property=widget) |
411 | * @controller: a `GtkEventController` |
412 | * |
413 | * Returns the `GtkWidget` this controller relates to. |
414 | * |
415 | * Returns: (transfer none): a `GtkWidget` |
416 | **/ |
417 | GtkWidget * |
418 | gtk_event_controller_get_widget (GtkEventController *controller) |
419 | { |
420 | GtkEventControllerPrivate *priv; |
421 | |
422 | g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), 0); |
423 | |
424 | priv = gtk_event_controller_get_instance_private (self: controller); |
425 | |
426 | return priv->widget; |
427 | } |
428 | |
429 | /** |
430 | * gtk_event_controller_reset: |
431 | * @controller: a `GtkEventController` |
432 | * |
433 | * Resets the @controller to a clean state. |
434 | */ |
435 | void |
436 | gtk_event_controller_reset (GtkEventController *controller) |
437 | { |
438 | GtkEventControllerClass *controller_class; |
439 | |
440 | g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller)); |
441 | |
442 | controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); |
443 | |
444 | if (controller_class->reset) |
445 | controller_class->reset (controller); |
446 | } |
447 | |
448 | /** |
449 | * gtk_event_controller_get_propagation_phase: (attributes org.gtk.Method.get_property=propagation-phase) |
450 | * @controller: a `GtkEventController` |
451 | * |
452 | * Gets the propagation phase at which @controller handles events. |
453 | * |
454 | * Returns: the propagation phase |
455 | */ |
456 | GtkPropagationPhase |
457 | gtk_event_controller_get_propagation_phase (GtkEventController *controller) |
458 | { |
459 | GtkEventControllerPrivate *priv; |
460 | |
461 | g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), GTK_PHASE_NONE); |
462 | |
463 | priv = gtk_event_controller_get_instance_private (self: controller); |
464 | |
465 | return priv->phase; |
466 | } |
467 | |
468 | /** |
469 | * gtk_event_controller_set_propagation_phase: (attributes org.gtk.Method.set_property=propagation-phase) |
470 | * @controller: a `GtkEventController` |
471 | * @phase: a propagation phase |
472 | * |
473 | * Sets the propagation phase at which a controller handles events. |
474 | * |
475 | * If @phase is %GTK_PHASE_NONE, no automatic event handling will be |
476 | * performed, but other additional gesture maintenance will. |
477 | */ |
478 | void |
479 | gtk_event_controller_set_propagation_phase (GtkEventController *controller, |
480 | GtkPropagationPhase phase) |
481 | { |
482 | GtkEventControllerPrivate *priv; |
483 | |
484 | g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller)); |
485 | g_return_if_fail (phase >= GTK_PHASE_NONE && phase <= GTK_PHASE_TARGET); |
486 | |
487 | priv = gtk_event_controller_get_instance_private (self: controller); |
488 | |
489 | if (priv->phase == phase) |
490 | return; |
491 | |
492 | priv->phase = phase; |
493 | |
494 | if (phase == GTK_PHASE_NONE) |
495 | gtk_event_controller_reset (controller); |
496 | |
497 | g_object_notify_by_pspec (G_OBJECT (controller), pspec: properties[PROP_PROPAGATION_PHASE]); |
498 | } |
499 | |
500 | /** |
501 | * gtk_event_controller_get_propagation_limit: (attributes org.gtk.Method.get_property=propagation-limit) |
502 | * @controller: a `GtkEventController` |
503 | * |
504 | * Gets the propagation limit of the event controller. |
505 | * |
506 | * Returns: the propagation limit |
507 | */ |
508 | GtkPropagationLimit |
509 | gtk_event_controller_get_propagation_limit (GtkEventController *controller) |
510 | { |
511 | GtkEventControllerPrivate *priv; |
512 | |
513 | g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), GTK_LIMIT_SAME_NATIVE); |
514 | |
515 | priv = gtk_event_controller_get_instance_private (self: controller); |
516 | |
517 | return priv->limit; |
518 | } |
519 | |
520 | /** |
521 | * gtk_event_controller_set_propagation_limit: (attributes org.gtk.Method.set_property=propagation-limit) |
522 | * @controller: a `GtkEventController` |
523 | * @limit: the propagation limit |
524 | * |
525 | * Sets the event propagation limit on the event controller. |
526 | * |
527 | * If the limit is set to %GTK_LIMIT_SAME_NATIVE, the controller |
528 | * won't handle events that are targeted at widgets on a different |
529 | * surface, such as popovers. |
530 | */ |
531 | void |
532 | gtk_event_controller_set_propagation_limit (GtkEventController *controller, |
533 | GtkPropagationLimit limit) |
534 | { |
535 | GtkEventControllerPrivate *priv; |
536 | |
537 | g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller)); |
538 | |
539 | priv = gtk_event_controller_get_instance_private (self: controller); |
540 | |
541 | if (priv->limit == limit) |
542 | return; |
543 | |
544 | priv->limit = limit; |
545 | |
546 | g_object_notify_by_pspec (G_OBJECT (controller), pspec: properties[PROP_PROPAGATION_LIMIT]); |
547 | } |
548 | |
549 | /** |
550 | * gtk_event_controller_get_name: (attributes org.gtk.Method.get_property=name) |
551 | * @controller: a `GtkEventController` |
552 | * |
553 | * Gets the name of @controller. |
554 | * |
555 | * Returns: (nullable): The controller name |
556 | */ |
557 | const char * |
558 | gtk_event_controller_get_name (GtkEventController *controller) |
559 | { |
560 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self: controller); |
561 | |
562 | g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), NULL); |
563 | |
564 | return priv->name; |
565 | } |
566 | |
567 | /** |
568 | * gtk_event_controller_set_name: (attributes org.gtk.Method.set_property=name) |
569 | * @controller: a `GtkEventController` |
570 | * @name: (nullable): a name for @controller |
571 | * |
572 | * Sets a name on the controller that can be used for debugging. |
573 | */ |
574 | void |
575 | gtk_event_controller_set_name (GtkEventController *controller, |
576 | const char *name) |
577 | { |
578 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self: controller); |
579 | |
580 | g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller)); |
581 | |
582 | g_free (mem: priv->name); |
583 | priv->name = g_strdup (str: name); |
584 | } |
585 | |
586 | GtkWidget * |
587 | gtk_event_controller_get_target (GtkEventController *controller) |
588 | { |
589 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self: controller); |
590 | |
591 | return priv->target; |
592 | } |
593 | |
594 | /** |
595 | * gtk_event_controller_get_current_event: |
596 | * @controller: a `GtkEventController` |
597 | * |
598 | * Returns the event that is currently being handled by the controller. |
599 | * |
600 | * At other times, %NULL is returned. |
601 | * |
602 | * Returns: (nullable) (transfer none): the event that is currently |
603 | * handled by @controller |
604 | */ |
605 | GdkEvent * |
606 | gtk_event_controller_get_current_event (GtkEventController *controller) |
607 | { |
608 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self: controller); |
609 | |
610 | return priv->event; |
611 | } |
612 | |
613 | /** |
614 | * gtk_event_controller_get_current_event_time: |
615 | * @controller: a `GtkEventController` |
616 | * |
617 | * Returns the timestamp of the event that is currently being |
618 | * handled by the controller. |
619 | * |
620 | * At other times, 0 is returned. |
621 | * |
622 | * Returns: timestamp of the event is currently handled by @controller |
623 | */ |
624 | guint32 |
625 | gtk_event_controller_get_current_event_time (GtkEventController *controller) |
626 | { |
627 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self: controller); |
628 | |
629 | if (priv->event) |
630 | return gdk_event_get_time (event: priv->event); |
631 | |
632 | return 0; |
633 | } |
634 | |
635 | /** |
636 | * gtk_event_controller_get_current_event_device: |
637 | * @controller: a `GtkEventController` |
638 | * |
639 | * Returns the device of the event that is currently being |
640 | * handled by the controller. |
641 | * |
642 | * At other times, %NULL is returned. |
643 | * |
644 | * Returns: (nullable) (transfer none): device of the event is |
645 | * currently handled by @controller |
646 | */ |
647 | GdkDevice * |
648 | gtk_event_controller_get_current_event_device (GtkEventController *controller) |
649 | { |
650 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self: controller); |
651 | |
652 | if (priv->event) |
653 | return gdk_event_get_device (event: priv->event); |
654 | |
655 | return NULL; |
656 | } |
657 | |
658 | /** |
659 | * gtk_event_controller_get_current_event_state: |
660 | * @controller: a `GtkEventController` |
661 | * |
662 | * Returns the modifier state of the event that is currently being |
663 | * handled by the controller. |
664 | * |
665 | * At other times, 0 is returned. |
666 | * |
667 | * Returns: modifier state of the event is currently handled by @controller |
668 | */ |
669 | GdkModifierType |
670 | gtk_event_controller_get_current_event_state (GtkEventController *controller) |
671 | { |
672 | GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self: controller); |
673 | |
674 | if (priv->event) |
675 | return gdk_event_get_modifier_state (event: priv->event); |
676 | |
677 | return 0; |
678 | } |
679 | |