From fa874b6f977fec82c1aa3b21729e9c8e9f2ba1cf Mon Sep 17 00:00:00 2001 From: amolinae06 Date: Tue, 1 Apr 2025 16:19:42 -0600 Subject: [PATCH] added movestack patch --- README.md | 2 + config.def.h | 7 ++- config.h | 29 +++++++--- dwl.c | 159 ++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 164 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index ac7d095..06d9aad 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/config.def.h b/config.def.h index 592d3c3..21fcb25 100644 --- a/config.def.h +++ b/config.def.h @@ -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} }, diff --git a/config.h b/config.h index 407977e..0aba276 100644 --- a/config.h +++ b/config.h @@ -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} }, diff --git a/dwl.c b/dwl.c index 68891c1..3a4251f 100644 --- a/dwl.c +++ b/dwl.c @@ -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