[libhandy] swipe-tracker: Special case dragging from buttons
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libhandy] swipe-tracker: Special case dragging from buttons
- Date: Fri, 25 Sep 2020 14:10:04 +0000 (UTC)
commit 52eabe10f52a53794a90921baa78792f99c304a9
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Wed Sep 23 13:29:02 2020 +0500
swipe-tracker: Special case dragging from buttons
Fixes https://source.puri.sm/Librem5/phosh/-/issues/373
src/hdy-swipe-tracker.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 2 deletions(-)
---
diff --git a/src/hdy-swipe-tracker.c b/src/hdy-swipe-tracker.c
index 0cbf4a44..5b1fc3e9 100644
--- a/src/hdy-swipe-tracker.c
+++ b/src/hdy-swipe-tracker.c
@@ -59,6 +59,7 @@ struct _HdySwipeTracker
gint start_x;
gint start_y;
+ gboolean use_capture_phase;
guint32 prev_time;
gdouble velocity;
@@ -113,6 +114,7 @@ reset (HdySwipeTracker *self)
self->start_x = 0;
self->start_y = 0;
+ self->use_capture_phase = FALSE;
self->prev_time = 0;
self->velocity = 0;
@@ -541,6 +543,27 @@ is_window_handle (GtkWidget *widget)
return parent == titlebar;
}
+/* HACK: Since we don't have _gtk_widget_consumes_motion(), we can't do a proper
+ * check for whether we can drag from a widget or not. So we trust the widgets
+ * to propagate or stop their events. However, GtkButton stops press events,
+ * making it impossible to drag from it.
+ */
+static gboolean
+should_force_drag (HdySwipeTracker *self,
+ GtkWidget *widget)
+{
+ GtkWidget *parent;
+
+ if (!GTK_IS_BUTTON (widget))
+ return FALSE;
+
+ parent = widget;
+ while (parent && !HDY_IS_SWIPEABLE (parent))
+ parent = gtk_widget_get_parent (parent);
+
+ return parent == GTK_WIDGET (self->swipeable);
+}
+
static gboolean
handle_event_cb (HdySwipeTracker *self,
GdkEvent *event)
@@ -553,6 +576,9 @@ handle_event_cb (HdySwipeTracker *self,
if (!self->enabled && self->state != HDY_SWIPE_TRACKER_STATE_SCROLLING)
return GDK_EVENT_PROPAGATE;
+ if (self->use_capture_phase)
+ return GDK_EVENT_PROPAGATE;
+
if (event->type == GDK_SCROLL)
return handle_scroll_event (self, event, FALSE);
@@ -592,16 +618,52 @@ captured_event_cb (HdySwipeable *swipeable,
GdkEvent *event)
{
HdySwipeTracker *self = hdy_swipeable_get_swipe_tracker (swipeable);
+ GtkWidget *widget;
+ GdkEventSequence *sequence;
+ gboolean retval;
+ GtkEventSequenceState state;
g_assert (HDY_IS_SWIPE_TRACKER (self));
if (!self->enabled && self->state != HDY_SWIPE_TRACKER_STATE_SCROLLING)
return GDK_EVENT_PROPAGATE;
- if (event->type != GDK_SCROLL)
+ if (event->type == GDK_SCROLL)
+ return handle_scroll_event (self, event, TRUE);
+
+ if (event->type != GDK_BUTTON_PRESS &&
+ event->type != GDK_BUTTON_RELEASE &&
+ event->type != GDK_MOTION_NOTIFY &&
+ event->type != GDK_TOUCH_BEGIN &&
+ event->type != GDK_TOUCH_END &&
+ event->type != GDK_TOUCH_UPDATE &&
+ event->type != GDK_TOUCH_CANCEL)
+ return GDK_EVENT_PROPAGATE;
+
+ widget = gtk_get_event_widget (event);
+
+ if (!self->use_capture_phase && !should_force_drag (self, widget))
+ return GDK_EVENT_PROPAGATE;
+
+ self->use_capture_phase = TRUE;
+
+ sequence = gdk_event_get_event_sequence (event);
+ retval = gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (self->touch_gesture), event);
+ state = gtk_gesture_get_sequence_state (self->touch_gesture, sequence);
+
+ if (state == GTK_EVENT_SEQUENCE_DENIED) {
+ gtk_event_controller_reset (GTK_EVENT_CONTROLLER (self->touch_gesture));
return GDK_EVENT_PROPAGATE;
+ }
+
+ if (self->state == HDY_SWIPE_TRACKER_STATE_SCROLLING) {
+ return GDK_EVENT_STOP;
+ } else if (self->state == HDY_SWIPE_TRACKER_STATE_FINISHING) {
+ reset (self);
+ return GDK_EVENT_STOP;
+ }
- return handle_scroll_event (self, event, TRUE);
+ return retval;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]