tRefactor window grabbing code - spkp - Stacking wayland compositor
(HTM) git clone git://git.z3bra.org/spkp.git
(DIR) Log
(DIR) Files
(DIR) Refs
---
(DIR) commit fc214f1bdbd96f8c8f6518120db23768668042ab
(DIR) parent cf4434bc0566759fbf2d1abf96cc6c2555673896
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Mon, 16 Nov 2020 16:04:59 +0100
Refactor window grabbing code
Diffstat:
M sp:kp.c | 186 +++++++++++++++----------------
1 file changed, 89 insertions(+), 97 deletions(-)
---
(DIR) diff --git a/sp:kp.c b/sp:kp.c
t@@ -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 */
t@@ -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;
t@@ -111,7 +109,6 @@ struct window {
int mapped;
double sx, sy;
- int area;
struct wl_listener map;
struct wl_listener unmap;
t@@ -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);
t@@ -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);
t@@ -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);
}
}
t@@ -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");
}
/*
t@@ -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,
t@@ -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;
}
}
t@@ -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.
*/
t@@ -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;
t@@ -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);