Fix 'mono' package typo
[mono-project.git] / bockbuild / mac-sdk / patches / gtk / 0019-Add-hack-to-lock-flow-of-scroll-events-to-window-whe.patch
blobedf5b8dad5fd6b54f24615fe5c14851278fd11b3
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
5 scroll started
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.
13 ---
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
19 --- a/gdk/gdkwindow.c
20 +++ b/gdk/gdkwindow.c
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 */
30 static void
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 */
44 /* Properties */
45 @@ -10702,6 +10712,64 @@ proxy_pointer_event (GdkDisplay *display,
46 GDK_BUTTON4_MASK | \
47 GDK_BUTTON5_MASK)
49 +#ifdef GDK_WINDOWING_QUARTZ
50 +static void
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.
56 + */
57 + GdkDisplay *display = data;
59 + g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
60 + NULL);
61 + g_object_set_qdata (G_OBJECT (display), quark_last_scroll_event_window,
62 + NULL);
65 +static void
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).
75 + */
76 + old_window = g_object_get_qdata (G_OBJECT (display),
77 + quark_last_scroll_pointer_window);
78 + if (old_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);
84 + if (old_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.
92 + */
93 + g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
94 + pointer_window);
95 + if (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,
100 + event_window);
101 + if (event_window)
102 + g_object_weak_ref (G_OBJECT (event_window),
103 + last_scroll_event_weak_ref_notify, display);
105 +#endif /* GDK_WINDOWING_QUARTZ */
107 static gboolean
108 proxy_button_event (GdkEvent *source_event,
109 gulong serial)
110 @@ -10769,6 +10837,32 @@ proxy_button_event (GdkEvent *source_event,
111 type, state,
112 NULL, serial);
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.
123 + */
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);
130 + else
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)
141 return TRUE;
144 1.7.10.2 (Apple Git-33)