spkp

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

commit fc214f1bdbd96f8c8f6518120db23768668042ab
parent cf4434bc0566759fbf2d1abf96cc6c2555673896
Author: Willy Goiffon <dev@z3bra.org>
Date:   Mon, 16 Nov 2020 16:04:59 +0100

Refactor window grabbing code

Diffstat:
Msp:kp.c | 186++++++++++++++++++++++++++++++++++++++-----------------------------------------
1 file changed, 89 insertions(+), 97 deletions(-)

diff --git a/sp:kp.c b/sp:kp.c @@ -33,18 +33,15 @@ #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) +#define DELTA(a,b) ((a)>(b)?(a)-(b):(b)-(a)) + #define CLEANMASK(mask) (mask & ~(WLR_MODIFIER_CAPS|WLR_MODIFIER_SHIFT)) enum { NORMAL, + UNGRAB, MOVE, RESIZE, - TELEPORT, -}; - -enum { - CONTENT, - BORDER, }; /* Internal compositor state */ @@ -59,10 +56,11 @@ struct spkp { int desktop; /* wether desktop is visible */ - int grabmode; - double gx, gy; - struct wlr_box grabbox; - struct window *grabbed; + struct { + int mode; + struct wlr_box box; + struct window *window; + } grab; struct wlr_cursor *cursor; struct wlr_xcursor_manager *cursor_mgr; @@ -111,7 +109,6 @@ struct window { int mapped; double sx, sy; - int area; struct wl_listener map; struct wl_listener unmap; @@ -200,6 +197,8 @@ static void add_pointer(struct spkp *, struct wlr_input_device *); static void render(struct wlr_surface *, int, int, void *); static void render_border(struct wlr_box *, struct rdata *, float *); static void focus(struct window *); +static void grab(struct window *, int, const char *); + static int dropprivilege(); static int keybinding(struct spkp *, uint32_t, uint32_t, enum wlr_key_state); static struct window *underneath(struct spkp *, double, double); @@ -366,8 +365,8 @@ cb_frame_output(struct wl_listener *listener, void *data) wlr_xdg_surface_for_each_surface(window->xdg, render, &rdata); } - if (server->grabmode != NORMAL) - render_border(&server->grabbox, &rdata, drawcolor); + if (server->grab.mode != NORMAL) + render_border(&server->grab.box, &rdata, drawcolor); /* render cursor by software in case the GPU doesn't handle it */ wlr_output_render_software_cursors(wlr_output, NULL); @@ -656,38 +655,33 @@ cb_motion(struct spkp *server, uint32_t time) seat = server->seat; - w = server->grabbed; - - switch(server->grabmode) { - case MOVE: - server->grabbox.x = server->cursor->x - server->gx; - server->grabbox.y = server->cursor->y - server->gy; - return; /* NOTREACHED */; - break; - case RESIZE: /* FALLTHROUGH */ - case TELEPORT: - server->grabbox.width = MAX(server->cursor->x - server->grabbox.x, 1); - server->grabbox.height = MAX(server->cursor->y - server->grabbox.y, 1); - return; - } - /* * reset focus and cursor image when no window is under the * pointer */ - w = underneath(server, server->cursor->x, server->cursor->y); - if (!w) { - wlr_seat_pointer_clear_focus(seat); + switch(server->grab.mode) { + case MOVE: + server->grab.box.x = server->cursor->x - server->grab.window->sx; + server->grab.box.y = server->cursor->y - server->grab.window->sy; + break; + case RESIZE: + server->grab.box.width = MAX(server->cursor->x - server->grab.box.x, 1); + server->grab.box.height = MAX(server->cursor->y - server->grab.box.y, 1); + break; + case NORMAL: wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, "left_ptr", server->cursor); - return; - } + w = underneath(server, server->cursor->x, server->cursor->y); + if (!w) { + wlr_seat_pointer_clear_focus(seat); + return; + } - if (w->surface) { - if (seat->pointer_state.focused_surface == w->surface) - wlr_seat_pointer_notify_motion(seat, time, w->sx, w->sy); - else + /* focus pointer when moving to a different surface */ + if (seat->pointer_state.focused_surface != w->surface) wlr_seat_pointer_notify_enter(seat, w->surface, w->sx, w->sy); + + wlr_seat_pointer_notify_motion(seat, time, w->sx, w->sy); } } @@ -763,28 +757,25 @@ cb_click(struct wl_listener *listener, void *data) void cb_click_release(struct spkp *server, struct wlr_event_pointer_button *ev) { - struct wlr_box geom; - - switch(server->grabmode) { - case TELEPORT: + switch(server->grab.mode) { case RESIZE: - geom.width = server->grabbox.width; - geom.height = server->grabbox.height; - wlr_xdg_toplevel_set_size(server->grabbed->xdg, geom.width, geom.height); - /* FALLTHROUGH */ + wlr_xdg_toplevel_set_size(server->grab.window->xdg, + server->grab.box.width, + server->grab.box.height); + break; case MOVE: - server->grabbed->x = server->grabbox.x; - server->grabbed->y = server->grabbox.y; + server->grab.window->x = server->grab.box.x; + server->grab.window->y = server->grab.box.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); - + ev->time_msec, ev->button, ev->state); + return; } - server->grabmode = NORMAL; + if (server->grab.mode != NORMAL) + grab(server->grab.window, UNGRAB, "left_ptr"); } /* @@ -797,34 +788,22 @@ cb_click_press(struct spkp *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) + if (server->grab.mode != NORMAL) return; kb = wlr_seat_get_keyboard(server->seat); w = underneath(server, server->cursor->x, server->cursor->y); + if (!w) + return; - /* pass down event when not grabbing a window */ - if (w) { - /* - * Save which window was clicked, and the coordinates - * of the event on that surface. - */ - server->grabbed = w; - server->gx = w->sx; - server->gy = w->sy; - server->grabbox.x = w->x; - server->grabbox.y = w->y; - - /* 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); if (kb->modifiers.depressed != mousemod) { wlr_seat_pointer_notify_button(server->seat, @@ -834,23 +813,11 @@ cb_click_press(struct spkp *server, struct wlr_event_pointer_button *ev) } 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->xdg, &geom); - server->grabmode = MOVE; - server->grabbox.width = geom.width; - server->grabbox.height = geom.height; + grab(w, MOVE, "hand2"); break; case BTN_RIGHT: - server->grabmode = RESIZE; - server->grabbox.width = w->sx + 2 * bordersize; - server->grabbox.height = w->sy + 2 * bordersize; + grab(w, RESIZE, "bottom_right_corner"); break; } } @@ -1036,13 +1003,47 @@ focus(struct window *window) wlr_xdg_toplevel_set_activated(toplevel, false); } - server->grabbed = window; - /* give keyboard focus to the toplevel window */ wlr_seat_keyboard_notify_enter(seat, window->xdg->surface, kb->keycodes, kb->num_keycodes, &kb->modifiers); } +void +grab(struct window *window, int mode, const char *cursor) +{ + struct spkp *server; + + server = window->server; + + if (mode == UNGRAB) { + server->grab.mode = NORMAL; + server->grab.window = NULL; + wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, + cursor, server->cursor); + return; + } + + if (server->grab.mode != NORMAL) + return; + + server->grab.mode = mode; + server->grab.window = window; + wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, + cursor, server->cursor); + + switch (mode) { + case MOVE: + wlr_xdg_surface_get_geometry(window->xdg, &(server->grab.box)); + server->grab.box.x = window->x; + server->grab.box.y = window->y; + break; + case RESIZE: + server->grab.box.x = window->x; + server->grab.box.y = window->y; + break; + } +} + /* * Drop current privileges to run as current user. */ @@ -1107,18 +1108,8 @@ underneath(struct spkp *server, double x, double y) w->surface = wlr_xdg_surface_surface_at(w->xdg, x - w->x, y - w->y, &w->sx, &w->sy); - if (w->surface) { - w->area = CONTENT; + if (w->surface) return w; - } - - if (server->cursor->x > w->x - bordersize - && server->cursor->y > w->y - bordersize - && server->cursor->x < w->x + w->xdg->surface->current.width + bordersize - && server->cursor->y < w->y + w->xdg->surface->current.height + bordersize) { - w->area = BORDER; - return w; - } } return NULL; @@ -1232,6 +1223,7 @@ main(int argc, char *argv[]) server.cursor = wlr_cursor_create(); server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24); + server.grab.mode = NORMAL; wl_list_init(&server.outputs); wl_list_init(&server.windows);