feat: add drag_corner drag_warp_cursor

This commit is contained in:
DreamMaoMao 2026-01-21 13:43:40 +08:00
parent d78526d1e9
commit 49921eadfa
4 changed files with 65 additions and 11 deletions

View file

@ -243,6 +243,8 @@ typedef struct {
int32_t idleinhibit_ignore_visible;
int32_t sloppyfocus;
int32_t warpcursor;
int32_t drag_corner;
int32_t drag_warp_cursor;
/* keyboard */
int32_t repeat_rate;
@ -1475,6 +1477,10 @@ void parse_option(Config *config, char *key, char *value) {
config->sloppyfocus = atoi(value);
} else if (strcmp(key, "warpcursor") == 0) {
config->warpcursor = atoi(value);
} else if (strcmp(key, "drag_corner") == 0) {
config->drag_corner = atoi(value);
} else if (strcmp(key, "drag_warp_cursor") == 0) {
config->drag_warp_cursor = atoi(value);
} else if (strcmp(key, "smartgaps") == 0) {
config->smartgaps = atoi(value);
} else if (strcmp(key, "repeat_rate") == 0) {
@ -2757,6 +2763,8 @@ void override_config(void) {
CLAMP_INT(config.idleinhibit_ignore_visible, 0, 1);
sloppyfocus = CLAMP_INT(config.sloppyfocus, 0, 1);
warpcursor = CLAMP_INT(config.warpcursor, 0, 1);
drag_corner = CLAMP_INT(config.drag_corner, 0, 4);
drag_warp_cursor = CLAMP_INT(config.drag_warp_cursor, 0, 1);
focus_cross_monitor = CLAMP_INT(config.focus_cross_monitor, 0, 1);
exchange_cross_monitor = CLAMP_INT(config.exchange_cross_monitor, 0, 1);
scratchpad_cross_monitor = CLAMP_INT(config.scratchpad_cross_monitor, 0, 1);
@ -2954,6 +2962,8 @@ void set_value_default() {
config.cursor_hide_timeout = cursor_hide_timeout;
config.warpcursor = warpcursor; /* Warp cursor to focused client */
config.drag_corner = drag_corner;
config.drag_warp_cursor = drag_warp_cursor;
config.repeat_rate = repeat_rate;
config.repeat_delay = repeat_delay;

View file

@ -101,7 +101,9 @@ int32_t overviewgappo = 30; /* overview时 窗口与窗口 缝隙大小 */
* behavior */
float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
int32_t warpcursor = 1; /* Warp cursor to focused client */
int32_t warpcursor = 1;
int32_t drag_corner = 3;
int32_t drag_warp_cursor = 1;
int32_t xwayland_persistence = 1; /* xwayland persistence */
int32_t syncobj_enable = 0;
int32_t adaptive_sync = 0;

View file

@ -338,6 +338,9 @@ int32_t killclient(const Arg *arg) {
}
int32_t moveresize(const Arg *arg) {
const char *cursors[] = {"nw-resize", "ne-resize", "sw-resize",
"se-resize"};
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
return 0;
xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL);
@ -363,10 +366,29 @@ int32_t moveresize(const Arg *arg) {
/* Doesn't work for X11 output - the next absolute motion event
* returns the cursor to where it started */
if (grabc->isfloating) {
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, "bottom_right_corner");
rzcorner = drag_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 (drag_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]);
} else {
wlr_cursor_set_xcursor(cursor, cursor_mgr, "grab");
}

View file

@ -841,6 +841,7 @@ static struct wl_list inputdevices;
static struct wl_list keyboard_shortcut_inhibitors;
static uint32_t cursor_mode;
static Client *grabc;
static int32_t rzcorner;
static int32_t grabcx, grabcy; /* client-relative */
static int32_t drag_begin_cursorx, drag_begin_cursory; /* client-relative */
static bool start_drag_window = false;
@ -3988,6 +3989,30 @@ void motionabsolute(struct wl_listener *listener, void *data) {
motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
}
void resize_floating_window(Client *grabc) {
int cdx = (int)round(cursor->x) - grabcx;
int cdy = (int)round(cursor->y) - grabcy;
cdx = !(rzcorner & 1) && grabc->geom.width - 2 * (int)grabc->bw - cdx < 1
? 0
: cdx;
cdy = !(rzcorner & 2) && grabc->geom.height - 2 * (int)grabc->bw - cdy < 1
? 0
: cdy;
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)};
grabc->float_geom = box;
resize(grabc, box, 1);
grabcx += cdx;
grabcy += cdy;
}
void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
double dy, double dx_unaccel, double dy_unaccel) {
double sx = 0, sy = 0, sx_confined, sy_confined;
@ -4065,14 +4090,9 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
} else if (cursor_mode == CurResize) {
if (grabc->isfloating) {
grabc->iscustomsize = 1;
grabc->float_geom = (struct wlr_box){
.x = grabc->geom.x,
.y = grabc->geom.y,
.width = (int32_t)round(cursor->x) - grabc->geom.x,
.height = (int32_t)round(cursor->y) - grabc->geom.y};
if (last_apply_drap_time == 0 ||
time - last_apply_drap_time > drag_refresh_interval) {
resize(grabc, grabc->float_geom, 1);
resize_floating_window(grabc);
last_apply_drap_time = time;
}
return;