Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b19e475c0 | ||
|
|
9358a29425 | ||
|
|
aabd07bdac | ||
|
|
2eee0bb260 | ||
|
|
c7dee58722 | ||
|
|
8920c56332 | ||
|
|
6613d9f9a1 | ||
|
|
9bffa845fa | ||
|
|
769034e98f | ||
|
|
ee30b6f84d | ||
|
|
dc5f7e3d47 | ||
|
|
488909a2fa | ||
|
|
21e5e102bf | ||
|
|
f7daadf079 | ||
|
|
0fc14ede76 | ||
|
|
7d0f2ff850 | ||
|
|
1aa4ad095b | ||
|
|
dd48066f94 | ||
|
|
e38d4bdbdd | ||
|
|
612b2ab3f2 | ||
|
|
44b5381d6b | ||
|
|
1401290377 | ||
|
|
981ab39697 | ||
|
|
33b8e1f063 | ||
|
|
ba256f42a1 | ||
|
|
8a5bbde0bd | ||
|
|
db50f34dc0 | ||
|
|
69d4dfb43a | ||
|
|
6a11b4530c | ||
|
|
6a41ceac61 | ||
|
|
71ee631c61 | ||
|
|
e1fd898bfd | ||
|
|
cf408703f9 | ||
|
|
54c71d1651 | ||
|
|
f4a432d615 | ||
|
|
677e8f3313 | ||
|
|
29e62ec08f | ||
|
|
e4069fb1a9 | ||
|
|
7e21ef94ef | ||
|
|
8fa8152673 | ||
|
|
383d48db77 | ||
|
|
1a6a99ba6e | ||
|
|
01a2d54c37 | ||
|
|
c5aeaaf1e0 | ||
|
|
80c3fce3c4 | ||
|
|
9561c13ca2 | ||
|
|
5a74676241 | ||
|
|
17bfbc5fdf | ||
|
|
075aef9975 | ||
|
|
5c9003d31a | ||
|
|
5b1a0bb79f | ||
|
|
dfe236ed74 | ||
|
|
91047bac7a | ||
|
|
3404bc1685 | ||
|
|
e9f7a96180 | ||
|
|
4cdad3186e | ||
|
|
159e9f564e | ||
|
|
9c76ce6b92 | ||
|
|
5e6b4cd602 | ||
|
|
4b87dda495 | ||
|
|
90ce966699 | ||
|
|
d0ae5da80c | ||
|
|
8708ca5968 | ||
|
|
bff719e6b8 | ||
|
|
9ea93189f2 | ||
|
|
eca73cfe87 | ||
|
|
8b5b6560c6 | ||
|
|
a2876fa4d0 | ||
|
|
810033e3ab | ||
|
|
6f0d0faf1f | ||
|
|
f280fc42f5 | ||
|
|
b8d9a58955 | ||
|
|
34a6f495af | ||
|
|
a0c25e32a0 | ||
|
|
67e712d144 | ||
|
|
97fb07677f | ||
|
|
1654f92be5 | ||
|
|
c6ac968c47 | ||
|
|
ceb7942b31 | ||
|
|
5777c15a39 | ||
|
|
610f6237db | ||
|
|
d3bbdfd666 | ||
|
|
ff2f6e4c71 | ||
|
|
43aa79d39d | ||
|
|
a2233ac5db | ||
|
|
81ad543f7d | ||
|
|
4a0301f44a | ||
|
|
e60146517f | ||
|
|
13b133c664 | ||
|
|
66e4384dc8 | ||
|
|
2de2f7378e | ||
|
|
6d2a787b8e | ||
|
|
c27c18553d | ||
|
|
fa5e367c25 | ||
|
|
cb939b14d5 | ||
|
|
64371037ed | ||
|
|
af5abe8ef2 | ||
|
|
b097196971 | ||
|
|
b0652ca1a7 | ||
|
|
25aeaeea6f | ||
|
|
f0768fad04 | ||
|
|
c03f507b3d | ||
|
|
af4963e1f7 | ||
|
|
71aff51298 | ||
|
|
cc99b5070c | ||
|
|
48c000f3f7 | ||
|
|
c07a44267b | ||
|
|
0e4b5133a0 | ||
|
|
71734d2eff | ||
|
|
12b196af6e | ||
|
|
4e6d2bff4f | ||
|
|
d081d7bd02 | ||
|
|
909fc854d6 | ||
|
|
225cc0071c | ||
|
|
ac8b76ddbf | ||
|
|
92c8a145ae | ||
|
|
8bb6d3f063 | ||
|
|
f98bb80103 | ||
|
|
49000bd117 | ||
|
|
ed7688fc0c | ||
|
|
4b6d73b7b1 | ||
|
|
8685f34dfe | ||
|
|
e93a948fcf | ||
|
|
9e89e3eec1 | ||
|
|
9ac1c56124 | ||
|
|
49e8d8e8dd | ||
|
|
c2fd785f19 | ||
|
|
2c1ef25774 | ||
|
|
51c85bdc49 | ||
|
|
062ca6ae9a |
@@ -0,0 +1,7 @@
|
||||
<<<<<<< HEAD
|
||||
*.o
|
||||
dwm
|
||||
=======
|
||||
dwm
|
||||
*.o
|
||||
>>>>>>> master
|
||||
@@ -6,6 +6,7 @@ include config.mk
|
||||
SRC = drw.c dwm.c util.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
|
||||
all: options dwm
|
||||
|
||||
options:
|
||||
@@ -36,7 +37,7 @@ dist: clean
|
||||
gzip dwm-${VERSION}.tar
|
||||
rm -rf dwm-${VERSION}
|
||||
|
||||
install: all
|
||||
install:
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp -f dwm ${DESTDIR}${PREFIX}/bin
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
||||
|
||||
+21
-4
@@ -2,6 +2,7 @@
|
||||
|
||||
/* appearance */
|
||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||
static const unsigned int gappx = 6; /* gaps between windows */
|
||||
static const unsigned int snap = 32; /* snap pixel */
|
||||
static const int showbar = 1; /* 0 means no bar */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
@@ -12,11 +13,18 @@ static const char col_gray2[] = "#444444";
|
||||
static const char col_gray3[] = "#bbbbbb";
|
||||
static const char col_gray4[] = "#eeeeee";
|
||||
static const char col_cyan[] = "#005577";
|
||||
static const unsigned int baralpha = 0xd0;
|
||||
static const unsigned int borderalpha = OPAQUE;
|
||||
static const char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
};
|
||||
static const unsigned int alphas[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
};
|
||||
|
||||
/* tagging */
|
||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||
@@ -26,22 +34,25 @@ static const Rule rules[] = {
|
||||
* WM_CLASS(STRING) = instance, class
|
||||
* WM_NAME(STRING) = title
|
||||
*/
|
||||
/* class instance title tags mask isfloating monitor */
|
||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||
/* class instance title tags mask isfloating CenterThisWindow? monitor */
|
||||
{ "st", NULL, NULL, 0, 0, 1, -1 },
|
||||
{ "Gimp", NULL, NULL, 0, 1, 0, -1 },
|
||||
{ "Firefox", NULL, NULL, 1 << 8, 0, 0, -1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||
static const int nmaster = 1; /* number of clients in master area */
|
||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||
static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
|
||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||
|
||||
#include "layouts.c"
|
||||
static const Layout layouts[] = {
|
||||
/* symbol arrange function */
|
||||
{ "[]=", tile }, /* first entry is default */
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
{ "HHH", grid },
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
@@ -60,11 +71,15 @@ 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 };
|
||||
static const char *termcmd[] = { "st", NULL };
|
||||
|
||||
#include "selfrestart.c"
|
||||
|
||||
static Key keys[] = {
|
||||
/* modifier key function argument */
|
||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
{ MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } },
|
||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||
@@ -77,6 +92,7 @@ static Key keys[] = {
|
||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
||||
{ MODKEY, XK_g, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XK_space, setlayout, {0} },
|
||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
||||
@@ -94,6 +110,7 @@ static Key keys[] = {
|
||||
TAGKEYS( XK_7, 6)
|
||||
TAGKEYS( XK_8, 7)
|
||||
TAGKEYS( XK_9, 8)
|
||||
{ MODKEY|ShiftMask, XK_r, self_restart, {0} },
|
||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <X11/XF86keysym.h>
|
||||
#include "selfrestart.c"
|
||||
|
||||
/* appearance */
|
||||
static const double fwr = 0.65; // first window width ratio
|
||||
static const double fhr = 0.8; // first window height ratio
|
||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||
static const unsigned int snap = 32; /* snap pixel */
|
||||
static const int showbar = 1; /* 0 means no bar */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
static const char *fonts[] = { "MesloLGS Font:pixelsize=15:antialias=true:autohint=true" };
|
||||
static const char dmenufont[] = "MesloLGS Font:pixelsize=15:antialias=true:autohint=true";
|
||||
static const unsigned int gappx = 6; /* gap pixel between windows */
|
||||
static const char col_black[] = "#010101";
|
||||
static const char col_grey[] = "#bbbbbb";
|
||||
static const char col_white[] = "#eeeeee";
|
||||
static const char col_red[] = "#cc1133";
|
||||
static const char col_darkgrey[] = "#222222";
|
||||
static const unsigned int baralpha = 0xd63;
|
||||
/* static const unsigned int borderalpha = OPAQUE; */
|
||||
static const unsigned int borderalpha = 0xd20;
|
||||
static const char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_grey, col_black, col_black },
|
||||
[SchemeSel] = { col_white, col_darkgrey, col_grey },
|
||||
};
|
||||
static const unsigned int alphas[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
};
|
||||
|
||||
/* tagging */
|
||||
/* static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; */
|
||||
static const char *tags[] = { " ", " ", " ", " ", " ", "✉", "7", "8", "9"};
|
||||
|
||||
static const Rule rules[] = {
|
||||
/* xprop(1):
|
||||
* WM_CLASS(STRING) = instance, class
|
||||
* WM_NAME(STRING) = title
|
||||
*/
|
||||
/* class instance title tags mask floating center monitor */
|
||||
{ "Gimp", NULL, NULL, 0, 1, 0, -1 },
|
||||
{ "Alacritty", NULL, NULL, 0, 0, 1, -1 },
|
||||
{ NULL, NULL, "st", 0, 1, 1, -1 },
|
||||
{ "firefox", "Navigator", "Firefox", 1 << 1, 0, 0, -1 },
|
||||
{ "Spotify", "spotify", NULL, 1 << 2, 0, 0, -1 },
|
||||
{ NULL, NULL, "Spotify", 1 << 2, 0, 0, -1 },
|
||||
{ "discord", "discord", "Discord", 1 << 3, 0, 0, -1 },
|
||||
{ "Caprine", "caprine", "Messenger", 1 << 4, 0, 0, -1 },
|
||||
{ "Geary", NULL, NULL, 1 << 5, 0, 0, -1 },
|
||||
{ NULL, NULL, "Calendar", 1 << 6, 0, 0, -1 },
|
||||
{ NULL, NULL, "Microsoft Teams", 1 << 7, 0, 0, -1 },
|
||||
{ "Slack", "slack", "Slack", 1 << 8, 0, 0, -1,},
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
static const float mfact = 0.5 ; /* factor of master area size [0.05..0.95] */
|
||||
static const int nmaster = 1; /* number of clients in master area */
|
||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||
|
||||
#include "layouts.c"
|
||||
static const Layout layouts[] = {
|
||||
/* symbol arrange function */
|
||||
{ "[]=", tile }, /* first entry is default */
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
{ "HHH", grid },
|
||||
};
|
||||
|
||||
/* 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} }, \
|
||||
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
||||
|
||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||
#define SHCMD(cmd) { .v = (const char*[]){ "/usr/bin/zsh", "-c", cmd, NULL } }
|
||||
#define PrintScreen 0x0000ff61
|
||||
|
||||
/* commands */
|
||||
static char dmenumon[2] = "0"; /* component of dmenu, manipulated in spawn() */
|
||||
/* static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_black, "-nf", col_grey, "-sb", col_darkgrey, "-sf", col_white, NULL }; */
|
||||
static const char *dmenucmd[] = { "rofi", "-show", "run", NULL };
|
||||
static const char *term[] = { ".local/bin/spawn-alacritty", NULL };
|
||||
static const char *slock[] = { "slock", NULL };
|
||||
static const char *nautilus[] = { "nautilus", NULL };
|
||||
static const char *firefox[] = { "firefox", NULL };
|
||||
static const char *downbright[] = { "brightnessctl", "s", "2%-", NULL };
|
||||
static const char *upbright[] = { "brightnessctl", "s", "2%+", NULL };
|
||||
static const char *upvol[] = { "pamixer", "--increase", "5", NULL };
|
||||
static const char *downvol[] = { "pamixer", "--decrease", "5", NULL };
|
||||
static const char *mutevol[] = { "pamixer", "--toggle-mute", NULL };
|
||||
static const char *spotifynext[] = { ".local/bin/musicctl", "next", NULL };
|
||||
static const char *spotifyprevious[] = { ".local/bin/musicctl", "previous", NULL };
|
||||
static const char *spotifytoggle[] = { ".local/bin/musicctl", "play-pause", NULL };
|
||||
static const char *spotifylike[] = { ".local/bin/spenv", "like", NULL };
|
||||
static const char *spotifyforward[] = { ".local/bin/spenv", "seek", "+10", NULL };
|
||||
static const char *spotifybackward[] = { ".local/bin/spenv", "seek", "-10", NULL };
|
||||
static const char *screenshot[] = { ".local/bin/screenshot", NULL };
|
||||
static const char *wppnext[] = { ".local/bin/wppenv", "--next", NULL };
|
||||
static const char *test[] = { "notify-send", "test", NULL };
|
||||
|
||||
|
||||
static Key keys[] = {
|
||||
/* modifier key function argument */
|
||||
{ 0, XF86XK_AudioMute, spawn, {.v = mutevol } },
|
||||
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol } },
|
||||
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvol } },
|
||||
{ 0, XF86XK_MonBrightnessUp, spawn, {.v = upbright } },
|
||||
{ 0, XF86XK_MonBrightnessDown, spawn, {.v = downbright } },
|
||||
{ 0, PrintScreen, spawn, {.v = screenshot } },
|
||||
{ MODKEY, XK_d, spawn, {.v = dmenucmd} },
|
||||
{ MODKEY, XK_Return, spawn, {.v = term} },
|
||||
{ MODKEY|ShiftMask, XK_l, spawn, {.v = slock} },
|
||||
{ MODKEY|ShiftMask, XK_t, spawn, {.v = test} },
|
||||
{ Mod1Mask, XK_w, spawn, {.v = wppnext} },
|
||||
{ Mod1Mask, XK_l, spawn, {.v = nautilus} },
|
||||
{ Mod1Mask, XK_f, spawn, {.v = firefox} },
|
||||
{ Mod1Mask, XK_d, spawn, {.v = spotifynext } },
|
||||
{ Mod1Mask, XK_s, spawn, {.v = spotifyprevious } },
|
||||
{ Mod1Mask, XK_k, spawn, {.v = spotifytoggle } },
|
||||
{ Mod1Mask, XK_a, spawn, {.v = spotifylike } },
|
||||
{ Mod1Mask|ShiftMask, XK_d, spawn, {.v = spotifyforward } },
|
||||
{ Mod1Mask|ShiftMask, XK_s, spawn, {.v = spotifybackward } },
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
{ MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } },
|
||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||
{ MODKEY, XK_o, incnmaster, {.i = -1 } },
|
||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||
{ MODKEY|ShiftMask, XK_Return, zoom, {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_g, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XK_space, setlayout, {0} },
|
||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {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 } },
|
||||
TAGKEYS( XK_1, 0)
|
||||
TAGKEYS( XK_2, 1)
|
||||
TAGKEYS( XK_3, 2)
|
||||
TAGKEYS( XK_4, 3)
|
||||
TAGKEYS( XK_5, 4)
|
||||
TAGKEYS( XK_6, 5)
|
||||
TAGKEYS( XK_7, 6)
|
||||
TAGKEYS( XK_8, 7)
|
||||
TAGKEYS( XK_9, 8)
|
||||
{ MODKEY|ShiftMask, XK_r, self_restart, {0} },
|
||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||
};
|
||||
|
||||
/* button definitions */
|
||||
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
|
||||
static Button buttons[] = {
|
||||
/* click event mask button function argument */
|
||||
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
|
||||
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
|
||||
{ ClkWinTitle, 0, Button2, zoom, {0} },
|
||||
{ ClkStatusText, 0, Button2, spawn, {.v = term} },
|
||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
||||
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
||||
{ ClkTagBar, 0, Button1, view, {0} },
|
||||
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
||||
};
|
||||
|
||||
@@ -7,8 +7,8 @@ VERSION = 6.3
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
X11INC = /usr/include/X11
|
||||
X11LIB = /usr/lib64/X11
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
@@ -19,11 +19,10 @@ FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
# OpenBSD (uncomment)
|
||||
#FREETYPEINC = ${X11INC}/freetype2
|
||||
#MANPREFIX = ${PREFIX}/man
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
|
||||
@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
|
||||
}
|
||||
|
||||
Drw *
|
||||
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
|
||||
{
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
||||
@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
|
||||
drw->root = root;
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
|
||||
drw->gc = XCreateGC(dpy, root, 0, NULL);
|
||||
drw->visual = visual;
|
||||
drw->depth = depth;
|
||||
drw->cmap = cmap;
|
||||
drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
|
||||
drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
|
||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
return drw;
|
||||
@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||
drw->h = h;
|
||||
if (drw->drawable)
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
||||
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font)
|
||||
}
|
||||
|
||||
void
|
||||
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||
drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
|
||||
{
|
||||
if (!drw || !dest || !clrname)
|
||||
return;
|
||||
|
||||
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
||||
DefaultColormap(drw->dpy, drw->screen),
|
||||
if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
|
||||
dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
|
||||
}
|
||||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr *
|
||||
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
|
||||
{
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < clrcount; i++)
|
||||
drw_clr_create(drw, &ret[i], clrnames[i]);
|
||||
drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -276,9 +280,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
d = XftDrawCreate(drw->dpy, drw->drawable,
|
||||
DefaultVisual(drw->dpy, drw->screen),
|
||||
DefaultColormap(drw->dpy, drw->screen));
|
||||
d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
|
||||
x += lpad;
|
||||
w -= lpad;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ typedef struct {
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
Visual *visual;
|
||||
unsigned int depth;
|
||||
Colormap cmap;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
Clr *scheme;
|
||||
@@ -27,7 +30,7 @@ typedef struct {
|
||||
} Drw;
|
||||
|
||||
/* Drawable abstraction */
|
||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
|
||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
void drw_free(Drw *drw);
|
||||
|
||||
@@ -39,8 +42,8 @@ unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
|
||||
Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
|
||||
@@ -30,6 +30,14 @@ top left corner. The tags which are applied to one or more windows are
|
||||
indicated with an empty square in the top left corner.
|
||||
.P
|
||||
dwm draws a small border around windows to indicate the focus state.
|
||||
.P
|
||||
On start, dwm can start additional programs that may be specified in two special
|
||||
shell scripts (see the FILES section below), autostart_blocking.sh and
|
||||
autostart.sh. The former is executed first and dwm will wait for its
|
||||
termination before starting. The latter is executed in the background before
|
||||
dwm enters its handler loop.
|
||||
.P
|
||||
Either of these files may be omitted.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
@@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state.
|
||||
.TP
|
||||
.B Mod1\-Button3
|
||||
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||
.SH FILES
|
||||
The files containing programs to be started along with dwm are searched for in
|
||||
the following directories:
|
||||
.IP "1. $XDG_DATA_HOME/dwm"
|
||||
.IP "2. $HOME/.local/share/dwm"
|
||||
.IP "3. $HOME/.dwm"
|
||||
.P
|
||||
The first existing directory is scanned for any of the autostart files below.
|
||||
.TP 15
|
||||
autostart.sh
|
||||
This file is started as a shell background process before dwm enters its handler
|
||||
loop.
|
||||
.TP 15
|
||||
autostart_blocking.sh
|
||||
This file is started before any autostart.sh; dwm waits for its termination.
|
||||
.SH CUSTOMIZATION
|
||||
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||
code. This keeps it fast, secure and simple.
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/keysym.h>
|
||||
@@ -52,11 +53,13 @@
|
||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
|
||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw + gappx)
|
||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||
|
||||
#define OPAQUE 0xffU
|
||||
|
||||
/* enums */
|
||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||
@@ -92,7 +95,7 @@ struct Client {
|
||||
int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, CenterThisWindow;
|
||||
Client *next;
|
||||
Client *snext;
|
||||
Monitor *mon;
|
||||
@@ -138,6 +141,7 @@ typedef struct {
|
||||
const char *title;
|
||||
unsigned int tags;
|
||||
int isfloating;
|
||||
int CenterThisWindow;
|
||||
int monitor;
|
||||
} Rule;
|
||||
|
||||
@@ -163,6 +167,8 @@ static void detachstack(Client *c);
|
||||
static Monitor *dirtomon(int dir);
|
||||
static void drawbar(Monitor *m);
|
||||
static void drawbars(void);
|
||||
static void enqueue(Client *c);
|
||||
static void enqueuestack(Client *c);
|
||||
static void enternotify(XEvent *e);
|
||||
static void expose(XEvent *e);
|
||||
static void focus(Client *c);
|
||||
@@ -185,7 +191,7 @@ static void monocle(Monitor *m);
|
||||
static void motionnotify(XEvent *e);
|
||||
static void movemouse(const Arg *arg);
|
||||
static Client *nexttiled(Client *c);
|
||||
static void pop(Client *);
|
||||
static void pop(Client *c);
|
||||
static void propertynotify(XEvent *e);
|
||||
static void quit(const Arg *arg);
|
||||
static Monitor *recttomon(int x, int y, int w, int h);
|
||||
@@ -193,7 +199,9 @@ static void resize(Client *c, int x, int y, int w, int h, int interact);
|
||||
static void resizeclient(Client *c, int x, int y, int w, int h);
|
||||
static void resizemouse(const Arg *arg);
|
||||
static void restack(Monitor *m);
|
||||
static void rotatestack(const Arg *arg);
|
||||
static void run(void);
|
||||
static void runautostart(void);
|
||||
static void scan(void);
|
||||
static int sendevent(Client *c, Atom proto);
|
||||
static void sendmon(Client *c, Monitor *m);
|
||||
@@ -209,7 +217,7 @@ static void sigchld(int unused);
|
||||
static void spawn(const Arg *arg);
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
static void tile(Monitor *);
|
||||
static void tile(Monitor *m);
|
||||
static void togglebar(const Arg *arg);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
@@ -228,15 +236,21 @@ static void updatetitle(Client *c);
|
||||
static void updatewindowtype(Client *c);
|
||||
static void updatewmhints(Client *c);
|
||||
static void view(const Arg *arg);
|
||||
static void warp(const Client *c);
|
||||
static Client *wintoclient(Window w);
|
||||
static Monitor *wintomon(Window w);
|
||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||
static void xinitvisual();
|
||||
static void zoom(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
static const char autostartblocksh[] = "autostart_blocking.sh";
|
||||
static const char autostartsh[] = "autostart.sh";
|
||||
static const char broken[] = "broken";
|
||||
static const char dwmdir[] = "dwm";
|
||||
static const char localshare[] = ".local/share";
|
||||
static char stext[256];
|
||||
static int screen;
|
||||
static int sw, sh; /* X display screen geometry width, height */
|
||||
@@ -269,6 +283,11 @@ static Drw *drw;
|
||||
static Monitor *mons, *selmon;
|
||||
static Window root, wmcheckwin;
|
||||
|
||||
static int useargb = 0;
|
||||
static Visual *visual;
|
||||
static int depth;
|
||||
static Colormap cmap;
|
||||
|
||||
/* configuration, allows nested code to access above variables */
|
||||
#include "config.h"
|
||||
|
||||
@@ -287,6 +306,7 @@ applyrules(Client *c)
|
||||
|
||||
/* rule matching */
|
||||
c->isfloating = 0;
|
||||
c->CenterThisWindow = 0;
|
||||
c->tags = 0;
|
||||
XGetClassHint(dpy, c->win, &ch);
|
||||
class = ch.res_class ? ch.res_class : broken;
|
||||
@@ -299,6 +319,7 @@ applyrules(Client *c)
|
||||
&& (!r->instance || strstr(instance, r->instance)))
|
||||
{
|
||||
c->isfloating = r->isfloating;
|
||||
c->CenterThisWindow = r->CenterThisWindow;
|
||||
c->tags |= r->tags;
|
||||
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||
if (m)
|
||||
@@ -709,7 +730,7 @@ 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 */
|
||||
if (m == selmon || 1) { /* status is only drawn on selected monitor */
|
||||
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);
|
||||
@@ -758,6 +779,28 @@ drawbars(void)
|
||||
drawbar(m);
|
||||
}
|
||||
|
||||
void
|
||||
enqueue(Client *c)
|
||||
{
|
||||
Client *l;
|
||||
for (l = c->mon->clients; l && l->next; l = l->next);
|
||||
if (l) {
|
||||
l->next = c;
|
||||
c->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
enqueuestack(Client *c)
|
||||
{
|
||||
Client *l;
|
||||
for (l = c->mon->stack; l && l->snext; l = l->snext);
|
||||
if (l) {
|
||||
l->snext = c;
|
||||
c->snext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
enternotify(XEvent *e)
|
||||
{
|
||||
@@ -834,6 +877,7 @@ focusmon(const Arg *arg)
|
||||
unfocus(selmon->sel, 0);
|
||||
selmon = m;
|
||||
focus(NULL);
|
||||
warp(selmon->sel);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1063,6 +1107,8 @@ manage(Window w, XWindowAttributes *wa)
|
||||
updatewindowtype(c);
|
||||
updatesizehints(c);
|
||||
updatewmhints(c);
|
||||
c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
|
||||
c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
|
||||
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||
grabbuttons(c, 0);
|
||||
if (!c->isfloating)
|
||||
@@ -1283,12 +1329,36 @@ void
|
||||
resizeclient(Client *c, int x, int y, int w, int h)
|
||||
{
|
||||
XWindowChanges wc;
|
||||
unsigned int n;
|
||||
unsigned int gapoffset;
|
||||
unsigned int gapincr;
|
||||
Client *nbc;
|
||||
|
||||
c->oldx = c->x; c->x = wc.x = x;
|
||||
c->oldy = c->y; c->y = wc.y = y;
|
||||
c->oldw = c->w; c->w = wc.width = w;
|
||||
c->oldh = c->h; c->h = wc.height = h;
|
||||
wc.border_width = c->bw;
|
||||
|
||||
/* Get number of clients for the client's monitor */
|
||||
for (n = 0, nbc = nexttiled(c->mon->clients); nbc; nbc = nexttiled(nbc->next), n++);
|
||||
|
||||
/* Do nothing if layout is floating */
|
||||
if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) {
|
||||
gapincr = gapoffset = 0;
|
||||
} else {
|
||||
/* Remove border and gap if layout is monocle or only one client */
|
||||
if (c->mon->lt[c->mon->sellt]->arrange == monocle || n == 1) {
|
||||
gapoffset = 0;
|
||||
gapincr = -2 * borderpx;
|
||||
wc.border_width = 0;
|
||||
} else {
|
||||
gapoffset = gappx;
|
||||
gapincr = 2 * gappx;
|
||||
}
|
||||
}
|
||||
|
||||
c->oldx = c->x; c->x = wc.x = x + gapoffset;
|
||||
c->oldy = c->y; c->y = wc.y = y + gapoffset;
|
||||
c->oldw = c->w; c->w = wc.width = w - gapincr;
|
||||
c->oldh = c->h; c->h = wc.height = h - gapincr;
|
||||
|
||||
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||
configure(c);
|
||||
XSync(dpy, False);
|
||||
@@ -1374,6 +1444,40 @@ restack(Monitor *m)
|
||||
}
|
||||
XSync(dpy, False);
|
||||
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
|
||||
if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && selmon->lt[selmon->sellt] != &layouts[2])
|
||||
warp(m->sel);
|
||||
}
|
||||
|
||||
void
|
||||
rotatestack(const Arg *arg)
|
||||
{
|
||||
Client *c = NULL, *f;
|
||||
|
||||
if (!selmon->sel)
|
||||
return;
|
||||
f = selmon->sel;
|
||||
if (arg->i > 0) {
|
||||
for (c = nexttiled(selmon->clients); c && nexttiled(c->next); c = nexttiled(c->next));
|
||||
if (c){
|
||||
detach(c);
|
||||
attach(c);
|
||||
detachstack(c);
|
||||
attachstack(c);
|
||||
}
|
||||
} else {
|
||||
if ((c = nexttiled(selmon->clients))){
|
||||
detach(c);
|
||||
enqueue(c);
|
||||
detachstack(c);
|
||||
enqueuestack(c);
|
||||
}
|
||||
}
|
||||
if (c){
|
||||
arrange(selmon);
|
||||
//unfocus(f, 1);
|
||||
focus(f);
|
||||
restack(selmon);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1387,6 +1491,83 @@ run(void)
|
||||
handler[ev.type](&ev); /* call handler */
|
||||
}
|
||||
|
||||
void
|
||||
runautostart(void)
|
||||
{
|
||||
char *pathpfx;
|
||||
char *path;
|
||||
char *xdgdatahome;
|
||||
char *home;
|
||||
struct stat sb;
|
||||
|
||||
if ((home = getenv("HOME")) == NULL)
|
||||
/* this is almost impossible */
|
||||
return;
|
||||
|
||||
/* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
|
||||
* otherwise use ~/.local/share/dwm as autostart script directory
|
||||
*/
|
||||
xdgdatahome = getenv("XDG_DATA_HOME");
|
||||
if (xdgdatahome != NULL && *xdgdatahome != '\0') {
|
||||
/* space for path segments, separators and nul */
|
||||
pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
|
||||
|
||||
if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
|
||||
free(pathpfx);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* space for path segments, separators and nul */
|
||||
pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
|
||||
+ strlen(dwmdir) + 3);
|
||||
|
||||
if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
|
||||
free(pathpfx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if the autostart script directory exists */
|
||||
if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
|
||||
/* the XDG conformant path does not exist or is no directory
|
||||
* so we try ~/.dwm instead
|
||||
*/
|
||||
char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
|
||||
if(pathpfx_new == NULL) {
|
||||
free(pathpfx);
|
||||
return;
|
||||
}
|
||||
pathpfx = pathpfx_new;
|
||||
|
||||
if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
|
||||
free(pathpfx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* try the blocking script first */
|
||||
path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
|
||||
if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
|
||||
free(path);
|
||||
free(pathpfx);
|
||||
}
|
||||
|
||||
if (access(path, X_OK) == 0)
|
||||
system(path);
|
||||
|
||||
/* now the non-blocking script */
|
||||
if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
|
||||
free(path);
|
||||
free(pathpfx);
|
||||
}
|
||||
|
||||
if (access(path, X_OK) == 0)
|
||||
system(strcat(path, " &"));
|
||||
|
||||
free(pathpfx);
|
||||
free(path);
|
||||
}
|
||||
|
||||
void
|
||||
scan(void)
|
||||
{
|
||||
@@ -1541,6 +1722,8 @@ setup(void)
|
||||
Atom utf8string;
|
||||
|
||||
/* clean up any zombies immediately */
|
||||
if (signal(SIGCHLD, sigchld) == SIG_ERR)
|
||||
die("can't install SIGCHLD handler:");
|
||||
sigchld(0);
|
||||
|
||||
/* init screen */
|
||||
@@ -1548,7 +1731,8 @@ setup(void)
|
||||
sw = DisplayWidth(dpy, screen);
|
||||
sh = DisplayHeight(dpy, screen);
|
||||
root = RootWindow(dpy, screen);
|
||||
drw = drw_create(dpy, screen, root, sw, sh);
|
||||
xinitvisual();
|
||||
drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap);
|
||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
lrpad = drw->fonts->h;
|
||||
@@ -1576,7 +1760,7 @@ setup(void)
|
||||
/* init appearance */
|
||||
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
scheme[i] = drw_scm_create(drw, colors[i], 3);
|
||||
scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3);
|
||||
/* init bars */
|
||||
updatebars();
|
||||
updatestatus();
|
||||
@@ -1638,8 +1822,6 @@ showhide(Client *c)
|
||||
void
|
||||
sigchld(int unused)
|
||||
{
|
||||
if (signal(SIGCHLD, sigchld) == SIG_ERR)
|
||||
die("can't install SIGCHLD handler:");
|
||||
while (0 < waitpid(-1, NULL, WNOHANG));
|
||||
}
|
||||
|
||||
@@ -1694,7 +1876,7 @@ tile(Monitor *m)
|
||||
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||
if (i < m->nmaster) {
|
||||
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
||||
resize(c, m->wx, m->wy + my, mw - (2*c->bw) + (n > 1 ? gappx : 0), h - (2*c->bw), 0);
|
||||
if (my + HEIGHT(c) < m->wh)
|
||||
my += HEIGHT(c);
|
||||
} else {
|
||||
@@ -1703,6 +1885,13 @@ tile(Monitor *m)
|
||||
if (ty + HEIGHT(c) < m->wh)
|
||||
ty += HEIGHT(c);
|
||||
}
|
||||
|
||||
if (n == 1 && selmon->sel->CenterThisWindow)
|
||||
resizeclient(selmon->sel,
|
||||
(selmon->mw - selmon->mw * fwr) / 2,
|
||||
(selmon->mh - selmon->mh * fhr) / 2,
|
||||
selmon->mw * fwr,
|
||||
selmon->mh * fhr);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1813,16 +2002,18 @@ updatebars(void)
|
||||
Monitor *m;
|
||||
XSetWindowAttributes wa = {
|
||||
.override_redirect = True,
|
||||
.background_pixmap = ParentRelative,
|
||||
.background_pixel = 0,
|
||||
.border_pixel = 0,
|
||||
.colormap = cmap,
|
||||
.event_mask = ButtonPressMask|ExposureMask
|
||||
};
|
||||
XClassHint ch = {"dwm", "dwm"};
|
||||
for (m = mons; m; m = m->next) {
|
||||
if (m->barwin)
|
||||
continue;
|
||||
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
|
||||
CopyFromParent, DefaultVisual(dpy, screen),
|
||||
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
|
||||
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth,
|
||||
InputOutput, visual,
|
||||
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
|
||||
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
|
||||
XMapRaised(dpy, m->barwin);
|
||||
XSetClassHint(dpy, m->barwin, &ch);
|
||||
@@ -1997,9 +2188,11 @@ updatesizehints(Client *c)
|
||||
void
|
||||
updatestatus(void)
|
||||
{
|
||||
Monitor* m;
|
||||
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
|
||||
strcpy(stext, "dwm-"VERSION);
|
||||
drawbar(selmon);
|
||||
for(m = mons; m; m = m->next)
|
||||
drawbar(m);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2054,6 +2247,28 @@ view(const Arg *arg)
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
warp(const Client *c)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (!c) {
|
||||
XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww/2, selmon->wy + selmon->wh/2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getrootptr(&x, &y) ||
|
||||
(x > c->x - c->bw &&
|
||||
y > c->y - c->bw &&
|
||||
x < c->x + c->w + c->bw*2 &&
|
||||
y < c->y + c->h + c->bw*2) ||
|
||||
(y > c->mon->by && y < c->mon->by + bh) ||
|
||||
(c->mon->topbar && !y))
|
||||
return;
|
||||
|
||||
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
|
||||
}
|
||||
|
||||
Client *
|
||||
wintoclient(Window w)
|
||||
{
|
||||
@@ -2120,6 +2335,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
xinitvisual()
|
||||
{
|
||||
XVisualInfo *infos;
|
||||
XRenderPictFormat *fmt;
|
||||
int nitems;
|
||||
int i;
|
||||
|
||||
XVisualInfo tpl = {
|
||||
.screen = screen,
|
||||
.depth = 32,
|
||||
.class = TrueColor
|
||||
};
|
||||
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
|
||||
|
||||
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
|
||||
visual = NULL;
|
||||
for(i = 0; i < nitems; i ++) {
|
||||
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
|
||||
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
|
||||
visual = infos[i].visual;
|
||||
depth = infos[i].depth;
|
||||
cmap = XCreateColormap(dpy, root, visual, AllocNone);
|
||||
useargb = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XFree(infos);
|
||||
|
||||
if (! visual) {
|
||||
visual = DefaultVisual(dpy, screen);
|
||||
depth = DefaultDepth(dpy, screen);
|
||||
cmap = DefaultColormap(dpy, screen);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
zoom(const Arg *arg)
|
||||
{
|
||||
@@ -2152,6 +2404,7 @@ main(int argc, char *argv[])
|
||||
die("pledge");
|
||||
#endif /* __OpenBSD__ */
|
||||
scan();
|
||||
runautostart();
|
||||
run();
|
||||
cleanup();
|
||||
XCloseDisplay(dpy);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
void
|
||||
grid(Monitor *m) {
|
||||
unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
|
||||
Client *c;
|
||||
|
||||
for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
||||
n++;
|
||||
|
||||
/* grid dimensions */
|
||||
for(rows = 0; rows <= n/2; rows++)
|
||||
if(rows*rows >= n)
|
||||
break;
|
||||
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
|
||||
|
||||
/* window geoms (cell height/width) */
|
||||
ch = m->wh / (rows ? rows : 1);
|
||||
cw = m->ww / (cols ? cols : 1);
|
||||
for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
||||
cx = m->wx + (i / rows) * cw;
|
||||
cy = m->wy + (i % rows) * ch;
|
||||
/* adjust height/width of last row/column's windows */
|
||||
ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
|
||||
aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
|
||||
resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
diff dwm-5.8.2/config.h dwm-5.8.2mod/config.h
|
||||
92a93
|
||||
> { ClkWinTitle, 0, Button3, startgesture, {0} },
|
||||
100a102,113
|
||||
> };
|
||||
>
|
||||
> //may want to reuse the architecture present in buttons[] and keys[]
|
||||
> static Gesture gestures[] = {
|
||||
> {"dl", spawn, SHCMD("konqueror") },
|
||||
> {"dr", spawn, SHCMD("pidgin" ) },
|
||||
> {"l", spawn, SHCMD("xterm") },
|
||||
> {"ld", spawn, SHCMD("gimp" ) },
|
||||
> {"lr", spawn, SHCMD("google-chrome") },
|
||||
> {"r" , spawn, SHCMD("firefox") },
|
||||
> {"rl", spawn, SHCMD("pavucontrol") },
|
||||
> {"du", spawn, SHCMD("kate") },
|
||||
Only in dwm-5.8.2mod: config.h~
|
||||
Binary files dwm-5.8.2/dwm and dwm-5.8.2mod/dwm differ
|
||||
diff dwm-5.8.2/dwm.c dwm-5.8.2mod/dwm.c
|
||||
73a74,79
|
||||
> char *name;
|
||||
> void (*func)(const Arg *arg);
|
||||
> const Arg arg;
|
||||
> } Gesture;
|
||||
>
|
||||
> typedef struct {
|
||||
244a251
|
||||
> static void startgesture(const Arg *arg);
|
||||
1248a1256,1318
|
||||
>
|
||||
> void
|
||||
> startgesture(const Arg *arg) {
|
||||
> int x, y, dx, dy, q;
|
||||
> int valid=0, listpos=0, gestpos=0, count=0;
|
||||
> char move, currGest[10];
|
||||
> XEvent ev;
|
||||
>
|
||||
> if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
|
||||
> None, cursor[CurMove], CurrentTime) != GrabSuccess)
|
||||
> return;
|
||||
> if(!getrootptr(&x, &y))
|
||||
> return;
|
||||
> do {
|
||||
> XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
|
||||
> switch (ev.type) {
|
||||
> case ConfigureRequest:
|
||||
> case Expose:
|
||||
> case MapRequest:
|
||||
> handler[ev.type](&ev);
|
||||
> break;
|
||||
> case MotionNotify:
|
||||
> if(count++ < 10)
|
||||
> break;
|
||||
> count = 0;
|
||||
> dx = ev.xmotion.x - x;
|
||||
> dy = ev.xmotion.y - y;
|
||||
> x = ev.xmotion.x;
|
||||
> y = ev.xmotion.y;
|
||||
>
|
||||
> if( abs(dx)/(abs(dy)+1) == 0 )
|
||||
> move = dy<0?'u':'d';
|
||||
> else
|
||||
> move = dx<0?'l':'r';
|
||||
>
|
||||
> if(move!=currGest[gestpos-1])
|
||||
> {
|
||||
> if(gestpos>9)
|
||||
> { ev.type++;
|
||||
> break;
|
||||
> }
|
||||
>
|
||||
> currGest[gestpos] = move;
|
||||
> currGest[++gestpos] = '\0';
|
||||
>
|
||||
> valid = 0;
|
||||
> for(q = 0; q<LENGTH(gestures); q++)
|
||||
> { if(!strcmp(currGest, gestures[q].name))
|
||||
> { valid++;
|
||||
> listpos = q;
|
||||
> }
|
||||
> }
|
||||
> }
|
||||
>
|
||||
> }
|
||||
> } while(ev.type != ButtonRelease);
|
||||
>
|
||||
> if(valid)
|
||||
> gestures[listpos].func(&(gestures[listpos].arg));
|
||||
>
|
||||
> XUngrabPointer(dpy, CurrentTime);
|
||||
> }
|
||||
>
|
||||
Only in dwm-5.8.2mod: dwm.c~
|
||||
Binary files dwm-5.8.2/dwm.o and dwm-5.8.2mod/dwm.o differ
|
||||
@@ -0,0 +1,289 @@
|
||||
From 51f9c34480b984e261a738e5295f518b42c2f29c Mon Sep 17 00:00:00 2001
|
||||
From: Petrus Karell <pk@petruskarell.fi>
|
||||
Date: Mon, 19 Oct 2020 19:15:24 +0300
|
||||
Subject: [PATCH] Allow dwm to have translucent bars, while keeping all
|
||||
the text on it opaque, just like the alpha-patch for st. Updated for 61bb8b2
|
||||
|
||||
---
|
||||
config.def.h | 7 ++++++
|
||||
config.mk | 2 +-
|
||||
drw.c | 26 ++++++++++++-----------
|
||||
drw.h | 9 +++++---
|
||||
dwm.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
5 files changed, 82 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 1c0b587..4f68fe8 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -12,11 +12,18 @@ static const char col_gray2[] = "#444444";
|
||||
static const char col_gray3[] = "#bbbbbb";
|
||||
static const char col_gray4[] = "#eeeeee";
|
||||
static const char col_cyan[] = "#005577";
|
||||
+static const unsigned int baralpha = 0xd0;
|
||||
+static const unsigned int borderalpha = OPAQUE;
|
||||
static const char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
};
|
||||
+static const unsigned int alphas[][3] = {
|
||||
+ /* fg bg border */
|
||||
+ [SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
+ [SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
+};
|
||||
|
||||
/* tagging */
|
||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||
diff --git a/config.mk b/config.mk
|
||||
index 7084c33..21b5404 100644
|
||||
--- a/config.mk
|
||||
+++ b/config.mk
|
||||
@@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
||||
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
diff --git a/drw.c b/drw.c
|
||||
index 4cdbcbe..fe3aadd 100644
|
||||
--- a/drw.c
|
||||
+++ b/drw.c
|
||||
@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
|
||||
}
|
||||
|
||||
Drw *
|
||||
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
|
||||
{
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
||||
@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
|
||||
drw->root = root;
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
|
||||
- drw->gc = XCreateGC(dpy, root, 0, NULL);
|
||||
+ drw->visual = visual;
|
||||
+ drw->depth = depth;
|
||||
+ drw->cmap = cmap;
|
||||
+ drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
|
||||
+ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
|
||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
return drw;
|
||||
@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||
drw->h = h;
|
||||
if (drw->drawable)
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
||||
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font)
|
||||
}
|
||||
|
||||
void
|
||||
-drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
|
||||
{
|
||||
if (!drw || !dest || !clrname)
|
||||
return;
|
||||
|
||||
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
||||
- DefaultColormap(drw->dpy, drw->screen),
|
||||
+ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
+
|
||||
+ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
|
||||
}
|
||||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr *
|
||||
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
+drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
|
||||
{
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < clrcount; i++)
|
||||
- drw_clr_create(drw, &ret[i], clrnames[i]);
|
||||
+ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
- d = XftDrawCreate(drw->dpy, drw->drawable,
|
||||
- DefaultVisual(drw->dpy, drw->screen),
|
||||
- DefaultColormap(drw->dpy, drw->screen));
|
||||
+ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
|
||||
x += lpad;
|
||||
w -= lpad;
|
||||
}
|
||||
diff --git a/drw.h b/drw.h
|
||||
index 4bcd5ad..a56f523 100644
|
||||
--- a/drw.h
|
||||
+++ b/drw.h
|
||||
@@ -20,6 +20,9 @@ typedef struct {
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
+ Visual *visual;
|
||||
+ unsigned int depth;
|
||||
+ Colormap cmap;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
Clr *scheme;
|
||||
@@ -27,7 +30,7 @@ typedef struct {
|
||||
} Drw;
|
||||
|
||||
/* Drawable abstraction */
|
||||
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
|
||||
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
void drw_free(Drw *drw);
|
||||
|
||||
@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
|
||||
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 664c527..d8005c7 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -57,6 +57,8 @@
|
||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||
|
||||
+#define OPAQUE 0xffU
|
||||
+
|
||||
/* enums */
|
||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||
@@ -233,6 +235,7 @@ static Monitor *wintomon(Window w);
|
||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||
+static void xinitvisual();
|
||||
static void zoom(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
@@ -269,6 +272,11 @@ static Drw *drw;
|
||||
static Monitor *mons, *selmon;
|
||||
static Window root, wmcheckwin;
|
||||
|
||||
+static int useargb = 0;
|
||||
+static Visual *visual;
|
||||
+static int depth;
|
||||
+static Colormap cmap;
|
||||
+
|
||||
/* configuration, allows nested code to access above variables */
|
||||
#include "config.h"
|
||||
|
||||
@@ -1542,7 +1550,8 @@ setup(void)
|
||||
sw = DisplayWidth(dpy, screen);
|
||||
sh = DisplayHeight(dpy, screen);
|
||||
root = RootWindow(dpy, screen);
|
||||
- drw = drw_create(dpy, screen, root, sw, sh);
|
||||
+ xinitvisual();
|
||||
+ drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap);
|
||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
lrpad = drw->fonts->h;
|
||||
@@ -1570,7 +1579,7 @@ setup(void)
|
||||
/* init appearance */
|
||||
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
- scheme[i] = drw_scm_create(drw, colors[i], 3);
|
||||
+ scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3);
|
||||
/* init bars */
|
||||
updatebars();
|
||||
updatestatus();
|
||||
@@ -1807,16 +1816,18 @@ updatebars(void)
|
||||
Monitor *m;
|
||||
XSetWindowAttributes wa = {
|
||||
.override_redirect = True,
|
||||
- .background_pixmap = ParentRelative,
|
||||
+ .background_pixel = 0,
|
||||
+ .border_pixel = 0,
|
||||
+ .colormap = cmap,
|
||||
.event_mask = ButtonPressMask|ExposureMask
|
||||
};
|
||||
XClassHint ch = {"dwm", "dwm"};
|
||||
for (m = mons; m; m = m->next) {
|
||||
if (m->barwin)
|
||||
continue;
|
||||
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
|
||||
- CopyFromParent, DefaultVisual(dpy, screen),
|
||||
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
|
||||
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth,
|
||||
+ InputOutput, visual,
|
||||
+ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
|
||||
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
|
||||
XMapRaised(dpy, m->barwin);
|
||||
XSetClassHint(dpy, m->barwin, &ch);
|
||||
@@ -2113,6 +2124,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+void
|
||||
+xinitvisual()
|
||||
+{
|
||||
+ XVisualInfo *infos;
|
||||
+ XRenderPictFormat *fmt;
|
||||
+ int nitems;
|
||||
+ int i;
|
||||
+
|
||||
+ XVisualInfo tpl = {
|
||||
+ .screen = screen,
|
||||
+ .depth = 32,
|
||||
+ .class = TrueColor
|
||||
+ };
|
||||
+ long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
|
||||
+
|
||||
+ infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
|
||||
+ visual = NULL;
|
||||
+ for(i = 0; i < nitems; i ++) {
|
||||
+ fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
|
||||
+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
|
||||
+ visual = infos[i].visual;
|
||||
+ depth = infos[i].depth;
|
||||
+ cmap = XCreateColormap(dpy, root, visual, AllocNone);
|
||||
+ useargb = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ XFree(infos);
|
||||
+
|
||||
+ if (! visual) {
|
||||
+ visual = DefaultVisual(dpy, screen);
|
||||
+ depth = DefaultDepth(dpy, screen);
|
||||
+ cmap = DefaultColormap(dpy, screen);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
zoom(const Arg *arg)
|
||||
{
|
||||
--
|
||||
2.28.0
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 7054c06..4448d46 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -11,6 +11,8 @@ static const char normfgcolor[] = "#bbbbbb";
|
||||
static const char selbordercolor[] = "#005577";
|
||||
static const char selbgcolor[] = "#005577";
|
||||
static const char selfgcolor[] = "#eeeeee";
|
||||
+static unsigned int baralpha = 0xd0;
|
||||
+static unsigned int borderalpha = OPAQUE;
|
||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||
static const unsigned int snap = 32; /* snap pixel */
|
||||
static const int showbar = 1; /* 0 means no bar */
|
||||
diff --git a/config.mk b/config.mk
|
||||
index 4eefb71..de25d2a 100644
|
||||
--- a/config.mk
|
||||
+++ b/config.mk
|
||||
@@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
||||
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
diff --git a/drw.c b/drw.c
|
||||
index f49200b..12e3ebc 100644
|
||||
--- a/drw.c
|
||||
+++ b/drw.c
|
||||
@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
|
||||
}
|
||||
|
||||
Drw *
|
||||
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
|
||||
{
|
||||
Drw *drw;
|
||||
|
||||
@@ -71,8 +71,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
|
||||
drw->root = root;
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
|
||||
- drw->gc = XCreateGC(dpy, root, 0, NULL);
|
||||
+ drw->visual = visual;
|
||||
+ drw->depth = depth;
|
||||
+ drw->cmap = cmap;
|
||||
+ drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
|
||||
+ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
|
||||
drw->fontcount = 0;
|
||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
@@ -86,7 +89,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||
drw->h = h;
|
||||
if (drw->drawable)
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
||||
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -180,16 +183,15 @@ drw_font_free(Fnt *font)
|
||||
}
|
||||
|
||||
Clr *
|
||||
-drw_clr_create(Drw *drw, const char *clrname)
|
||||
+drw_clr_create(Drw *drw, const char *clrname, unsigned int alpha)
|
||||
{
|
||||
Clr *clr;
|
||||
|
||||
clr = ecalloc(1, sizeof(Clr));
|
||||
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
||||
- DefaultColormap(drw->dpy, drw->screen),
|
||||
+ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
|
||||
clrname, &clr->rgb))
|
||||
die("error, cannot allocate color '%s'\n", clrname);
|
||||
- clr->pix = clr->rgb.pixel;
|
||||
+ clr->pix = (clr->rgb.pixel & 0x00ffffffU) | (alpha << 24);
|
||||
|
||||
return clr;
|
||||
}
|
||||
@@ -245,9 +247,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex
|
||||
XSetForeground(drw->dpy, drw->gc, invert ?
|
||||
drw->scheme->fg->pix : drw->scheme->bg->pix);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
- d = XftDrawCreate(drw->dpy, drw->drawable,
|
||||
- DefaultVisual(drw->dpy, drw->screen),
|
||||
- DefaultColormap(drw->dpy, drw->screen));
|
||||
+ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
|
||||
}
|
||||
|
||||
curfont = drw->fonts[0];
|
||||
diff --git a/drw.h b/drw.h
|
||||
index e3b8515..1fed824 100644
|
||||
--- a/drw.h
|
||||
+++ b/drw.h
|
||||
@@ -30,6 +30,9 @@ typedef struct {
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
+ Visual *visual;
|
||||
+ unsigned int depth;
|
||||
+ Colormap cmap;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
ClrScheme *scheme;
|
||||
@@ -43,7 +46,7 @@ typedef struct {
|
||||
} Extnts;
|
||||
|
||||
/* Drawable abstraction */
|
||||
-Drw *drw_create(Display *, int, Window, unsigned int, unsigned int);
|
||||
+Drw *drw_create(Display *, int, Window, unsigned int, unsigned int, Visual*, unsigned int, Colormap);
|
||||
void drw_resize(Drw *, unsigned int, unsigned int);
|
||||
void drw_free(Drw *);
|
||||
|
||||
@@ -55,7 +58,7 @@ void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *);
|
||||
unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int);
|
||||
|
||||
/* Colour abstraction */
|
||||
-Clr *drw_clr_create(Drw *, const char *);
|
||||
+Clr *drw_clr_create(Drw *, const char *, unsigned int);
|
||||
void drw_clr_free(Clr *);
|
||||
|
||||
/* Cursor abstraction */
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 0362114..17fe373 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -57,6 +57,8 @@
|
||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h)
|
||||
|
||||
+#define OPAQUE 0xffU
|
||||
+
|
||||
/* enums */
|
||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||
enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */
|
||||
@@ -232,6 +234,7 @@ static Monitor *wintomon(Window w);
|
||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||
+static void xinitvisual();
|
||||
static void zoom(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
@@ -267,6 +270,11 @@ static Drw *drw;
|
||||
static Monitor *mons, *selmon;
|
||||
static Window root;
|
||||
|
||||
+static int useargb = 0;
|
||||
+static Visual *visual;
|
||||
+static int depth;
|
||||
+static Colormap cmap;
|
||||
+
|
||||
/* configuration, allows nested code to access above variables */
|
||||
#include "config.h"
|
||||
|
||||
@@ -1556,7 +1564,8 @@ setup(void)
|
||||
sw = DisplayWidth(dpy, screen);
|
||||
sh = DisplayHeight(dpy, screen);
|
||||
root = RootWindow(dpy, screen);
|
||||
- drw = drw_create(dpy, screen, root, sw, sh);
|
||||
+ xinitvisual();
|
||||
+ drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap);
|
||||
drw_load_fonts(drw, fonts, LENGTH(fonts));
|
||||
if (!drw->fontcount)
|
||||
die("no fonts could be loaded.\n");
|
||||
@@ -1580,12 +1589,12 @@ setup(void)
|
||||
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
||||
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
|
||||
/* init appearance */
|
||||
- scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor);
|
||||
- scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor);
|
||||
- scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor);
|
||||
- scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor);
|
||||
- scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor);
|
||||
- scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor);
|
||||
+ scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor, borderalpha);
|
||||
+ scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor, baralpha);
|
||||
+ scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor, OPAQUE);
|
||||
+ scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor, borderalpha);
|
||||
+ scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor, baralpha);
|
||||
+ scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor, OPAQUE);
|
||||
/* init bars */
|
||||
updatebars();
|
||||
updatestatus();
|
||||
@@ -1798,15 +1807,17 @@ updatebars(void)
|
||||
Monitor *m;
|
||||
XSetWindowAttributes wa = {
|
||||
.override_redirect = True,
|
||||
- .background_pixmap = ParentRelative,
|
||||
+ .background_pixel = 0,
|
||||
+ .border_pixel = 0,
|
||||
+ .colormap = cmap,
|
||||
.event_mask = ButtonPressMask|ExposureMask
|
||||
};
|
||||
for (m = mons; m; m = m->next) {
|
||||
if (m->barwin)
|
||||
continue;
|
||||
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
|
||||
- CopyFromParent, DefaultVisual(dpy, screen),
|
||||
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
|
||||
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth,
|
||||
+ InputOutput, visual,
|
||||
+ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
|
||||
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
|
||||
XMapRaised(dpy, m->barwin);
|
||||
}
|
||||
@@ -2107,6 +2118,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
|
||||
}
|
||||
|
||||
void
|
||||
+xinitvisual()
|
||||
+{
|
||||
+ XVisualInfo *infos;
|
||||
+ XRenderPictFormat *fmt;
|
||||
+ int nitems;
|
||||
+ int i;
|
||||
+
|
||||
+ XVisualInfo tpl = {
|
||||
+ .screen = screen,
|
||||
+ .depth = 32,
|
||||
+ .class = TrueColor
|
||||
+ };
|
||||
+ long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
|
||||
+
|
||||
+ infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
|
||||
+ visual = NULL;
|
||||
+ for(i = 0; i < nitems; i ++) {
|
||||
+ fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
|
||||
+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
|
||||
+ visual = infos[i].visual;
|
||||
+ depth = infos[i].depth;
|
||||
+ cmap = XCreateColormap(dpy, root, visual, AllocNone);
|
||||
+ useargb = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ XFree(infos);
|
||||
+
|
||||
+ if (! visual) {
|
||||
+ visual = DefaultVisual(dpy, screen);
|
||||
+ depth = DefaultDepth(dpy, screen);
|
||||
+ cmap = DefaultColormap(dpy, screen);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
zoom(const Arg *arg)
|
||||
{
|
||||
Client *c = selmon->sel;
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -up dwm/dwm.c dwmmod/dwm.c
|
||||
--- dwm/dwm.c 2020-06-25 00:21:30.383692180 -0300
|
||||
+++ dwmmod/dwm.c 2020-06-25 00:20:35.643692330 -0300
|
||||
@@ -1057,6 +1057,8 @@ manage(Window w, XWindowAttributes *wa)
|
||||
updatewindowtype(c);
|
||||
updatesizehints(c);
|
||||
updatewmhints(c);
|
||||
+ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
|
||||
+ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
|
||||
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||
grabbuttons(c, 0);
|
||||
if (!c->isfloating)
|
||||
@@ -0,0 +1,335 @@
|
||||
From c80bbb393b741bfa428fdbebc0027e6ff2c4b69d Mon Sep 17 00:00:00 2001
|
||||
From: mihirlad55 <mihirlad55@gmail.com>
|
||||
Date: Sun, 26 Sep 2021 00:36:41 +0000
|
||||
Subject: [PATCH] Add support for managing external status bars
|
||||
|
||||
This patch allows dwm to manage other status bars such as
|
||||
polybar/lemonbar without them needing to set override-redirect. For
|
||||
all intents and purposes, DWM treats this bar as if it were its own
|
||||
and as a result helps the status bar and DWM live in harmony.
|
||||
|
||||
This has a few advantages
|
||||
* The bar does not block fullscreen windows
|
||||
* DWM makes room for the status bar, so windows do not overlap the bar
|
||||
* The bar can be hidden/killed and DWM will not keep an unsightly gap
|
||||
where the bar was
|
||||
* DWM receives EnterNotify events when your cursor enters the bar
|
||||
|
||||
To use another status bar, set usealtbar to 1 in your config.h and set
|
||||
altbarclass to the class name (can be found using xprop) to the class
|
||||
name of your status bar. Also make sure that if your status bar will
|
||||
be displayed on top, topbar is set to 1 in your config, and if it will
|
||||
be displayed on bottom, topbar is set to 0. This patch does not
|
||||
support bars that are not docked at the top or at the bottom of your
|
||||
monitor.
|
||||
|
||||
The patch is developed at https://github.com/mihirlad55/dwm-anybar
|
||||
---
|
||||
config.def.h | 3 ++
|
||||
dwm.c | 114 ++++++++++++++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 103 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index a2ac963..04ba79c 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -5,6 +5,9 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||
static const unsigned int snap = 32; /* snap pixel */
|
||||
static const int showbar = 1; /* 0 means no bar */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
+static const int usealtbar = 1; /* 1 means use non-dwm status bar */
|
||||
+static const char *altbarclass = "Polybar"; /* Alternate bar class name */
|
||||
+static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */
|
||||
static const char *fonts[] = { "monospace:size=10" };
|
||||
static const char dmenufont[] = "monospace:size=10";
|
||||
static const char col_gray1[] = "#222222";
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 5e4d494..5b83358 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -47,8 +47,8 @@
|
||||
/* macros */
|
||||
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
||||
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
||||
-#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
||||
- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||
+#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \
|
||||
+ * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my)))
|
||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
@@ -116,7 +116,7 @@ struct Monitor {
|
||||
float mfact;
|
||||
int nmaster;
|
||||
int num;
|
||||
- int by; /* bar geometry */
|
||||
+ int by, bh; /* bar geometry */
|
||||
int mx, my, mw, mh; /* screen size */
|
||||
int wx, wy, ww, wh; /* window area */
|
||||
unsigned int seltags;
|
||||
@@ -179,6 +179,7 @@ static void incnmaster(const Arg *arg);
|
||||
static void keypress(XEvent *e);
|
||||
static void killclient(const Arg *arg);
|
||||
static void manage(Window w, XWindowAttributes *wa);
|
||||
+static void managealtbar(Window win, XWindowAttributes *wa);
|
||||
static void mappingnotify(XEvent *e);
|
||||
static void maprequest(XEvent *e);
|
||||
static void monocle(Monitor *m);
|
||||
@@ -207,6 +208,7 @@ static void seturgent(Client *c, int urg);
|
||||
static void showhide(Client *c);
|
||||
static void sigchld(int unused);
|
||||
static void spawn(const Arg *arg);
|
||||
+static void spawnbar();
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
static void tile(Monitor *);
|
||||
@@ -216,6 +218,7 @@ static void toggletag(const Arg *arg);
|
||||
static void toggleview(const Arg *arg);
|
||||
static void unfocus(Client *c, int setfocus);
|
||||
static void unmanage(Client *c, int destroyed);
|
||||
+static void unmanagealtbar(Window w);
|
||||
static void unmapnotify(XEvent *e);
|
||||
static void updatebarpos(Monitor *m);
|
||||
static void updatebars(void);
|
||||
@@ -230,6 +233,7 @@ static void updatewmhints(Client *c);
|
||||
static void view(const Arg *arg);
|
||||
static Client *wintoclient(Window w);
|
||||
static Monitor *wintomon(Window w);
|
||||
+static int wmclasscontains(Window win, const char *class, const char *name);
|
||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||
@@ -505,8 +509,10 @@ cleanupmon(Monitor *mon)
|
||||
for (m = mons; m && m->next != mon; m = m->next);
|
||||
m->next = mon->next;
|
||||
}
|
||||
- XUnmapWindow(dpy, mon->barwin);
|
||||
- XDestroyWindow(dpy, mon->barwin);
|
||||
+ if (!usealtbar) {
|
||||
+ XUnmapWindow(dpy, mon->barwin);
|
||||
+ XDestroyWindow(dpy, mon->barwin);
|
||||
+ }
|
||||
free(mon);
|
||||
}
|
||||
|
||||
@@ -568,7 +574,7 @@ configurenotify(XEvent *e)
|
||||
for (c = m->clients; c; c = c->next)
|
||||
if (c->isfullscreen)
|
||||
resizeclient(c, m->mx, m->my, m->mw, m->mh);
|
||||
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
|
||||
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh);
|
||||
}
|
||||
focus(NULL);
|
||||
arrange(NULL);
|
||||
@@ -639,6 +645,7 @@ createmon(void)
|
||||
m->nmaster = nmaster;
|
||||
m->showbar = showbar;
|
||||
m->topbar = topbar;
|
||||
+ m->bh = bh;
|
||||
m->lt[0] = &layouts[0];
|
||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||
@@ -649,10 +656,13 @@ void
|
||||
destroynotify(XEvent *e)
|
||||
{
|
||||
Client *c;
|
||||
+ Monitor *m;
|
||||
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
||||
|
||||
if ((c = wintoclient(ev->window)))
|
||||
unmanage(c, 1);
|
||||
+ else if (usealtbar && (m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||
+ unmanagealtbar(ev->window);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -696,6 +706,9 @@ dirtomon(int dir)
|
||||
void
|
||||
drawbar(Monitor *m)
|
||||
{
|
||||
+ if (usealtbar)
|
||||
+ return;
|
||||
+
|
||||
int x, w, tw = 0;
|
||||
int boxs = drw->fonts->h / 9;
|
||||
int boxw = drw->fonts->h / 6 + 2;
|
||||
@@ -1077,6 +1090,25 @@ manage(Window w, XWindowAttributes *wa)
|
||||
focus(NULL);
|
||||
}
|
||||
|
||||
+void
|
||||
+managealtbar(Window win, XWindowAttributes *wa)
|
||||
+{
|
||||
+ Monitor *m;
|
||||
+ if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
|
||||
+ return;
|
||||
+
|
||||
+ m->barwin = win;
|
||||
+ m->by = wa->y;
|
||||
+ bh = m->bh = wa->height;
|
||||
+ updatebarpos(m);
|
||||
+ arrange(m);
|
||||
+ XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||
+ XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
|
||||
+ XMapWindow(dpy, win);
|
||||
+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
||||
+ (unsigned char *) &win, 1);
|
||||
+}
|
||||
+
|
||||
void
|
||||
mappingnotify(XEvent *e)
|
||||
{
|
||||
@@ -1097,7 +1129,9 @@ maprequest(XEvent *e)
|
||||
return;
|
||||
if (wa.override_redirect)
|
||||
return;
|
||||
- if (!wintoclient(ev->window))
|
||||
+ if (usealtbar && wmclasscontains(ev->window, altbarclass, ""))
|
||||
+ managealtbar(ev->window, &wa);
|
||||
+ else if (!wintoclient(ev->window))
|
||||
manage(ev->window, &wa);
|
||||
}
|
||||
|
||||
@@ -1393,7 +1427,9 @@ scan(void)
|
||||
if (!XGetWindowAttributes(dpy, wins[i], &wa)
|
||||
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
|
||||
continue;
|
||||
- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
||||
+ if (usealtbar && wmclasscontains(wins[i], altbarclass, ""))
|
||||
+ managealtbar(wins[i], &wa);
|
||||
+ else if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
||||
manage(wins[i], &wa);
|
||||
}
|
||||
for (i = 0; i < num; i++) { /* now the transients */
|
||||
@@ -1546,7 +1582,7 @@ setup(void)
|
||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
lrpad = drw->fonts->h;
|
||||
- bh = drw->fonts->h + 2;
|
||||
+ bh = usealtbar ? 0 : drw->fonts->h + 2;
|
||||
updategeom();
|
||||
/* init atoms */
|
||||
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
||||
@@ -1595,6 +1631,7 @@ setup(void)
|
||||
XSelectInput(dpy, root, wa.event_mask);
|
||||
grabkeys();
|
||||
focus(NULL);
|
||||
+ spawnbar();
|
||||
}
|
||||
|
||||
|
||||
@@ -1653,6 +1690,13 @@ spawn(const Arg *arg)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+spawnbar()
|
||||
+{
|
||||
+ if (*altbarcmd)
|
||||
+ system(altbarcmd);
|
||||
+}
|
||||
+
|
||||
void
|
||||
tag(const Arg *arg)
|
||||
{
|
||||
@@ -1704,7 +1748,7 @@ togglebar(const Arg *arg)
|
||||
{
|
||||
selmon->showbar = !selmon->showbar;
|
||||
updatebarpos(selmon);
|
||||
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||
+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
@@ -1787,10 +1831,26 @@ unmanage(Client *c, int destroyed)
|
||||
arrange(m);
|
||||
}
|
||||
|
||||
+void
|
||||
+unmanagealtbar(Window w)
|
||||
+{
|
||||
+ Monitor *m = wintomon(w);
|
||||
+
|
||||
+ if (!m)
|
||||
+ return;
|
||||
+
|
||||
+ m->barwin = 0;
|
||||
+ m->by = 0;
|
||||
+ m->bh = 0;
|
||||
+ updatebarpos(m);
|
||||
+ arrange(m);
|
||||
+}
|
||||
+
|
||||
void
|
||||
unmapnotify(XEvent *e)
|
||||
{
|
||||
Client *c;
|
||||
+ Monitor *m;
|
||||
XUnmapEvent *ev = &e->xunmap;
|
||||
|
||||
if ((c = wintoclient(ev->window))) {
|
||||
@@ -1798,12 +1858,16 @@ unmapnotify(XEvent *e)
|
||||
setclientstate(c, WithdrawnState);
|
||||
else
|
||||
unmanage(c, 0);
|
||||
- }
|
||||
+ } else if (usealtbar && (m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||
+ unmanagealtbar(ev->window);
|
||||
}
|
||||
|
||||
void
|
||||
updatebars(void)
|
||||
{
|
||||
+ if (usealtbar)
|
||||
+ return;
|
||||
+
|
||||
Monitor *m;
|
||||
XSetWindowAttributes wa = {
|
||||
.override_redirect = True,
|
||||
@@ -1829,11 +1893,11 @@ updatebarpos(Monitor *m)
|
||||
m->wy = m->my;
|
||||
m->wh = m->mh;
|
||||
if (m->showbar) {
|
||||
- m->wh -= bh;
|
||||
+ m->wh -= m->bh;
|
||||
m->by = m->topbar ? m->wy : m->wy + m->wh;
|
||||
- m->wy = m->topbar ? m->wy + bh : m->wy;
|
||||
+ m->wy = m->topbar ? m->wy + m->bh : m->wy;
|
||||
} else
|
||||
- m->by = -bh;
|
||||
+ m->by = -m->bh;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2077,6 +2141,28 @@ wintomon(Window w)
|
||||
return selmon;
|
||||
}
|
||||
|
||||
+int
|
||||
+wmclasscontains(Window win, const char *class, const char *name)
|
||||
+{
|
||||
+ XClassHint ch = { NULL, NULL };
|
||||
+ int res = 1;
|
||||
+
|
||||
+ if (XGetClassHint(dpy, win, &ch)) {
|
||||
+ if (ch.res_name && strstr(ch.res_name, name) == NULL)
|
||||
+ res = 0;
|
||||
+ if (ch.res_class && strstr(ch.res_class, class) == NULL)
|
||||
+ res = 0;
|
||||
+ } else
|
||||
+ res = 0;
|
||||
+
|
||||
+ if (ch.res_class)
|
||||
+ XFree(ch.res_class);
|
||||
+ if (ch.res_name)
|
||||
+ XFree(ch.res_name);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
/* There's no way to check accesses to destroyed windows, thus those cases are
|
||||
* ignored (especially on UnmapNotify's). Other types of errors call Xlibs
|
||||
* default error handler, which may call exit. */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
commit 5918623c5bd7fda155bf9dc3d33890c4ae1722d0
|
||||
Author: Simon Bremer <simon.bremer@tum.de>
|
||||
Date: Thu Dec 22 17:31:07 2016 +0100
|
||||
|
||||
Applied and fixed autostart patch for previous version;
|
||||
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index d27cb67..066ed71 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -194,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h);
|
||||
static void resizemouse(const Arg *arg);
|
||||
static void restack(Monitor *m);
|
||||
static void run(void);
|
||||
+static void runAutostart(void);
|
||||
static void scan(void);
|
||||
static int sendevent(Client *c, Atom proto);
|
||||
static void sendmon(Client *c, Monitor *m);
|
||||
@@ -1386,6 +1387,12 @@ run(void)
|
||||
}
|
||||
|
||||
void
|
||||
+runAutostart(void) {
|
||||
+ system("cd ~/.dwm; ./autostart_blocking.sh");
|
||||
+ system("cd ~/.dwm; ./autostart.sh &");
|
||||
+}
|
||||
+
|
||||
+void
|
||||
scan(void)
|
||||
{
|
||||
unsigned int i, num;
|
||||
@@ -2145,6 +2152,7 @@ main(int argc, char *argv[])
|
||||
checkotherwm();
|
||||
setup();
|
||||
scan();
|
||||
+ runAutostart();
|
||||
run();
|
||||
cleanup();
|
||||
XCloseDisplay(dpy);
|
||||
@@ -0,0 +1,179 @@
|
||||
From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001
|
||||
From: Gan Ainm <gan.ainm.riomhphost@gmail.com>
|
||||
Date: Wed, 10 Jun 2020 10:59:02 +0000
|
||||
Subject: [PATCH] dwm-xdgautostart-6.2.diff
|
||||
|
||||
===================================================================
|
||||
---
|
||||
dwm.1 | 23 +++++++++++++++++
|
||||
dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 105 insertions(+)
|
||||
|
||||
diff --git a/dwm.1 b/dwm.1
|
||||
index 13b3729..9533aa6 100644
|
||||
--- a/dwm.1
|
||||
+++ b/dwm.1
|
||||
@@ -30,6 +30,14 @@ top left corner. The tags which are applied to one or more windows are
|
||||
indicated with an empty square in the top left corner.
|
||||
.P
|
||||
dwm draws a small border around windows to indicate the focus state.
|
||||
+.P
|
||||
+On start, dwm can start additional programs that may be specified in two special
|
||||
+shell scripts (see the FILES section below), autostart_blocking.sh and
|
||||
+autostart.sh. The former is executed first and dwm will wait for its
|
||||
+termination before starting. The latter is executed in the background before
|
||||
+dwm enters its handler loop.
|
||||
+.P
|
||||
+Either of these files may be omitted.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
@@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state.
|
||||
.TP
|
||||
.B Mod1\-Button3
|
||||
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||
+.SH FILES
|
||||
+The files containing programs to be started along with dwm are searched for in
|
||||
+the following directories:
|
||||
+.IP "1. $XDG_DATA_HOME/dwm"
|
||||
+.IP "2. $HOME/.local/share/dwm"
|
||||
+.IP "3. $HOME/.dwm"
|
||||
+.P
|
||||
+The first existing directory is scanned for any of the autostart files below.
|
||||
+.TP 15
|
||||
+autostart.sh
|
||||
+This file is started as a shell background process before dwm enters its handler
|
||||
+loop.
|
||||
+.TP 15
|
||||
+autostart_blocking.sh
|
||||
+This file is started before any autostart.sh; dwm waits for its termination.
|
||||
.SH CUSTOMIZATION
|
||||
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||
code. This keeps it fast, secure and simple.
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 4465af1..2156b49 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/keysym.h>
|
||||
@@ -193,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h);
|
||||
static void resizemouse(const Arg *arg);
|
||||
static void restack(Monitor *m);
|
||||
static void run(void);
|
||||
+static void runautostart(void);
|
||||
static void scan(void);
|
||||
static int sendevent(Client *c, Atom proto);
|
||||
static void sendmon(Client *c, Monitor *m);
|
||||
@@ -235,7 +237,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||
static void zoom(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
+static const char autostartblocksh[] = "autostart_blocking.sh";
|
||||
+static const char autostartsh[] = "autostart.sh";
|
||||
static const char broken[] = "broken";
|
||||
+static const char dwmdir[] = "dwm";
|
||||
+static const char localshare[] = ".local/share";
|
||||
static char stext[256];
|
||||
static int screen;
|
||||
static int sw, sh; /* X display screen geometry width, height */
|
||||
@@ -1380,6 +1386,83 @@ run(void)
|
||||
handler[ev.type](&ev); /* call handler */
|
||||
}
|
||||
|
||||
+void
|
||||
+runautostart(void)
|
||||
+{
|
||||
+ char *pathpfx;
|
||||
+ char *path;
|
||||
+ char *xdgdatahome;
|
||||
+ char *home;
|
||||
+ struct stat sb;
|
||||
+
|
||||
+ if ((home = getenv("HOME")) == NULL)
|
||||
+ /* this is almost impossible */
|
||||
+ return;
|
||||
+
|
||||
+ /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
|
||||
+ * otherwise use ~/.local/share/dwm as autostart script directory
|
||||
+ */
|
||||
+ xdgdatahome = getenv("XDG_DATA_HOME");
|
||||
+ if (xdgdatahome != NULL && *xdgdatahome != '\0') {
|
||||
+ /* space for path segments, separators and nul */
|
||||
+ pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
|
||||
+
|
||||
+ if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
|
||||
+ free(pathpfx);
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* space for path segments, separators and nul */
|
||||
+ pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
|
||||
+ + strlen(dwmdir) + 3);
|
||||
+
|
||||
+ if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
|
||||
+ free(pathpfx);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* check if the autostart script directory exists */
|
||||
+ if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
|
||||
+ /* the XDG conformant path does not exist or is no directory
|
||||
+ * so we try ~/.dwm instead
|
||||
+ */
|
||||
+ char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
|
||||
+ if(pathpfx_new == NULL) {
|
||||
+ free(pathpfx);
|
||||
+ return;
|
||||
+ }
|
||||
+ pathpfx = pathpfx_new;
|
||||
+
|
||||
+ if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
|
||||
+ free(pathpfx);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* try the blocking script first */
|
||||
+ path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
|
||||
+ if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
|
||||
+ free(path);
|
||||
+ free(pathpfx);
|
||||
+ }
|
||||
+
|
||||
+ if (access(path, X_OK) == 0)
|
||||
+ system(path);
|
||||
+
|
||||
+ /* now the non-blocking script */
|
||||
+ if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
|
||||
+ free(path);
|
||||
+ free(pathpfx);
|
||||
+ }
|
||||
+
|
||||
+ if (access(path, X_OK) == 0)
|
||||
+ system(strcat(path, " &"));
|
||||
+
|
||||
+ free(pathpfx);
|
||||
+ free(path);
|
||||
+}
|
||||
+
|
||||
void
|
||||
scan(void)
|
||||
{
|
||||
@@ -2142,6 +2223,7 @@ main(int argc, char *argv[])
|
||||
die("pledge");
|
||||
#endif /* __OpenBSD__ */
|
||||
scan();
|
||||
+ runautostart();
|
||||
run();
|
||||
cleanup();
|
||||
XCloseDisplay(dpy);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From 1529909466206016f2101457bbf37c67195714c8 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Leszczak <szatan@gecc.xyz>
|
||||
Date: Fri, 22 Nov 2019 10:46:53 +0800
|
||||
Subject: [PATCH] Fix transparent borders
|
||||
|
||||
When terminal has transparency then its borders also become transparent.
|
||||
Fix it by removing transparency from any pixels drawn.
|
||||
---
|
||||
drw.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drw.c b/drw.c
|
||||
index 8fd1ca4..490a592 100644
|
||||
--- a/drw.c
|
||||
+++ b/drw.c
|
||||
@@ -202,6 +202,8 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||
DefaultColormap(drw->dpy, drw->screen),
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
+
|
||||
+ dest->pixel |= 0xff << 24;
|
||||
}
|
||||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
# HG changeset patch
|
||||
# User Barbu Paul - Gheorghe <barbu.paul.gheorghe@gmail.com>
|
||||
# Date 1354650884 -7200
|
||||
# Node ID 6c472a21a5887c5295a331c48c4da188ec2c8413
|
||||
# Parent aaab44133a6830c9a00263731d098c01cc1d6fb5
|
||||
selfrestart now magically locates the current dwm (no need to hardcode a path)
|
||||
|
||||
diff -r aaab44133a68 -r 6c472a21a588 config.def.h
|
||||
--- a/config.def.h Tue Dec 04 21:54:44 2012 +0200
|
||||
+++ b/config.def.h Tue Dec 04 21:54:44 2012 +0200
|
||||
@@ -54,6 +54,8 @@
|
||||
static const char *termcmd[] = { "urxvtc", NULL };
|
||||
static const char *filemancmd[] = { "thunar", NULL };
|
||||
|
||||
+#include "selfrestart.c"
|
||||
+
|
||||
static Key keys[] = {
|
||||
/* modifier key function argument */
|
||||
{ MODKEY, XK_r, spawn, {.v = dmenucmd } },
|
||||
@@ -89,6 +91,7 @@
|
||||
TAGKEYS( XK_7, 6)
|
||||
TAGKEYS( XK_8, 7)
|
||||
TAGKEYS( XK_9, 8)
|
||||
+ { MODKEY|ShiftMask, XK_r, self_restart, {0} },
|
||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||
};
|
||||
|
||||
@@ -108,4 +111,3 @@
|
||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
||||
};
|
||||
-
|
||||
diff -r aaab44133a68 -r 6c472a21a588 selfrestart.c
|
||||
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||
+++ b/selfrestart.c Tue Dec 04 21:54:44 2012 +0200
|
||||
@@ -0,0 +1,65 @@
|
||||
+#include <unistd.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+/**
|
||||
+ * Magically finds the current's executable path
|
||||
+ *
|
||||
+ * I'm doing the do{}while(); trick because Linux (what I'm running) is not
|
||||
+ * POSIX compilant and so lstat() cannot be trusted on /proc entries
|
||||
+ *
|
||||
+ * @return char* the path of the current executable
|
||||
+ */
|
||||
+char *get_dwm_path(){
|
||||
+ struct stat s;
|
||||
+ int r, length, rate = 42;
|
||||
+ char *path = NULL;
|
||||
+
|
||||
+ if(lstat("/proc/self/exe", &s) == -1){
|
||||
+ perror("lstat:");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ length = s.st_size + 1 - rate;
|
||||
+
|
||||
+ do{
|
||||
+ length+=rate;
|
||||
+
|
||||
+ free(path);
|
||||
+ path = malloc(sizeof(char) * length);
|
||||
+
|
||||
+ if(path == NULL){
|
||||
+ perror("malloc:");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ r = readlink("/proc/self/exe", path, length);
|
||||
+
|
||||
+ if(r == -1){
|
||||
+ perror("readlink:");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }while(r >= length);
|
||||
+
|
||||
+ path[r] = '\0';
|
||||
+
|
||||
+ return path;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * self-restart
|
||||
+ *
|
||||
+ * Initially inspired by: Yu-Jie Lin
|
||||
+ * https://sites.google.com/site/yjlnotes/notes/dwm
|
||||
+ */
|
||||
+void self_restart(const Arg *arg) {
|
||||
+ char *const argv[] = {get_dwm_path(), NULL};
|
||||
+
|
||||
+ if(argv[0] == NULL){
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ execv(argv[0], argv);
|
||||
+}
|
||||
@@ -0,0 +1,102 @@
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index fd77a07..09737d7 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -64,6 +64,8 @@ static Key keys[] = {
|
||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
+ { MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } },
|
||||
+ { MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } },
|
||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 421bf27..1ec8b10 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -165,6 +165,8 @@ static void detachstack(Client *c);
|
||||
static Monitor *dirtomon(int dir);
|
||||
static void drawbar(Monitor *m);
|
||||
static void drawbars(void);
|
||||
+static void enqueue(Client *c);
|
||||
+static void enqueuestack(Client *c);
|
||||
static void enternotify(XEvent *e);
|
||||
static void expose(XEvent *e);
|
||||
static void focus(Client *c);
|
||||
@@ -194,6 +196,7 @@ static void resize(Client *c, int x, int y, int w, int h, int interact);
|
||||
static void resizeclient(Client *c, int x, int y, int w, int h);
|
||||
static void resizemouse(const Arg *arg);
|
||||
static void restack(Monitor *m);
|
||||
+static void rotatestack(const Arg *arg);
|
||||
static void run(void);
|
||||
static void scan(void);
|
||||
static int sendevent(Client *c, Atom proto);
|
||||
@@ -765,6 +768,28 @@ drawbars(void)
|
||||
}
|
||||
|
||||
void
|
||||
+enqueue(Client *c)
|
||||
+{
|
||||
+ Client *l;
|
||||
+ for (l = c->mon->clients; l && l->next; l = l->next);
|
||||
+ if (l) {
|
||||
+ l->next = c;
|
||||
+ c->next = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+enqueuestack(Client *c)
|
||||
+{
|
||||
+ Client *l;
|
||||
+ for (l = c->mon->stack; l && l->snext; l = l->snext);
|
||||
+ if (l) {
|
||||
+ l->snext = c;
|
||||
+ c->snext = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
enternotify(XEvent *e)
|
||||
{
|
||||
Client *c;
|
||||
@@ -1390,6 +1415,38 @@ restack(Monitor *m)
|
||||
}
|
||||
|
||||
void
|
||||
+rotatestack(const Arg *arg)
|
||||
+{
|
||||
+ Client *c = NULL, *f;
|
||||
+
|
||||
+ if (!selmon->sel)
|
||||
+ return;
|
||||
+ f = selmon->sel;
|
||||
+ if (arg->i > 0) {
|
||||
+ for (c = nexttiled(selmon->clients); c && nexttiled(c->next); c = nexttiled(c->next));
|
||||
+ if (c){
|
||||
+ detach(c);
|
||||
+ attach(c);
|
||||
+ detachstack(c);
|
||||
+ attachstack(c);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if ((c = nexttiled(selmon->clients))){
|
||||
+ detach(c);
|
||||
+ enqueue(c);
|
||||
+ detachstack(c);
|
||||
+ enqueuestack(c);
|
||||
+ }
|
||||
+ }
|
||||
+ if (c){
|
||||
+ arrange(selmon);
|
||||
+ //unfocus(f, 1);
|
||||
+ focus(f);
|
||||
+ restack(selmon);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
run(void)
|
||||
{
|
||||
XEvent ev;
|
||||
@@ -0,0 +1,166 @@
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index a96f33c..24b1eeb 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -163,6 +163,7 @@ static void detachstack(Client *c);
|
||||
static Monitor *dirtomon(int dir);
|
||||
static void drawbar(Monitor *m);
|
||||
static void drawbars(void);
|
||||
+static int drawstatusbar(Monitor *m, int bh, char* text);
|
||||
static void enternotify(XEvent *e);
|
||||
static void expose(XEvent *e);
|
||||
static void focus(Client *c);
|
||||
@@ -237,7 +238,7 @@ static void zoom(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
static const char broken[] = "broken";
|
||||
-static char stext[256];
|
||||
+static char stext[1024];
|
||||
static int screen;
|
||||
static int sw, sh; /* X display screen geometry width, height */
|
||||
static int bh, blw = 0; /* bar geometry */
|
||||
@@ -485,7 +486,7 @@ cleanup(void)
|
||||
cleanupmon(mons);
|
||||
for (i = 0; i < CurLast; i++)
|
||||
drw_cur_free(drw, cursor[i]);
|
||||
- for (i = 0; i < LENGTH(colors); i++)
|
||||
+ for (i = 0; i < LENGTH(colors) + 1; i++)
|
||||
free(scheme[i]);
|
||||
XDestroyWindow(dpy, wmcheckwin);
|
||||
drw_free(drw);
|
||||
@@ -693,6 +694,114 @@ dirtomon(int dir)
|
||||
return m;
|
||||
}
|
||||
|
||||
+int
|
||||
+drawstatusbar(Monitor *m, int bh, char* stext) {
|
||||
+ int ret, i, w, x, len;
|
||||
+ short isCode = 0;
|
||||
+ char *text;
|
||||
+ char *p;
|
||||
+
|
||||
+ len = strlen(stext) + 1 ;
|
||||
+ if (!(text = (char*) malloc(sizeof(char)*len)))
|
||||
+ die("malloc");
|
||||
+ p = text;
|
||||
+ memcpy(text, stext, len);
|
||||
+
|
||||
+ /* compute width of the status text */
|
||||
+ w = 0;
|
||||
+ i = -1;
|
||||
+ while (text[++i]) {
|
||||
+ if (text[i] == '^') {
|
||||
+ if (!isCode) {
|
||||
+ isCode = 1;
|
||||
+ text[i] = '\0';
|
||||
+ w += TEXTW(text) - lrpad;
|
||||
+ text[i] = '^';
|
||||
+ if (text[++i] == 'f')
|
||||
+ w += atoi(text + ++i);
|
||||
+ } else {
|
||||
+ isCode = 0;
|
||||
+ text = text + i + 1;
|
||||
+ i = -1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (!isCode)
|
||||
+ w += TEXTW(text) - lrpad;
|
||||
+ else
|
||||
+ isCode = 0;
|
||||
+ text = p;
|
||||
+
|
||||
+ w += 2; /* 1px padding on both sides */
|
||||
+ ret = x = m->ww - w;
|
||||
+
|
||||
+ drw_setscheme(drw, scheme[LENGTH(colors)]);
|
||||
+ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
|
||||
+ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
|
||||
+ drw_rect(drw, x, 0, w, bh, 1, 1);
|
||||
+ x++;
|
||||
+
|
||||
+ /* process status text */
|
||||
+ i = -1;
|
||||
+ while (text[++i]) {
|
||||
+ if (text[i] == '^' && !isCode) {
|
||||
+ isCode = 1;
|
||||
+
|
||||
+ text[i] = '\0';
|
||||
+ w = TEXTW(text) - lrpad;
|
||||
+ drw_text(drw, x, 0, w, bh, 0, text, 0);
|
||||
+
|
||||
+ x += w;
|
||||
+
|
||||
+ /* process code */
|
||||
+ while (text[++i] != '^') {
|
||||
+ if (text[i] == 'c') {
|
||||
+ char buf[8];
|
||||
+ memcpy(buf, (char*)text+i+1, 7);
|
||||
+ buf[7] = '\0';
|
||||
+ drw_clr_create(drw, &drw->scheme[ColFg], buf);
|
||||
+ i += 7;
|
||||
+ } else if (text[i] == 'b') {
|
||||
+ char buf[8];
|
||||
+ memcpy(buf, (char*)text+i+1, 7);
|
||||
+ buf[7] = '\0';
|
||||
+ drw_clr_create(drw, &drw->scheme[ColBg], buf);
|
||||
+ i += 7;
|
||||
+ } else if (text[i] == 'd') {
|
||||
+ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
|
||||
+ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
|
||||
+ } else if (text[i] == 'r') {
|
||||
+ int rx = atoi(text + ++i);
|
||||
+ while (text[++i] != ',');
|
||||
+ int ry = atoi(text + ++i);
|
||||
+ while (text[++i] != ',');
|
||||
+ int rw = atoi(text + ++i);
|
||||
+ while (text[++i] != ',');
|
||||
+ int rh = atoi(text + ++i);
|
||||
+
|
||||
+ drw_rect(drw, rx + x, ry, rw, rh, 1, 0);
|
||||
+ } else if (text[i] == 'f') {
|
||||
+ x += atoi(text + ++i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ text = text + i + 1;
|
||||
+ i=-1;
|
||||
+ isCode = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!isCode) {
|
||||
+ w = TEXTW(text) - lrpad;
|
||||
+ drw_text(drw, x, 0, w, bh, 0, text, 0);
|
||||
+ }
|
||||
+
|
||||
+ drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
+ free(p);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void
|
||||
drawbar(Monitor *m)
|
||||
{
|
||||
@@ -707,9 +816,7 @@ drawbar(Monitor *m)
|
||||
|
||||
/* draw status first so it can be overdrawn by tags later */
|
||||
if (m == selmon) { /* status is only drawn on selected monitor */
|
||||
- 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);
|
||||
+ tw = m->ww - drawstatusbar(m, bh, stext);
|
||||
}
|
||||
|
||||
for (c = m->clients; c; c = c->next) {
|
||||
@@ -1571,7 +1678,8 @@ setup(void)
|
||||
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
||||
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
|
||||
/* init appearance */
|
||||
- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
|
||||
+ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
|
||||
+ scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3);
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
scheme[i] = drw_scm_create(drw, colors[i], 3);
|
||||
/* init bars */
|
||||
@@ -0,0 +1,25 @@
|
||||
diff -up a/dwm.c b/dwm.c
|
||||
--- a/dwm.c 2020-07-09 16:49:10.023585649 +0200
|
||||
+++ b/dwm.c 2020-07-09 16:49:43.497542191 +0200
|
||||
@@ -702,7 +702,7 @@ drawbar(Monitor *m)
|
||||
Client *c;
|
||||
|
||||
/* draw status first so it can be overdrawn by tags later */
|
||||
- if (m == selmon) { /* status is only drawn on selected monitor */
|
||||
+ if (m == selmon || 1) { /* status is only drawn on selected monitor */
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
|
||||
drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
|
||||
@@ -1987,9 +1987,11 @@ updatesizehints(Client *c)
|
||||
void
|
||||
updatestatus(void)
|
||||
{
|
||||
+ Monitor* m;
|
||||
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
|
||||
strcpy(stext, "dwm-"VERSION);
|
||||
- drawbar(selmon);
|
||||
+ for(m = mons; m; m = m->next)
|
||||
+ drawbar(m);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -0,0 +1,208 @@
|
||||
From f58c7e4fd05ec13383518ccd51663167d45e92d0 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Bylinka <daniel.bylinka@gmail.com>
|
||||
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
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 1c0b587..b67825e 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -103,7 +103,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, sigdwmblocks, {.i = 1} },
|
||||
+ { ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
|
||||
+ { ClkStatusText, 0, Button3, sigdwmblocks, {.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 4465af1..c600131 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -156,6 +156,7 @@ static void clientmessage(XEvent *e);
|
||||
static void configure(Client *c);
|
||||
static void configurenotify(XEvent *e);
|
||||
static void configurerequest(XEvent *e);
|
||||
+static void copyvalidchars(char *text, char *rawtext);
|
||||
static Monitor *createmon(void);
|
||||
static void destroynotify(XEvent *e);
|
||||
static void detach(Client *c);
|
||||
@@ -169,6 +170,7 @@ static void focus(Client *c);
|
||||
static void focusin(XEvent *e);
|
||||
static void focusmon(const Arg *arg);
|
||||
static void focusstack(const Arg *arg);
|
||||
+static int getdwmblockspid();
|
||||
static int getrootptr(int *x, int *y);
|
||||
static long getstate(Window w);
|
||||
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
||||
@@ -205,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 sigdwmblocks(const Arg *arg);
|
||||
static void spawn(const Arg *arg);
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
@@ -237,6 +240,9 @@ static void zoom(const Arg *arg);
|
||||
/* variables */
|
||||
static const char broken[] = "broken";
|
||||
static char stext[256];
|
||||
+static char rawstext[256];
|
||||
+static int dwmblockssig;
|
||||
+pid_t dwmblockspid = 0;
|
||||
static int screen;
|
||||
static int sw, sh; /* X display screen geometry width, height */
|
||||
static int bh, blw = 0; /* bar geometry */
|
||||
@@ -439,9 +445,26 @@ buttonpress(XEvent *e)
|
||||
arg.ui = 1 << i;
|
||||
} else if (ev->x < x + blw)
|
||||
click = ClkLtSymbol;
|
||||
- else if (ev->x > selmon->ww - TEXTW(stext))
|
||||
+ else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) {
|
||||
click = ClkStatusText;
|
||||
- else
|
||||
+
|
||||
+ char *text = rawstext;
|
||||
+ int i = -1;
|
||||
+ char ch;
|
||||
+ dwmblockssig = 0;
|
||||
+ while (text[++i]) {
|
||||
+ if ((unsigned char)text[i] < ' ') {
|
||||
+ ch = text[i];
|
||||
+ text[i] = '\0';
|
||||
+ x += TEXTW(text) - lrpad;
|
||||
+ text[i] = ch;
|
||||
+ text += i+1;
|
||||
+ i = -1;
|
||||
+ if (x >= ev->x) break;
|
||||
+ dwmblockssig = ch;
|
||||
+ }
|
||||
+ }
|
||||
+ } else
|
||||
click = ClkWinTitle;
|
||||
} else if ((c = wintoclient(ev->window))) {
|
||||
focus(c);
|
||||
@@ -627,6 +650,19 @@ configurerequest(XEvent *e)
|
||||
XSync(dpy, False);
|
||||
}
|
||||
|
||||
+void
|
||||
+copyvalidchars(char *text, char *rawtext)
|
||||
+{
|
||||
+ int i = -1, j = 0;
|
||||
+
|
||||
+ while(rawtext[++i]) {
|
||||
+ if ((unsigned char)rawtext[i] >= ' ') {
|
||||
+ text[j++] = rawtext[i];
|
||||
+ }
|
||||
+ }
|
||||
+ text[j] = '\0';
|
||||
+}
|
||||
+
|
||||
Monitor *
|
||||
createmon(void)
|
||||
{
|
||||
@@ -871,6 +907,18 @@ getatomprop(Client *c, Atom prop)
|
||||
return atom;
|
||||
}
|
||||
|
||||
+int
|
||||
+getdwmblockspid()
|
||||
+{
|
||||
+ char buf[16];
|
||||
+ FILE *fp = popen("pidof -s dwmblocks", "r");
|
||||
+ fgets(buf, sizeof(buf), fp);
|
||||
+ pid_t pid = strtoul(buf, NULL, 10);
|
||||
+ pclose(fp);
|
||||
+ dwmblockspid = pid;
|
||||
+ return pid != 0 ? 0 : -1;
|
||||
+}
|
||||
+
|
||||
int
|
||||
getrootptr(int *x, int *y)
|
||||
{
|
||||
@@ -1636,6 +1684,23 @@ sigchld(int unused)
|
||||
while (0 < waitpid(-1, NULL, WNOHANG));
|
||||
}
|
||||
|
||||
+void
|
||||
+sigdwmblocks(const Arg *arg)
|
||||
+{
|
||||
+ union sigval sv;
|
||||
+ sv.sival_int = (dwmblockssig << 8) | arg->i;
|
||||
+ if (!dwmblockspid)
|
||||
+ if (getdwmblockspid() == -1)
|
||||
+ return;
|
||||
+
|
||||
+ if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) {
|
||||
+ if (errno == ESRCH) {
|
||||
+ if (!getdwmblockspid())
|
||||
+ sigqueue(dwmblockspid, SIGUSR1, sv);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
spawn(const Arg *arg)
|
||||
{
|
||||
@@ -1987,8 +2052,10 @@ updatesizehints(Client *c)
|
||||
void
|
||||
updatestatus(void)
|
||||
{
|
||||
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
|
||||
+ if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
|
||||
strcpy(stext, "dwm-"VERSION);
|
||||
+ else
|
||||
+ copyvalidchars(stext, rawstext);
|
||||
drawbar(selmon);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
diff -up dwm-6.2-original/config.def.h dwm-6.2-modified/config.def.h
|
||||
--- dwm-6.2-original/config.def.h 2019-02-02 14:55:28.000000000 +0200
|
||||
+++ dwm-6.2-modified/config.def.h 2019-11-18 19:36:22.515566509 +0200
|
||||
@@ -26,9 +26,9 @@ static const Rule rules[] = {
|
||||
* WM_CLASS(STRING) = instance, class
|
||||
* WM_NAME(STRING) = title
|
||||
*/
|
||||
- /* class instance title tags mask isfloating monitor */
|
||||
- { "Gimp", NULL, NULL, 0, 1, -1 },
|
||||
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||
+ /* class instance title tags mask switchtotag isfloating monitor */
|
||||
+ { "Gimp", NULL, NULL, 0, 0, 1, -1 },
|
||||
+ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
diff -up dwm-6.2-original/dwm.c dwm-6.2-modified/dwm.c
|
||||
--- dwm-6.2-original/dwm.c 2019-02-02 14:55:28.000000000 +0200
|
||||
+++ dwm-6.2-modified/dwm.c 2019-11-18 19:37:18.792187705 +0200
|
||||
@@ -92,6 +92,7 @@ struct Client {
|
||||
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
+ unsigned int switchtotag;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||
Client *next;
|
||||
Client *snext;
|
||||
@@ -137,6 +138,7 @@ typedef struct {
|
||||
const char *instance;
|
||||
const char *title;
|
||||
unsigned int tags;
|
||||
+ unsigned int switchtotag;
|
||||
int isfloating;
|
||||
int monitor;
|
||||
} Rule;
|
||||
@@ -302,6 +304,11 @@ applyrules(Client *c)
|
||||
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||
if (m)
|
||||
c->mon = m;
|
||||
+ if (r->switchtotag) {
|
||||
+ Arg a = { .ui = r->tags };
|
||||
+ c->switchtotag = selmon->tagset[selmon->seltags];
|
||||
+ view(&a);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (ch.res_class)
|
||||
@@ -1782,6 +1789,10 @@ unmanage(Client *c, int destroyed)
|
||||
focus(NULL);
|
||||
updateclientlist();
|
||||
arrange(m);
|
||||
+ if (c->switchtotag) {
|
||||
+ Arg a = { .ui = c->switchtotag };
|
||||
+ view(&a);
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
@@ -0,0 +1,101 @@
|
||||
From 58414bee958f2e7ed91d6fe31f503ec4a406981b Mon Sep 17 00:00:00 2001
|
||||
From: cirala <thim@cederlund.de>
|
||||
Date: Fri, 19 Nov 2021 18:14:07 +0100
|
||||
Subject: [PATCH] Fix for dwm-uselessgap
|
||||
Previous versions of the patch doubles the
|
||||
gap between the master and slave stacks.
|
||||
|
||||
---
|
||||
config.def.h | 3 ++-
|
||||
dwm.c | 38 +++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 33 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index a2ac963..17a205f 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
/* appearance */
|
||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||
+static const unsigned int gappx = 6; /* gaps between windows */
|
||||
static const unsigned int snap = 32; /* snap pixel */
|
||||
static const int showbar = 1; /* 0 means no bar */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
@@ -34,7 +35,7 @@ static const Rule rules[] = {
|
||||
/* layout(s) */
|
||||
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||
static const int nmaster = 1; /* number of clients in master area */
|
||||
-static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||
+static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
|
||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||
|
||||
static const Layout layouts[] = {
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 5e4d494..b626e89 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -52,8 +52,8 @@
|
||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
-#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||
-#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
+#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
|
||||
+#define HEIGHT(X) ((X)->h + 2 * (X)->bw + gappx)
|
||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||
|
||||
@@ -1277,12 +1277,36 @@ void
|
||||
resizeclient(Client *c, int x, int y, int w, int h)
|
||||
{
|
||||
XWindowChanges wc;
|
||||
+ unsigned int n;
|
||||
+ unsigned int gapoffset;
|
||||
+ unsigned int gapincr;
|
||||
+ Client *nbc;
|
||||
|
||||
- c->oldx = c->x; c->x = wc.x = x;
|
||||
- c->oldy = c->y; c->y = wc.y = y;
|
||||
- c->oldw = c->w; c->w = wc.width = w;
|
||||
- c->oldh = c->h; c->h = wc.height = h;
|
||||
wc.border_width = c->bw;
|
||||
+
|
||||
+ /* Get number of clients for the client's monitor */
|
||||
+ for (n = 0, nbc = nexttiled(c->mon->clients); nbc; nbc = nexttiled(nbc->next), n++);
|
||||
+
|
||||
+ /* Do nothing if layout is floating */
|
||||
+ if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) {
|
||||
+ gapincr = gapoffset = 0;
|
||||
+ } else {
|
||||
+ /* Remove border and gap if layout is monocle or only one client */
|
||||
+ if (c->mon->lt[c->mon->sellt]->arrange == monocle || n == 1) {
|
||||
+ gapoffset = 0;
|
||||
+ gapincr = -2 * borderpx;
|
||||
+ wc.border_width = 0;
|
||||
+ } else {
|
||||
+ gapoffset = gappx;
|
||||
+ gapincr = 2 * gappx;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ c->oldx = c->x; c->x = wc.x = x + gapoffset;
|
||||
+ c->oldy = c->y; c->y = wc.y = y + gapoffset;
|
||||
+ c->oldw = c->w; c->w = wc.width = w - gapincr;
|
||||
+ c->oldh = c->h; c->h = wc.height = h - gapincr;
|
||||
+
|
||||
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||
configure(c);
|
||||
XSync(dpy, False);
|
||||
@@ -1688,7 +1712,7 @@ tile(Monitor *m)
|
||||
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||
if (i < m->nmaster) {
|
||||
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
||||
+ resize(c, m->wx, m->wy + my, mw - (2*c->bw) + (n > 1 ? gappx : 0), h - (2*c->bw), 0);
|
||||
if (my + HEIGHT(c) < m->wh)
|
||||
my += HEIGHT(c);
|
||||
} else {
|
||||
--
|
||||
2.33.1
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 4465af1..bf74f60 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -227,6 +227,7 @@ static void updatetitle(Client *c);
|
||||
static void updatewindowtype(Client *c);
|
||||
static void updatewmhints(Client *c);
|
||||
static void view(const Arg *arg);
|
||||
+static void warp(const Client *c);
|
||||
static Client *wintoclient(Window w);
|
||||
static Monitor *wintomon(Window w);
|
||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||
@@ -827,6 +828,7 @@ focusmon(const Arg *arg)
|
||||
unfocus(selmon->sel, 0);
|
||||
selmon = m;
|
||||
focus(NULL);
|
||||
+ warp(selmon->sel);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1367,6 +1369,8 @@ restack(Monitor *m)
|
||||
}
|
||||
XSync(dpy, False);
|
||||
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
|
||||
+ if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && selmon->lt[selmon->sellt] != &layouts[2])
|
||||
+ warp(m->sel);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2044,6 +2048,28 @@ view(const Arg *arg)
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
+void
|
||||
+warp(const Client *c)
|
||||
+{
|
||||
+ int x, y;
|
||||
+
|
||||
+ if (!c) {
|
||||
+ XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww/2, selmon->wy + selmon->wh/2);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!getrootptr(&x, &y) ||
|
||||
+ (x > c->x - c->bw &&
|
||||
+ y > c->y - c->bw &&
|
||||
+ x < c->x + c->w + c->bw*2 &&
|
||||
+ y < c->y + c->h + c->bw*2) ||
|
||||
+ (y > c->mon->by && y < c->mon->by + bh) ||
|
||||
+ (c->mon->topbar && !y))
|
||||
+ return;
|
||||
+
|
||||
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
|
||||
+}
|
||||
+
|
||||
Client *
|
||||
wintoclient(Window w)
|
||||
{
|
||||
@@ -0,0 +1,188 @@
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 1c0b587..5db7d05 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -7,15 +7,16 @@ static const int showbar = 1; /* 0 means no bar */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
static const char *fonts[] = { "monospace:size=10" };
|
||||
static const char dmenufont[] = "monospace:size=10";
|
||||
-static const char col_gray1[] = "#222222";
|
||||
-static const char col_gray2[] = "#444444";
|
||||
-static const char col_gray3[] = "#bbbbbb";
|
||||
-static const char col_gray4[] = "#eeeeee";
|
||||
-static const char col_cyan[] = "#005577";
|
||||
-static const char *colors[][3] = {
|
||||
- /* fg bg border */
|
||||
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
+static char normbgcolor[] = "#222222";
|
||||
+static char normbordercolor[] = "#444444";
|
||||
+static char normfgcolor[] = "#bbbbbb";
|
||||
+static char selfgcolor[] = "#eeeeee";
|
||||
+static char selbordercolor[] = "#005577";
|
||||
+static char selbgcolor[] = "#005577";
|
||||
+static char *colors[][3] = {
|
||||
+ /* fg bg border */
|
||||
+ [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor },
|
||||
+ [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor },
|
||||
};
|
||||
|
||||
/* tagging */
|
||||
@@ -56,7 +57,7 @@ static const Layout layouts[] = {
|
||||
|
||||
/* 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 };
|
||||
+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 Key keys[] = {
|
||||
@@ -84,6 +85,7 @@ static Key keys[] = {
|
||||
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
||||
+ { MODKEY, XK_F5, xrdb, {.v = NULL } },
|
||||
TAGKEYS( XK_1, 0)
|
||||
TAGKEYS( XK_2, 1)
|
||||
TAGKEYS( XK_3, 2)
|
||||
diff --git a/drw.c b/drw.c
|
||||
index 8fd1ca4..e4968a0 100644
|
||||
--- a/drw.c
|
||||
+++ b/drw.c
|
||||
@@ -207,7 +207,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr *
|
||||
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
+drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
|
||||
{
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
diff --git a/drw.h b/drw.h
|
||||
index 4bcd5ad..42b04ce 100644
|
||||
--- a/drw.h
|
||||
+++ b/drw.h
|
||||
@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||
+Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 4465af1..7fa45c5 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xproto.h>
|
||||
+#include <X11/Xresource.h>
|
||||
#include <X11/Xutil.h>
|
||||
#ifdef XINERAMA
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
@@ -56,6 +57,21 @@
|
||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||
+#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \
|
||||
+ if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \
|
||||
+ int i = 1; \
|
||||
+ for (; i <= 6; i++) { \
|
||||
+ if (value.addr[i] < 48) break; \
|
||||
+ if (value.addr[i] > 57 && value.addr[i] < 65) break; \
|
||||
+ if (value.addr[i] > 70 && value.addr[i] < 97) break; \
|
||||
+ if (value.addr[i] > 102) break; \
|
||||
+ } \
|
||||
+ if (i == 7) { \
|
||||
+ strncpy(V, value.addr, 7); \
|
||||
+ V[7] = '\0'; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ }
|
||||
|
||||
/* enums */
|
||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||
@@ -177,6 +193,7 @@ static void grabkeys(void);
|
||||
static void incnmaster(const Arg *arg);
|
||||
static void keypress(XEvent *e);
|
||||
static void killclient(const Arg *arg);
|
||||
+static void loadxrdb(void);
|
||||
static void manage(Window w, XWindowAttributes *wa);
|
||||
static void mappingnotify(XEvent *e);
|
||||
static void maprequest(XEvent *e);
|
||||
@@ -232,6 +249,7 @@ static Monitor *wintomon(Window w);
|
||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||
+static void xrdb(const Arg *arg);
|
||||
static void zoom(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
@@ -1014,6 +1032,37 @@ killclient(const Arg *arg)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+loadxrdb()
|
||||
+{
|
||||
+ Display *display;
|
||||
+ char * resm;
|
||||
+ XrmDatabase xrdb;
|
||||
+ char *type;
|
||||
+ XrmValue value;
|
||||
+
|
||||
+ display = XOpenDisplay(NULL);
|
||||
+
|
||||
+ if (display != NULL) {
|
||||
+ resm = XResourceManagerString(display);
|
||||
+
|
||||
+ if (resm != NULL) {
|
||||
+ xrdb = XrmGetStringDatabase(resm);
|
||||
+
|
||||
+ if (xrdb != NULL) {
|
||||
+ XRDB_LOAD_COLOR("dwm.normbordercolor", normbordercolor);
|
||||
+ XRDB_LOAD_COLOR("dwm.normbgcolor", normbgcolor);
|
||||
+ XRDB_LOAD_COLOR("dwm.normfgcolor", normfgcolor);
|
||||
+ XRDB_LOAD_COLOR("dwm.selbordercolor", selbordercolor);
|
||||
+ XRDB_LOAD_COLOR("dwm.selbgcolor", selbgcolor);
|
||||
+ XRDB_LOAD_COLOR("dwm.selfgcolor", selfgcolor);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ XCloseDisplay(display);
|
||||
+}
|
||||
+
|
||||
void
|
||||
manage(Window w, XWindowAttributes *wa)
|
||||
{
|
||||
@@ -2110,6 +2159,17 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+void
|
||||
+xrdb(const Arg *arg)
|
||||
+{
|
||||
+ loadxrdb();
|
||||
+ int i;
|
||||
+ for (i = 0; i < LENGTH(colors); i++)
|
||||
+ scheme[i] = drw_scm_create(drw, colors[i], 3);
|
||||
+ focus(NULL);
|
||||
+ arrange(NULL);
|
||||
+}
|
||||
+
|
||||
void
|
||||
zoom(const Arg *arg)
|
||||
{
|
||||
@@ -2136,6 +2196,8 @@ main(int argc, char *argv[])
|
||||
if (!(dpy = XOpenDisplay(NULL)))
|
||||
die("dwm: cannot open display");
|
||||
checkotherwm();
|
||||
+ XrmInitialize();
|
||||
+ loadxrdb();
|
||||
setup();
|
||||
#ifdef __OpenBSD__
|
||||
if (pledge("stdio rpath proc exec", NULL) == -1)
|
||||
@@ -0,0 +1,75 @@
|
||||
diff -up a/dwmblocks.c b/dwmblocks.c
|
||||
--- a/dwmblocks.c 2020-12-22 14:25:05.289247774 +0200
|
||||
+++ b/dwmblocks.c 2020-12-22 14:29:39.744943965 +0200
|
||||
@@ -28,6 +28,7 @@ typedef struct {
|
||||
void dummysighandler(int num);
|
||||
#endif
|
||||
void sighandler(int num);
|
||||
+void buttonhandler(int sig, siginfo_t *si, void *ucontext);
|
||||
void getcmds(int time);
|
||||
void getsigcmds(unsigned int signal);
|
||||
void setupsignals();
|
||||
@@ -52,14 +53,31 @@ static void (*writestatus) () = pstdout;
|
||||
|
||||
static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
|
||||
static char statusstr[2][STATUSLENGTH];
|
||||
+static char button[] = "\0";
|
||||
static int statusContinue = 1;
|
||||
static int returnStatus = 0;
|
||||
|
||||
//opens process *cmd and stores output in *output
|
||||
void getcmd(const Block *block, char *output)
|
||||
{
|
||||
+ if (block->signal)
|
||||
+ {
|
||||
+ output[0] = block->signal;
|
||||
+ output++;
|
||||
+ }
|
||||
strcpy(output, block->icon);
|
||||
- FILE *cmdf = popen(block->command, "r");
|
||||
+ FILE *cmdf;
|
||||
+ if (*button)
|
||||
+ {
|
||||
+ setenv("BUTTON", button, 1);
|
||||
+ cmdf = popen(block->command,"r");
|
||||
+ *button = '\0';
|
||||
+ unsetenv("BUTTON");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cmdf = popen(block->command,"r");
|
||||
+ }
|
||||
if (!cmdf)
|
||||
return;
|
||||
int i = strlen(block->icon);
|
||||
@@ -105,9 +123,15 @@ void setupsignals()
|
||||
signal(i, dummysighandler);
|
||||
#endif
|
||||
|
||||
+ struct sigaction sa;
|
||||
for (unsigned int i = 0; i < LENGTH(blocks); i++) {
|
||||
- if (blocks[i].signal > 0)
|
||||
+ if (blocks[i].signal > 0) {
|
||||
signal(SIGMINUS+blocks[i].signal, sighandler);
|
||||
+ sigaddset(&sa.sa_mask, SIGRTMIN+blocks[i].signal); // ignore signal when handling SIGUSR1
|
||||
+ }
|
||||
+ sa.sa_sigaction = buttonhandler;
|
||||
+ sa.sa_flags = SA_SIGINFO;
|
||||
+ sigaction(SIGUSR1, &sa, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -173,6 +197,13 @@ void dummysighandler(int signum)
|
||||
{
|
||||
return;
|
||||
}
|
||||
+
|
||||
+void buttonhandler(int sig, siginfo_t *si, void *ucontext)
|
||||
+{
|
||||
+ *button = '0' + si->si_value.sival_int & 0xff;
|
||||
+ getsigcmds(si->si_value.sival_int >> 8);
|
||||
+ writestatus();
|
||||
+}
|
||||
#endif
|
||||
|
||||
void sighandler(int signum)
|
||||
@@ -0,0 +1,66 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Magically finds the current's executable path
|
||||
*
|
||||
* I'm doing the do{}while(); trick because Linux (what I'm running) is not
|
||||
* POSIX compilant and so lstat() cannot be trusted on /proc entries
|
||||
*
|
||||
* @return char* the path of the current executable
|
||||
*/
|
||||
char *get_dwm_path(){
|
||||
struct stat s;
|
||||
int r, length, rate = 42;
|
||||
char *path = NULL;
|
||||
|
||||
if(lstat("/proc/self/exe", &s) == -1){
|
||||
perror("lstat:");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = s.st_size + 1 - rate;
|
||||
|
||||
do{
|
||||
length+=rate;
|
||||
|
||||
free(path);
|
||||
path = malloc(sizeof(char) * length);
|
||||
|
||||
if(path == NULL){
|
||||
perror("malloc:");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = readlink("/proc/self/exe", path, length);
|
||||
|
||||
if(r == -1){
|
||||
perror("readlink:");
|
||||
return NULL;
|
||||
}
|
||||
}while(r >= length);
|
||||
|
||||
path[r] = '\0';
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* self-restart
|
||||
*
|
||||
* Initially inspired by: Yu-Jie Lin
|
||||
* https://sites.google.com/site/yjlnotes/notes/dwm
|
||||
*/
|
||||
void self_restart(const Arg *arg) {
|
||||
char *const argv[] = {get_dwm_path(), NULL};
|
||||
|
||||
if(argv[0] == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
execv(argv[0], argv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user