added movestack patch

This commit is contained in:
λmolinae 2025-04-01 16:19:42 -06:00
parent eeae37586f
commit fa874b6f97
4 changed files with 164 additions and 33 deletions

View file

@ -17,6 +17,7 @@ philosophy. Like dwm, dwl is:
- [attachtop](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/attachtop)
- [autostart](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/autostart)
- [bar](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/bar)
- [barcolors](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/barcolors)
- [barheight](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/barheight)
- [centeredmaster](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/centeredmaster)
- [column](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/column)
@ -26,6 +27,7 @@ philosophy. Like dwm, dwl is:
- [genericgaps](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/genericgaps)
- [hide_vacant_tags](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/hide_vacant_tags)
- [inputdevicerules](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/inputdevicerules)
- [movestack](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/movestack)
- [nextlayout](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/nextlayout)
- [pertag](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/pertag)
- [primaryselection](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/primaryselection)

View file

@ -15,6 +15,7 @@ static const float rootcolor[] = COLOR(0x000000ff);
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */
static float swallowborder = 1.0f; /* add this multiplied by borderpx to border when a client is swallowed */
static const char *cursor_theme = NULL;
static const char cursor_size[] = "24"; /* Make sure it's a valid integer, otherwise things will break */
static uint32_t colors[][3] = {
@ -182,6 +183,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|WLR_MODIFIER_SHIFT, XKB_KEY_i, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_a, rotatetags, {.i = VIEW_L} },
@ -219,8 +222,8 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_n, nextlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT, XKB_KEY_a, toggleswallow, {0} },
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT, XKB_KEY_A, toggleautoswallow,{0} },
{ MODKEY, XKB_KEY_a, toggleswallow, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, toggleautoswallow,{0} },
{ MODKEY, XKB_KEY_u, togglepointer, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },

View file

