From c35fb342aab4fef5174f56d0df634990a4b74ae8 Mon Sep 17 00:00:00 2001 From: joshua Date: Sat, 23 Dec 2023 16:38:46 -0500 Subject: Got systray to play nicely with status bar --- config.def.h | 6 +- config.h | 254 +++++++++++++++++++++++++++++---------------- dwm.c | 109 ++++++++++++++++++- patches/dwm-statuscmd.diff | 208 +++++++++++++++++++++++++++++++++++++ 4 files changed, 482 insertions(+), 95 deletions(-) create mode 100644 patches/dwm-statuscmd.diff diff --git a/config.def.h b/config.def.h index 5e00946..a46ca8e 100644 --- a/config.def.h +++ b/config.def.h @@ -107,6 +107,8 @@ static const Layout layouts[] = { /* helper for spawning shell commands in the pre dwm-5.0 fashion */ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } +#define STATUSBAR "dwmblocks" + /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; @@ -198,7 +200,9 @@ static const Button buttons[] = { { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkStatusText, 0, Button1, sigstatusbar, {.i = 1} }, + { ClkStatusText, 0, Button2, sigstatusbar, {.i = 2} }, + { ClkStatusText, 0, Button3, sigstatusbar, {.i = 3} }, { ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button1, resizemouse, {0} }, diff --git a/config.h b/config.h index 5e00946..843566b 100644 --- a/config.h +++ b/config.h @@ -1,29 +1,33 @@ /* See LICENSE file for copyright and license details. */ +/* Constants */ +#define TERMINAL "st" +#define TERMCLASS "St" + /* appearance */ -static unsigned int borderpx = 1; /* border pixel of windows */ +static unsigned int borderpx = 3; /* border pixel of windows */ static unsigned int snap = 32; /* snap pixel */ -static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ static const unsigned int systrayspacing = 2; /* systray spacing */ static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ static const int showsystray = 1; /* 0 means no systray */ -static unsigned int gappih = 20; /* horiz inner gap between windows */ +static unsigned int gappih = 10; /* horiz inner gap between windows */ static unsigned int gappiv = 10; /* vert inner gap between windows */ static unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ -static unsigned int gappov = 30; /* vert outer gap between windows and screen edge */ +static unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ +static int swallowfloating = 0; /* 1 means swallow floating windows by default */ static int smartgaps = 0; /* 1 means no outer gap when there is only one window */ static int showbar = 1; /* 0 means no bar */ static int topbar = 1; /* 0 means bottom bar */ -static char font[] = "monospace:size=10"; +static char font[] = "monospace:size=10"; static char dmenufont[] = "monospace:size=10"; -static const char *fonts[] = { font, "Mononoki Nerd Font:pixelsize=22:antialias=true:autohint=true", "JoyPixels:pixelsize=20:antialias=true:autohint=true" }; +static const char *fonts[] = { font, "Mononoki Nerd Font:pixelsize=16:antialias=true:autohint=true", "JoyPixels:pixelsize=16:antialias=true:autohint=true" }; static char normbgcolor[] = "#222222"; static char normbordercolor[] = "#444444"; static char normfgcolor[] = "#bbbbbb"; static char selfgcolor[] = "#eeeeee"; -static char selbordercolor[] = "#005577"; +static char selbordercolor[] = "#770000"; static char selbgcolor[] = "#005577"; static char *colors[][3] = { /* fg bg border */ @@ -37,12 +41,10 @@ typedef struct { } Sp; const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL }; const char *spcmd2[] = {"st", "-n", "spfm", "-g", "144x41", "-e", "ranger", NULL }; -const char *spcmd3[] = {"keepassxc", NULL }; static Sp scratchpads[] = { /* name cmd */ {"spterm", spcmd1}, {"spranger", spcmd2}, - {"keepassxc", spcmd3}, }; @@ -53,15 +55,16 @@ static const Rule rules[] = { * WM_CLASS(STRING) = instance, class * WM_NAME(STRING) = title */ - /* class instance title tags mask isfloating isterminal noswallow monitor */ - { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, - { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 }, - { "St", NULL, NULL, 0, 0, 1, 0, -1 }, - { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ + /* class instance title tags mask isfloating isterminal noswallow monitor */ + { TERMCLASS, NULL, NULL, 0, 0, 1, 0, -1 }, + { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ + { NULL, "spterm", NULL, SPTAG(0), 1, 1, 0, -1 }, + { NULL, "spcalc", NULL, SPTAG(1), 1, 1, 0, -1 }, + { "Dwarf_Fortress", NULL, "Dwarf Fortress", 0, 0, 0, 1, -1 }, }; /* layout(s) */ -static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static float mfact = 0.5; /* factor of master area size [0.05..0.95] */ static int nmaster = 1; /* number of clients in master area */ static int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ @@ -89,7 +92,7 @@ static const Layout layouts[] = { }; /* key definitions */ -#define MODKEY Mod1Mask +#define MODKEY Mod4Mask #define TAGKEYS(KEY,TAG) \ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ @@ -98,19 +101,21 @@ static const Layout layouts[] = { #define STACKKEYS(MOD,ACTION) \ { MOD, XK_j, ACTION##stack, {.i = INC(+1) } }, \ { MOD, XK_k, ACTION##stack, {.i = INC(-1) } }, \ - { MOD, XK_grave, ACTION##stack, {.i = PREVSEL } }, \ - { MOD, XK_q, ACTION##stack, {.i = 0 } }, \ - { MOD, XK_a, ACTION##stack, {.i = 1 } }, \ - { MOD, XK_z, ACTION##stack, {.i = 2 } }, \ - { MOD, XK_x, ACTION##stack, {.i = -1 } }, + { MOD, XK_v, ACTION##stack, {.i = 0 } }, \ + /* { MOD, XK_grave, ACTION##stack, {.i = PREVSEL } }, \ */ + /* { MOD, XK_a, ACTION##stack, {.i = 1 } }, \ */ + /* { MOD, XK_z, ACTION##stack, {.i = 2 } }, \ */ + /* { MOD, XK_x, ACTION##stack, {.i = -1 } }, */ /* helper for spawning shell commands in the pre dwm-5.0 fashion */ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } +#define STATUSBAR "dwmblocks" + /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; -static const char *termcmd[] = { "st", NULL }; +static const char *termcmd[] = { TERMINAL, NULL }; /* * Xresources preferences to load at startup @@ -118,66 +123,37 @@ static const char *termcmd[] = { "st", NULL }; ResourcePref resources[] = { { "font", STRING, &font }, { "dmenufont", STRING, &dmenufont }, - { "color0", STRING, &normbgcolor }, - { "color0", STRING, &normbordercolor }, - { "color4", STRING, &normfgcolor }, - { "color4", STRING, &selbgcolor }, - { "color8", STRING, &selbordercolor }, - { "color0", STRING, &selfgcolor }, - { "borderpx", INTEGER, &borderpx }, - { "snap", INTEGER, &snap }, - { "showbar", INTEGER, &showbar }, - { "topbar", INTEGER, &topbar }, - { "nmaster", INTEGER, &nmaster }, - { "resizehints", INTEGER, &resizehints }, - { "mfact", FLOAT, &mfact }, + { "color0", STRING, &normbordercolor }, + { "color8", STRING, &selbordercolor }, + { "color0", STRING, &normbgcolor }, + { "color4", STRING, &normfgcolor }, + { "color0", STRING, &selfgcolor }, + { "color4", STRING, &selbgcolor }, + { "snap", INTEGER, &snap }, + { "borderpx", INTEGER, &borderpx }, + { "showbar", INTEGER, &showbar }, + { "topbar", INTEGER, &topbar }, + { "nmaster", INTEGER, &nmaster }, + { "resizehints", INTEGER, &resizehints }, + { "mfact", FLOAT, &mfact }, + { "gappih", INTEGER, &gappih }, + { "gappiv", INTEGER, &gappiv }, + { "gappoh", INTEGER, &gappoh }, + { "gappov", INTEGER, &gappov }, + { "swallowfloating", INTEGER, &swallowfloating }, + { "smartgaps", INTEGER, &smartgaps }, }; +#include + static const Key keys[] = { /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - STACKKEYS(MODKEY, focus) - STACKKEYS(MODKEY|ShiftMask, push) - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, - { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY|ShiftMask, XK_f, togglefullscr, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - { MODKEY, XK_y, togglescratch, {.ui = 0 } }, - { MODKEY, XK_u, togglescratch, {.ui = 1 } }, - { MODKEY, XK_x, togglescratch, {.ui = 2 } }, + + /* Terminal and dmenu */ + { MODKEY, XK_d, spawn, {.v = dmenucmd } }, + { MODKEY, XK_Return, spawn, {.v = termcmd } }, + + /* Tag Control */ TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) @@ -187,24 +163,124 @@ static const Key keys[] = { TAGKEYS( XK_7, 6) TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_BackSpace, quit, {0} }, - { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + + /* Misc. Programs */ + { MODKEY, XK_w, spawn, SHCMD("browser") }, + { MODKEY, XK_e, spawn, SHCMD("thunderbird") }, + { MODKEY, XK_n, spawn, SHCMD("gtk-pipe-viewer") }, + { MODKEY|ShiftMask, XK_n, spawn, SHCMD(TERMINAL " -e newsboat") }, + { MODKEY, XK_r, spawn, SHCMD(TERMINAL " -e lf") }, + { MODKEY|ShiftMask, XK_r, spawn, SHCMD(TERMINAL " -e htop") }, + + /* Misc. scripts */ + { MODKEY|ShiftMask, XK_q, spawn, SHCMD("sysact") }, + { MODKEY|ShiftMask, XK_d, spawn, SHCMD("passmenu") }, + { MODKEY, XK_grave, spawn, SHCMD("dmenuunicode") }, + { MODKEY, XK_F12, spawn, SHCMD("remaps & notify-send \\\"⌨️ Keyboard remapping...\\\" \\\"Re-running keyboard defaults for any newly plugged-in keyboards.\\\"") }, + { MODKEY, XK_Print, spawn, SHCMD("dmenurecord") }, + { MODKEY|ShiftMask, XK_Print, spawn, SHCMD("dmenurecord kill") }, + { MODKEY, XK_Delete, spawn, SHCMD("dmenurecord kill") }, + { ShiftMask, XK_Print, spawn, SHCMD("maimpick") }, + { 0, XK_Print, spawn, SHCMD("maim pic-full-$(date '+%y%m%d-%H%M-%S').png") }, + { MODKEY, XK_F9, spawn, SHCMD("dmenumount") }, + { MODKEY, XK_F10, spawn, SHCMD("dmenuumount") }, + + /* Layout selection */ + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, /* tile */ + { MODKEY|ShiftMask, XK_u, setlayout, {.v = &layouts[1]} }, /* monocle */ + { MODKEY, XK_y, setlayout, {.v = &layouts[2]} }, /* spiral */ + { MODKEY|ShiftMask, XK_y, setlayout, {.v = &layouts[3]} }, /* dwindle */ + { MODKEY, XK_u, setlayout, {.v = &layouts[4]} }, /* deck */ + { MODKEY|ShiftMask, XK_t, setlayout, {.v = &layouts[5]} }, /* bstack */ + { MODKEY, XK_i, setlayout, {.v = &layouts[11]} }, /* centeredmaster */ + { MODKEY|ShiftMask, XK_i, setlayout, {.v = &layouts[12]} }, /* centeredfloatingmaster */ + + /* Audio Control */ + { MODKEY, XK_F4, spawn, SHCMD(TERMINAL " -e pulsemixer; kill -44 $(pidof dwmblocks)") }, + { 0, XF86XK_AudioMute, spawn, SHCMD("pamixer -t; kill -44 $(pidof dwmblocks)") }, + { 0, XF86XK_AudioRaiseVolume, spawn, SHCMD("pamixer --allow-boost -i 3; kill -44 $(pidof dwmblocks)") }, + { 0, XF86XK_AudioLowerVolume, spawn, SHCMD("pamixer --allow-boost -d 3; kill -44 $(pidof dwmblocks)") }, + + /* Music */ + { MODKEY, XK_m, spawn, SHCMD(TERMINAL " -e ncmpcpp") }, + { MODKEY, XK_p, spawn, SHCMD("mpc toggle") }, + { MODKEY|ShiftMask, XK_p, spawn, SHCMD("mpc pause ; pauseallmpv") }, + { MODKEY, XK_bracketleft, spawn, SHCMD("mpc seek -10") }, + { MODKEY|ShiftMask, XK_bracketleft, spawn, SHCMD("mpc seek -60") }, + { MODKEY, XK_bracketright, spawn, SHCMD("mpc seek +10") }, + { MODKEY|ShiftMask, XK_bracketright, spawn, SHCMD("mpc seek +60") }, + + /* Monitor controls */ + { MODKEY, XK_F3, spawn, SHCMD("displayselect") }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + + /* Display controls */ + { 0, XF86XK_MonBrightnessUp, spawn, SHCMD("xbacklight -inc 3") }, + { 0, XF86XK_MonBrightnessDown, spawn, SHCMD("xbacklight -dec 3") }, + + /* Sleep Control */ + { 0, XF86XK_Sleep, spawn, SHCMD("doas zzz") }, + + /* Gap Controls */ + { MODKEY, XK_a, togglegaps, {0} }, + { MODKEY|ShiftMask, XK_a, defaultgaps, {0} }, + { MODKEY, XK_z, incrgaps, {.i = +3 } }, + { MODKEY, XK_x, incrgaps, {.i = -3 } }, + /* { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } }, */ + /* { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, */ + /* { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } }, */ + /* { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, */ + /* { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } }, */ + /* { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, */ + /* { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } }, */ + /* { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, */ + /* { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } }, */ + /* { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, */ + /* { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } }, */ + /* { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, */ + + /* dwm Controls */ + STACKKEYS(MODKEY, focus) + STACKKEYS(MODKEY|ShiftMask, push) + { MODKEY, XK_Tab, view, {0} }, + { MODKEY, XK_q, killclient, {0} }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_o, incnmaster, {.i = +1 } }, + { MODKEY|ShiftMask, XK_o, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_space, zoom, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_f, togglefullscr, {0} }, + { MODKEY|ShiftMask, XK_Return, togglescratch, {.ui = 0 } }, + { MODKEY, XK_apostrophe, togglescratch, {.ui = 1 } }, }; -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static const Button buttons[] = { + +static Button buttons[] = { /* click event mask button function argument */ - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, +#ifndef __OpenBSD__ { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkStatusText, 0, Button1, sigstatusbar, {.i = 1} }, + { ClkStatusText, 0, Button2, sigstatusbar, {.i = 2} }, + { ClkStatusText, 0, Button3, sigstatusbar, {.i = 3} }, + { ClkStatusText, 0, Button4, sigstatusbar, {.i = 4} }, + { ClkStatusText, 0, Button5, sigstatusbar, {.i = 5} }, + { ClkStatusText, ShiftMask, Button1, sigstatusbar, {.i = 6} }, +#endif { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button1, resizemouse, {0} }, + { ClkClientWin, MODKEY, Button2, defaultgaps, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkClientWin, MODKEY, Button4, incrgaps, {.i = +1} }, + { ClkClientWin, MODKEY, Button5, incrgaps, {.i = -1} }, { ClkTagBar, 0, Button1, view, {0} }, { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkRootWin, 0, Button2, togglebar, {0} }, }; - diff --git a/dwm.c b/dwm.c index 0e116eb..7ff8f2e 100644 --- a/dwm.c +++ b/dwm.c @@ -230,6 +230,7 @@ static void focusstack(const Arg *arg); static Atom getatomprop(Client *c, Atom prop); static int getrootptr(int *x, int *y); static long getstate(Window w); +static pid_t getstatusbarpid(); static unsigned int getsystraywidth(); static int gettextprop(Window w, Atom atom, char *text, unsigned int size); static void grabbuttons(Client *c, int focused); @@ -257,6 +258,7 @@ static void resizemouse(const Arg *arg); static void resizerequest(XEvent *e); static void restack(Monitor *m); static void run(void); +static void runAutostart(void); static void scan(void); static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); static void sendmon(Client *c, Monitor *m); @@ -271,6 +273,7 @@ static void showhide(Client *c); static void sighup(int unused); static void sigterm(int unused); static void spawn(const Arg *arg); +static void sigstatusbar(const Arg *arg); static Monitor *systraytomon(Monitor *m); static int stackpos(const Arg *arg); static void tag(const Arg *arg); @@ -318,6 +321,9 @@ static pid_t winpid(Window w); static Systray *systray = NULL; static const char broken[] = "broken"; static char stext[256]; +static int statusw; +static int statussig; +static pid_t statuspid = -1; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh; /* bar height */ @@ -562,6 +568,7 @@ buttonpress(XEvent *e) Client *c; Monitor *m; XButtonPressedEvent *ev = &e->xbutton; + char *text, *s, ch; click = ClkRootWin; /* focus monitor if necessary */ @@ -580,9 +587,23 @@ buttonpress(XEvent *e) arg.ui = 1 << i; } else if (ev->x < x + TEXTW(selmon->ltsymbol)) click = ClkLtSymbol; - else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) + else if (ev->x > selmon->ww - statusw - getsystraywidth()) { click = ClkStatusText; - else + x = selmon->ww - statusw; + statussig = 0; + for (text = s = stext; *s && x <= ev->x; s++) { + if ((unsigned char)(*s) < ' ') { + ch = *s; + *s = '\0'; + x += TEXTW(text) - lrpad; + *s = ch; + text = s + 1; + if (x >= ev->x) + break; + statussig = ch; + } + } + } else click = ClkWinTitle; } else if ((c = wintoclient(ev->window))) { focus(c); @@ -918,9 +939,25 @@ drawbar(Monitor *m) /* draw status first so it can be overdrawn by tags later */ if (m == selmon) { /* status is only drawn on selected monitor */ + char *text, *s, ch; drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding */ - drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0); + + x = 0; + for (text = s = stext; *s; s++) { + if ((unsigned char)(*s) < ' ') { + ch = *s; + *s = '\0'; + tw = TEXTW(text) - lrpad; + drw_text(drw, m->ww - statusw + x - stw, 0, tw, bh, 0, text, 0); + x += tw; + *s = ch; + text = s + 1; + } + } + tw = TEXTW(text) - lrpad / 2 + 2; /* 2px extra right padding */ + drw_text(drw, m->ww - statusw + x - stw - 6, 0, tw, bh, 0, text, 0); + tw = statusw; + } resizebarwin(m); @@ -1097,6 +1134,30 @@ getsystraywidth() return w ? w + systrayspacing : 1; } +pid_t +getstatusbarpid() +{ + char buf[32], *str = buf, *c; + FILE *fp; + + if (statuspid > 0) { + snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid); + if ((fp = fopen(buf, "r"))) { + fgets(buf, sizeof(buf), fp); + while ((c = strchr(str, '/'))) + str = c + 1; + fclose(fp); + if (!strcmp(str, STATUSBAR)) + return statuspid; + } + } + if (!(fp = popen("pidof -s "STATUSBAR, "r"))) + return -1; + fgets(buf, sizeof(buf), fp); + pclose(fp); + return strtol(buf, NULL, 10); +} + int getrootptr(int *x, int *y) { @@ -1691,6 +1752,12 @@ run(void) handler[ev.type](&ev); /* call handler */ } +void +runAutostart(void) { + system("killall -q dwmblocks; dwmblocks &"); +} + + void scan(void) { @@ -1986,6 +2053,20 @@ sigterm(int unused) quit(&a); } +void +sigstatusbar(const Arg *arg) +{ + union sigval sv; + + if (!statussig) + return; + sv.sival_int = arg->i; + if ((statuspid = getstatusbarpid()) <= 0) + return; + + sigqueue(statuspid, SIGRTMIN+statussig, sv); +} + void spawn(const Arg *arg) { @@ -2422,8 +2503,25 @@ updatesizehints(Client *c) void updatestatus(void) { - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) { strcpy(stext, "dwm-"VERSION); + statusw = TEXTW(stext) - lrpad + 2; + } else { + char *text, *s, ch; + + statusw = 0; + for (text = s = stext; *s; s++) { + if ((unsigned char)(*s) < ' ') { + ch = *s; + *s = '\0'; + statusw += TEXTW(text) - lrpad; + *s = ch; + text = s + 1; + } + } + statusw += TEXTW(text) - lrpad + 2; + + } drawbar(selmon); updatesystray(); } @@ -2908,6 +3006,7 @@ main(int argc, char *argv[]) die("pledge"); #endif /* __OpenBSD__ */ scan(); + runAutostart(); run(); if(restart) execvp(argv[0], argv); cleanup(); diff --git a/patches/dwm-statuscmd.diff b/patches/dwm-statuscmd.diff new file mode 100644 index 0000000..4b26420 --- /dev/null +++ b/patches/dwm-statuscmd.diff @@ -0,0 +1,208 @@ +From f58c7e4fd05ec13383518ccd51663167d45e92d0 Mon Sep 17 00:00:00 2001 +From: Daniel Bylinka +Date: Fri, 2 Apr 2021 19:02:58 +0200 +Subject: [PATCH] [statuscmd] Signal mouse button and click location to status + monitor + +--- + config.def.h | 6 +++- + dwm.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 100 insertions(+), 6 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..154a59b 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -54,6 +54,8 @@ static const Layout layouts[] = { + /* helper for spawning shell commands in the pre dwm-5.0 fashion */ + #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + ++#define STATUSBAR "dwmblocks" ++ + /* commands */ + static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ + static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; +@@ -103,7 +105,9 @@ static Button buttons[] = { + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, +- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, ++ { ClkStatusText, 0, Button1, sigstatusbar, {.i = 1} }, ++ { ClkStatusText, 0, Button2, sigstatusbar, {.i = 2} }, ++ { ClkStatusText, 0, Button3, sigstatusbar, {.i = 3} }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, +diff --git a/dwm.c b/dwm.c +index b0b3466..d871457 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -172,6 +172,7 @@ static void focusstack(const Arg *arg); + static Atom getatomprop(Client *c, Atom prop); + static int getrootptr(int *x, int *y); + static long getstate(Window w); ++static pid_t getstatusbarpid(); + static int gettextprop(Window w, Atom atom, char *text, unsigned int size); + static void grabbuttons(Client *c, int focused); + static void grabkeys(void); +@@ -206,6 +207,7 @@ static void setup(void); + static void seturgent(Client *c, int urg); + static void showhide(Client *c); + static void sigchld(int unused); ++static void sigstatusbar(const Arg *arg); + static void spawn(const Arg *arg); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); +@@ -238,6 +240,9 @@ static void zoom(const Arg *arg); + /* variables */ + static const char broken[] = "broken"; + static char stext[256]; ++static int statusw; ++static int statussig; ++static pid_t statuspid = -1; + static int screen; + static int sw, sh; /* X display screen geometry width, height */ + static int bh, blw = 0; /* bar geometry */ +@@ -422,6 +427,7 @@ buttonpress(XEvent *e) + Client *c; + Monitor *m; + XButtonPressedEvent *ev = &e->xbutton; ++ char *text, *s, ch; + + click = ClkRootWin; + /* focus monitor if necessary */ +@@ -440,9 +446,23 @@ buttonpress(XEvent *e) + arg.ui = 1 << i; + } else if (ev->x < x + blw) + click = ClkLtSymbol; +- else if (ev->x > selmon->ww - (int)TEXTW(stext)) ++ else if (ev->x > selmon->ww - statusw) { ++ x = selmon->ww - statusw; + click = ClkStatusText; +- else ++ statussig = 0; ++ for (text = s = stext; *s && x <= ev->x; s++) { ++ if ((unsigned char)(*s) < ' ') { ++ ch = *s; ++ *s = '\0'; ++ x += TEXTW(text) - lrpad; ++ *s = ch; ++ text = s + 1; ++ if (x >= ev->x) ++ break; ++ statussig = ch; ++ } ++ } ++ } else + click = ClkWinTitle; + } else if ((c = wintoclient(ev->window))) { + focus(c); +@@ -704,9 +724,24 @@ drawbar(Monitor *m) + + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) { /* status is only drawn on selected monitor */ ++ char *text, *s, ch; + drw_setscheme(drw, scheme[SchemeNorm]); +- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ +- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); ++ ++ x = 0; ++ for (text = s = stext; *s; s++) { ++ if ((unsigned char)(*s) < ' ') { ++ ch = *s; ++ *s = '\0'; ++ tw = TEXTW(text) - lrpad; ++ drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0); ++ x += tw; ++ *s = ch; ++ text = s + 1; ++ } ++ } ++ tw = TEXTW(text) - lrpad + 2; ++ drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0); ++ tw = statusw; + } + + for (c = m->clients; c; c = c->next) { +@@ -872,6 +907,30 @@ getatomprop(Client *c, Atom prop) + return atom; + } + ++pid_t ++getstatusbarpid() ++{ ++ char buf[32], *str = buf, *c; ++ FILE *fp; ++ ++ if (statuspid > 0) { ++ snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid); ++ if ((fp = fopen(buf, "r"))) { ++ fgets(buf, sizeof(buf), fp); ++ while ((c = strchr(str, '/'))) ++ str = c + 1; ++ fclose(fp); ++ if (!strcmp(str, STATUSBAR)) ++ return statuspid; ++ } ++ } ++ if (!(fp = popen("pidof -s "STATUSBAR, "r"))) ++ return -1; ++ fgets(buf, sizeof(buf), fp); ++ pclose(fp); ++ return strtol(buf, NULL, 10); ++} ++ + int + getrootptr(int *x, int *y) + { +@@ -1637,6 +1696,20 @@ sigchld(int unused) + while (0 < waitpid(-1, NULL, WNOHANG)); + } + ++void ++sigstatusbar(const Arg *arg) ++{ ++ union sigval sv; ++ ++ if (!statussig) ++ return; ++ sv.sival_int = arg->i; ++ if ((statuspid = getstatusbarpid()) <= 0) ++ return; ++ ++ sigqueue(statuspid, SIGRTMIN+statussig, sv); ++} ++ + void + spawn(const Arg *arg) + { +@@ -1990,8 +2063,25 @@ updatesizehints(Client *c) + void + updatestatus(void) + { +- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) ++ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) { + strcpy(stext, "dwm-"VERSION); ++ statusw = TEXTW(stext) - lrpad + 2; ++ } else { ++ char *text, *s, ch; ++ ++ statusw = 0; ++ for (text = s = stext; *s; s++) { ++ if ((unsigned char)(*s) < ' ') { ++ ch = *s; ++ *s = '\0'; ++ statusw += TEXTW(text) - lrpad; ++ *s = ch; ++ text = s + 1; ++ } ++ } ++ statusw += TEXTW(text) - lrpad + 2; ++ ++ } + drawbar(selmon); + } + +-- +2.31.0 + -- cgit v1.2.3