Commit d9a9530f authored by Dan Torop's avatar Dan Torop Committed by Olivier Fourdan

wayland: selectively cancel key repeat on key release

Under Wayland, when multiple keys are pressed and the user releases a
key, key repeat should continue unless the key released is the one
currently repeating.

In the case of:

- key1 press
- key1 repeat
- key2 press -> key1 repeat stopped
- key2 repeat
- key2 release

The behavior should be to cancel keyboard repeat, though key1 is still
held down. This is consistent with prior X11/XWayland behavior.

The following also must work:

- key1 press
- key2 press
- key2 release
- key2 press
- key1 release
- key2 should continue to repeat

The fix for bug #778019 should continue to work:

- key1 press
- key1 repeat
- key2 press -> key1 repeat stopped
- key1 release
- key2 should repeat

The choice to change the counter nkeys to the flag repeat_active
helps to solve the second test case.

https://bugzilla.gnome.org/show_bug.cgi?id=781285
parent 2d41d772
......@@ -227,7 +227,6 @@ struct _GdkWaylandSeat
guint32 repeat_key;
guint32 repeat_count;
gint64 repeat_deadline;
gint32 nkeys;
GSettings *keyboard_settings;
uint32_t keyboard_time;
uint32_t keyboard_key_serial;
......@@ -1869,7 +1868,7 @@ keyboard_handle_enter (void *data,
seat->keyboard_focus = wl_surface_get_user_data (surface);
g_object_ref (seat->keyboard_focus);
seat->nkeys = 0;
seat->repeat_key = 0;
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (seat->keyboard_focus);
......@@ -1926,7 +1925,7 @@ keyboard_handle_leave (void *data,
g_object_unref (seat->keyboard_focus);
seat->keyboard_focus = NULL;
seat->nkeys = 0;
seat->repeat_key = 0;
GDK_NOTE (EVENTS,
g_message ("focus out, seat %p surface %p",
......@@ -2126,12 +2125,11 @@ deliver_key_event (GdkWaylandSeat *seat,
GDK_NOTE (EVENTS,
g_message ("keyboard %s event%s, code %d, sym %d, "
"string %s, mods 0x%x, with %i key%s pressed",
"string %s, mods 0x%x",
(state ? "press" : "release"),
(from_key_repeat ? " (repeat)" : ""),
event->key.hardware_keycode, event->key.keyval,
event->key.string, event->key.state,
seat->nkeys, (seat->nkeys > 1 ? "s" : "")));
event->key.string, event->key.state));
if (!xkb_keymap_key_repeats (xkb_keymap, key))
return;
......@@ -2144,16 +2142,14 @@ deliver_key_event (GdkWaylandSeat *seat,
if (state) /* Another key is pressed */
{
seat->repeat_key = key;
seat->nkeys++;
}
else /* a key is released */
else if (seat->repeat_key == key) /* Repeated key is released */
{
/* The compositor may send us more key releases than key presses */
seat->nkeys = MAX (0, seat->nkeys - 1);
seat->repeat_key = 0;
}
}
if (seat->nkeys == 0)
if (!seat->repeat_key)
return;
seat->repeat_count++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment