spkp

Stacking wayland compositor
git clone git://git.z3bra.org/spkp.git
Log | Files | Refs

commit a8b09a56046536686e6a00db338d02e08d5fb05d
parent 08dafffce80305abfea7da9365ac9850f4b7f8c1
Author: Willy Goiffon <dev@z3bra.org>
Date:   Sun, 15 Nov 2020 16:02:04 +0100

Refactor mouse click events handling

Diffstat:
Mconfig.def.h | 2++
Msp:kp.c | 150+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
2 files changed, 92 insertions(+), 60 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -18,3 +18,5 @@ struct key keys[] = { { LOGO , XKB_KEY_Return, kb_exec , {.v = "alacritty"} }, { LOGO , XKB_KEY_d , kb_desktop , {0 } }, }; + +xkb_mod_mask_t mousemod = LOGO; diff --git a/sp:kp.c b/sp:kp.c @@ -188,6 +188,8 @@ static void cb_motion(struct state *, uint32_t); static void cb_motion_relative(struct wl_listener *, void *); static void cb_motion_absolute(struct wl_listener *, void *); static void cb_click(struct wl_listener *, void *); +static void cb_click_press(struct state *, struct wlr_event_pointer_button *); +static void cb_click_release(struct state *, struct wlr_event_pointer_button *); static void cb_scroll(struct wl_listener *, void *); static void cb_paint_cursor(struct wl_listener *, void *); @@ -700,56 +702,82 @@ cb_click(struct wl_listener *listener, void *data) { struct state *server; struct wlr_event_pointer_button *ev; - struct window *w; - struct wlr_keyboard *kb; - struct wlr_box geom; server = wl_container_of(listener, server, click); - kb = wlr_seat_get_keyboard(server->seat); ev = data; - if (ev->state == WLR_BUTTON_RELEASED) { - switch(server->grabmode) { - case MOVE: - case TELEPORT: - server->grabbed->x = server->grabbox.x; - server->grabbed->y = server->grabbox.y; - if (server->grabmode == MOVE) - break; - /* FALLTHROUGH */ - case RESIZE: - geom.width = server->grabbox.width; - geom.height = server->grabbox.height; - wlr_xdg_toplevel_set_size(server->grabbed->toplevel, geom.width, geom.height); - break; - case NORMAL: - /* pass down event when not grabbing a window */ - wlr_seat_pointer_notify_button(server->seat, - ev->time_msec, ev->button, ev->state); + switch (ev->state) { + case WLR_BUTTON_RELEASED: + cb_click_release(server, ev); + break; + case WLR_BUTTON_PRESSED: + cb_click_press(server, ev); + break; + } +} + +/* + * Mouse button was released. There are only 2 different use cases: + * either we where grabbing a window to move/resize it, or not. + * In the first case, it means the operation is over, so me must + * move/resize the window. + * When it's not, the event is simply passed down to the focused window. + */ +void +cb_click_release(struct state *server, struct wlr_event_pointer_button *ev) +{ + struct wlr_box geom; + + switch(server->grabmode) { + case TELEPORT: + case RESIZE: + geom.width = server->grabbox.width; + geom.height = server->grabbox.height; + wlr_xdg_toplevel_set_size(server->grabbed->toplevel, geom.width, geom.height); + /* FALLTHROUGH */ + case MOVE: + server->grabbed->x = server->grabbox.x; + server->grabbed->y = server->grabbox.y; + break; + + default: + /* pass down event when not grabbing a window */ + wlr_seat_pointer_notify_button(server->seat, + ev->time_msec, ev->button, ev->state); - } - server->grabmode = NORMAL; - return; } + server->grabmode = NORMAL; +} - if (kb->modifiers.depressed & WLR_MODIFIER_LOGO && ev->button == BTN_MIDDLE) { - server->grabmode = TELEPORT; - server->grabbox.x = server->cursor->x; - server->grabbox.y = server->cursor->y; - server->grabbox.width = 1; - server->grabbox.height = 1; +/* + * Mouse button was pressed. If the modifier key is held down, we enter + * the "grab mode", which will move and/or resize the clicked or focused + * window, and will terminate when the button is released. + */ +void +cb_click_press(struct state *server, struct wlr_event_pointer_button *ev) +{ + struct window *w; + struct wlr_keyboard *kb; + struct wlr_box geom; + + /* Ignore all press events when a window is grabbed */ + if (server->grabmode != NORMAL) return; - } - /* stop processing if no window is under the cursor */ - if (!(w = underneath(server, server->cursor->x, server->cursor->y))) + kb = wlr_seat_get_keyboard(server->seat); + + if (kb->modifiers.depressed != mousemod) { + wlr_seat_pointer_notify_button(server->seat, + ev->time_msec, ev->button, ev->state); return; + } - if ((w->area == BORDER || (kb->modifiers.depressed & WLR_MODIFIER_LOGO)) - && ev->state == WLR_BUTTON_PRESSED - && server->grabmode == NORMAL) { + w = underneath(server, server->cursor->x, server->cursor->y); + /* pass down event when not grabbing a window */ + if (w) { /* * Save which window was clicked, and the coordinates * of the event on that surface. @@ -760,31 +788,33 @@ cb_click(struct wl_listener *listener, void *data) server->grabbox.x = w->x; server->grabbox.y = w->y; - switch (ev->button) { - case BTN_LEFT: - wlr_xdg_surface_get_geometry(w->toplevel, &geom); - server->grabbox.width = geom.width; - server->grabbox.height = geom.height; - server->grabmode = MOVE; - break; - case BTN_RIGHT: - server->grabmode = RESIZE; - server->grabbox.width = w->sx + 2 * bordersize; - server->grabbox.height = w->sy + 2 * bordersize; - break; - } - } - - /* pass down event when not grabbing a window */ - if (server->grabmode == NORMAL) - wlr_seat_pointer_notify_button(server->seat, - ev->time_msec, ev->button, ev->state); + /* bring window to the front */ + wl_list_remove(&w->link); + wl_list_insert(&server->windows, &w->link); - /* bring window to the front */ - wl_list_remove(&w->link); - wl_list_insert(&server->windows, &w->link); + focus(w); + } - focus(w); + switch (ev->button) { + case BTN_MIDDLE: + server->grabmode = TELEPORT; + server->grabbox.x = server->cursor->x; + server->grabbox.y = server->cursor->y; + server->grabbox.width = 1; + server->grabbox.height = 1; + break; + case BTN_LEFT: + wlr_xdg_surface_get_geometry(w->toplevel, &geom); + server->grabmode = MOVE; + server->grabbox.width = geom.width; + server->grabbox.height = geom.height; + break; + case BTN_RIGHT: + server->grabmode = RESIZE; + server->grabbox.width = w->sx + 2 * bordersize; + server->grabbox.height = w->sy + 2 * bordersize; + break; + } } /*