Arm repeat for repeatable shortcuts
1ebc9753631f772b47ea3ac2c526b016903ad115
1 parent
ed6e245f
swm.c
+19 -13
| 2318 | 2318 | } |
|
| 2319 | 2319 | /* A configure acknowledgement may be committed before the client attaches |
|
| 2320 | 2320 | * the matching buffer. Keep the pending layout geometry until pixels for |
|
| 2321 | 2321 | * that configure arrive; otherwise the old buffer can trigger a resize |
|
| 2322 | 2322 | * loop between its dimensions and the requested dimensions. */ |
|
| 2323 | - | if (c->resize && |
|
| 2324 | - | !(client_surface(c)->current.committed & WLR_SURFACE_STATE_BUFFER)) |
|
| 2323 | + | if (c->resize && !(client_surface(c)->current.committed & WLR_SURFACE_STATE_BUFFER)) |
|
| 2325 | 2324 | return; |
|
| 2326 | 2325 | old_geom = c->geom; |
|
| 2327 | 2326 | ||
| 2328 | 2327 | /* Floating applications may choose their own size. Applications may also |
|
| 2329 | 2328 | * round a compositor-requested size. Match the frame to the committed |
| 2334 | 2333 | (struct swm_box *)&c->geom, geom.width, geom.height, c->bw, c->resize_edges |
|
| 2335 | 2334 | ); |
|
| 2336 | 2335 | } |
|
| 2337 | 2336 | if (c->resize && c->mon) { |
|
| 2338 | 2337 | uint32_t resize_serial = c->resize; |
|
| 2339 | - | int latest = |
|
| 2340 | - | serial_at_least(c->surface.xdg->current.configure_serial, resize_serial); |
|
| 2338 | + | int latest = serial_at_least(c->surface.xdg->current.configure_serial, resize_serial); |
|
| 2341 | 2339 | ||
| 2342 | 2340 | apply_bounds(c, &c->mon->w); |
|
| 2343 | 2341 | resize_apply(c); |
|
| 2344 | 2342 | ||
| 2345 | 2343 | if (latest) |
| 3844 | 3842 | *word &= ~mask; |
|
| 3845 | 3843 | return false; |
|
| 3846 | 3844 | } |
|
| 3847 | 3845 | return true; |
|
| 3848 | 3846 | } |
|
| 3847 | + | /* Arm shortcut repeat after a repeatable compositor binding is pressed. */ |
|
| 3848 | + | static void key_repeat_begin( |
|
| 3849 | + | keyboard_group_t *group, const xkb_keysym_t *syms, int nsyms, uint32_t mods |
|
| 3850 | + | ) { |
|
| 3851 | + | group->nsyms = nsyms; |
|
| 3852 | + | group->keysyms = syms; |
|
| 3853 | + | group->mods = mods; |
|
| 3854 | + | wl_event_source_timer_update( |
|
| 3855 | + | group->key_repeat_source, group->wlr_group->keyboard.repeat_info.delay |
|
| 3856 | + | ); |
|
| 3857 | + | } |
|
| 3858 | + | ||
| 3849 | 3859 | /* Handle shortcuts and forward unhandled key events to the focused application. */ |
|
| 3850 | 3860 | void key_press(struct wl_listener *listener, void *data) { |
|
| 3851 | 3861 | int i; |
|
| 3852 | 3862 | ||
| 3853 | 3863 | /* This event is raised when a key is pressed or released. */ |
| 3868 | 3878 | /* Handle shortcuts only on key press and while the session is unlocked. */ |
|
| 3869 | 3879 | if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
|
| 3870 | 3880 | for (i = 0; i < nsyms; i++) |
|
| 3871 | 3881 | handled |= key_binding(mods, syms[i], 0); |
|
| 3872 | 3882 | } |
|
| 3873 | - | if ((handled & 2) && group->wlr_group->keyboard.repeat_info.delay > 0) { |
|
| 3874 | - | group->mods = mods; |
|
| 3875 | - | wl_event_source_timer_update( |
|
| 3876 | - | group->key_repeat_source, group->wlr_group->keyboard.repeat_info.delay |
|
| 3877 | - | ); |
|
| 3878 | - | } else { |
|
| 3883 | + | if ((handled & 2) && group->wlr_group->keyboard.repeat_info.delay > 0) |
|
| 3884 | + | key_repeat_begin(group, syms, nsyms, mods); |
|
| 3885 | + | else { |
|
| 3879 | 3886 | group->nsyms = 0; |
|
| 3880 | 3887 | wl_event_source_timer_update(group->key_repeat_source, 0); |
|
| 3881 | 3888 | } |
|
| 3882 | 3889 | if (!key_event_should_forward(group, event->keycode, event->state, handled)) |
|
| 3883 | 3890 | return; |
| 5306 | 5313 | static void client_translate_monitor(client_t *c, monitor_t *oldmon, monitor_t *newmon) { |
|
| 5307 | 5314 | struct wlr_box *geom; |
|
| 5308 | 5315 | ||
| 5309 | 5316 | if (!c || !oldmon || !newmon || oldmon == newmon) |
|
| 5310 | 5317 | return; |
|
| 5311 | - | geom = c->is_fullscreen ? &c->prev : &c->geom; |
|
| 5318 | + | geom = c->is_fullscreen ? &c->prev : &c->geom; |
|
| 5312 | 5319 | geom->x += newmon->m.x - oldmon->m.x; |
|
| 5313 | 5320 | geom->y += newmon->m.y - oldmon->m.y; |
|
| 5314 | 5321 | } |
|
| 5315 | 5322 | ||
| 5316 | 5323 | /* Fit a window to the display it was just moved to. */ |
| 6916 | 6923 | wl_list_remove(&c->unmap.link); |
|
| 6917 | 6924 | } |
|
| 6918 | 6925 | ||
| 6919 | 6926 | /* Read X11's urgency hint; deleting WM_HINTS clears urgency. */ |
|
| 6920 | 6927 | static bool x11_hints_urgent(client_t *c) { |
|
| 6921 | - | return c->surface.xwayland->hints && |
|
| 6922 | - | xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); |
|
| 6928 | + | return c->surface.xwayland->hints && xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); |
|
| 6923 | 6929 | } |
|
| 6924 | 6930 | ||
| 6925 | 6931 | /* Update urgency and input behavior from an X11 window's hints. */ |
|
| 6926 | 6932 | void set_hints(struct wl_listener *listener, void *data) { |
|
| 6927 | 6933 | client_t *c = wl_container_of(listener, c, set_hints); |
test/unit.c
+8 -6
| 1110 | 1110 | assert(key_binding(MOD, XKB_KEY_j, true) == 2); |
|
| 1111 | 1111 | assert(key_binding(0, XKB_KEY_NoSymbol, 0) == 0); |
|
| 1112 | 1112 | ||
| 1113 | 1113 | loop = wl_event_loop_create(); |
|
| 1114 | 1114 | assert(loop); |
|
| 1115 | - | group.wlr_group = &keyboard_group; |
|
| 1116 | - | group.nsyms = 1; |
|
| 1117 | - | group.keysyms = &symbol; |
|
| 1118 | - | group.mods = MOD; |
|
| 1119 | - | keyboard_group.keyboard.repeat_info.rate = 25; |
|
| 1120 | - | group.key_repeat_source = wl_event_loop_add_timer(loop, key_repeat, &group); |
|
| 1115 | + | group.wlr_group = &keyboard_group; |
|
| 1116 | + | keyboard_group.keyboard.repeat_info.rate = 25; |
|
| 1117 | + | keyboard_group.keyboard.repeat_info.delay = 300; |
|
| 1118 | + | group.key_repeat_source = wl_event_loop_add_timer(loop, key_repeat, &group); |
|
| 1121 | 1119 | assert(group.key_repeat_source); |
|
| 1120 | + | key_repeat_begin(&group, &symbol, 1, MOD); |
|
| 1121 | + | assert(group.nsyms == 1); |
|
| 1122 | + | assert(group.keysyms == &symbol); |
|
| 1123 | + | assert(group.mods == MOD); |
|
| 1122 | 1124 | assert(key_repeat(&group) == 0); |
|
| 1123 | 1125 | wl_event_source_remove(group.key_repeat_source); |
|
| 1124 | 1126 | wl_event_loop_destroy(loop); |
|
| 1125 | 1127 | } |
|
| 1126 | 1128 |