File gtk3-bnc854844-bgo699574-fix-scroll-events.patch of Package gtk3.openSUSE_13.1_Update
From 336df3f3fe149a41be664be1352941329fba5349 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sat, 16 Nov 2013 23:32:58 +0100
Subject: [PATCH 1/3] gdk: be more selective resetting scroll events
It's been reported in several applications that scrolling feels jerky
since commit cc7b3985b3e31.
Investigation reported that the combination of passive 4-7 button grabs
on the toplevel and the presence of native subwindows might trigger
too often crossing events from the child window to the toplevel and
back as scroll "buttons" trigger the passive grab. Those crossing events
would reset the scroll valuators rendering scrolling from jerky on
touchpads (where there's intermediate smooth events between the emulated
button ones) to ineffective on regular mouse wheels (where the crossing
event would reset the valuators right before the single smooth scroll
event we get is delivered)
So, only reset scroll valuators when the pointer enters the toplevel
(we only care about this when the pointer is on the window after it's
been possibly scrolling somewhere else), and it doesn't come from an
inferior.
The situations where this happened varied though, the native subwindow
could be one created explicitly by the application, or created indirectly
through gdk_window_ensure_native(). The latter was mainly the case for
evolution (through gtk_selection_set_owner()) and any GtkScrolledWindow
under the oxygen-gtk3 theme (through gdk_window_set_composited())
https://bugzilla.gnome.org/show_bug.cgi?id=699574
---
gdk/x11/gdkdevicemanager-xi2.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 0584eac..a2897b4 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1567,18 +1567,22 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
GUINT_TO_POINTER (xev->sourceid));
gdk_event_set_source_device (event, source_device);
- if (gdk_device_get_device_type (source_device) != GDK_DEVICE_TYPE_MASTER)
- _gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
- else
+ if (ev->evtype == XI_Enter && xev->detail != XINotifyInferior &&
+ gdk_window_get_window_type (window) == GDK_WINDOW_TOPLEVEL)
{
- GList *slaves, *l;
+ if (gdk_device_get_device_type (source_device) != GDK_DEVICE_TYPE_MASTER)
+ _gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
+ else
+ {
+ GList *slaves, *l;
- slaves = gdk_device_list_slave_devices (source_device);
+ slaves = gdk_device_list_slave_devices (source_device);
- for (l = slaves; l; l = l->next)
- _gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
+ for (l = slaves; l; l = l->next)
+ _gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
- g_list_free (slaves);
+ g_list_free (slaves);
+ }
}
event->crossing.mode = translate_crossing_mode (xev->mode);
--
1.8.4
From 21c24f45954134a64e889df8c6f202df96afe453 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 17 Nov 2013 00:14:06 +0100
Subject: [PATCH 2/3] x11: Add extra debug spew on XI2 crossing and button
events
This information will be useful in case someone stumbles on a situation
similar to https://bugzilla.gnome.org/show_bug.cgi?id=699574, so we can
figure out where do the crossing events come from or go to easily.
---
gdk/x11/gdkdevicemanager-xi2.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index a2897b4..7dba5a6 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1221,6 +1221,15 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
GdkDevice *source_device;
+ GDK_NOTE (EVENTS,
+ g_message ("button %s:\twindow %ld\n\tdevice:%u\n"
+ "\tsource device:%u\n\tbutton number: %u\n"
+ "\tx,y: %.2f %.2f",
+ (ev->evtype == XI_ButtonPress) ? "press" : "release",
+ xev->event, xev->detail,
+ xev->deviceid, xev->sourceid,
+ xev->event_x, xev->event_y));
+
if (ev->evtype == XI_ButtonRelease &&
(xev->detail >= 4 && xev->detail <= 7))
return FALSE;
@@ -1547,6 +1556,15 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
XIEnterEvent *xev = (XIEnterEvent *) ev;
GdkDevice *device, *source_device;
+ GDK_NOTE (EVENTS,
+ g_message ("%s notify:\twindow %ld\n\tsubwindow:%ld\n"
+ "\tdevice: %u\n\tsource device: %u\n"
+ "\tnotify type: %u\n\tcrossing mode: %u",
+ (ev->evtype == XI_Enter) ? "enter" : "leave",
+ xev->event, xev->child,
+ xev->deviceid, xev->sourceid,
+ xev->detail, xev->mode));
+
event->crossing.type = (ev->evtype == XI_Enter) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY;
event->crossing.x = (gdouble) xev->event_x / scale;
--
1.8.4
From 7f713fe6e61dc26447acd3b60e9f5a5c71cc2d35 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 18 Nov 2013 22:12:18 +0100
Subject: [PATCH 3/3] gdk: Ignore crossings generated by passive grabs when
resetting scroll axes
Passive grabs may take pointer focus out of the application, even though
the pointer didn't leave the window, but those events still trigger resetting
of the scroll axes. This is most visible with compiz, and possibly other
reparenting WMs, where passive grabs happen on the WM-managed window that
is a parent of the application toplevel.
As it is not possible to have scrolling happening on the timespan a passive
grab takes action, it is entirely safe for GTK+ to assume none happened if
it gets a crossing event of that nature.
https://bugzilla.gnome.org/show_bug.cgi?id=699574#c33
---
gdk/x11/gdkdevicemanager-xi2.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 7dba5a6..87d2810 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1585,7 +1585,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
GUINT_TO_POINTER (xev->sourceid));
gdk_event_set_source_device (event, source_device);
- if (ev->evtype == XI_Enter && xev->detail != XINotifyInferior &&
+ if (ev->evtype == XI_Enter &&
+ xev->detail != XINotifyInferior && xev->mode != XINotifyPassiveUngrab &&
gdk_window_get_window_type (window) == GDK_WINDOW_TOPLEVEL)
{
if (gdk_device_get_device_type (source_device) != GDK_DEVICE_TYPE_MASTER)
--
1.8.4