@ -10,7 +10,6 @@ static const unsigned int gappih = 4; /* horiz inner gap between windo
static const unsigned int gappiv = 4; /* vert inner gap between windows */
static const unsigned int gappoh = 1; /* horiz outer gap between windows and screen edge */
static const unsigned int gappov = 1; /* vert outer gap between windows and screen edge */
static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */
static const char *cursor_theme = "macOS";
static const char cursor_size[] = "28"; /* Make sure it's a valid integer, otherwise things will break */
static const int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */
@ -19,6 +18,8 @@ static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = {"Inconsolata:size=12"};
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */
static float swallowborder = 1.0f; /* add this multiplied by borderpx to border when a client is swallowed */
enum {
VIEW_L = -1,
@ -43,8 +44,9 @@ static const Env envs[] = {
/* Autostart */
static const char *const autostart[] = {
"/usr/lib/xdg-desktop-portal", "-r", NULL,
"/usr/lib/xdg-desktop-portal-wlr", "-r", NULL,
"touch", "/tmp/swaylock-sleep", "&&", "inotifyd", "swaylock", "/tmp/swaylock-sleep", NULL,
"/usr/libexec/xdg-desktop-portal", "-r", NULL,
"/usr/libexec/xdg-desktop-portal-wlr", "-r", NULL,
"wbg", WALLPAPER, NULL,
"foot", "--server", NULL,
"swayidle", NULL,
@ -54,8 +56,8 @@ static const char *const autostart[] = {
/* 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 isterm noswallow monitor */
/* examples: */
/* app_id title tags mask isfloating isterm noswallow monitor */
/* examples: */
{ "foot", NULL, 0, 0, 1, 1, -1 }, /* make foot swallow clients that are not foot */
{ "Gimp_EXAMPLE", NULL, 0, 1, 0, 0, -1 }, /* Start on currently visible tags floating, not tiled */
{ "firefox_EXAMPLE", NULL, 1 << 8, 0, 0, 0, -1 }, /* Start on ONLY tag "9" */
@ -153,7 +155,7 @@ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
*/
static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
static const double accel_speed = 0.3;
static const double accel_speed = 0.2;
/* You can choose between:
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
@ -180,8 +182,12 @@ static const char *fmgrcmd[] = { "footclient", "--title", "lf", "lf", NULL }; //
static const char *sptfcmd[] = { "footclient", "--title", "Spotify", "spotify_player", NULL }; // Spotify client
static const char *ncmxcmd[] = { "footclient", "--title", "ncpamixer", "ncpamixer", NULL }; // Volume control
static const char *blthcmd[] = { "footclient", "--title", "bluetui", "bluetui", NULL }; // Bluetooth manager
static const char *pdfrcmd[] = { "zathura", NULL }; // PDF reader
static const char *brwscmd[] = { "librewolf", NULL }; // Web Browser
static const char *lockcmd[] = { "swaylock", NULL }; // Launch swaylock
static const char *camrcmd[] = { "camera", NULL }; // Launch mpv window showing my camera
static const char *camrcmd[] = { "camera", NULL }; // Launch mpv window showing my cameras
static const char *rgsscmd[] = { "rgnss", NULL }; // Region screenshoot
static const char *fssscmd[] = { "fsss", NULL }; // Takes screenshot
static const char *recscmd[] = { "recordscreen", NULL }; // Launch recording menu
static const char *pwmncmd[] = { "powermenu", NULL }; // Launch powermenu
static const char *emojcmd[] = { "tofiunicode", NULL }; // Launch emoji menu
@ -196,15 +202,18 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_e, spawn, {.v = fmgrcmd} },
{ MODKEY, XKB_KEY_s, spawn, {.v = sptfcmd} },
{ MODKEY, XKB_KEY_b, spawn, {.v = blthcmd} },
//{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, spawn, {.v = pdfrcmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, spawn, {.v = brwscmd} },
{ MODKEY, XKB_KEY_v, spawn, {.v = ncmxcmd} },
{ MODKEY, XKB_KEY_l, spawn, {.v = lockcmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, spawn, {.v = camrcmd} },
{ WLR_MODIFIER_SHIFT, XKB_KEY_Print, spawn, {.v = recscmd} },
{ 0, XKB_KEY_Print, spawn, {.v = rgsscmd} },
{ WLR_MODIFIER_SHIFT, XKB_KEY_Print, spawn, {.v = fssscmd} },
{ WLR_MODIFIER_CTRL, XKB_KEY_Print, spawn, {.v = recscmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, spawn, {.v = emojcmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, spawn, {.v = pwmncmd} },
{ MODKEY, XKB_KEY_Delete, spawn, {.v = btopcmd} },
{ MODKEY, XKB_KEY_m, spawn, {.v = musicmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, spawn, SHCMD("grim -g \"$(slurp -d)\" - | wl-copy") },
{ 0, XKB_KEY_XF86AudioMicMute, spawn,SHCMD("wpctl set-mute @DEFAULT_SOURCE@ toggle && pkill -RTMIN+3 slstatus") },
{ WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioLowerVolume, spawn,SHCMD("wpctl set-volume -l 1.0 @DEFAULT_SOURCE@ 5%- && pkill -RTMIN+3 slstatus") },
{ WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioRaiseVolume, spawn,SHCMD("wpctl set-volume -l 1.0 @DEFAULT_SOURCE@ 5%+ && pkill -RTMIN+3 slstatus") },
@ -217,6 +226,8 @@ static const Key keys[] = {
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, togglesticky, {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|WLR_MODIFIER_CTRL, XKB_KEY_q, incnmaster, {.i = -1} },
{ MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_e, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_a, rotatetags, {.i = VIEW_L} },

159
dwl.c
View file

@ -84,14 +84,15 @@
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]) && !(C)->swallowedby || C->issticky)
#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]) && !(C)->swallowedby)
#define LENGTH(X) (sizeof X / sizeof X[0])
#define END(A) ((A) + LENGTH(A))
#define TAGMASK ((1u << LENGTH(tags)) - 1)
#define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L)))
#define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0)
#define BORDERPX(C) (borderpx + ((C)->swallowing ? (C)->swallowing->bw : 0))
#define BORDERPX(C) (borderpx + ((C)->swallowing ? (int)ceilf(swallowborder * (C)->swallowing->bw) : 0))
#define TEXTW(mon, text) (drwl_font_getwidth(mon->drw, text) + mon->lrpad)
#define PREFIX(str, prefix) !strncmp(str, prefix, strlen(prefix))
/* enums */
enum { SchemeNorm, SchemeSel, SchemeUrg }; /* color schemes */
@ -159,11 +160,11 @@ struct Client {
unsigned int bw;
uint32_t tags;
int isfloating, isurgent, isfullscreen, issticky;
int isterm, noswallow;
int isterm, noswallow;
uint32_t resize; /* configure serial of a pending resize */
pid_t pid;
Client *swallowing; /* client being hidden */
Client *swallowedby;
pid_t pid;
Client *swallowing; /* client being hidden */
Client *swallowedby;
};
typedef struct {
@ -359,6 +360,7 @@ static void destroykeyboardgroup(struct wl_listener *listener, void *data);
static Monitor *dirtomon(enum wlr_direction dir);
static void drawbar(Monitor *m);
static void drawbars(void);
static int drawstatus(Monitor *m);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
@ -384,6 +386,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);
@ -418,9 +421,9 @@ static void setmon(Client *c, Monitor *m, uint32_t newtags);
static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
static void swallow(Client *c, Client *toswallow);
static void spawn(const Arg *arg);
static void startdrag(struct wl_listener *listener, void *data);
static void swallow(Client *c, Client *toswallow);
static int statusin(int fd, unsigned int mask, void *data);
static void switchxkbrule(const Arg *arg);
static void tag(const Arg *arg);
@ -511,7 +514,7 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
static char stext[256];
static char stext[512];
static struct wl_event_source *status_event_source;
static const struct wlr_buffer_impl buffer_impl = {
@ -1872,11 +1875,8 @@ drawbar(Monitor *m)
return;
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
drwl_setscheme(m->drw, colors[SchemeNorm]);
tw = TEXTW(m, stext) - m->lrpad + 2; /* 2px right padding */
drwl_text(m->drw, m->b.width - tw, 0, tw, m->b.height, 0, stext, 0);
}
if (m == selmon) /* status is only drawn on selected monitor */
tw = drawstatus(m);
wl_list_for_each(c, &clients, link) {
if (c->mon != m)
@ -1928,6 +1928,88 @@ drawbars(void)
drawbar(m);
}
int
drawstatus(Monitor *m)
{
int x, tw, iw;
char rstext[512] = "";
char *p, *argstart, *argend, *itext;
uint32_t scheme[3], *color;
/* calculate real width of stext */
for (p = stext; *p; p++) {
if (PREFIX(p, "^^")) {
strncat(rstext, p, 2);
p++;
} else if (PREFIX(p, "^fg(") || PREFIX(p, "^bg(")) {
argend = strchr(p, ')');
if (!argend) { /* ignore this command */
argstart = strchr(p, '(') + 1;
strncat(rstext, p, argstart - p);
p = argstart - 1;
} else {
p = argend;
}
} else {
strncat(rstext, p, 1);
}
}
tw = TEXTW(m, rstext) - m->lrpad;
x = m->b.width - tw;
itext = stext;
scheme[0] = colors[SchemeNorm][0];
scheme[1] = colors[SchemeNorm][1];
drwl_setscheme(m->drw, scheme);
for (p = stext; *p; p++) {
if (PREFIX(p, "^^")) {
p++;
} else if (PREFIX(p, "^fg(") || PREFIX(p, "^bg(")) {
argstart = strchr(p, '(') + 1;
argend = strchr(argstart, ')');
if (!argend) { /* ignore this command */
p = argstart - 1;
continue;
}
*p = '\0';
iw = TEXTW(m, itext) - m->lrpad;
if (*itext) /* only draw text if there is something to draw */
x = drwl_text(m->drw, x, 0, iw, m->b.height, 0, itext, 0);
*p = '^';
if (PREFIX(p, "^fg("))
color = &scheme[0];
else
color = &scheme[1];
if (argend != argstart) {
*argend = '\0';
*color = strtoul(argstart, NULL, 16);
*color = *color << 8 | 0xff; /* add alpha channel */
*argend = ')';
} else {
*color = 0; /* reset */
}
/* reset color back to normal if none was provided */
if (!scheme[0])
scheme[0] = colors[SchemeNorm][0];
if (!scheme[1])
scheme[1] = colors[SchemeNorm][1];
itext = argend + 1;
drwl_setscheme(m->drw, scheme);
p = argend;
}
}
iw = TEXTW(m, itext) - m->lrpad;
if (*itext)
drwl_text(m->drw, x, 0, iw, m->b.height, 0, itext, 0);
return tw;
}
void
focusclient(Client *c, int lift)
{
@ -2497,6 +2579,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)
{
@ -2731,7 +2855,6 @@ outputmgrtest(struct wl_listener *listener, void *data)
pid_t
parentpid(pid_t pid)
{
#ifdef __linux__
unsigned int v = 0;
FILE *f;
char buf[256];
@ -2741,14 +2864,6 @@ parentpid(pid_t pid)
fscanf(f, "%*u %*s %*c %u", &v);
fclose(f);
return (pid_t)v;
#elif defined(__FreeBSD__)
struct kinfo_proc kip;
size_t len = sizeof(struct kinfo_proc);
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, p };
if (sysctl(mib, 4, &kip, &len, NULL, 0) < 0 || len == 0)
return 0;
return kip.ki_ppid;
#endif
}
void