From c2b0b9aace969ecb19e703c8d53d157eb1072559 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 12 Nov 2013 15:10:22 -0500 Subject: [PATCH] input-device-xi2: Calculate the correct state for button events The state that the X server sends for button events, by specification, contains the button state before the event. We need to synthesize in the result of the event in order to determine what the current button state is. https://bugzilla.gnome.org/show_bug.cgi?id=712322 --- clutter/x11/clutter-input-device-xi2.c | 63 ++++++++++++++++---------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/clutter/x11/clutter-input-device-xi2.c b/clutter/x11/clutter-input-device-xi2.c index 20ac71c44..9490c521e 100644 --- a/clutter/x11/clutter-input-device-xi2.c +++ b/clutter/x11/clutter-input-device-xi2.c @@ -95,6 +95,26 @@ clutter_input_device_xi2_init (ClutterInputDeviceXI2 *self) { } +static ClutterModifierType +get_modifier_for_button (int i) +{ + switch (i) + { + case 1: + return CLUTTER_BUTTON1_MASK; + case 2: + return CLUTTER_BUTTON2_MASK; + case 3: + return CLUTTER_BUTTON3_MASK; + case 4: + return CLUTTER_BUTTON4_MASK; + case 5: + return CLUTTER_BUTTON5_MASK; + default: + return 0; + } +} + void _clutter_input_device_xi2_translate_state (ClutterEvent *event, XIModifierState *modifiers_state, @@ -125,34 +145,27 @@ _clutter_input_device_xi2_translate_state (ClutterEvent *event, if (!XIMaskIsSet (buttons_state->mask, i)) continue; - switch (i) - { - case 1: - button |= CLUTTER_BUTTON1_MASK; - break; - - case 2: - button |= CLUTTER_BUTTON2_MASK; - break; - - case 3: - button |= CLUTTER_BUTTON3_MASK; - break; - - case 4: - button |= CLUTTER_BUTTON4_MASK; - break; - - case 5: - button |= CLUTTER_BUTTON5_MASK; - break; - - default: - break; - } + button |= get_modifier_for_button (i); } } + /* The XIButtonState sent in the event specifies the + * state of the buttons before the event. In order to + * get the current state of the buttons, we need to + * filter out the current button. + */ + switch (event->type) + { + case CLUTTER_BUTTON_PRESS: + button |= (get_modifier_for_button (event->button.button)); + break; + case CLUTTER_BUTTON_RELEASE: + button &= ~(get_modifier_for_button (event->button.button)); + break; + default: + break; + } + effective = button | base | latched | locked; if (group_state) effective |= (group_state->effective) << 13;