forked from AuroraMiddleware/gtk
x11: Query pointer devices' scroll valuators on toplevel enter events
We used to "invalidate" scroll valuators, so the next scroll event could be used as the base for the next scroll deltas. This has the inconvenience that it invariably consumes the first event received after enter and, due to interactions with WM overeager passive button grabs, there's a possibility we don't scroll at all if we receive interleaved "smooth scroll" XI_Motion events and XI_Enter events (Normally triggered by regular scroll wheels in mice). In order to fix this, and at the expense of some sync-call overhead on XI_Enter events (one XIQueryDevice call per slave device), query the current scroll valuator state for all the slaves of the entered pointer, so we do know beforehand the right base values. If new devices are plugged while the pointer is on top of the client, the initialized scroll values will match the valuators'. https://bugzilla.gnome.org/show_bug.cgi?id=750994 https://bugzilla.gnome.org/show_bug.cgi?id=750870
This commit is contained in:
parent
8c9e426dc5
commit
77b8495bc4
@ -40,7 +40,6 @@ struct _ScrollValuator
|
||||
{
|
||||
guint n_valuator : 4;
|
||||
guint direction : 4;
|
||||
guint last_value_valid : 1;
|
||||
gdouble last_value;
|
||||
gdouble increment;
|
||||
};
|
||||
@ -819,8 +818,8 @@ _gdk_x11_device_xi2_add_scroll_valuator (GdkX11DeviceXI2 *device,
|
||||
|
||||
scroll.n_valuator = n_valuator;
|
||||
scroll.direction = direction;
|
||||
scroll.last_value_valid = FALSE;
|
||||
scroll.increment = increment;
|
||||
scroll.last_value = 0;
|
||||
|
||||
g_array_append_val (device->scroll_valuators, scroll);
|
||||
}
|
||||
@ -851,18 +850,10 @@ _gdk_x11_device_xi2_get_scroll_delta (GdkX11DeviceXI2 *device,
|
||||
if (delta_ret)
|
||||
*delta_ret = 0;
|
||||
|
||||
if (scroll->last_value_valid)
|
||||
{
|
||||
if (delta_ret)
|
||||
*delta_ret = (valuator_value - scroll->last_value) / scroll->increment;
|
||||
if (delta_ret)
|
||||
*delta_ret = (valuator_value - scroll->last_value) / scroll->increment;
|
||||
|
||||
scroll->last_value = valuator_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
scroll->last_value = valuator_value;
|
||||
scroll->last_value_valid = TRUE;
|
||||
}
|
||||
scroll->last_value = valuator_value;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -872,17 +863,33 @@ _gdk_x11_device_xi2_get_scroll_delta (GdkX11DeviceXI2 *device,
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_device_xi2_reset_scroll_valuators (GdkX11DeviceXI2 *device)
|
||||
_gdk_device_xi2_revalidate_scroll_valuators (GdkX11DeviceXI2 *device)
|
||||
{
|
||||
guint i;
|
||||
GdkDisplay *display;
|
||||
XIDeviceInfo *info;
|
||||
gint i, ndevices;
|
||||
|
||||
display = gdk_device_get_display (GDK_DEVICE (device));
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
info = XIQueryDevice (GDK_DISPLAY_XDISPLAY (display),
|
||||
device->device_id, &ndevices);
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
for (i = 0; i < device->scroll_valuators->len; i++)
|
||||
{
|
||||
XIValuatorClassInfo *valuator;
|
||||
ScrollValuator *scroll;
|
||||
|
||||
scroll = &g_array_index (device->scroll_valuators, ScrollValuator, i);
|
||||
scroll->last_value_valid = FALSE;
|
||||
valuator = (XIValuatorClassInfo *) info->classes[scroll->n_valuator + 1];
|
||||
scroll->last_value = valuator->value;
|
||||
}
|
||||
|
||||
XIFreeDeviceInfo (info);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -824,13 +824,11 @@ handle_device_changed (GdkX11DeviceManagerXI2 *device_manager,
|
||||
XIDeviceChangedEvent *ev)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device, *source_device;
|
||||
GdkDevice *device;
|
||||
|
||||
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
|
||||
device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (ev->deviceid));
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (ev->sourceid));
|
||||
|
||||
if (device)
|
||||
{
|
||||
@ -841,9 +839,6 @@ handle_device_changed (GdkX11DeviceManagerXI2 *device_manager,
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (device), "changed");
|
||||
}
|
||||
|
||||
if (source_device)
|
||||
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
|
||||
}
|
||||
|
||||
static GdkCrossingMode
|
||||
@ -1683,16 +1678,16 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
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)
|
||||
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
|
||||
if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
|
||||
_gdk_device_xi2_revalidate_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 (device);
|
||||
|
||||
for (l = slaves; l; l = l->next)
|
||||
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
|
||||
_gdk_device_xi2_revalidate_scroll_valuators (l->data);
|
||||
|
||||
g_list_free (slaves);
|
||||
}
|
||||
|
@ -246,6 +246,8 @@ gboolean _gdk_x11_device_xi2_get_scroll_delta (GdkX11DeviceXI2 *device,
|
||||
GdkScrollDirection *direction_ret,
|
||||
gdouble *delta_ret);
|
||||
void _gdk_device_xi2_reset_scroll_valuators (GdkX11DeviceXI2 *device);
|
||||
void _gdk_device_xi2_revalidate_scroll_valuators (GdkX11DeviceXI2 *device);
|
||||
|
||||
|
||||
gdouble gdk_x11_device_xi2_get_last_axis_value (GdkX11DeviceXI2 *device,
|
||||
gint n_axis);
|
||||
|
Loading…
Reference in New Issue
Block a user