From f109808140cd6323b3a100663a10e048ae32e3a0 Mon Sep 17 00:00:00 2001 From: mmistika Date: Thu, 17 Jul 2025 11:59:18 +0200 Subject: [PATCH] Add configurable window resize Signed-off-by: mmistika --- config.def.h | 12 ++++++++++++ dwl.c | 45 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/config.def.h b/config.def.h index 22d2171..e404549 100644 --- a/config.def.h +++ b/config.def.h @@ -20,6 +20,18 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca /* logging */ static int log_level = WLR_ERROR; +/* window resizing */ +/* resize_corner: + * 0: top-left + * 1: top-right + * 2: bottom-left + * 3: bottom-right + * 4: closest to the cursor + */ +static const int resize_corner = 4; +static const int warp_cursor = 1; /* 1: warp to corner, 0: don’t warp */ +static const int lock_cursor = 0; /* 1: lock cursor, 0: don't lock */ + /* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */ static const Rule rules[] = { /* app_id title tags mask isfloating monitor */ diff --git a/dwl.c b/dwl.c index c717c1d..aacd074 100644 --- a/dwl.c +++ b/dwl.c @@ -407,6 +407,7 @@ static KeyboardGroup *kb_group; static unsigned int cursor_mode; static Client *grabc; static int grabcx, grabcy; /* client-relative */ +static int rzcorner; static struct wlr_output_layout *output_layout; static struct wlr_box sgeom; @@ -1873,8 +1874,24 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d .width = grabc->geom.width, .height = grabc->geom.height}, 1); return; } else if (cursor_mode == CurResize) { - resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, - .width = (int)round(cursor->x) - grabc->geom.x, .height = (int)round(cursor->y) - grabc->geom.y}, 1); + int cdx = (int)round(cursor->x) - grabcx; + int cdy = (int)round(cursor->y) - grabcy; + + const struct wlr_box box = { + .x = grabc->geom.x + (rzcorner & 1 ? 0 : cdx), + .y = grabc->geom.y + (rzcorner & 2 ? 0 : cdy), + .width = grabc->geom.width + (rzcorner & 1 ? cdx : -cdx), + .height = grabc->geom.height + (rzcorner & 2 ? cdy : -cdy) + }; + resize(grabc, box, 1); + + if (!lock_cursor) { + grabcx += cdx; + grabcy += cdy; + } else { + wlr_cursor_warp_closest(cursor, NULL, grabcx, grabcy); + } + return; } @@ -1920,12 +1937,24 @@ moveresize(const Arg *arg) wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); break; case CurResize: - /* Doesn't work for X11 output - the next absolute motion event - * returns the cursor to where it started */ - wlr_cursor_warp_closest(cursor, NULL, - grabc->geom.x + grabc->geom.width, - grabc->geom.y + grabc->geom.height); - wlr_cursor_set_xcursor(cursor, cursor_mgr, "se-resize"); + const char *cursors[] = { "nw-resize", "ne-resize", "sw-resize", "se-resize" }; + + rzcorner = resize_corner; + grabcx = (int)round(cursor->x); + grabcy = (int)round(cursor->y); + + if (rzcorner == 4) + /* identify the closest corner index */ + rzcorner = (grabcx - grabc->geom.x < grabc->geom.x + grabc->geom.width - grabcx ? 0 : 1) + + (grabcy - grabc->geom.y < grabc->geom.y + grabc->geom.height - grabcy ? 0 : 2); + + if (warp_cursor) { + grabcx = rzcorner & 1 ? grabc->geom.x + grabc->geom.width : grabc->geom.x; + grabcy = rzcorner & 2 ? grabc->geom.y + grabc->geom.height : grabc->geom.y; + wlr_cursor_warp_closest(cursor, NULL, grabcx, grabcy); + } + + wlr_cursor_set_xcursor(cursor, cursor_mgr, cursors[rzcorner]); break; } } -- 2.50.1