Stop shortcut repeat when modifiers change
915709c54aa4a1c7f98913d0e9bb431c8eab1dd4
1 parent
10145e82
swm.c
+13 -5
| 3903 | 3903 | wl_event_source_timer_update( |
|
| 3904 | 3904 | group->key_repeat_source, group->wlr_group->keyboard.repeat_info.delay |
|
| 3905 | 3905 | ); |
|
| 3906 | 3906 | } |
|
| 3907 | 3907 | ||
| 3908 | + | /* Clear the active shortcut and disarm its repeat timer. */ |
|
| 3909 | + | static void key_repeat_stop(keyboard_group_t *group) { |
|
| 3910 | + | group->nsyms = 0; |
|
| 3911 | + | group->repeat_keycode = 0; |
|
| 3912 | + | wl_event_source_timer_update(group->key_repeat_source, 0); |
|
| 3913 | + | } |
|
| 3914 | + | ||
| 3908 | 3915 | /* Return whether this event supersedes the active shortcut repeat. */ |
|
| 3909 | 3916 | static bool key_repeat_should_stop( |
|
| 3910 | 3917 | keyboard_group_t *group, const struct wlr_keyboard_key_event *event |
|
| 3911 | 3918 | ) { |
|
| 3912 | 3919 | if (!group->nsyms) |
| 3949 | 3956 | for (i = 0; i < nsyms; i++) |
|
| 3950 | 3957 | handled |= key_binding(mods, syms[i], 0); |
|
| 3951 | 3958 | } |
|
| 3952 | 3959 | if ((handled & 2) && group->wlr_group->keyboard.repeat_info.delay > 0) |
|
| 3953 | 3960 | key_repeat_begin(group, syms, nsyms, mods, event->keycode); |
|
| 3954 | - | else if (key_repeat_should_stop(group, event)) { |
|
| 3955 | - | group->nsyms = 0; |
|
| 3956 | - | group->repeat_keycode = 0; |
|
| 3957 | - | wl_event_source_timer_update(group->key_repeat_source, 0); |
|
| 3958 | - | } |
|
| 3961 | + | else if (key_repeat_should_stop(group, event)) |
|
| 3962 | + | key_repeat_stop(group); |
|
| 3959 | 3963 | if (!key_event_should_forward(group, event->keycode, event->state, handled)) |
|
| 3960 | 3964 | return; |
|
| 3961 | 3965 | ||
| 3962 | 3966 | wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); |
|
| 3963 | 3967 | /* Send unhandled keys to the input method or focused application. */ |
| 3974 | 3978 | void key_press_modifiers(struct wl_listener *listener, void *data) { |
|
| 3975 | 3979 | /* A modifier such as Shift or Alt changed. */ |
|
| 3976 | 3980 | keyboard_group_t *group = wl_container_of(listener, group, modifiers); |
|
| 3977 | 3981 | struct wlr_input_method_keyboard_grab_v2 *grab; |
|
| 3978 | 3982 | ||
| 3983 | + | if (group->nsyms && CLEANMASK(group->mods) != |
|
| 3984 | + | CLEANMASK(wlr_keyboard_get_modifiers(&group->wlr_group->keyboard))) |
|
| 3985 | + | key_repeat_stop(group); |
|
| 3986 | + | ||
| 3979 | 3987 | wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); |
|
| 3980 | 3988 | /* Send modifiers to the input method or focused application. */ |
|
| 3981 | 3989 | if ((grab = input_method_grab(group))) { |
|
| 3982 | 3990 | wlr_input_method_keyboard_grab_v2_set_keyboard(grab, &group->wlr_group->keyboard); |
|
| 3983 | 3991 | wlr_input_method_keyboard_grab_v2_send_modifiers( |
test/clients.py
+48 -0
| 905 | 905 | lock.destroy() |
|
| 906 | 906 | connection.roundtrips() |
|
| 907 | 907 | connection.close() |
|
| 908 | 908 | ||
| 909 | 909 | ||
| 910 | + | def shortcut_repeat() -> None: |
|
| 911 | + | """Stop a held focus shortcut when its modifier is released.""" |
|
| 912 | + | ||
| 913 | + | connection = Connection(WlCompositor, WlShm, WlSeat, XdgWmBase, ZwpVirtualKeyboardManagerV1) |
|
| 914 | + | seat = connection.get(WlSeat) |
|
| 915 | + | virtual = connection.get(ZwpVirtualKeyboardManagerV1).create_virtual_keyboard(seat) |
|
| 916 | + | keymap, indices = keymap_text() |
|
| 917 | + | with tempfile.TemporaryFile(dir=os.environ.get("SWM_TEST_DIR")) as stream: |
|
| 918 | + | stream.write(keymap + b"\0") |
|
| 919 | + | stream.flush() |
|
| 920 | + | virtual.keymap(WlKeyboard.keymap_format.xkb_v1, stream.fileno(), len(keymap) + 1) |
|
| 921 | + | connection.roundtrips() |
|
| 922 | + | keyboard = seat.get_keyboard() |
|
| 923 | + | focused = [] |
|
| 924 | + | repeat = [] |
|
| 925 | + | keyboard.dispatcher["enter"] = lambda proxy, serial, surface, keys: focused.append(surface) |
|
| 926 | + | keyboard.dispatcher["repeat_info"] = lambda proxy, rate, delay: repeat.append((rate, delay)) |
|
| 927 | + | first = Window(connection, "repeat-first", 0xFF224466) |
|
| 928 | + | second = Window(connection, "repeat-second", 0xFF336699) |
|
| 929 | + | connection.roundtrips(4) |
|
| 930 | + | configured = int((Path(os.environ["SWM_TEST_BUILD"]) / "modkey").read_text()) |
|
| 931 | + | modifier, code = ("alt", 56) if configured == 8 else ("logo", 125) |
|
| 932 | + | virtual.key(0, code, 1) |
|
| 933 | + | virtual.modifiers(1 << indices[modifier], 0, 0, 0) |
|
| 934 | + | virtual.key(1, 36, 1) |
|
| 935 | + | connection.roundtrips(2) |
|
| 936 | + | count = len(focused) |
|
| 937 | + | rate, delay = repeat[-1] |
|
| 938 | + | time.sleep(delay / 1000 + 2 / rate) |
|
| 939 | + | connection.roundtrips(3) |
|
| 940 | + | if len(focused) <= count: |
|
| 941 | + | raise Failure("held focus shortcut did not repeat") |
|
| 942 | + | virtual.key(2, code, 0) |
|
| 943 | + | virtual.modifiers(0, 0, 0, 0) |
|
| 944 | + | connection.roundtrips(2) |
|
| 945 | + | count = len(focused) |
|
| 946 | + | time.sleep(3 / rate) |
|
| 947 | + | connection.roundtrips(3) |
|
| 948 | + | if len(focused) != count: |
|
| 949 | + | raise Failure("focus shortcut kept repeating after modifier release") |
|
| 950 | + | virtual.key(3, 36, 0) |
|
| 951 | + | first.destroy() |
|
| 952 | + | second.destroy() |
|
| 953 | + | virtual.destroy() |
|
| 954 | + | connection.close() |
|
| 955 | + | ||
| 956 | + | ||
| 910 | 957 | def input_method_keys() -> None: |
|
| 911 | 958 | """Check keyboard grabs and input-method key reinjection.""" |
|
| 912 | 959 | ||
| 913 | 960 | connection = Connection( |
|
| 914 | 961 | WlCompositor, WlShm, WlSeat, XdgWmBase, |
| 1120 | 1167 | popup_surface.destroy() |
|
| 1121 | 1168 | text.destroy() |
|
| 1122 | 1169 | method.destroy() |
|
| 1123 | 1170 | connection.close() |
|
| 1124 | 1171 | input_method_keys() |
|
| 1172 | + | shortcut_repeat() |
|
| 1125 | 1173 | ||
| 1126 | 1174 | ||
| 1127 | 1175 | def x11(arguments: list[str]) -> None: |
|
| 1128 | 1176 | """Exercise managed, configured, fullscreen, and unmanaged X11 windows.""" |
|
| 1129 | 1177 |