From 07ad746a6fc90d833497253d891eb0519ad8ed49 Mon Sep 17 00:00:00 2001 From: mmistika Date: Thu, 17 Jul 2025 15:50:26 +0200 Subject: [PATCH] better-resize: 0.7 --- patches/better-resize/README.md | 48 ++++++++ patches/better-resize/better-resize-0.7.patch | 107 ++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 patches/better-resize/README.md create mode 100644 patches/better-resize/better-resize-0.7.patch diff --git a/patches/better-resize/README.md b/patches/better-resize/README.md new file mode 100644 index 0000000..9c43862 --- /dev/null +++ b/patches/better-resize/README.md @@ -0,0 +1,48 @@ +### Description +This patch allows you to configure window resizing more flexibly. +It introduces three options with the following possible values: + +- warp_cursor: +``` + 0 - the mouse cursor remains in its original position at the start of the resize. + 1 - the cursor is automatically warped to the selected corner before resizing begins. +``` + +- lock_cursor: +``` + 0 - the cursor can move freely during the resize. + 1 - the cursor position is completely frozen for the entire duration of the resize. +``` + +- resize_corner: +``` + 0: top-left + 1: top-right + 2: bottom-left + 3: bottom-right + 4: selects the corner based on the current mouse quadrant +``` + +### Demos +All demos below use resize_corner = 4: +| no warp + no lock | warp + lock | +|-|-| +| ![demo-nowarp-nolock](https://github.com/mmistika/dwl-better-resize/blob/main/demo/demo-nowarp-nolock.gif?raw=true) | ![demo-warp-lock](https://github.com/mmistika/dwl-better-resize/blob/main/demo/demo-warp-lock.gif?raw=true) | + +| no warp + lock | warp + no lock | +|-|-| +| ![demo-nowarp-lock](https://github.com/mmistika/dwl-better-resize/blob/main/demo/demo-nowarp-lock.gif?raw=true) | ![demo-warp-nolock](https://github.com/mmistika/dwl-better-resize/blob/main/demo/demo-warp-nolock.gif?raw=true) | + +### Known Issues (warp + lock) +The combination of warp_cursor and lock_cursor is not recommended without outer gaps. +If the selected resize corner aligns exactly with a screen corner, the cursor gets locked there and cannot be moved outward, so resizing only works inward. +To resize outward, you must restart the resize operation with the cursor positioned somewhere away from the screen corner. +This happens because the locked cursor cannot move past the screen edge, and therefore cannot generate a non-zero delta to resize outward. + +On multihead setups, if the resize corner is near another screen, the window may switch monitors upon completion of the resize. + +### Download +- [0.7](/dwl/dwl-patches/raw/branch/main/patches/better-resize/better-resize-0.7.patch) + +### Authors +- [mmistika](https://codeberg.org/mmistika) diff --git a/patches/better-resize/better-resize-0.7.patch b/patches/better-resize/better-resize-0.7.patch new file mode 100644 index 0000000..1269800 --- /dev/null +++ b/patches/better-resize/better-resize-0.7.patch @@ -0,0 +1,107 @@ +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 +