spkp

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

commit 04b58256de532860bd83b89a2137732da40f057b
parent 2226711ec174f0a3b4efcb46cd57daad2fca92a2
Author: Willy Goiffon <dev@z3bra.org>
Date:   Mon,  9 Nov 2020 20:02:56 +0100

Add basic move and resize feature with the mouse

Diffstat:
Mcompositor.c | 74+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/compositor.c b/compositor.c @@ -21,11 +21,19 @@ #include <wlr/types/wlr_xcursor_manager.h> #include <wlr/types/wlr_xdg_shell.h> +#include <linux/input-event-codes.h> + #include "xdg-shell-protocol.h" #include "arg.h" #include "config.h" +enum { + NORMAL, + MOVE, + RESIZE, +}; + /* keep track of internal compositor state */ struct state { struct wl_display *dpy; @@ -36,6 +44,9 @@ struct state { struct wlr_seat *seat; + int grabmode; + struct window *grabbed; + struct wlr_cursor *cursor; struct wlr_xcursor_manager *cursor_mgr; @@ -414,7 +425,8 @@ cb_kb_key(struct wl_listener *listener, void *data) } } -void cb_req_cursor(struct wl_listener *listener, void *data) +void +cb_req_cursor(struct wl_listener *listener, void *data) { struct state *server; struct wlr_seat_pointer_request_set_cursor_event *ev; @@ -429,7 +441,8 @@ void cb_req_cursor(struct wl_listener *listener, void *data) } -void cb_motion(struct state *server, uint32_t time) +void +cb_motion(struct state *server, uint32_t time) { double x, y, sx, sy; struct window *w; @@ -438,6 +451,25 @@ void cb_motion(struct state *server, uint32_t time) seat = server->seat; + w = server->grabbed; + + struct wlr_box geom; + switch(server->grabmode) { + case MOVE: + wlr_xdg_surface_get_geometry(w->surface, &geom); + w->x = server->cursor->x - geom.width/2; + w->y = server->cursor->y - geom.height/2; + return; /* NOTREACHED */; + break; + case RESIZE: + wlr_xdg_surface_get_geometry(w->surface, &geom); + geom.width = server->cursor->x - w->x; + geom.height = server->cursor->y - w->y; + wlr_xdg_toplevel_set_size(w->surface, geom.width, geom.height); + return; /* NOTREACHED */; + break; + } + /* * reset focus and cursor image when no window is under the * pointer @@ -467,7 +499,8 @@ void cb_motion(struct state *server, uint32_t time) /* * Cursor moved, reporting relative coordinates. */ -void cb_motion_relative(struct wl_listener *listener, void *data) +void +cb_motion_relative(struct wl_listener *listener, void *data) { struct state *server; struct wlr_event_pointer_motion *ev; @@ -476,11 +509,11 @@ void cb_motion_relative(struct wl_listener *listener, void *data) ev = data; wlr_cursor_move(server->cursor, ev->device, ev->delta_x, ev->delta_y); - cb_motion(server, ev->time_msec); } -void cb_motion_absolute(struct wl_listener *listener, void *data) +void +cb_motion_absolute(struct wl_listener *listener, void *data) { struct state *server; struct wlr_event_pointer_motion_absolute *ev; @@ -489,27 +522,44 @@ void cb_motion_absolute(struct wl_listener *listener, void *data) ev = data; wlr_cursor_warp_absolute(server->cursor, ev->device, ev->x, ev->y); - cb_motion(server, ev->time_msec); } -void cb_click(struct wl_listener *listener, void *data) +void +cb_click(struct wl_listener *listener, void *data) { double x, y, sx, sy; struct state *server; struct wlr_event_pointer_button *ev; struct window *w; struct wlr_surface *surface; + struct wlr_keyboard *kb; server = wl_container_of(listener, server, click); + kb = wlr_seat_get_keyboard(server->seat); ev = data; + w = underneath(server, server->cursor->x, server->cursor->y); + if (kb->modifiers.depressed & WLR_MODIFIER_LOGO && ev->state == WLR_BUTTON_PRESSED) { + switch (ev->button) { + case BTN_LEFT: + server->grabbed = w; + server->grabmode = MOVE; + break; + case BTN_RIGHT: + server->grabbed = w; + server->grabmode = RESIZE; + break; + } + } + wlr_seat_pointer_notify_button(server->seat, ev->time_msec, ev->button, ev->state); - if (ev->state == WLR_BUTTON_RELEASED) + if (ev->state == WLR_BUTTON_RELEASED) { + server->grabmode = NORMAL; return; + } - w = underneath(server, server->cursor->x, server->cursor->y); if (!w) { wlr_seat_pointer_clear_focus(server->seat); return; @@ -530,7 +580,8 @@ void cb_click(struct wl_listener *listener, void *data) } -void cb_scroll(struct wl_listener *listener, void *data) +void +cb_scroll(struct wl_listener *listener, void *data) { struct state *server; struct wlr_event_pointer_axis *ev; @@ -542,7 +593,8 @@ void cb_scroll(struct wl_listener *listener, void *data) ev->delta, ev->delta_discrete, ev->source); } -void cb_paint_cursor(struct wl_listener *listener, void *data) +void +cb_paint_cursor(struct wl_listener *listener, void *data) { struct state *server;