diff --git a/dwl-bak/config.def.h b/dwl-bak/config.def.h index 0e40959..5008b91 100644 --- a/dwl-bak/config.def.h +++ b/dwl-bak/config.def.h @@ -146,6 +146,8 @@ static const Key keys[] = { { MODKEY, XKB_KEY_b, togglebar, {0} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} }, { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} }, @@ -160,6 +162,14 @@ static const Key keys[] = { { MODKEY, XKB_KEY_space, setlayout, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, + { MODKEY, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 40, 0, 0 }}}, + { MODKEY, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, -40, 0, 0 }}}, + { MODKEY, XKB_KEY_Right, moveresizekb, {.v = (int []){ 40, 0, 0, 0 }}}, + { MODKEY, XKB_KEY_Left, moveresizekb, {.v = (int []){ -40, 0, 0, 0 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 0, 0, 40 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, 0, 0, -40 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, moveresizekb, {.v = (int []){ 0, 0, 40, 0 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, moveresizekb, {.v = (int []){ 0, 0, -40, 0 }}}, { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, diff --git a/dwl-bak/config.def.h.orig b/dwl-bak/config.def.h.orig index 8ccbea3..87594bc 100644 --- a/dwl-bak/config.def.h.orig +++ b/dwl-bak/config.def.h.orig @@ -29,6 +29,13 @@ static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; /* logging */ static int log_level = WLR_ERROR; +/* Autostart */ +static const char *const autostart[] = { + "wbg", "/path/to/your/image", NULL, + NULL /* terminate */ +}; + + /* 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 */ @@ -153,6 +160,14 @@ static const Key keys[] = { { MODKEY, XKB_KEY_space, setlayout, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, + { MODKEY, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 40, 0, 0 }}}, + { MODKEY, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, -40, 0, 0 }}}, + { MODKEY, XKB_KEY_Right, moveresizekb, {.v = (int []){ 40, 0, 0, 0 }}}, + { MODKEY, XKB_KEY_Left, moveresizekb, {.v = (int []){ -40, 0, 0, 0 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 0, 0, 40 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, 0, 0, -40 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, moveresizekb, {.v = (int []){ 0, 0, 40, 0 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, moveresizekb, {.v = (int []){ 0, 0, -40, 0 }}}, { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, diff --git a/dwl-bak/dwl.c b/dwl-bak/dwl.c index c6c419e..b048466 100644 --- a/dwl-bak/dwl.c +++ b/dwl-bak/dwl.c @@ -313,6 +313,7 @@ static void destroylayersurfacenotify(struct wl_listener *listener, void *data); static void destroylock(SessionLock *lock, int unlocked); static void destroylocksurface(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data); +static void moveresizekb(const Arg *arg); static void destroypointerconstraint(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data); static void destroysessionmgr(struct wl_listener *listener, void *data); @@ -338,6 +339,7 @@ static void locksession(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); static void monocle(Monitor *m); +static void movestack(const Arg *arg); static void motionabsolute(struct wl_listener *listener, void *data); static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, double sy, double sx_unaccel, double sy_unaccel); @@ -389,6 +391,7 @@ static void urgent(struct wl_listener *listener, void *data); static void view(const Arg *arg); static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualpointer(struct wl_listener *listener, void *data); +static void warpcursor(const Client *c); static Monitor *xytomon(double x, double y); static void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny); @@ -569,6 +572,7 @@ arrange(Monitor *m) m->lt[m->sellt]->arrange(m); motionnotify(0, NULL, 0, 0, 0, 0); checkidleinhibitor(NULL); + warpcursor(focustop(selmon)); } void @@ -1627,6 +1631,10 @@ focusclient(Client *c, int lift) if (locked) return; + /* Warp cursor to center of client if it is outside */ + if (lift) + warpcursor(c); + /* Raise client in stacking order if requested */ if (c && lift) wlr_scene_node_raise_to_top(&c->scene->node); @@ -2080,6 +2088,48 @@ monocle(Monitor *m) wlr_scene_node_raise_to_top(&c->scene->node); } +void +movestack(const Arg *arg) +{ + Client *c, *sel = focustop(selmon); + + if (!sel) { + return; + } + + if (wl_list_length(&clients) <= 1) { + return; + } + + if (arg->i > 0) { + wl_list_for_each(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + } else { + wl_list_for_each_reverse(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + /* backup one client */ + c = wl_container_of(c->link.prev, c, link); + } + + wl_list_remove(&sel->link); + wl_list_insert(&c->link, &sel->link); + arrange(selmon); +} + void motionabsolute(struct wl_listener *listener, void *data) { @@ -3036,6 +3086,24 @@ togglegaps(const Arg *arg) arrange(selmon); } +void +moveresizekb(const Arg *arg) +{ + Client *c = focustop(selmon); + Monitor *m = selmon; + + if(!(m && arg && arg->v && c && c->isfloating)) { + return; + } + + resize(c, (struct wlr_box){ + .x = c->geom.x + ((int *)arg->v)[0], + .y = c->geom.y + ((int *)arg->v)[1], + .width = c->geom.width + ((int *)arg->v)[2], + .height = c->geom.height + ((int *)arg->v)[3], + }, 1); +} + void toggletag(const Arg *arg) { @@ -3320,6 +3388,27 @@ virtualpointer(struct wl_listener *listener, void *data) wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); } +void +warpcursor(const Client *c) { + if (cursor_mode != CurNormal) { + return; + } + if (!c && selmon) { + wlr_cursor_warp_closest(cursor, + NULL, + selmon->w.x + selmon->w.width / 2.0 , + selmon->w.y + selmon->w.height / 2.0); + } + else if ( c && (cursor->x < c->geom.x || + cursor->x > c->geom.x + c->geom.width || + cursor->y < c->geom.y || + cursor->y > c->geom.y + c->geom.height)) + wlr_cursor_warp_closest(cursor, + NULL, + c->geom.x + c->geom.width / 2.0, + c->geom.y + c->geom.height / 2.0); +} + Monitor * xytomon(double x, double y) { diff --git a/dwl-bak/dwl.c.orig b/dwl-bak/dwl.c.orig index 4b5c419..9b5663e 100644 --- a/dwl-bak/dwl.c.orig +++ b/dwl-bak/dwl.c.orig @@ -274,6 +274,7 @@ static void arrange(Monitor *m); static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); +static void autostartexec(void); static void axisnotify(struct wl_listener *listener, void *data); static bool baracceptsinput(struct wlr_scene_buffer *buffer, double *sx, double *sy); static void bufdestroy(struct wlr_buffer *buffer); @@ -312,6 +313,7 @@ static void destroylayersurfacenotify(struct wl_listener *listener, void *data); static void destroylock(SessionLock *lock, int unlocked); static void destroylocksurface(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data); +static void moveresizekb(const Arg *arg); static void destroypointerconstraint(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data); static void destroysessionmgr(struct wl_listener *listener, void *data); @@ -337,6 +339,7 @@ static void locksession(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); static void monocle(Monitor *m); +static void movestack(const Arg *arg); static void motionabsolute(struct wl_listener *listener, void *data); static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, double sy, double sx_unaccel, double sy_unaccel); @@ -478,6 +481,9 @@ static xcb_atom_t netatom[NetLast]; /* attempt to encapsulate suck into one file */ #include "client.h" +static pid_t *autostart_pids; +static size_t autostart_len; + /* function implementations */ void applybounds(Client *c, struct wlr_box *bbox) @@ -631,6 +637,27 @@ arrangelayers(Monitor *m) } } +void +autostartexec(void) { + const char *const *p; + size_t i = 0; + + /* count entries */ + for (p = autostart; *p; autostart_len++, p++) + while (*++p); + + autostart_pids = calloc(autostart_len, sizeof(pid_t)); + for (p = autostart; *p; i++, p++) { + if ((autostart_pids[i] = fork()) == 0) { + setsid(); + execvp(*p, (char *const *)p); + die("dwl: execvp %s:", *p); + } + /* skip arguments */ + while (*++p); + } +} + void axisnotify(struct wl_listener *listener, void *data) { @@ -829,11 +856,21 @@ checkidleinhibitor(struct wlr_surface *exclude) void cleanup(void) { + size_t i; #ifdef XWAYLAND wlr_xwayland_destroy(xwayland); xwayland = NULL; #endif wl_display_destroy_clients(dpy); + + /* kill child processes */ + for (i = 0; i < autostart_len; i++) { + if (0 < autostart_pids[i]) { + kill(autostart_pids[i], SIGTERM); + waitpid(autostart_pids[i], NULL, 0); + } + } + if (child_pid > 0) { kill(-child_pid, SIGTERM); waitpid(child_pid, NULL, 0); @@ -1742,18 +1779,31 @@ void handlesig(int signo) { if (signo == SIGCHLD) { -#ifdef XWAYLAND siginfo_t in; /* wlroots expects to reap the XWayland process itself, so we * use WNOWAIT to keep the child waitable until we know it's not * XWayland. */ while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid - && (!xwayland || in.si_pid != xwayland->server->pid)) - waitpid(in.si_pid, NULL, 0); -#else - while (waitpid(-1, NULL, WNOHANG) > 0); +#ifdef XWAYLAND + && (!xwayland || in.si_pid != xwayland->server->pid) #endif + ) { + pid_t *p, *lim; + waitpid(in.si_pid, NULL, 0); + if (in.si_pid == child_pid) + child_pid = -1; + if (!(p = autostart_pids)) + continue; + lim = &p[autostart_len]; + + for (; p < lim; p++) { + if (*p == in.si_pid) { + *p = -1; + break; + } + } + } } else if (signo == SIGINT || signo == SIGTERM) { quit(NULL); } @@ -2032,6 +2082,48 @@ monocle(Monitor *m) wlr_scene_node_raise_to_top(&c->scene->node); } +void +movestack(const Arg *arg) +{ + Client *c, *sel = focustop(selmon); + + if (!sel) { + return; + } + + if (wl_list_length(&clients) <= 1) { + return; + } + + if (arg->i > 0) { + wl_list_for_each(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + } else { + wl_list_for_each_reverse(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + /* backup one client */ + c = wl_container_of(c->link.prev, c, link); + } + + wl_list_remove(&sel->link); + wl_list_insert(&c->link, &sel->link); + arrange(selmon); +} + void motionabsolute(struct wl_listener *listener, void *data) { @@ -2433,6 +2525,7 @@ run(char *startup_cmd) die("startup: backend_start"); /* Now that the socket exists and the backend is started, run the startup command */ + autostartexec(); if (startup_cmd) { if ((child_pid = fork()) < 0) die("startup: fork:"); @@ -2987,6 +3080,24 @@ togglegaps(const Arg *arg) arrange(selmon); } +void +moveresizekb(const Arg *arg) +{ + Client *c = focustop(selmon); + Monitor *m = selmon; + + if(!(m && arg && arg->v && c && c->isfloating)) { + return; + } + + resize(c, (struct wlr_box){ + .x = c->geom.x + ((int *)arg->v)[0], + .y = c->geom.y + ((int *)arg->v)[1], + .width = c->geom.width + ((int *)arg->v)[2], + .height = c->geom.height + ((int *)arg->v)[3], + }, 1); +} + void toggletag(const Arg *arg) { diff --git a/dwl.o b/dwl.o new file mode 100644 index 0000000..3f44baa Binary files /dev/null and b/dwl.o differ diff --git a/dwl/config.def.h b/dwl/config.def.h index 87594bc..5008b91 100644 --- a/dwl/config.def.h +++ b/dwl/config.def.h @@ -146,6 +146,8 @@ static const Key keys[] = { { MODKEY, XKB_KEY_b, togglebar, {0} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} }, { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} }, diff --git a/dwl/config.def.h.orig b/dwl/config.def.h.orig index 0e40959..87594bc 100644 --- a/dwl/config.def.h.orig +++ b/dwl/config.def.h.orig @@ -160,6 +160,14 @@ static const Key keys[] = { { MODKEY, XKB_KEY_space, setlayout, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, + { MODKEY, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 40, 0, 0 }}}, + { MODKEY, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, -40, 0, 0 }}}, + { MODKEY, XKB_KEY_Right, moveresizekb, {.v = (int []){ 40, 0, 0, 0 }}}, + { MODKEY, XKB_KEY_Left, moveresizekb, {.v = (int []){ -40, 0, 0, 0 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 0, 0, 40 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, 0, 0, -40 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, moveresizekb, {.v = (int []){ 0, 0, 40, 0 }}}, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, moveresizekb, {.v = (int []){ 0, 0, -40, 0 }}}, { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, diff --git a/dwl/config.mk b/dwl/config.mk index fb99950..8eb3757 100644 --- a/dwl/config.mk +++ b/dwl/config.mk @@ -14,4 +14,4 @@ XLIBS = XWAYLAND = -DXWAYLAND XLIBS = xcb xcb-icccm -CC = gcc +CC = /usr/lib/llvm/20/bin/clang diff --git a/dwl/dwl.c b/dwl/dwl.c index 1613d8c..b048466 100644 --- a/dwl/dwl.c +++ b/dwl/dwl.c @@ -339,6 +339,7 @@ static void locksession(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); static void monocle(Monitor *m); +static void movestack(const Arg *arg); static void motionabsolute(struct wl_listener *listener, void *data); static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, double sy, double sx_unaccel, double sy_unaccel); @@ -390,6 +391,7 @@ static void urgent(struct wl_listener *listener, void *data); static void view(const Arg *arg); static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualpointer(struct wl_listener *listener, void *data); +static void warpcursor(const Client *c); static Monitor *xytomon(double x, double y); static void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny); @@ -570,6 +572,7 @@ arrange(Monitor *m) m->lt[m->sellt]->arrange(m); motionnotify(0, NULL, 0, 0, 0, 0); checkidleinhibitor(NULL); + warpcursor(focustop(selmon)); } void @@ -1628,6 +1631,10 @@ focusclient(Client *c, int lift) if (locked) return; + /* Warp cursor to center of client if it is outside */ + if (lift) + warpcursor(c); + /* Raise client in stacking order if requested */ if (c && lift) wlr_scene_node_raise_to_top(&c->scene->node); @@ -2081,6 +2088,48 @@ monocle(Monitor *m) wlr_scene_node_raise_to_top(&c->scene->node); } +void +movestack(const Arg *arg) +{ + Client *c, *sel = focustop(selmon); + + if (!sel) { + return; + } + + if (wl_list_length(&clients) <= 1) { + return; + } + + if (arg->i > 0) { + wl_list_for_each(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + } else { + wl_list_for_each_reverse(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + /* backup one client */ + c = wl_container_of(c->link.prev, c, link); + } + + wl_list_remove(&sel->link); + wl_list_insert(&c->link, &sel->link); + arrange(selmon); +} + void motionabsolute(struct wl_listener *listener, void *data) { @@ -3339,6 +3388,27 @@ virtualpointer(struct wl_listener *listener, void *data) wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); } +void +warpcursor(const Client *c) { + if (cursor_mode != CurNormal) { + return; + } + if (!c && selmon) { + wlr_cursor_warp_closest(cursor, + NULL, + selmon->w.x + selmon->w.width / 2.0 , + selmon->w.y + selmon->w.height / 2.0); + } + else if ( c && (cursor->x < c->geom.x || + cursor->x > c->geom.x + c->geom.width || + cursor->y < c->geom.y || + cursor->y > c->geom.y + c->geom.height)) + wlr_cursor_warp_closest(cursor, + NULL, + c->geom.x + c->geom.width / 2.0, + c->geom.y + c->geom.height / 2.0); +} + Monitor * xytomon(double x, double y) { diff --git a/dwl/dwl.c.orig b/dwl/dwl.c.orig index c6c419e..9b5663e 100644 --- a/dwl/dwl.c.orig +++ b/dwl/dwl.c.orig @@ -313,6 +313,7 @@ static void destroylayersurfacenotify(struct wl_listener *listener, void *data); static void destroylock(SessionLock *lock, int unlocked); static void destroylocksurface(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data); +static void moveresizekb(const Arg *arg); static void destroypointerconstraint(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data); static void destroysessionmgr(struct wl_listener *listener, void *data); @@ -338,6 +339,7 @@ static void locksession(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); static void monocle(Monitor *m); +static void movestack(const Arg *arg); static void motionabsolute(struct wl_listener *listener, void *data); static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, double sy, double sx_unaccel, double sy_unaccel); @@ -2080,6 +2082,48 @@ monocle(Monitor *m) wlr_scene_node_raise_to_top(&c->scene->node); } +void +movestack(const Arg *arg) +{ + Client *c, *sel = focustop(selmon); + + if (!sel) { + return; + } + + if (wl_list_length(&clients) <= 1) { + return; + } + + if (arg->i > 0) { + wl_list_for_each(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + } else { + wl_list_for_each_reverse(c, &sel->link, link) { + if (&c->link == &clients) { + c = wl_container_of(&clients, c, link); + break; /* wrap past the sentinel node */ + } + if (VISIBLEON(c, selmon) || &c->link == &clients) { + break; /* found it */ + } + } + /* backup one client */ + c = wl_container_of(c->link.prev, c, link); + } + + wl_list_remove(&sel->link); + wl_list_insert(&c->link, &sel->link); + arrange(selmon); +} + void motionabsolute(struct wl_listener *listener, void *data) { @@ -3036,6 +3080,24 @@ togglegaps(const Arg *arg) arrange(selmon); } +void +moveresizekb(const Arg *arg) +{ + Client *c = focustop(selmon); + Monitor *m = selmon; + + if(!(m && arg && arg->v && c && c->isfloating)) { + return; + } + + resize(c, (struct wlr_box){ + .x = c->geom.x + ((int *)arg->v)[0], + .y = c->geom.y + ((int *)arg->v)[1], + .width = c->geom.width + ((int *)arg->v)[2], + .height = c->geom.height + ((int *)arg->v)[3], + }, 1); +} + void toggletag(const Arg *arg) {