Skip to main content

gtk4/auto/
gesture.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4#![allow(deprecated)]
5
6use crate::{EventController, EventSequenceState, ffi};
7use glib::{
8    object::ObjectType as _,
9    prelude::*,
10    signal::{SignalHandlerId, connect_raw},
11    translate::*,
12};
13use std::boxed::Box as Box_;
14
15glib::wrapper! {
16    /// The base class for gesture recognition.
17    ///
18    /// Although [`Gesture`][crate::Gesture] is quite generalized to serve as a base for
19    /// multi-touch gestures, it is suitable to implement single-touch and
20    /// pointer-based gestures (using the special [`None`] [`gdk::EventSequence`][crate::gdk::EventSequence]
21    /// value for these).
22    ///
23    /// The number of touches that a [`Gesture`][crate::Gesture] need to be recognized is
24    /// controlled by the [`n-points`][struct@crate::Gesture#n-points] property, if a
25    /// gesture is keeping track of less or more than that number of sequences,
26    /// it won't check whether the gesture is recognized.
27    ///
28    /// As soon as the gesture has the expected number of touches, it will check
29    /// regularly if it is recognized, the criteria to consider a gesture as
30    /// "recognized" is left to [`Gesture`][crate::Gesture] subclasses.
31    ///
32    /// A recognized gesture will then emit the following signals:
33    ///
34    /// - [`begin`][struct@crate::Gesture#begin] when the gesture is recognized.
35    /// - [`update`][struct@crate::Gesture#update], whenever an input event is processed.
36    /// - [`end`][struct@crate::Gesture#end] when the gesture is no longer recognized.
37    ///
38    /// ## Event propagation
39    ///
40    /// In order to receive events, a gesture needs to set a propagation phase
41    /// through [`EventControllerExt::set_propagation_phase()`][crate::prelude::EventControllerExt::set_propagation_phase()].
42    ///
43    /// In the capture phase, events are propagated from the toplevel down
44    /// to the target widget, and gestures that are attached to containers
45    /// above the widget get a chance to interact with the event before it
46    /// reaches the target.
47    ///
48    /// In the bubble phase, events are propagated up from the target widget
49    /// to the toplevel, and gestures that are attached to containers above
50    /// the widget get a chance to interact with events that have not been
51    /// handled yet.
52    ///
53    /// ## States of a sequence
54    ///
55    /// Whenever input interaction happens, a single event may trigger a cascade
56    /// of [`Gesture`][crate::Gesture]s, both across the parents of the widget receiving the
57    /// event and in parallel within an individual widget. It is a responsibility
58    /// of the widgets using those gestures to set the state of touch sequences
59    /// accordingly in order to enable cooperation of gestures around the
60    /// [`gdk::EventSequence`][crate::gdk::EventSequence]s triggering those.
61    ///
62    /// Within a widget, gestures can be grouped through [`GestureExt::group_with()`][crate::prelude::GestureExt::group_with()].
63    /// Grouped gestures synchronize the state of sequences, so calling
64    /// [`GestureExt::set_state()`][crate::prelude::GestureExt::set_state()] on one will effectively propagate
65    /// the state throughout the group.
66    ///
67    /// By default, all sequences start out in the [`EventSequenceState::None`][crate::EventSequenceState::None] state,
68    /// sequences in this state trigger the gesture event handler, but event
69    /// propagation will continue unstopped by gestures.
70    ///
71    /// If a sequence enters into the [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] state, the gesture
72    /// group will effectively ignore the sequence, letting events go unstopped
73    /// through the gesture, but the "slot" will still remain occupied while
74    /// the touch is active.
75    ///
76    /// If a sequence enters in the [`EventSequenceState::Claimed`][crate::EventSequenceState::Claimed] state, the gesture
77    /// group will grab all interaction on the sequence, by:
78    ///
79    /// - Setting the same sequence to [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] on every other
80    ///   gesture group within the widget, and every gesture on parent widgets
81    ///   in the propagation chain.
82    /// - Emitting [`cancel`][struct@crate::Gesture#cancel] on every gesture in widgets
83    ///   underneath in the propagation chain.
84    /// - Stopping event propagation after the gesture group handles the event.
85    ///
86    /// Note: if a sequence is set early to [`EventSequenceState::Claimed`][crate::EventSequenceState::Claimed] on
87    /// `GDK_TOUCH_BEGIN`/`GDK_BUTTON_PRESS` (so those events are captured before
88    /// reaching the event widget, this implies [`PropagationPhase::Capture`][crate::PropagationPhase::Capture]), one similar
89    /// event will be emulated if the sequence changes to [`EventSequenceState::Denied`][crate::EventSequenceState::Denied].
90    /// This way event coherence is preserved before event propagation is unstopped
91    /// again.
92    ///
93    /// Sequence states can't be changed freely.
94    /// See [`GestureExt::set_state()`][crate::prelude::GestureExt::set_state()] to know about the possible
95    /// lifetimes of a [`gdk::EventSequence`][crate::gdk::EventSequence].
96    ///
97    /// ## Touchpad gestures
98    ///
99    /// On the platforms that support it, [`Gesture`][crate::Gesture] will handle transparently
100    /// touchpad gesture events. The only precautions users of [`Gesture`][crate::Gesture] should
101    /// do to enable this support are:
102    ///
103    /// - If the gesture has [`PropagationPhase::None`][crate::PropagationPhase::None], ensuring events of type
104    ///   `GDK_TOUCHPAD_SWIPE` and `GDK_TOUCHPAD_PINCH` are handled by the [`Gesture`][crate::Gesture]
105    ///
106    /// This is an Abstract Base Class, you cannot instantiate it.
107    ///
108    /// ## Properties
109    ///
110    ///
111    /// #### `n-points`
112    ///  The number of touch points that trigger
113    /// recognition on this gesture.
114    ///
115    /// Readable | Writeable | Construct Only
116    /// <details><summary><h4>EventController</h4></summary>
117    ///
118    ///
119    /// #### `name`
120    ///  The name for this controller, typically used for debugging purposes.
121    ///
122    /// Readable | Writeable
123    ///
124    ///
125    /// #### `propagation-limit`
126    ///  The limit for which events this controller will handle.
127    ///
128    /// Readable | Writeable
129    ///
130    ///
131    /// #### `propagation-phase`
132    ///  The propagation phase at which this controller will handle events.
133    ///
134    /// Readable | Writeable
135    ///
136    ///
137    /// #### `widget`
138    ///  The widget receiving the `GdkEvents` that the controller will handle.
139    ///
140    /// Readable
141    /// </details>
142    ///
143    /// ## Signals
144    ///
145    ///
146    /// #### `begin`
147    ///  Emitted when the gesture is recognized.
148    ///
149    /// This means the number of touch sequences matches
150    /// [`n-points`][struct@crate::Gesture#n-points].
151    ///
152    /// Note: These conditions may also happen when an extra touch
153    /// (eg. a third touch on a 2-touches gesture) is lifted, in that
154    /// situation @sequence won't pertain to the current set of active
155    /// touches, so don't rely on this being true.
156    ///
157    ///
158    ///
159    ///
160    /// #### `cancel`
161    ///  Emitted whenever a sequence is cancelled.
162    ///
163    /// This usually happens on active touches when
164    /// [`EventControllerExt::reset()`][crate::prelude::EventControllerExt::reset()] is called on @gesture
165    /// (manually, due to grabs...), or the individual @sequence
166    /// was claimed by parent widgets' controllers (see
167    /// [`GestureExt::set_sequence_state()`][crate::prelude::GestureExt::set_sequence_state()]).
168    ///
169    /// @gesture must forget everything about @sequence as in
170    /// response to this signal.
171    ///
172    ///
173    ///
174    ///
175    /// #### `end`
176    ///  Emitted when @gesture either stopped recognizing the event
177    /// sequences as something to be handled, or the number of touch
178    /// sequences became higher or lower than [`n-points`][struct@crate::Gesture#n-points].
179    ///
180    /// Note: @sequence might not pertain to the group of sequences that
181    /// were previously triggering recognition on @gesture (ie. a just
182    /// pressed touch sequence that exceeds [`n-points`][struct@crate::Gesture#n-points]).
183    /// This situation may be detected by checking through
184    /// [`GestureExt::handles_sequence()`][crate::prelude::GestureExt::handles_sequence()].
185    ///
186    ///
187    ///
188    ///
189    /// #### `sequence-state-changed`
190    ///  Emitted whenever a sequence state changes.
191    ///
192    /// See [`GestureExt::set_sequence_state()`][crate::prelude::GestureExt::set_sequence_state()] to know
193    /// more about the expectable sequence lifetimes.
194    ///
195    ///
196    ///
197    ///
198    /// #### `update`
199    ///  Emitted whenever an event is handled while the gesture is recognized.
200    ///
201    /// @sequence is guaranteed to pertain to the set of active touches.
202    ///
203    ///
204    ///
205    /// # Implements
206    ///
207    /// [`GestureExt`][trait@crate::prelude::GestureExt], [`EventControllerExt`][trait@crate::prelude::EventControllerExt], [`trait@glib::ObjectExt`], [`EventControllerExtManual`][trait@crate::prelude::EventControllerExtManual]
208    #[doc(alias = "GtkGesture")]
209    pub struct Gesture(Object<ffi::GtkGesture, ffi::GtkGestureClass>) @extends EventController;
210
211    match fn {
212        type_ => || ffi::gtk_gesture_get_type(),
213    }
214}
215
216impl Gesture {
217    pub const NONE: Option<&'static Gesture> = None;
218}
219
220/// Trait containing all [`struct@Gesture`] methods.
221///
222/// # Implementors
223///
224/// [`GestureRotate`][struct@crate::GestureRotate], [`GestureSingle`][struct@crate::GestureSingle], [`GestureZoom`][struct@crate::GestureZoom], [`Gesture`][struct@crate::Gesture]
225pub trait GestureExt: IsA<Gesture> + 'static {
226    /// If there are touch sequences being currently handled by @self,
227    /// returns [`true`] and fills in @rect with the bounding box containing
228    /// all active touches.
229    ///
230    /// Otherwise, [`false`] will be returned.
231    ///
232    /// Note: This function will yield unexpected results on touchpad
233    /// gestures. Since there is no correlation between physical and
234    /// pixel distances, these will look as if constrained in an
235    /// infinitely small area, @rect width and height will thus be 0
236    /// regardless of the number of touchpoints.
237    ///
238    /// # Returns
239    ///
240    /// [`true`] if there are active touches, [`false`] otherwise
241    ///
242    /// ## `rect`
243    /// bounding box containing all active touches.
244    #[doc(alias = "gtk_gesture_get_bounding_box")]
245    #[doc(alias = "get_bounding_box")]
246    fn bounding_box(&self) -> Option<gdk::Rectangle> {
247        unsafe {
248            let mut rect = gdk::Rectangle::uninitialized();
249            let ret = from_glib(ffi::gtk_gesture_get_bounding_box(
250                self.as_ref().to_glib_none().0,
251                rect.to_glib_none_mut().0,
252            ));
253            if ret { Some(rect) } else { None }
254        }
255    }
256
257    /// If there are touch sequences being currently handled by @self,
258    /// returns [`true`] and fills in @x and @y with the center of the bounding
259    /// box containing all active touches.
260    ///
261    /// Otherwise, [`false`] will be returned.
262    ///
263    /// # Returns
264    ///
265    /// [`false`] if no active touches are present, [`true`] otherwise
266    ///
267    /// ## `x`
268    /// X coordinate for the bounding box center
269    ///
270    /// ## `y`
271    /// Y coordinate for the bounding box center
272    #[doc(alias = "gtk_gesture_get_bounding_box_center")]
273    #[doc(alias = "get_bounding_box_center")]
274    fn bounding_box_center(&self) -> Option<(f64, f64)> {
275        unsafe {
276            let mut x = std::mem::MaybeUninit::uninit();
277            let mut y = std::mem::MaybeUninit::uninit();
278            let ret = from_glib(ffi::gtk_gesture_get_bounding_box_center(
279                self.as_ref().to_glib_none().0,
280                x.as_mut_ptr(),
281                y.as_mut_ptr(),
282            ));
283            if ret {
284                Some((x.assume_init(), y.assume_init()))
285            } else {
286                None
287            }
288        }
289    }
290
291    /// Returns the logical [`gdk::Device`][crate::gdk::Device] that is currently operating
292    /// on @self.
293    ///
294    /// This returns [`None`] if the gesture is not being interacted.
295    ///
296    /// # Returns
297    ///
298    /// a [`gdk::Device`][crate::gdk::Device]
299    #[doc(alias = "gtk_gesture_get_device")]
300    #[doc(alias = "get_device")]
301    fn device(&self) -> Option<gdk::Device> {
302        unsafe { from_glib_none(ffi::gtk_gesture_get_device(self.as_ref().to_glib_none().0)) }
303    }
304
305    /// Returns all gestures in the group of @self
306    ///
307    /// # Returns
308    ///
309    /// The list
310    ///   of [`Gesture`][crate::Gesture]s, free with g_list_free()
311    #[doc(alias = "gtk_gesture_get_group")]
312    #[doc(alias = "get_group")]
313    fn group(&self) -> Vec<Gesture> {
314        unsafe {
315            FromGlibPtrContainer::from_glib_container(ffi::gtk_gesture_get_group(
316                self.as_ref().to_glib_none().0,
317            ))
318        }
319    }
320
321    /// Returns the last event that was processed for @sequence.
322    ///
323    /// Note that the returned pointer is only valid as long as the
324    /// @sequence is still interpreted by the @self. If in doubt,
325    /// you should make a copy of the event.
326    /// ## `sequence`
327    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
328    ///
329    /// # Returns
330    ///
331    /// The last event from @sequence
332    #[doc(alias = "gtk_gesture_get_last_event")]
333    #[doc(alias = "get_last_event")]
334    fn last_event(&self, sequence: Option<&gdk::EventSequence>) -> Option<gdk::Event> {
335        unsafe {
336            from_glib_none(ffi::gtk_gesture_get_last_event(
337                self.as_ref().to_glib_none().0,
338                mut_override(sequence.to_glib_none().0),
339            ))
340        }
341    }
342
343    /// Returns the [`gdk::EventSequence`][crate::gdk::EventSequence] that was last updated on @self.
344    ///
345    /// # Returns
346    ///
347    /// The last updated sequence
348    #[doc(alias = "gtk_gesture_get_last_updated_sequence")]
349    #[doc(alias = "get_last_updated_sequence")]
350    fn last_updated_sequence(&self) -> Option<gdk::EventSequence> {
351        unsafe {
352            from_glib_none(ffi::gtk_gesture_get_last_updated_sequence(
353                self.as_ref().to_glib_none().0,
354            ))
355        }
356    }
357
358    /// If @sequence is currently being interpreted by @self,
359    /// returns [`true`] and fills in @x and @y with the last coordinates
360    /// stored for that event sequence.
361    ///
362    /// The coordinates are always relative to the widget allocation.
363    /// ## `sequence`
364    /// a [`gdk::EventSequence`][crate::gdk::EventSequence], or [`None`] for pointer events
365    ///
366    /// # Returns
367    ///
368    /// [`true`] if @sequence is currently interpreted
369    ///
370    /// ## `x`
371    /// return location for X axis of the sequence coordinates
372    ///
373    /// ## `y`
374    /// return location for Y axis of the sequence coordinates
375    #[doc(alias = "gtk_gesture_get_point")]
376    #[doc(alias = "get_point")]
377    fn point(&self, sequence: Option<&gdk::EventSequence>) -> Option<(f64, f64)> {
378        unsafe {
379            let mut x = std::mem::MaybeUninit::uninit();
380            let mut y = std::mem::MaybeUninit::uninit();
381            let ret = from_glib(ffi::gtk_gesture_get_point(
382                self.as_ref().to_glib_none().0,
383                mut_override(sequence.to_glib_none().0),
384                x.as_mut_ptr(),
385                y.as_mut_ptr(),
386            ));
387            if ret {
388                Some((x.assume_init(), y.assume_init()))
389            } else {
390                None
391            }
392        }
393    }
394
395    /// Returns the @sequence state, as seen by @self.
396    /// ## `sequence`
397    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
398    ///
399    /// # Returns
400    ///
401    /// The sequence state in @self
402    #[doc(alias = "gtk_gesture_get_sequence_state")]
403    #[doc(alias = "get_sequence_state")]
404    fn sequence_state(&self, sequence: &gdk::EventSequence) -> EventSequenceState {
405        unsafe {
406            from_glib(ffi::gtk_gesture_get_sequence_state(
407                self.as_ref().to_glib_none().0,
408                mut_override(sequence.to_glib_none().0),
409            ))
410        }
411    }
412
413    /// Returns the list of `GdkEventSequences` currently being interpreted
414    /// by @self.
415    ///
416    /// # Returns
417    ///
418    /// A list
419    ///   of [`gdk::EventSequence`][crate::gdk::EventSequence], the list elements are owned by GTK and must
420    ///   not be freed or modified, the list itself must be deleted
421    ///   through g_list_free()
422    #[doc(alias = "gtk_gesture_get_sequences")]
423    #[doc(alias = "get_sequences")]
424    fn sequences(&self) -> Vec<gdk::EventSequence> {
425        unsafe {
426            FromGlibPtrContainer::from_glib_container(ffi::gtk_gesture_get_sequences(
427                self.as_ref().to_glib_none().0,
428            ))
429        }
430    }
431
432    /// Adds @gesture to the same group than @self.
433    ///
434    /// Gestures are by default isolated in their own groups.
435    ///
436    /// Both gestures must have been added to the same widget before
437    /// they can be grouped.
438    ///
439    /// When gestures are grouped, the state of `GdkEventSequences`
440    /// is kept in sync for all of those, so calling
441    /// [`set_sequence_state()`][Self::set_sequence_state()], on one will transfer
442    /// the same value to the others.
443    ///
444    /// Groups also perform an "implicit grabbing" of sequences, if a
445    /// [`gdk::EventSequence`][crate::gdk::EventSequence] state is set to [`EventSequenceState::Claimed`][crate::EventSequenceState::Claimed]
446    /// on one group, every other gesture group attached to the same
447    /// [`Widget`][crate::Widget] will switch the state for that sequence to
448    /// [`EventSequenceState::Denied`][crate::EventSequenceState::Denied].
449    /// ## `gesture`
450    /// a [`Gesture`][crate::Gesture]
451    #[doc(alias = "gtk_gesture_group")]
452    #[doc(alias = "group")]
453    fn group_with(&self, gesture: &impl IsA<Gesture>) {
454        unsafe {
455            ffi::gtk_gesture_group(
456                self.as_ref().to_glib_none().0,
457                gesture.as_ref().to_glib_none().0,
458            );
459        }
460    }
461
462    /// Returns [`true`] if @self is currently handling events
463    /// corresponding to @sequence.
464    /// ## `sequence`
465    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
466    ///
467    /// # Returns
468    ///
469    /// [`true`] if @self is handling @sequence, [`false`] otherwise
470    #[doc(alias = "gtk_gesture_handles_sequence")]
471    fn handles_sequence(&self, sequence: Option<&gdk::EventSequence>) -> bool {
472        unsafe {
473            from_glib(ffi::gtk_gesture_handles_sequence(
474                self.as_ref().to_glib_none().0,
475                mut_override(sequence.to_glib_none().0),
476            ))
477        }
478    }
479
480    /// Returns [`true`] if the gesture is currently active.
481    ///
482    /// A gesture is active while there are touch sequences
483    /// interacting with it.
484    ///
485    /// # Returns
486    ///
487    /// [`true`] if gesture is active
488    #[doc(alias = "gtk_gesture_is_active")]
489    fn is_active(&self) -> bool {
490        unsafe { from_glib(ffi::gtk_gesture_is_active(self.as_ref().to_glib_none().0)) }
491    }
492
493    /// Returns [`true`] if both gestures pertain to the same group.
494    /// ## `other`
495    /// another [`Gesture`][crate::Gesture]
496    ///
497    /// # Returns
498    ///
499    /// whether the gestures are grouped
500    #[doc(alias = "gtk_gesture_is_grouped_with")]
501    fn is_grouped_with(&self, other: &impl IsA<Gesture>) -> bool {
502        unsafe {
503            from_glib(ffi::gtk_gesture_is_grouped_with(
504                self.as_ref().to_glib_none().0,
505                other.as_ref().to_glib_none().0,
506            ))
507        }
508    }
509
510    /// Returns [`true`] if the gesture is currently recognized.
511    ///
512    /// A gesture is recognized if there are as many interacting
513    /// touch sequences as required by @self.
514    ///
515    /// # Returns
516    ///
517    /// [`true`] if gesture is recognized
518    #[doc(alias = "gtk_gesture_is_recognized")]
519    fn is_recognized(&self) -> bool {
520        unsafe {
521            from_glib(ffi::gtk_gesture_is_recognized(
522                self.as_ref().to_glib_none().0,
523            ))
524        }
525    }
526
527    /// Sets the state of @sequence in @self.
528    ///
529    /// Sequences start in state [`EventSequenceState::None`][crate::EventSequenceState::None], and whenever
530    /// they change state, they can never go back to that state. Likewise,
531    /// sequences in state [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] cannot turn back to
532    /// a not denied state. With these rules, the lifetime of an event
533    /// sequence is constrained to the next four:
534    ///
535    /// * None
536    /// * None → Denied
537    /// * None → Claimed
538    /// * None → Claimed → Denied
539    ///
540    /// Note: Due to event handling ordering, it may be unsafe to set the
541    /// state on another gesture within a [`begin`][struct@crate::Gesture#begin] signal
542    /// handler, as the callback might be executed before the other gesture
543    /// knows about the sequence. A safe way to perform this could be:
544    ///
545    /// **⚠️ The following code is in c ⚠️**
546    ///
547    /// ```c
548    /// static void
549    /// first_gesture_begin_cb (GtkGesture       *first_gesture,
550    ///                         GdkEventSequence *sequence,
551    ///                         gpointer          user_data)
552    /// {
553    ///   gtk_gesture_set_sequence_state (first_gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
554    ///   gtk_gesture_set_sequence_state (second_gesture, sequence, GTK_EVENT_SEQUENCE_DENIED);
555    /// }
556    ///
557    /// static void
558    /// second_gesture_begin_cb (GtkGesture       *second_gesture,
559    ///                          GdkEventSequence *sequence,
560    ///                          gpointer          user_data)
561    /// {
562    ///   if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
563    ///     gtk_gesture_set_sequence_state (second_gesture, sequence, GTK_EVENT_SEQUENCE_DENIED);
564    /// }
565    /// ```
566    ///
567    /// If both gestures are in the same group, just set the state on
568    /// the gesture emitting the event, the sequence will be already
569    /// be initialized to the group's global state when the second
570    /// gesture processes the event.
571    ///
572    /// # Deprecated since 4.10
573    ///
574    /// Use [`set_state()`][Self::set_state()]
575    /// ## `sequence`
576    /// a [`gdk::EventSequence`][crate::gdk::EventSequence]
577    /// ## `state`
578    /// the sequence state
579    ///
580    /// # Returns
581    ///
582    /// [`true`] if @sequence is handled by @self,
583    ///   and the state is changed successfully
584    #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
585    #[allow(deprecated)]
586    #[doc(alias = "gtk_gesture_set_sequence_state")]
587    fn set_sequence_state(&self, sequence: &gdk::EventSequence, state: EventSequenceState) -> bool {
588        unsafe {
589            from_glib(ffi::gtk_gesture_set_sequence_state(
590                self.as_ref().to_glib_none().0,
591                mut_override(sequence.to_glib_none().0),
592                state.into_glib(),
593            ))
594        }
595    }
596
597    /// Sets the state of all sequences that @self is currently
598    /// interacting with.
599    ///
600    /// Sequences start in state [`EventSequenceState::None`][crate::EventSequenceState::None], and whenever
601    /// they change state, they can never go back to that state. Likewise,
602    /// sequences in state [`EventSequenceState::Denied`][crate::EventSequenceState::Denied] cannot turn back to
603    /// a not denied state. With these rules, the lifetime of an event
604    /// sequence is constrained to the next four:
605    ///
606    /// * None
607    /// * None → Denied
608    /// * None → Claimed
609    /// * None → Claimed → Denied
610    ///
611    /// Note: Due to event handling ordering, it may be unsafe to set the
612    /// state on another gesture within a [`begin`][struct@crate::Gesture#begin] signal
613    /// handler, as the callback might be executed before the other gesture
614    /// knows about the sequence. A safe way to perform this could be:
615    ///
616    /// **⚠️ The following code is in c ⚠️**
617    ///
618    /// ```c
619    /// static void
620    /// first_gesture_begin_cb (GtkGesture       *first_gesture,
621    ///                         GdkEventSequence *sequence,
622    ///                         gpointer          user_data)
623    /// {
624    ///   gtk_gesture_set_state (first_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
625    ///   gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
626    /// }
627    ///
628    /// static void
629    /// second_gesture_begin_cb (GtkGesture       *second_gesture,
630    ///                          GdkEventSequence *sequence,
631    ///                          gpointer          user_data)
632    /// {
633    ///   if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
634    ///     gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
635    /// }
636    /// ```
637    ///
638    /// If both gestures are in the same group, just set the state on
639    /// the gesture emitting the event, the sequence will be already
640    /// be initialized to the group's global state when the second
641    /// gesture processes the event.
642    /// ## `state`
643    /// the sequence state
644    ///
645    /// # Returns
646    ///
647    /// [`true`] if the state of at least one sequence
648    ///   was changed successfully
649    #[doc(alias = "gtk_gesture_set_state")]
650    fn set_state(&self, state: EventSequenceState) -> bool {
651        unsafe {
652            from_glib(ffi::gtk_gesture_set_state(
653                self.as_ref().to_glib_none().0,
654                state.into_glib(),
655            ))
656        }
657    }
658
659    /// Separates @self into an isolated group.
660    #[doc(alias = "gtk_gesture_ungroup")]
661    fn ungroup(&self) {
662        unsafe {
663            ffi::gtk_gesture_ungroup(self.as_ref().to_glib_none().0);
664        }
665    }
666
667    /// The number of touch points that trigger
668    /// recognition on this gesture.
669    #[doc(alias = "n-points")]
670    fn n_points(&self) -> u32 {
671        ObjectExt::property(self.as_ref(), "n-points")
672    }
673
674    /// Emitted when the gesture is recognized.
675    ///
676    /// This means the number of touch sequences matches
677    /// [`n-points`][struct@crate::Gesture#n-points].
678    ///
679    /// Note: These conditions may also happen when an extra touch
680    /// (eg. a third touch on a 2-touches gesture) is lifted, in that
681    /// situation @sequence won't pertain to the current set of active
682    /// touches, so don't rely on this being true.
683    /// ## `sequence`
684    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that made the gesture
685    ///   to be recognized
686    #[doc(alias = "begin")]
687    fn connect_begin<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
688        &self,
689        f: F,
690    ) -> SignalHandlerId {
691        unsafe extern "C" fn begin_trampoline<
692            P: IsA<Gesture>,
693            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
694        >(
695            this: *mut ffi::GtkGesture,
696            sequence: *mut gdk::ffi::GdkEventSequence,
697            f: glib::ffi::gpointer,
698        ) {
699            unsafe {
700                let f: &F = &*(f as *const F);
701                f(
702                    Gesture::from_glib_borrow(this).unsafe_cast_ref(),
703                    Option::<gdk::EventSequence>::from_glib_borrow(sequence)
704                        .as_ref()
705                        .as_ref(),
706                )
707            }
708        }
709        unsafe {
710            let f: Box_<F> = Box_::new(f);
711            connect_raw(
712                self.as_ptr() as *mut _,
713                c"begin".as_ptr() as *const _,
714                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
715                    begin_trampoline::<Self, F> as *const (),
716                )),
717                Box_::into_raw(f),
718            )
719        }
720    }
721
722    /// Emitted whenever a sequence is cancelled.
723    ///
724    /// This usually happens on active touches when
725    /// [`EventControllerExt::reset()`][crate::prelude::EventControllerExt::reset()] is called on @gesture
726    /// (manually, due to grabs...), or the individual @sequence
727    /// was claimed by parent widgets' controllers (see
728    /// [`set_sequence_state()`][Self::set_sequence_state()]).
729    ///
730    /// @gesture must forget everything about @sequence as in
731    /// response to this signal.
732    /// ## `sequence`
733    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was cancelled
734    #[doc(alias = "cancel")]
735    fn connect_cancel<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
736        &self,
737        f: F,
738    ) -> SignalHandlerId {
739        unsafe extern "C" fn cancel_trampoline<
740            P: IsA<Gesture>,
741            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
742        >(
743            this: *mut ffi::GtkGesture,
744            sequence: *mut gdk::ffi::GdkEventSequence,
745            f: glib::ffi::gpointer,
746        ) {
747            unsafe {
748                let f: &F = &*(f as *const F);
749                f(
750                    Gesture::from_glib_borrow(this).unsafe_cast_ref(),
751                    Option::<gdk::EventSequence>::from_glib_borrow(sequence)
752                        .as_ref()
753                        .as_ref(),
754                )
755            }
756        }
757        unsafe {
758            let f: Box_<F> = Box_::new(f);
759            connect_raw(
760                self.as_ptr() as *mut _,
761                c"cancel".as_ptr() as *const _,
762                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
763                    cancel_trampoline::<Self, F> as *const (),
764                )),
765                Box_::into_raw(f),
766            )
767        }
768    }
769
770    /// Emitted when @gesture either stopped recognizing the event
771    /// sequences as something to be handled, or the number of touch
772    /// sequences became higher or lower than [`n-points`][struct@crate::Gesture#n-points].
773    ///
774    /// Note: @sequence might not pertain to the group of sequences that
775    /// were previously triggering recognition on @gesture (ie. a just
776    /// pressed touch sequence that exceeds [`n-points`][struct@crate::Gesture#n-points]).
777    /// This situation may be detected by checking through
778    /// [`handles_sequence()`][Self::handles_sequence()].
779    /// ## `sequence`
780    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that made gesture
781    ///   recognition to finish
782    #[doc(alias = "end")]
783    fn connect_end<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
784        &self,
785        f: F,
786    ) -> SignalHandlerId {
787        unsafe extern "C" fn end_trampoline<
788            P: IsA<Gesture>,
789            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
790        >(
791            this: *mut ffi::GtkGesture,
792            sequence: *mut gdk::ffi::GdkEventSequence,
793            f: glib::ffi::gpointer,
794        ) {
795            unsafe {
796                let f: &F = &*(f as *const F);
797                f(
798                    Gesture::from_glib_borrow(this).unsafe_cast_ref(),
799                    Option::<gdk::EventSequence>::from_glib_borrow(sequence)
800                        .as_ref()
801                        .as_ref(),
802                )
803            }
804        }
805        unsafe {
806            let f: Box_<F> = Box_::new(f);
807            connect_raw(
808                self.as_ptr() as *mut _,
809                c"end".as_ptr() as *const _,
810                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
811                    end_trampoline::<Self, F> as *const (),
812                )),
813                Box_::into_raw(f),
814            )
815        }
816    }
817
818    /// Emitted whenever a sequence state changes.
819    ///
820    /// See [`set_sequence_state()`][Self::set_sequence_state()] to know
821    /// more about the expectable sequence lifetimes.
822    /// ## `sequence`
823    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was cancelled
824    /// ## `state`
825    /// the new sequence state
826    #[doc(alias = "sequence-state-changed")]
827    fn connect_sequence_state_changed<
828        F: Fn(&Self, Option<&gdk::EventSequence>, EventSequenceState) + 'static,
829    >(
830        &self,
831        f: F,
832    ) -> SignalHandlerId {
833        unsafe extern "C" fn sequence_state_changed_trampoline<
834            P: IsA<Gesture>,
835            F: Fn(&P, Option<&gdk::EventSequence>, EventSequenceState) + 'static,
836        >(
837            this: *mut ffi::GtkGesture,
838            sequence: *mut gdk::ffi::GdkEventSequence,
839            state: ffi::GtkEventSequenceState,
840            f: glib::ffi::gpointer,
841        ) {
842            unsafe {
843                let f: &F = &*(f as *const F);
844                f(
845                    Gesture::from_glib_borrow(this).unsafe_cast_ref(),
846                    Option::<gdk::EventSequence>::from_glib_borrow(sequence)
847                        .as_ref()
848                        .as_ref(),
849                    from_glib(state),
850                )
851            }
852        }
853        unsafe {
854            let f: Box_<F> = Box_::new(f);
855            connect_raw(
856                self.as_ptr() as *mut _,
857                c"sequence-state-changed".as_ptr() as *const _,
858                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
859                    sequence_state_changed_trampoline::<Self, F> as *const (),
860                )),
861                Box_::into_raw(f),
862            )
863        }
864    }
865
866    /// Emitted whenever an event is handled while the gesture is recognized.
867    ///
868    /// @sequence is guaranteed to pertain to the set of active touches.
869    /// ## `sequence`
870    /// the [`gdk::EventSequence`][crate::gdk::EventSequence] that was updated
871    #[doc(alias = "update")]
872    fn connect_update<F: Fn(&Self, Option<&gdk::EventSequence>) + 'static>(
873        &self,
874        f: F,
875    ) -> SignalHandlerId {
876        unsafe extern "C" fn update_trampoline<
877            P: IsA<Gesture>,
878            F: Fn(&P, Option<&gdk::EventSequence>) + 'static,
879        >(
880            this: *mut ffi::GtkGesture,
881            sequence: *mut gdk::ffi::GdkEventSequence,
882            f: glib::ffi::gpointer,
883        ) {
884            unsafe {
885                let f: &F = &*(f as *const F);
886                f(
887                    Gesture::from_glib_borrow(this).unsafe_cast_ref(),
888                    Option::<gdk::EventSequence>::from_glib_borrow(sequence)
889                        .as_ref()
890                        .as_ref(),
891                )
892            }
893        }
894        unsafe {
895            let f: Box_<F> = Box_::new(f);
896            connect_raw(
897                self.as_ptr() as *mut _,
898                c"update".as_ptr() as *const _,
899                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
900                    update_trampoline::<Self, F> as *const (),
901                )),
902                Box_::into_raw(f),
903            )
904        }
905    }
906}
907
908impl<O: IsA<Gesture>> GestureExt for O {}