1 From 026f9bc1846eae8fa98a307975fedce1f61d9cd5 Mon Sep 17 00:00:00 2001
2 From: Kristian Rietveld <kris@lanedo.com>
3 Date: Fri, 28 Sep 2012 08:24:05 +0200
4 Subject: [PATCH 19/68] Add hack to lock flow of scroll events to window where
7 A bit evil but there is probably no other way, because this is very
8 different from GDK's usual behavior.
10 There's one quirk left, if you start a scroll and move to another GTK+
11 window in the same process and click, the click won't be processed until
12 the folow of momentum events has ended.
14 gdk/gdkwindow.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 1 file changed, 94 insertions(+)
17 diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
18 index 1843873..1dac543 100644
21 @@ -434,6 +434,10 @@ accumulate_get_window (GSignalInvocationHint *ihint,
24 static GQuark quark_pointer_window = 0;
25 +#ifdef GDK_WINDOWING_QUARTZ
26 +static GQuark quark_last_scroll_pointer_window = 0;
27 +static GQuark quark_last_scroll_event_window = 0;
28 +#endif /* GDK_WINDOWING_QUARTZ */
31 gdk_window_class_init (GdkWindowObjectClass *klass)
32 @@ -478,6 +482,12 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
33 drawable_class->get_source_drawable = gdk_window_get_source_drawable;
35 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
36 +#ifdef GDK_WINDOWING_QUARTZ
37 + quark_last_scroll_pointer_window =
38 + g_quark_from_static_string ("gtk-last-scroll-pointer-window");
39 + quark_last_scroll_event_window =
40 + g_quark_from_static_string ("gtk-last-scroll-event-window");
41 +#endif /* GDK_WINDOWING_QUARTZ */
45 @@ -10702,6 +10712,64 @@ proxy_pointer_event (GdkDisplay *display,
49 +#ifdef GDK_WINDOWING_QUARTZ
51 +last_scroll_event_weak_ref_notify (gpointer data,
52 + GObject *where_the_object_was)
54 + /* If any of pointer_window or event_window is destroyed, we unset
55 + * both values in the display's qdata.
57 + GdkDisplay *display = data;
59 + g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
61 + g_object_set_qdata (G_OBJECT (display), quark_last_scroll_event_window,
66 +set_last_scroll_event_windows (GdkDisplay *display,
67 + GdkWindow *pointer_window,
68 + GdkWindow *event_window)
70 + GdkWindow *old_window;
72 + /* Check whether the values are still set from a previous scroll,
73 + * if so we need to release the weak references. (If they are no
74 + * longer set, we assume the weak ref notify callback was called).
76 + old_window = g_object_get_qdata (G_OBJECT (display),
77 + quark_last_scroll_pointer_window);
79 + g_object_weak_unref (G_OBJECT (old_window),
80 + last_scroll_event_weak_ref_notify, display);
82 + old_window = g_object_get_qdata (G_OBJECT (display),
83 + quark_last_scroll_event_window);
85 + g_object_weak_unref (G_OBJECT (old_window),
86 + last_scroll_event_weak_ref_notify, display);
88 + /* Set new values and setup weak references. Note that pointer_window
89 + * and event_window can be NULL, in which case GDK won't proxy the
90 + * event. In this case we store NULL into the qdata so that we won't
91 + * store the scroll event.
93 + g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
96 + g_object_weak_ref (G_OBJECT (pointer_window),
97 + last_scroll_event_weak_ref_notify, display);
99 + g_object_set_qdata (G_OBJECT (display), quark_last_scroll_event_window,
102 + g_object_weak_ref (G_OBJECT (event_window),
103 + last_scroll_event_weak_ref_notify, display);
105 +#endif /* GDK_WINDOWING_QUARTZ */
108 proxy_button_event (GdkEvent *source_event,
110 @@ -10769,6 +10837,32 @@ proxy_button_event (GdkEvent *source_event,
114 +#ifdef GDK_WINDOWING_QUARTZ
115 + /* A Quartz-specific hack we cannot handle from within the backend
116 + * unfortunately. For scroll events with precise deltas (i.e. these
117 + * generated by the Mac touchpad or Magic Mouse, we want to lock the
118 + * flow of events belonging to a single gesture to the window the
119 + * gesture was started on. The default behavior of GDK, which insists
120 + * to send events to the window under the pointer or discard the
121 + * events when there's no GDK window under the pointer, makes it
122 + * impossible to implement this differently.
124 + if (type == GDK_SCROLL && source_event->scroll.has_deltas)
126 + if (source_event->scroll.phase == GDK_EVENT_SCROLL_PHASE_START)
128 + set_last_scroll_event_windows (display, pointer_window, event_win);
132 + pointer_window = g_object_get_qdata (G_OBJECT (display),
133 + quark_last_scroll_pointer_window);
134 + event_win = g_object_get_qdata (G_OBJECT (display),
135 + quark_last_scroll_event_window);
138 +#endif /* GDK_WINDOWING_QUARTZ */
140 if (event_win == NULL || display->ignore_core_events)
144 1.7.10.2 (Apple Git-33)