spkp

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

commit 1813f99552e6c439f35ea791a67b413734820345
parent 2d59a0706e0f4c00478a50b3b7e027a179bf7a78
Author: Willy Goiffon <dev@z3bra.org>
Date:   Fri, 13 Nov 2020 15:49:07 +0100

Use a drawing box to move/resize windows

Diffstat:
Mcompositor.c | 85++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 52 insertions(+), 33 deletions(-)

diff --git a/compositor.c b/compositor.c @@ -29,6 +29,7 @@ #include "arg.h" +#define MAX(a,b) ((a)>(b)?(a):(b)) #define CLEANMASK(mask) (mask & ~(WLR_MODIFIER_CAPS|WLR_MODIFIER_SHIFT)) enum { @@ -54,6 +55,7 @@ struct state { int grabmode; double gx, gy; + struct wlr_box grabbox; struct window *grabbed; struct wlr_cursor *cursor; @@ -335,17 +337,22 @@ cb_frame_output(struct wl_listener *listener, void *data) wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); wlr_renderer_clear(renderer, background); + rdata.output = wlr_output; + rdata.renderer = renderer; + wl_list_for_each_reverse(window, &output->server->windows, link) { if (!window->mapped) continue; - rdata.output = wlr_output; rdata.window = window; - rdata.renderer = renderer; clock_gettime(CLOCK_MONOTONIC, &rdata.when); wlr_xdg_surface_for_each_surface(window->toplevel, render, &rdata); } + struct state *server = output->server; + if (server->grabmode != NORMAL) + render_border(&server->grabbox, &rdata, 1); + /* render cursor by software in case the GPU doesn't handle it */ wlr_output_render_software_cursors(wlr_output, NULL); @@ -585,21 +592,16 @@ cb_motion(struct state *server, uint32_t time) w = server->grabbed; - struct wlr_box geom; switch(server->grabmode) { case MOVE: - wlr_xdg_surface_get_geometry(w->toplevel, &geom); - w->x = server->cursor->x - server->gx; - w->y = server->cursor->y - server->gy; + server->grabbox.x = server->cursor->x - server->gx; + server->grabbox.y = server->cursor->y - server->gy; return; /* NOTREACHED */; break; case RESIZE: - wlr_xdg_surface_get_geometry(w->toplevel, &geom); - geom.width = server->cursor->x - geom.x - w->x; - geom.height = server->cursor->y - geom.y - w->y; - wlr_xdg_toplevel_set_size(w->toplevel, geom.width, geom.height); - return; /* NOTREACHED */; - break; + server->grabbox.width = MAX(server->cursor->x - server->grabbox.x, 100); + server->grabbox.height = MAX(server->cursor->y - server->grabbox.y, 100); + return; } /* @@ -672,52 +674,69 @@ cb_click(struct wl_listener *listener, void *data) 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: + server->grabbed->x = server->grabbox.x; + server->grabbed->y = server->grabbox.y; + break; + 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); + + } + server->grabmode = NORMAL; + return; + } + w = underneath(server, server->cursor->x, server->cursor->y); /* don't enter grab mode when there is no window under the pointer */ if (!w) { - wlr_seat_pointer_clear_focus(server->seat); - server->grabmode = NORMAL; return; } if ((w->area == BORDER || (kb->modifiers.depressed & WLR_MODIFIER_LOGO)) && ev->state == WLR_BUTTON_PRESSED && server->grabmode == NORMAL) { + + /* + * 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; + 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); - - /* every release event would reset the grab mode */ - if (ev->state == WLR_BUTTON_RELEASED) { - server->grabmode = NORMAL; - return; - } - - /* - * 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; - /* bring window to the front */ wl_list_remove(&w->link); wl_list_insert(&server->windows, &w->link);