tRefactor mouse click events handling - spkp - Stacking wayland compositor
(HTM) git clone git://git.z3bra.org/spkp.git
(DIR) Log
(DIR) Files
(DIR) Refs
---
(DIR) commit a8b09a56046536686e6a00db338d02e08d5fb05d
(DIR) parent 08dafffce80305abfea7da9365ac9850f4b7f8c1
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Sun, 15 Nov 2020 16:02:04 +0100
Refactor mouse click events handling
Diffstat:
M config.def.h | 2 ++
M sp:kp.c | 150 +++++++++++++++++++-------------
2 files changed, 92 insertions(+), 60 deletions(-)
---
(DIR) diff --git a/config.def.h b/config.def.h
t@@ -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;
(DIR) diff --git a/sp:kp.c b/sp:kp.c
t@@ -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 *);
t@@ -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.
t@@ -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;
+ }
}
/*