better-resize: 0.7

This commit is contained in:
mmistika 2025-07-17 15:50:26 +02:00
parent 12747d1fc6
commit 07ad746a6f
No known key found for this signature in database
2 changed files with 155 additions and 0 deletions

View File

@ -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)

View File

@ -0,0 +1,107 @@
From f109808140cd6323b3a100663a10e048ae32e3a0 Mon Sep 17 00:00:00 2001
From: mmistika <mistikasoft@gmail.com>
Date: Thu, 17 Jul 2025 11:59:18 +0200
Subject: [PATCH] Add configurable window resize
Signed-off-by: mmistika <mistikasoft@gmail.com>
---
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: dont 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