6bdd276d05
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
145 lines
5.4 KiB
Diff
145 lines
5.4 KiB
Diff
From 026f9bc1846eae8fa98a307975fedce1f61d9cd5 Mon Sep 17 00:00:00 2001
|
|
From: Kristian Rietveld <kris@lanedo.com>
|
|
Date: Fri, 28 Sep 2012 08:24:05 +0200
|
|
Subject: [PATCH 19/68] Add hack to lock flow of scroll events to window where
|
|
scroll started
|
|
|
|
A bit evil but there is probably no other way, because this is very
|
|
different from GDK's usual behavior.
|
|
|
|
There's one quirk left, if you start a scroll and move to another GTK+
|
|
window in the same process and click, the click won't be processed until
|
|
the folow of momentum events has ended.
|
|
---
|
|
gdk/gdkwindow.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 94 insertions(+)
|
|
|
|
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
|
|
index 1843873..1dac543 100644
|
|
--- a/gdk/gdkwindow.c
|
|
+++ b/gdk/gdkwindow.c
|
|
@@ -434,6 +434,10 @@ accumulate_get_window (GSignalInvocationHint *ihint,
|
|
}
|
|
|
|
static GQuark quark_pointer_window = 0;
|
|
+#ifdef GDK_WINDOWING_QUARTZ
|
|
+static GQuark quark_last_scroll_pointer_window = 0;
|
|
+static GQuark quark_last_scroll_event_window = 0;
|
|
+#endif /* GDK_WINDOWING_QUARTZ */
|
|
|
|
static void
|
|
gdk_window_class_init (GdkWindowObjectClass *klass)
|
|
@@ -478,6 +482,12 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
|
|
drawable_class->get_source_drawable = gdk_window_get_source_drawable;
|
|
|
|
quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
|
|
+#ifdef GDK_WINDOWING_QUARTZ
|
|
+ quark_last_scroll_pointer_window =
|
|
+ g_quark_from_static_string ("gtk-last-scroll-pointer-window");
|
|
+ quark_last_scroll_event_window =
|
|
+ g_quark_from_static_string ("gtk-last-scroll-event-window");
|
|
+#endif /* GDK_WINDOWING_QUARTZ */
|
|
|
|
|
|
/* Properties */
|
|
@@ -10702,6 +10712,64 @@ proxy_pointer_event (GdkDisplay *display,
|
|
GDK_BUTTON4_MASK | \
|
|
GDK_BUTTON5_MASK)
|
|
|
|
+#ifdef GDK_WINDOWING_QUARTZ
|
|
+static void
|
|
+last_scroll_event_weak_ref_notify (gpointer data,
|
|
+ GObject *where_the_object_was)
|
|
+{
|
|
+ /* If any of pointer_window or event_window is destroyed, we unset
|
|
+ * both values in the display's qdata.
|
|
+ */
|
|
+ GdkDisplay *display = data;
|
|
+
|
|
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
|
|
+ NULL);
|
|
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_event_window,
|
|
+ NULL);
|
|
+}
|
|
+
|
|
+static void
|
|
+set_last_scroll_event_windows (GdkDisplay *display,
|
|
+ GdkWindow *pointer_window,
|
|
+ GdkWindow *event_window)
|
|
+{
|
|
+ GdkWindow *old_window;
|
|
+
|
|
+ /* Check whether the values are still set from a previous scroll,
|
|
+ * if so we need to release the weak references. (If they are no
|
|
+ * longer set, we assume the weak ref notify callback was called).
|
|
+ */
|
|
+ old_window = g_object_get_qdata (G_OBJECT (display),
|
|
+ quark_last_scroll_pointer_window);
|
|
+ if (old_window)
|
|
+ g_object_weak_unref (G_OBJECT (old_window),
|
|
+ last_scroll_event_weak_ref_notify, display);
|
|
+
|
|
+ old_window = g_object_get_qdata (G_OBJECT (display),
|
|
+ quark_last_scroll_event_window);
|
|
+ if (old_window)
|
|
+ g_object_weak_unref (G_OBJECT (old_window),
|
|
+ last_scroll_event_weak_ref_notify, display);
|
|
+
|
|
+ /* Set new values and setup weak references. Note that pointer_window
|
|
+ * and event_window can be NULL, in which case GDK won't proxy the
|
|
+ * event. In this case we store NULL into the qdata so that we won't
|
|
+ * store the scroll event.
|
|
+ */
|
|
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
|
|
+ pointer_window);
|
|
+ if (pointer_window)
|
|
+ g_object_weak_ref (G_OBJECT (pointer_window),
|
|
+ last_scroll_event_weak_ref_notify, display);
|
|
+
|
|
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_event_window,
|
|
+ event_window);
|
|
+ if (event_window)
|
|
+ g_object_weak_ref (G_OBJECT (event_window),
|
|
+ last_scroll_event_weak_ref_notify, display);
|
|
+}
|
|
+#endif /* GDK_WINDOWING_QUARTZ */
|
|
+
|
|
static gboolean
|
|
proxy_button_event (GdkEvent *source_event,
|
|
gulong serial)
|
|
@@ -10769,6 +10837,32 @@ proxy_button_event (GdkEvent *source_event,
|
|
type, state,
|
|
NULL, serial);
|
|
|
|
+#ifdef GDK_WINDOWING_QUARTZ
|
|
+ /* A Quartz-specific hack we cannot handle from within the backend
|
|
+ * unfortunately. For scroll events with precise deltas (i.e. these
|
|
+ * generated by the Mac touchpad or Magic Mouse, we want to lock the
|
|
+ * flow of events belonging to a single gesture to the window the
|
|
+ * gesture was started on. The default behavior of GDK, which insists
|
|
+ * to send events to the window under the pointer or discard the
|
|
+ * events when there's no GDK window under the pointer, makes it
|
|
+ * impossible to implement this differently.
|
|
+ */
|
|
+ if (type == GDK_SCROLL && source_event->scroll.has_deltas)
|
|
+ {
|
|
+ if (source_event->scroll.phase == GDK_EVENT_SCROLL_PHASE_START)
|
|
+ {
|
|
+ set_last_scroll_event_windows (display, pointer_window, event_win);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pointer_window = g_object_get_qdata (G_OBJECT (display),
|
|
+ quark_last_scroll_pointer_window);
|
|
+ event_win = g_object_get_qdata (G_OBJECT (display),
|
|
+ quark_last_scroll_event_window);
|
|
+ }
|
|
+ }
|
|
+#endif /* GDK_WINDOWING_QUARTZ */
|
|
+
|
|
if (event_win == NULL || display->ignore_core_events)
|
|
return TRUE;
|
|
|
|
--
|
|
1.7.10.2 (Apple Git-33)
|