diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c index 55fb65a3b..d3d59df6b 100644 --- a/clutter/x11/clutter-backend-x11.c +++ b/clutter/x11/clutter-backend-x11.c @@ -158,12 +158,10 @@ clutter_x11_register_input_devices (ClutterBackendX11 *backend) device_type = CLUTTER_POINTER_DEVICE; break; -#if 0 /* XInput1 is broken for keyboards */ case IsXExtensionKeyboard: device_type = CLUTTER_KEYBOARD_DEVICE; break; -#endif case IsXExtensionDevice: device_type = CLUTTER_EXTENSION_DEVICE; diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 6858cfd65..1a3a260fc 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -267,9 +267,10 @@ set_user_time (ClutterBackendX11 *backend_x11, } } -#if 0 /* See XInput keyboard comment below HAVE_XINPUT */ +#ifdef HAVE_XINPUT static void -convert_xdevicekey_to_xkey (XDeviceKeyEvent *xkev, XEvent *xevent) +convert_xdevicekey_to_xkey (XDeviceKeyEvent *xkev, + XEvent *xevent) { xevent->xany.type = xevent->xkey.type = xkev->type; xevent->xkey.serial = xkev->serial; @@ -808,11 +809,14 @@ event_translate (ClutterBackend *backend, #ifdef HAVE_XINPUT int *ev_types = backend_x11->event_types; int button_press, button_release; + int key_press, key_release; int motion_notify; button_press = ev_types[CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT]; button_release = ev_types[CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT]; motion_notify = ev_types[CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT]; + key_press = ev_types[CLUTTER_X11_XINPUT_KEY_PRESS_EVENT]; + key_release = ev_types[CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT]; CLUTTER_NOTE (EVENT, "XInput event type: %d", xevent->type); @@ -924,6 +928,26 @@ event_translate (ClutterBackend *backend, res = TRUE; } + else if (xevent->type == key_press || xevent->type == key_release) + { + /* the XInput 1.x handling of key presses/releases is broken: + * it makes key repeat, key presses and releases outside the + * window not generate events even when the window has focus + */ + XDeviceKeyEvent *xkev = (XDeviceKeyEvent *) xevent; + XEvent xevent_converted; + + convert_xdevicekey_to_xkey (xkev, &xevent_converted); + + event->key.type = event->type = (xevent->type == key_press) + ? CLUTTER_KEY_PRESS + : CLUTTER_KEY_RELEASE; + + translate_key_event (backend, event, &xevent_converted); + + if (xevent->type == key_press) + set_user_time (backend_x11, &xwindow, xkev->time); + } else #endif /* HAVE_XINPUT */ { diff --git a/clutter/x11/clutter-input-device-x11.c b/clutter/x11/clutter-input-device-x11.c index 94b67d2a9..b62ca8a0c 100644 --- a/clutter/x11/clutter-input-device-x11.c +++ b/clutter/x11/clutter-input-device-x11.c @@ -142,6 +142,7 @@ _clutter_input_device_x11_construct (ClutterInputDevice *device, { XInputClassInfo *xclass_info = x_device->classes + i; int *button_press, *button_release, *motion_notify; + int *key_press, *key_release; button_press = &backend->event_types[CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT]; @@ -150,22 +151,28 @@ _clutter_input_device_x11_construct (ClutterInputDevice *device, motion_notify = &backend->event_types[CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT]; + key_press = + &backend->event_types[CLUTTER_X11_XINPUT_KEY_PRESS_EVENT]; + key_release = + &backend->event_types[CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT]; + switch (xclass_info->input_class) { -#if 0 - /* XInput 1.x is broken for keyboards: */ + /* event though XInput 1.x is broken for keyboard-like devices + * it might still be useful to track them down; the core keyboard + * will handle the right events anyway + */ case KeyClass: - DeviceKeyPress (xdevice, - backend->event_types[CLUTTER_X11_XINPUT_KEY_PRESS_EVENT], + DeviceKeyPress (x_device, + *key_press, device_x11->xevent_list[n_events]); n_events++; - DeviceKeyRelease (xdevice, - backend->event_types[CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT], + DeviceKeyRelease (x_device, + *key_release, device_x11->xevent_list[n_events]); n_events++; break; -#endif case ButtonClass: DeviceButtonPress (x_device, diff --git a/tests/interactive/test-devices.c b/tests/interactive/test-devices.c index 6af0ce590..e286a064c 100644 --- a/tests/interactive/test-devices.c +++ b/tests/interactive/test-devices.c @@ -105,13 +105,15 @@ test_devices_main (int argc, char **argv) ClutterInputDeviceType device_type; ClutterActor *hand = NULL; - device_type = clutter_input_device_get_device_type (device); - if (device_type == CLUTTER_POINTER_DEVICE) - { - g_print ("got a pointer device '%s' with id %d...\n", - clutter_input_device_get_device_name (device), - clutter_input_device_get_device_id (device)); + g_print ("got a %s device '%s' with id %d...\n", + device_type_name (device), + clutter_input_device_get_device_name (device), + clutter_input_device_get_device_id (device)); + device_type = clutter_input_device_get_device_type (device); + if (device_type == CLUTTER_POINTER_DEVICE || + device_type == CLUTTER_EXTENSION_DEVICE) + { hand = clutter_texture_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png",