backends/x11: Call meta_backend_update_last_device() from XI_DeviceChanged

On X11, calling this function on meta_display_handle_events() will not catch
mouse events happening over clients, so poke directly in the backend for
XI_DeviceChanged events, which mutter will get on device switches.

The code has been slightly refactored so we deal with XIEvents at a single
handle_input_event() function.

https://bugzilla.gnome.org/show_bug.cgi?id=712775
This commit is contained in:
Carlos Garnacho 2015-02-11 15:04:04 +01:00
parent a30ca3e62f
commit af9d8f1931

View File

@ -144,6 +144,24 @@ translate_crossing_event (MetaBackendX11 *x11,
enter_event->event = meta_backend_x11_get_xwindow (x11); enter_event->event = meta_backend_x11_get_xwindow (x11);
} }
static void
handle_device_change (MetaBackendX11 *x11,
XIEvent *event)
{
XIDeviceChangedEvent *device_changed;
if (event->evtype != XI_DeviceChanged)
return;
device_changed = (XIDeviceChangedEvent *) event;
if (device_changed->reason != XISlaveSwitch)
return;
meta_backend_update_last_device (META_BACKEND (x11),
device_changed->sourceid);
}
/* Clutter makes the assumption that there is only one X window /* Clutter makes the assumption that there is only one X window
* per stage, which is a valid assumption to make for a generic * per stage, which is a valid assumption to make for a generic
* application toolkit. As such, it will ignore any events sent * application toolkit. As such, it will ignore any events sent
@ -155,7 +173,32 @@ translate_crossing_event (MetaBackendX11 *x11,
*/ */
static void static void
maybe_spoof_event_as_stage_event (MetaBackendX11 *x11, maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
XEvent *event) XIEvent *input_event)
{
switch (input_event->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
case XI_TouchBegin:
case XI_TouchUpdate:
case XI_TouchEnd:
translate_device_event (x11, (XIDeviceEvent *) input_event);
break;
case XI_Enter:
case XI_Leave:
translate_crossing_event (x11, (XIEnterEvent *) input_event);
break;
default:
break;
}
}
static void
handle_input_event (MetaBackendX11 *x11,
XEvent *event)
{ {
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
@ -164,25 +207,10 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
{ {
XIEvent *input_event = (XIEvent *) event->xcookie.data; XIEvent *input_event = (XIEvent *) event->xcookie.data;
switch (input_event->evtype) if (input_event->evtype == XI_DeviceChanged)
{ handle_device_change (x11, input_event);
case XI_Motion: else
case XI_ButtonPress: maybe_spoof_event_as_stage_event (x11, input_event);
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
case XI_TouchBegin:
case XI_TouchUpdate:
case XI_TouchEnd:
translate_device_event (x11, (XIDeviceEvent *) input_event);
break;
case XI_Enter:
case XI_Leave:
translate_crossing_event (x11, (XIEnterEvent *) input_event);
break;
default:
break;
}
} }
} }
@ -251,7 +279,7 @@ handle_host_xevent (MetaBackend *backend,
if (!bypass_clutter) if (!bypass_clutter)
{ {
maybe_spoof_event_as_stage_event (x11, event); handle_input_event (x11, event);
clutter_x11_handle_event (event); clutter_x11_handle_event (event);
} }