Compare commits

..

No commits in common. "master" and "dwm-6.5" have entirely different histories.

50 changed files with 140 additions and 6035 deletions

8
.gitignore vendored
View File

@ -1,8 +0,0 @@
config.h
drw.o
dwm
dwm.o
util.o
patches/unused/
*.orig
*.rej

View File

@ -20,7 +20,7 @@ dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz config.h
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean
mkdir -p dwm-${VERSION}

View File

@ -2,100 +2,35 @@
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int gappx = 18; /* gap pixel between windows */
static const unsigned int snap = 32; /* snap pixel */
static const int swallowfloating = 0; /* 1 means swallow floating windows by default */
static const int showbar = 1; /* 0 means no standard bar */
static const int topbar = 1; /* 0 means standard bar at bottom */
static const int extrabar = 1; /* 0 means no extra bar */
static const char statussep = ';'; /* separator between statuses */
static const int user_bh = 2; /* 2 is the default spacing around the bar's font */
static const int vertpad = 10; /* vertical padding of bar */
static const int sidepad = 10; /* horizontal padding of bar */
static const char *fonts[] = { "Hack Nerd Font:size=10" };
static const char dmenufont[] = "Hack Nerd Font:size=10";
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 unsigned int baralpha = 230;
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 },
[SchemeHid] = { col_cyan, col_gray1, col_cyan },
[SchemeLay] = { col_cyan, "#00ff00", col_cyan },
[SchemeWf] = { col_cyan, "#00ffff", col_cyan },
};
static const unsigned int alphas[][3] = {
/* fg bg border*/
[SchemeNorm] = { OPAQUE, baralpha, borderalpha },
[SchemeSel] = { OPAQUE, baralpha, borderalpha },
[SchemeHid] = { OPAQUE, baralpha, borderalpha },
[SchemeLay] = { OPAQUE, baralpha, borderalpha },
[SchemeWf] = { OPAQUE, baralpha, borderalpha },
};
static const char *const autostart[] = {
"picom", NULL,
"unclutter", NULL,
"dwmblocks", NULL,
NULL /* terminate */
};
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
/* launcher commands (They must be NULL terminated) */
static const char* browser[] = { "firefox", "--newwindow", "search.brave.com", NULL };
static const char* terminal[] = { "st", NULL };
static const Launcher launchers[] = {
{ terminal, "st" },
{ browser, "firefox" }
};
static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */
static const unsigned int ulinestroke = 2; /* thickness / height of the underline */
static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */
static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */
static const char *tagsel[][2] = {
{ "#ffffff", "#ff0000" },
{ "#ffffff", "#ff7f00" },
{ "#000000", "#ffff00" },
{ "#000000", "#00ff00" },
{ "#ffffff", "#0000ff" },
{ "#ffffff", "#4b0082" },
{ "#ffffff", "#9400d3" },
{ "#000000", "#ffffff" },
{ "#ffffff", "#000000" },
};
static const unsigned int tagalpha[] = { OPAQUE, baralpha };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating isfakefullscreen isterminal noswallow monitor */
{ "Gimp", NULL, NULL, 0, 1, 0, 0, 0, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, -1, -1 },
{ "St", NULL, NULL, 0, 0, 0, 1, 0, -1 },
{ NULL, NULL, "Event Tester", 0, 0, 0, 0, 1, -1 }, /* xev */
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
static const char topicon[128] = "\uf435";
/* icon to indicate always on top floating windows */
/* window following */
#define WFACTIVE '>'
#define WFINACTIVE 'v'
#define WFDEFAULT WFINACTIVE
/* 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 */
@ -107,17 +42,15 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
{ "[D]", deck },
};
/* key definitions */
#define MODKEY Mod4Mask
#define MODKEY Mod1Mask
#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} }, \
{ Mod1Mask|ShiftMask, KEY, swaptags, {.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*[]){ "/bin/sh", "-c", cmd, NULL } }
@ -126,63 +59,32 @@ static const Layout layouts[] = {
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 };
static const char *layoutmenu_cmd = "layoutmenu.sh";
#include "exitdwm.c"
static const Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY|ShiftMask, XK_b, toggleextrabar, {0} },
{ MODKEY, XK_n, togglefollow, {0} },
{ MODKEY, XK_j, focusstackvis, {.i = +1 } },
{ MODKEY, XK_k, focusstackvis, {.i = -1 } },
{ MODKEY|ShiftMask, XK_j, focusstackhid, {.i = +1 } },
{ MODKEY|ShiftMask, XK_k, focusstackhid, {.i = -1 } },
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_r, resetlayout, {0} },
{ MODKEY, 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_r, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY|ShiftMask, XK_t, togglealwaysontop, {0} },
{ MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } },
{ MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } },
{ MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } },
{ MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } },
{ MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } },
{ MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } },
{ MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } },
{ MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } },
{ MODKEY|ControlMask, XK_Up, moveresizeedge, {.v = "t"} },
{ MODKEY|ControlMask, XK_Down, moveresizeedge, {.v = "b"} },
{ MODKEY|ControlMask, XK_Left, moveresizeedge, {.v = "l"} },
{ MODKEY|ControlMask, XK_Right, moveresizeedge, {.v = "r"} },
{ MODKEY|ControlMask|ShiftMask, XK_Up, moveresizeedge, {.v = "T"} },
{ MODKEY|ControlMask|ShiftMask, XK_Down, moveresizeedge, {.v = "B"} },
{ MODKEY|ControlMask|ShiftMask, XK_Left, moveresizeedge, {.v = "L"} },
{ MODKEY|ControlMask|ShiftMask, XK_Right, moveresizeedge, {.v = "R"} },
{ MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
{ MODKEY|Mod1Mask, XK_f, togglefakefullscr, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
{ MODKEY, XK_s, show, {0} },
{ MODKEY|ShiftMask, XK_s, showall, {0} },
{ MODKEY, XK_h, hide, {0} },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
@ -192,8 +94,7 @@ static const Key keys[] = {
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_e, exitdwm, {0} }
{ MODKEY|ShiftMask, XK_q, quit, {0} },
};
/* button definitions */
@ -201,14 +102,9 @@ static const Key keys[] = {
static const Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, layoutmenu, {0} },
{ ClkFollowSymbol, 0, Button1, togglefollow, {0} },
{ ClkWinTitle, 0, Button1, togglewin, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkExBarLeftStatus, 0, Button2, spawn, {.v = termcmd } },
{ ClkExBarMiddle, 0, Button2, spawn, {.v = termcmd } },
{ ClkExBarRightStatus, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },

View File

@ -20,11 +20,10 @@ FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = ${X11INC}/freetype2
#MANPREFIX = ${PREFIX}/man
#KVMLIB = -lkvm
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender -lX11-xcb -lxcb -lxcb-res ${KVMLIB}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}

0
dmc.c
View File

30
drw.c
View File

@ -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, Visual *visual, unsigned int depth, Colormap cmap)
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw = ecalloc(1, sizeof(Drw));
@ -70,11 +70,8 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
drw->root = root;
drw->w = w;
drw->h = h;
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->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
@ -90,7 +87,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, drw->depth);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
}
void
@ -184,22 +181,21 @@ drw_fontset_free(Fnt *font)
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
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[], const unsigned int alphas[], size_t clrcount)
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
@ -209,7 +205,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], si
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
@ -267,14 +263,16 @@ 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, drw->visual, drw->cmap);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad;
w -= lpad;
}
usedfont = drw->fonts;
if (!ellipsis_width && render)
ellipsis_width = drw_fontset_getwidth(drw, "");
ellipsis_width = drw_fontset_getwidth(drw, "...");
while (1) {
ew = ellipsis_len = utf8strlen = 0;
utf8str = text;
@ -328,7 +326,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
w -= ew;
}
if (render && overflow)
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "", invert);
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
if (!*text || overflow) {
break;

9
drw.h
View File

@ -20,9 +20,6 @@ typedef struct {
Display *dpy;
int screen;
Window root;
Visual *visual;
unsigned int depth;
Colormap cmap;
Drawable drawable;
GC gc;
Clr *scheme;
@ -30,7 +27,7 @@ typedef struct {
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
@ -42,8 +39,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, unsigned int alpha);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);

19
dwm.1
View File

@ -44,8 +44,7 @@ command.
.TP
.B Button1
click on a tag label to display all windows with that tag, click on the layout
label toggles between tiled and floating layout, click on the window follow
icon toggles it on and off.
label toggles between tiled and floating layout.
.TP
.B Button3
click on a tag label adds/removes all windows with that tag to/from the view.
@ -81,9 +80,6 @@ Send focused window to next screen, if any.
.B Mod1\-b
Toggles bar on and off.
.TP
.B Mod1\-n
Toggles window following on and off.
.TP
.B Mod1\-t
Sets tiled layout.
.TP
@ -120,9 +116,6 @@ Zooms/cycles focused window to/from master area (tiled layouts only).
.B Mod1\-Shift\-c
Close focused window.
.TP
.B Mod1\-Shift\-f
Toggle fullscreen for focused window.
.TP
.B Mod1\-Shift\-space
Toggle focused window between tiled and floating state.
.TP
@ -149,9 +142,6 @@ Add/remove all windows with nth tag to/from the view.
.TP
.B Mod1\-Shift\-q
Quit dwm.
.TP
.B Mod1\-Control\-Shift\-q
Restart dwm.
.SS Mouse commands
.TP
.B Mod1\-Button1
@ -165,13 +155,6 @@ Resize focused window while dragging. Tiled windows will be toggled to the float
.SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.
.SH SIGNALS
.TP
.B SIGHUP - 1
Restart the dwm process.
.TP
.B SIGTERM - 15
Cleanly terminate the dwm process.
.SH SEE ALSO
.BR dmenu (1),
.BR st (1)

1617
dwm.c

File diff suppressed because it is too large Load Diff

View File

@ -1,87 +0,0 @@
# include <stdio.h>
# include <string.h>
void exitdwm ()
{
# if \
defined S_LOCK || \
defined S_RESTART_DWM || \
defined S_OFFSCREEN || \
defined S_EXIT || \
defined S_REBOOT || \
defined S_SHUTDOWN || \
defined S_LOCK_ICON || \
defined S_RESTART_DWM_ICON || \
defined S_OFFSCREEN_ICON || \
defined S_EXIT_ICON || \
defined S_REBOOT_ICON || \
defined S_SHUTDOWN_ICON || \
defined S_FORMAT || \
defined S_FORMAT_CLEAR
# error (conflicting macro names)
# endif
# define S_LOCK "Lock"
# define S_RESTART_DWM "restart Dwm"
# define S_OFFSCREEN "Off-screen"
# define S_EXIT "Exit"
# define S_REBOOT "Reboot"
# define S_SHUTDOWN "Shutdown"
# define S_LOCK_ICON "\uf023" // <= FontAwesome icons
# define S_RESTART_DWM_ICON "\uf01e"
# define S_OFFSCREEN_ICON "\uf108"
# define S_EXIT_ICON "\uf2f5"
# define S_REBOOT_ICON "\uf021"
# define S_SHUTDOWN_ICON "\uf011"
# define S_FORMAT(ACTION) S_##ACTION##_ICON " " S_##ACTION
# define S_FORMAT_CLEAR "sed 's/^..//'"
FILE * exit_menu = popen (
"echo \""
S_FORMAT (LOCK) "\n"
S_FORMAT (RESTART_DWM) "\n"
S_FORMAT (OFFSCREEN) "\n"
S_FORMAT (EXIT) "\n"
S_FORMAT (REBOOT) "\n"
S_FORMAT (SHUTDOWN)
"\" | dmenu -p exit: | " S_FORMAT_CLEAR
,
"r"
);
char exit_action [16];
if (
exit_menu == NULL ||
fscanf (exit_menu, "%15[a-zA-Z -]", exit_action) == EOF
) {
fputs ("Error. Failure in exit_dwm.", stderr);
goto close_streams;
}
if (strcmp (exit_action, S_LOCK) == 0) system ("slock & sleep .5; xset dpms force off");
else if (strcmp (exit_action, S_RESTART_DWM) == 0) quit (& (const Arg) {1});
else if (strcmp (exit_action, S_OFFSCREEN) == 0) system ("sleep .5; xset dpms force off");
else if (strcmp (exit_action, S_EXIT) == 0) quit (& (const Arg) {0});
else if (strcmp (exit_action, S_REBOOT) == 0) system ("systemctl reboot");
else if (strcmp (exit_action, S_SHUTDOWN) == 0) system ("systemctl poweroff -i");
close_streams:
pclose (exit_menu);
# undef S_LOCK
# undef S_RESTART_DWM
# undef S_OFFSCREEN
# undef S_EXIT
# undef S_REBOOT
# undef S_SHUTDOWN
# undef S_LOCK_ICON
# undef S_RESTART_DWM_ICON
# undef S_OFFSCREEN_ICON
# undef S_EXIT_ICON
# undef S_REBOOT_ICON
# undef S_SHUTDOWN_ICON
# undef S_FORMAT
# undef S_FORMAT_CLEAR
}

View File

@ -1,31 +0,0 @@
diff --git a/dwm.c b/dwm.c
index 5646a5c..27e29df 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1283,12 +1283,26 @@ void
resizeclient(Client *c, int x, int y, int w, int h)
{
XWindowChanges wc;
+ unsigned int n;
+ 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;
+
+ for (n = 0, nbc = nexttiled(c->mon->clients); nbc; nbc = nexttiled(nbc->next), n++);
+
+ if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) {
+ } else {
+ if (c->mon->lt[c->mon->sellt]->arrange == monocle || n == 1) {
+ wc.border_width = 0;
+ c->w = wc.width += c->bw * 2;
+ c->h = wc.height += c->bw * 2;
+ }
+ }
+
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);

View File

@ -1,77 +0,0 @@
From e655302a4bd74c1f2778f94761c87381d1dfc0e2 Mon Sep 17 00:00:00 2001
From: midspec <obleque@protonmail.com>
Date: Sat, 4 Nov 2023 19:17:50 +0000
Subject: [PATCH] Add window-gaps for the tile-layout
Adds gaps between windows in the tile-layout. The proposed advantage to some
other patches which try to accomplish the same goal is that the gap-size between
master and stack, window and window, and window and screen-edge is the
same. The gap-size can be configured in the config.h with the
gappx-variable.
---
config.def.h | 1 +
dwm.c | 23 +++++++++++++----------
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 9efa774..82ba41f 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 = 18; /* gap pixel 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 */
diff --git a/dwm.c b/dwm.c
index f1d86b2..fa8b3d6 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1687,28 +1687,31 @@ tagmon(const Arg *arg)
void
tile(Monitor *m)
{
- unsigned int i, n, h, mw, my, ty;
+ unsigned int i, n, h, mw, my, ty, ns;
Client *c;
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
if (n == 0)
return;
- if (n > m->nmaster)
+ if (n > m->nmaster) {
mw = m->nmaster ? m->ww * m->mfact : 0;
- else
+ ns = m->nmaster > 0 ? 2 : 1;
+ } else {
mw = m->ww;
- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ ns = 1;
+ }
+ for(i = 0, my = ty = gappx, 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);
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - gappx;
+ resize(c, m->wx + gappx, m->wy + my, mw - (2*c->bw) - gappx*(5-ns)/2, h - (2*c->bw), False);
if (my + HEIGHT(c) < m->wh)
- my += HEIGHT(c);
+ my += HEIGHT(c) + gappx;
} else {
- h = (m->wh - ty) / (n - i);
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
+ h = (m->wh - ty) / (n - i) - gappx;
+ resize(c, m->wx + mw + gappx/ns, m->wy + ty, m->ww - mw - (2*c->bw) - gappx*(5-ns)/2, h - (2*c->bw), False);
if (ty + HEIGHT(c) < m->wh)
- ty += HEIGHT(c);
+ ty += HEIGHT(c) + gappx;
}
}
--
2.42.0

View File

@ -1,288 +0,0 @@
From ad5887df95fda706291c81ee143d0786a1717b12 Mon Sep 17 00:00:00 2001
From: getimiskon <getimiskon@disroot.org>
Date: Sat, 1 Apr 2023 16:22:01 +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 348f655.
---
config.def.h | 7 +++++++
config.mk | 2 +-
drw.c | 26 ++++++++++++-----------
drw.h | 9 +++++---
dwm.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++------
5 files changed, 81 insertions(+), 22 deletions(-)
diff --git a/config.def.h b/config.def.h
index 9efa774..8b3789a 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 ba64d3d..d609c42 100644
--- a/config.mk
+++ b/config.mk
@@ -23,7 +23,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_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
diff --git a/drw.c b/drw.c
index a58a2b4..d18e8d8 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
@@ -181,21 +184,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;
@@ -205,7 +209,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;
}
@@ -263,9 +267,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 6471431..2143533 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);
@@ -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);
diff --git a/dwm.c b/dwm.c
index c2bd871..3b34de8 100644
--- a/dwm.c
+++ b/dwm.c
@@ -56,6 +56,7 @@
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#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 */
@@ -232,6 +233,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 */
@@ -268,6 +270,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"
@@ -1558,7 +1565,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;
@@ -1586,7 +1594,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();
@@ -1813,16 +1821,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);
@@ -2120,6 +2130,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.40.0

View File

@ -1,25 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 1c0b587..9814500 100644
--- a/config.def.h
+++ b/config.def.h
@@ -5,6 +5,7 @@ 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 user_bh = 2; /* 2 is the default spacing around the bar's font */
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 4465af1..2c27cb3 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1545,7 +1545,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 = drw->fonts->h + user_bh;
updategeom();
/* init atoms */
utf8string = XInternAtom(dpy, "UTF8_STRING", False);

View File

@ -1,118 +0,0 @@
From a3cfb215f7f647d83d67e33df8f33a73e43bd65f Mon Sep 17 00:00:00 2001
From: Bakkeby <bakkeby@gmail.com>
Date: Wed, 20 Oct 2021 09:14:07 +0200
Subject: [PATCH] barpadding: adds space between the statusbar and the edge of
the screen
---
config.def.h | 2 ++
dwm.c | 25 +++++++++++++++----------
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index a2ac963..f0b739f 100644
--- a/config.def.h
+++ b/config.def.h
@@ -5,6 +5,8 @@ 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 vertpad = 10; /* vertical padding of bar */
+static const int sidepad = 10; /* horizontal padding of bar */
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..df6d0d7 100644
--- a/dwm.c
+++ b/dwm.c
@@ -242,6 +242,8 @@ static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
static int lrpad; /* sum of left and right padding for text */
+static int vp; /* vertical padding for bar */
+static int sp; /* side padding for bar */
static int (*xerrorxlib)(Display *, XErrorEvent *);
static unsigned int numlockmask = 0;
static void (*handler[LASTEvent]) (XEvent *) = {
@@ -568,7 +570,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 + sp, m->by + vp, m->ww - 2 * sp, bh);
}
focus(NULL);
arrange(NULL);
@@ -706,7 +708,7 @@ drawbar(Monitor *m)
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);
+ drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0);
}
for (c = m->clients; c; c = c->next) {
@@ -732,12 +734,12 @@ drawbar(Monitor *m)
if ((w = m->ww - tw - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ drw_text(drw, x, 0, w - 2 * sp, bh, lrpad / 2, m->sel->name, 0);
if (m->sel->isfloating)
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
} else {
drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, x, 0, w, bh, 1, 1);
+ drw_rect(drw, x, 0, w - 2 * sp, bh, 1, 1);
}
}
drw_map(drw, m->barwin, 0, 0, m->ww, bh);
@@ -1547,7 +1549,10 @@ setup(void)
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
bh = drw->fonts->h + 2;
+ sp = sidepad;
+ vp = (topbar == 1) ? vertpad : - vertpad;
updategeom();
+
/* init atoms */
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
@@ -1704,7 +1709,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 + sp, selmon->by + vp, selmon->ww - 2 * sp, bh);
arrange(selmon);
}
@@ -1814,7 +1819,7 @@ updatebars(void)
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),
+ m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
@@ -1829,11 +1834,11 @@ updatebarpos(Monitor *m)
m->wy = m->my;
m->wh = m->mh;
if (m->showbar) {
- m->wh -= bh;
- m->by = m->topbar ? m->wy : m->wy + m->wh;
- m->wy = m->topbar ? m->wy + bh : m->wy;
+ m->wh = m->wh - vertpad - bh;
+ m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad;
+ m->wy = m->topbar ? m->wy + bh + vp : m->wy;
} else
- m->by = -bh;
+ m->by = -bh - vp;
}
void
--
2.33.0

View File

@ -1,61 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 1c0b587..80d0e6e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -21,6 +21,20 @@ static const char *colors[][3] = {
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+static const char *tagsel[][2] = {
+ { "#ffffff", "#ff0000" },
+ { "#ffffff", "#ff7f00" },
+ { "#000000", "#ffff00" },
+ { "#000000", "#00ff00" },
+ { "#ffffff", "#0000ff" },
+ { "#ffffff", "#4b0082" },
+ { "#ffffff", "#9400d3" },
+ { "#000000", "#ffffff" },
+ { "#ffffff", "#000000" },
+};
+
+static const unsigned int tagalpha[] = { OPAQUE, baralpha };
+
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
diff --git a/dwm.c b/dwm.c
index b0b3466..23d1c46 100644
--- a/dwm.c
+++ b/dwm.c
@@ -264,6 +264,7 @@ static Atom wmatom[WMLast], netatom[NetLast];
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
+static Clr **tagscheme;
static Display *dpy;
static Drw *drw;
static Monitor *mons, *selmon;
@@ -717,7 +718,7 @@ drawbar(Monitor *m)
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
w = TEXTW(tags[i]);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+ drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm]));
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
if (occ & 1 << i)
drw_rect(drw, x + boxs, boxs, boxw, boxw,
@@ -1568,9 +1569,14 @@ setup(void)
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
/* init appearance */
+ if (LENGTH(tags) > LENGTH(tagsel))
+ die("too few color schemes for the tags");
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], 3);
+ tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *));
+ for (i = 0; i < LENGTH(tagsel); i++)
+ tagscheme[i] = drw_scm_create(drw, tagsel[i], tagalpha, 2);
/* init bars */
updatebars();
updatestatus();

View File

@ -1,22 +0,0 @@
diff --git a/drw.c b/drw.c
index ced7d37..95da860 100644
--- a/drw.c
+++ b/drw.c
@@ -285,7 +285,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
usedfont = drw->fonts;
if (!ellipsis_width && render)
- ellipsis_width = drw_fontset_getwidth(drw, "...");
+ ellipsis_width = drw_fontset_getwidth(drw, "…");
while (1) {
ew = ellipsis_len = utf8strlen = 0;
utf8str = text;
@@ -339,7 +339,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
w -= ew;
}
if (render && overflow)
- drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
+ drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "…", invert);
if (!*text || overflow) {
break;

View File

@ -1,446 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 061ad66..05f18e5 100644
--- a/config.def.h
+++ b/config.def.h
@@ -16,6 +16,7 @@ static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ [SchemeHid] = { col_cyan, col_gray1, col_cyan },
};
/* tagging */
@@ -64,8 +65,10 @@ static const Key keys[] = {
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
+ { MODKEY, XK_j, focusstackvis, {.i = +1 } },
+ { MODKEY, XK_k, focusstackvis, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_j, focusstackhid, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_k, focusstackhid, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
@@ -84,6 +87,9 @@ static const Key keys[] = {
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
+ { MODKEY, XK_s, show, {0} },
+ { MODKEY|ShiftMask, XK_s, showall, {0} },
+ { MODKEY, XK_h, hide, {0} },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
@@ -102,6 +108,7 @@ static const Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkWinTitle, 0, Button1, togglewin, {0} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
diff --git a/dwm.c b/dwm.c
index e5efb6a..0d18e1b 100644
--- a/dwm.c
+++ b/dwm.c
@@ -50,6 +50,7 @@
#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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
+#define HIDDEN(C) ((getstate(C->win) == IconicState))
#define LENGTH(X) (sizeof X / sizeof X[0])
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
@@ -59,7 +60,7 @@
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel }; /* color schemes */
+enum { SchemeNorm, SchemeSel, SchemeHid }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
@@ -117,6 +118,8 @@ struct Monitor {
int nmaster;
int num;
int by; /* bar geometry */
+ int btw; /* width of tasks portion of bar */
+ int bt; /* number of tasks */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
@@ -124,6 +127,7 @@ struct Monitor {
unsigned int tagset[2];
int showbar;
int topbar;
+ int hidsel;
Client *clients;
Client *sel;
Client *stack;
@@ -168,13 +172,17 @@ static void expose(XEvent *e);
static void focus(Client *c);
static void focusin(XEvent *e);
static void focusmon(const Arg *arg);
-static void focusstack(const Arg *arg);
+static void focusstackvis(const Arg *arg);
+static void focusstackhid(const Arg *arg);
+static void focusstack(int inc, int vis);
static Atom getatomprop(Client *c, Atom prop);
static int getrootptr(int *x, int *y);
static long getstate(Window w);
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, int focused);
static void grabkeys(void);
+static void hide(const Arg *arg);
+static void hidewin(Client *c);
static void incnmaster(const Arg *arg);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
@@ -204,6 +212,9 @@ static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setup(void);
static void seturgent(Client *c, int urg);
+static void show(const Arg *arg);
+static void showall(const Arg *arg);
+static void showwin(Client *c);
static void showhide(Client *c);
static void sigchld(int unused);
static void spawn(const Arg *arg);
@@ -214,6 +225,7 @@ static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
+static void togglewin(const Arg *arg);
static void unfocus(Client *c, int setfocus);
static void unmanage(Client *c, int destroyed);
static void unmapnotify(XEvent *e);
@@ -442,10 +454,25 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + TEXTW(selmon->ltsymbol))
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - (int)TEXTW(stext))
+ /* 2px right padding */
+ else if (ev->x > selmon->ww - TEXTW(stext) + lrpad - 2)
click = ClkStatusText;
- else
- click = ClkWinTitle;
+ else {
+ x += TEXTW(selmon->ltsymbol);
+ c = m->clients;
+
+ if (c) {
+ do {
+ if (!ISVISIBLE(c))
+ continue;
+ else
+ x +=(1.0 / (double)m->bt) * m->btw;
+ } while (ev->x > x && (c = c->next));
+
+ click = ClkWinTitle;
+ arg.v = c;
+ }
+ }
} else if ((c = wintoclient(ev->window))) {
focus(c);
restack(selmon);
@@ -455,7 +482,7 @@ buttonpress(XEvent *e)
for (i = 0; i < LENGTH(buttons); i++)
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
+ buttons[i].func((click == ClkTagBar || click == ClkWinTitle) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
}
void
@@ -699,7 +726,7 @@ dirtomon(int dir)
void
drawbar(Monitor *m)
{
- int x, w, tw = 0;
+ int x, w, tw = 0, n = 0, scm;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
@@ -716,6 +743,8 @@ drawbar(Monitor *m)
}
for (c = m->clients; c; c = c->next) {
+ if (ISVISIBLE(c))
+ n++;
occ |= c->tags;
if (c->isurgent)
urg |= c->tags;
@@ -736,16 +765,36 @@ drawbar(Monitor *m)
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
if ((w = m->ww - tw - x) > bh) {
- if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
- if (m->sel->isfloating)
- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+ if (n > 0) {
+ int remainder = w % n;
+ int tabw = (1.0 / (double)n) * w + 1;
+ for (c = m->clients; c; c = c->next) {
+ if (!ISVISIBLE(c))
+ continue;
+ if (m->sel == c)
+ scm = SchemeSel;
+ else if (HIDDEN(c))
+ scm = SchemeHid;
+ else
+ scm = SchemeNorm;
+ drw_setscheme(drw, scheme[scm]);
+
+ if (remainder >= 0) {
+ if (remainder == 0) {
+ tabw--;
+ }
+ remainder--;
+ }
+ drw_text(drw, x, 0, tabw, bh, lrpad / 2, c->name, 0);
+ x += tabw;
+ }
} else {
drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, x, 0, w, bh, 1, 1);
}
}
+ m->bt = n;
+ m->btw = w;
drw_map(drw, m->barwin, 0, 0, m->ww, bh);
}
@@ -791,9 +840,17 @@ void
focus(Client *c)
{
if (!c || !ISVISIBLE(c))
- for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
- if (selmon->sel && selmon->sel != c)
+ for (c = selmon->stack; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->snext);
+ if (selmon->sel && selmon->sel != c) {
unfocus(selmon->sel, 0);
+
+ if (selmon->hidsel) {
+ hidewin(selmon->sel);
+ if (c)
+ arrange(c->mon);
+ selmon->hidsel = 0;
+ }
+ }
if (c) {
if (c->mon != selmon)
selmon = c->mon;
@@ -837,28 +894,52 @@ focusmon(const Arg *arg)
}
void
-focusstack(const Arg *arg)
+focusstackvis(const Arg *arg) {
+ focusstack(arg->i, 0);
+}
+
+void
+focusstackhid(const Arg *arg) {
+ focusstack(arg->i, 1);
+}
+
+void
+focusstack(int inc, int hid)
{
Client *c = NULL, *i;
-
- if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
+ // if no client selected AND exclude hidden client; if client selected but fullscreened
+ if ((!selmon->sel && !hid) || (selmon->sel && selmon->sel->isfullscreen && lockfullscreen))
return;
- if (arg->i > 0) {
- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
+ if (!selmon->clients)
+ return;
+ if (inc > 0) {
+ if (selmon->sel)
+ for (c = selmon->sel->next;
+ c && (!ISVISIBLE(c) || (!hid && HIDDEN(c)));
+ c = c->next);
if (!c)
- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
+ for (c = selmon->clients;
+ c && (!ISVISIBLE(c) || (!hid && HIDDEN(c)));
+ c = c->next);
} else {
- for (i = selmon->clients; i != selmon->sel; i = i->next)
- if (ISVISIBLE(i))
- c = i;
+ if (selmon->sel) {
+ for (i = selmon->clients; i != selmon->sel; i = i->next)
+ if (ISVISIBLE(i) && !(!hid && HIDDEN(i)))
+ c = i;
+ } else
+ c = selmon->clients;
if (!c)
for (; i; i = i->next)
- if (ISVISIBLE(i))
+ if (ISVISIBLE(i) && !(!hid && HIDDEN(i)))
c = i;
}
if (c) {
focus(c);
restack(selmon);
+ if (HIDDEN(c)) {
+ showwin(c);
+ c->mon->hidsel = 1;
+ }
}
}
@@ -968,6 +1049,36 @@ grabkeys(void)
}
}
+void
+hide(const Arg *arg)
+{
+ hidewin(selmon->sel);
+ focus(NULL);
+ arrange(selmon);
+}
+
+void
+hidewin(Client *c) {
+ if (!c || HIDDEN(c))
+ return;
+
+ Window w = c->win;
+ static XWindowAttributes ra, ca;
+
+ // more or less taken directly from blackbox's hide() function
+ XGrabServer(dpy);
+ XGetWindowAttributes(dpy, root, &ra);
+ XGetWindowAttributes(dpy, w, &ca);
+ // prevent UnmapNotify events
+ XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
+ XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask);
+ XUnmapWindow(dpy, w);
+ setclientstate(c, IconicState);
+ XSelectInput(dpy, root, ra.your_event_mask);
+ XSelectInput(dpy, w, ca.your_event_mask);
+ XUngrabServer(dpy);
+}
+
void
incnmaster(const Arg *arg)
{
@@ -1070,12 +1181,14 @@ manage(Window w, XWindowAttributes *wa)
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
- setclientstate(c, NormalState);
+ if (!HIDDEN(c))
+ setclientstate(c, NormalState);
if (c->mon == selmon)
unfocus(selmon->sel, 0);
c->mon->sel = c;
arrange(c->mon);
- XMapWindow(dpy, c->win);
+ if (!HIDDEN(c))
+ XMapWindow(dpy, c->win);
focus(NULL);
}
@@ -1196,7 +1309,7 @@ movemouse(const Arg *arg)
Client *
nexttiled(Client *c)
{
- for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
+ for (; c && (c->isfloating || !ISVISIBLE(c) || HIDDEN(c)); c = c->next);
return c;
}
@@ -1249,6 +1362,16 @@ propertynotify(XEvent *e)
void
quit(const Arg *arg)
{
+ // fix: reloading dwm keeps all the hidden clients hidden
+ Monitor *m;
+ Client *c;
+ for (m = mons; m; m = m->next) {
+ if (m) {
+ for (c = m->stack; c; c = c->next)
+ if (c && HIDDEN(c)) showwin(c);
+ }
+ }
+
running = 0;
}
@@ -1610,6 +1733,42 @@ seturgent(Client *c, int urg)
XFree(wmh);
}
+void
+show(const Arg *arg)
+{
+ if (selmon->hidsel)
+ selmon->hidsel = 0;
+ showwin(selmon->sel);
+}
+
+void
+showall(const Arg *arg)
+{
+ Client *c = NULL;
+ selmon->hidsel = 0;
+ for (c = selmon->clients; c; c = c->next) {
+ if (ISVISIBLE(c))
+ showwin(c);
+ }
+ if (!selmon->sel) {
+ for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
+ if (c)
+ focus(c);
+ }
+ restack(selmon);
+}
+
+void
+showwin(Client *c)
+{
+ if (!c || !HIDDEN(c))
+ return;
+
+ XMapWindow(dpy, c->win);
+ setclientstate(c, NormalState);
+ arrange(c->mon);
+}
+
void
showhide(Client *c)
{
@@ -1744,6 +1903,23 @@ toggleview(const Arg *arg)
}
}
+void
+togglewin(const Arg *arg)
+{
+ Client *c = (Client*)arg->v;
+
+ if (c == selmon->sel) {
+ hidewin(c);
+ focus(NULL);
+ arrange(c->mon);
+ } else {
+ if (HIDDEN(c))
+ showwin(c);
+ focus(c);
+ restack(selmon);
+ }
+}
+
void
unfocus(Client *c, int setfocus)
{

View File

@ -1,248 +0,0 @@
diff --git a/config.def.h b/config.def.h
--- a/config.def.h
+++ b/config.def.h
@@ -3,8 +3,10 @@
/* appearance */
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 showbar = 1; /* 0 means no standard bar */
+static const int topbar = 1; /* 0 means standard bar at bottom */
+static const int extrabar = 1; /* 0 means no extra bar */
+static const char statussep = ';'; /* separator between statuses */
static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222";
@@ -65,6 +67,7 @@ static Key keys[] = {
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
+ { MODKEY|ShiftMask, XK_b, toggleextrabar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
@@ -105,6 +108,9 @@ static Button buttons[] = {
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
+ { ClkExBarLeftStatus, 0, Button2, spawn, {.v = termcmd } },
+ { ClkExBarMiddle, 0, Button2, spawn, {.v = termcmd } },
+ { ClkExBarRightStatus, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
diff --git a/dwm.c b/dwm.c
--- a/dwm.c
+++ b/dwm.c
@@ -65,6 +65,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+ ClkExBarLeftStatus, ClkExBarMiddle, ClkExBarRightStatus,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
typedef union {
@@ -117,6 +118,7 @@ struct Monitor {
int nmaster;
int num;
int by; /* bar geometry */
+ int eby; /* extra bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
@@ -124,11 +126,13 @@ struct Monitor {
unsigned int tagset[2];
int showbar;
int topbar;
+ int extrabar;
Client *clients;
Client *sel;
Client *stack;
Monitor *next;
Window barwin;
+ Window extrabarwin;
const Layout *lt[2];
};
@@ -211,6 +215,7 @@ static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *);
static void togglebar(const Arg *arg);
+static void toggleextrabar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
@@ -238,6 +243,8 @@ static void zoom(const Arg *arg);
/* variables */
static const char broken[] = "broken";
static char stext[256];
+static char estextl[256];
+static char estextr[256];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -444,6 +451,13 @@ buttonpress(XEvent *e)
click = ClkStatusText;
else
click = ClkWinTitle;
+ } else if (ev->window == selmon->extrabarwin) {
+ if (ev->x < (int)TEXTW(estextl))
+ click = ClkExBarLeftStatus;
+ else if (ev->x > selmon->ww - (int)TEXTW(estextr))
+ click = ClkExBarRightStatus;
+ else
+ click = ClkExBarMiddle;
} else if ((c = wintoclient(ev->window))) {
focus(c);
restack(selmon);
@@ -506,7 +520,9 @@ cleanupmon(Monitor *mon)
m->next = mon->next;
}
XUnmapWindow(dpy, mon->barwin);
+ XUnmapWindow(dpy, mon->extrabarwin);
XDestroyWindow(dpy, mon->barwin);
+ XDestroyWindow(dpy, mon->extrabarwin);
free(mon);
}
@@ -569,6 +585,7 @@ configurenotify(XEvent *e)
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->extrabarwin, m->wx, m->eby, m->ww, bh);
}
focus(NULL);
arrange(NULL);
@@ -639,6 +656,7 @@ createmon(void)
m->nmaster = nmaster;
m->showbar = showbar;
m->topbar = topbar;
+ m->extrabar = extrabar;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
@@ -696,7 +714,7 @@ dirtomon(int dir)
void
drawbar(Monitor *m)
{
- int x, w, tw = 0;
+ int x, w, tw = 0, etwl = 0, etwr = 0;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
@@ -741,6 +759,17 @@ drawbar(Monitor *m)
}
}
drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+
+ if (m == selmon) { /* extra status is only drawn on selected monitor */
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ /* clear default bar draw buffer by drawing a blank rectangle */
+ drw_rect(drw, 0, 0, m->ww, bh, 1, 1);
+ etwr = TEXTW(estextr) - lrpad + 2; /* 2px right padding */
+ drw_text(drw, m->ww - etwr, 0, etwr, bh, 0, estextr, 0);
+ etwl = TEXTW(estextl);
+ drw_text(drw, 0, 0, etwl, bh, 0, estextl, 0);
+ drw_map(drw, m->extrabarwin, 0, 0, m->ww, bh);
+ }
}
void
@@ -1708,6 +1737,15 @@ togglebar(const Arg *arg)
arrange(selmon);
}
+void
+toggleextrabar(const Arg *arg)
+{
+ selmon->extrabar = !selmon->extrabar;
+ updatebarpos(selmon);
+ XMoveResizeWindow(dpy, selmon->extrabarwin, selmon->wx, selmon->eby, selmon->ww, bh);
+ arrange(selmon);
+}
+
void
togglefloating(const Arg *arg)
{
@@ -1812,14 +1850,22 @@ updatebars(void)
};
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);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
- XMapRaised(dpy, m->barwin);
- XSetClassHint(dpy, m->barwin, &ch);
+ if (!m->barwin) {
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+ CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+ XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
+ XMapRaised(dpy, m->barwin);
+ XSetClassHint(dpy, m->barwin, &ch);
+ }
+ if (!m->extrabarwin) {
+ m->extrabarwin = XCreateWindow(dpy, root, m->wx, m->eby, m->ww, bh, 0, DefaultDepth(dpy, screen),
+ CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+ XDefineCursor(dpy, m->extrabarwin, cursor[CurNormal]->cursor);
+ XMapRaised(dpy, m->extrabarwin);
+ XSetClassHint(dpy, m->extrabarwin, &ch);
+ }
}
}
@@ -1834,6 +1880,12 @@ updatebarpos(Monitor *m)
m->wy = m->topbar ? m->wy + bh : m->wy;
} else
m->by = -bh;
+ if (m->extrabar) {
+ m->wh -= bh;
+ m->eby = !m->topbar ? m->wy : m->wy + m->wh;
+ m->wy = !m->topbar ? m->wy + bh : m->wy;
+ } else
+ m->eby = -bh;
}
void
@@ -1990,8 +2042,26 @@ updatesizehints(Client *c)
void
updatestatus(void)
{
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
+ char text[768];
+ if (!gettextprop(root, XA_WM_NAME, text, sizeof(text))) {
strcpy(stext, "dwm-"VERSION);
+ estextl[0] = '\0';
+ estextr[0] = '\0';
+ } else {
+ char *l = strchr(text, statussep);
+ if (l) {
+ *l = '\0'; l++;
+ strncpy(estextl, l, sizeof(estextl) - 1);
+ } else
+ estextl[0] = '\0';
+ char *r = strchr(estextl, statussep);
+ if (r) {
+ *r = '\0'; r++;
+ strncpy(estextr, r, sizeof(estextr) - 1);
+ } else
+ estextr[0] = '\0';
+ strncpy(stext, text, sizeof(stext) - 1);
+ }
drawbar(selmon);
}
@@ -2070,7 +2140,7 @@ wintomon(Window w)
if (w == root && getrootptr(&x, &y))
return recttomon(x, y, 1, 1);
for (m = mons; m; m = m->next)
- if (w == m->barwin)
+ if (w == m->barwin || w == m->extrabarwin)
return m;
if ((c = wintoclient(w)))
return c->mon;

View File

@ -1,12 +0,0 @@
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)

View File

@ -1,54 +0,0 @@
diff -up dwm-6.3/dwm.c dwm-6.3-attachbottom/dwm.c
--- dwm-6.3/dwm.c 2022-01-07 12:42:18.000000000 +0100
+++ dwm-6.3-attachbottom/dwm.c 2022-08-17 22:14:41.813809073 +0200
@@ -147,6 +147,7 @@ static int applysizehints(Client *c, int
static void arrange(Monitor *m);
static void arrangemon(Monitor *m);
static void attach(Client *c);
+static void attachbottom(Client *c);
static void attachstack(Client *c);
static void buttonpress(XEvent *e);
static void checkotherwm(void);
@@ -408,6 +409,15 @@ attach(Client *c)
}
void
+attachbottom(Client *c)
+{
+ Client **tc;
+ c->next = NULL;
+ for (tc = &c->mon->clients; *tc; tc = &(*tc)->next);
+ *tc = c;
+}
+
+void
attachstack(Client *c)
{
c->snext = c->mon->stack;
@@ -1066,7 +1076,7 @@ manage(Window w, XWindowAttributes *wa)
c->isfloating = c->oldstate = trans != None || c->isfixed;
if (c->isfloating)
XRaiseWindow(dpy, c->win);
- attach(c);
+ attachbottom(c);
attachstack(c);
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
@@ -1421,7 +1431,7 @@ sendmon(Client *c, Monitor *m)
detachstack(c);
c->mon = m;
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
- attach(c);
+ attachbottom(c);
attachstack(c);
focus(NULL);
arrange(NULL);
@@ -1903,7 +1913,7 @@ updategeom(void)
m->clients = c->next;
detachstack(c);
c->mon = mons;
- attach(c);
+ attachbottom(c);
attachstack(c);
}
if (m == selmon)

View File

@ -1,224 +0,0 @@
diff -up a/dwm.c b/dwm.c
--- a/dwm.c 2020-05-23 00:20:34.877944603 +0200
+++ b/dwm.c 2020-06-22 12:49:55.298859682 +0200
@@ -111,6 +111,7 @@ typedef struct {
void (*arrange)(Monitor *);
} Layout;
+typedef struct Pertag Pertag;
struct Monitor {
char ltsymbol[16];
float mfact;
@@ -130,6 +131,7 @@ struct Monitor {
Monitor *next;
Window barwin;
const Layout *lt[2];
+ Pertag *pertag;
};
typedef struct {
@@ -271,6 +273,15 @@ static Window root, wmcheckwin;
/* configuration, allows nested code to access above variables */
#include "config.h"
+struct Pertag {
+ unsigned int curtag, prevtag; /* current and previous tag */
+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
+ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
+};
+
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
@@ -631,6 +642,7 @@ Monitor *
createmon(void)
{
Monitor *m;
+ unsigned int i;
m = ecalloc(1, sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
@@ -641,6 +653,20 @@ createmon(void)
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+ m->pertag = ecalloc(1, sizeof(Pertag));
+ m->pertag->curtag = m->pertag->prevtag = 1;
+
+ for (i = 0; i <= LENGTH(tags); i++) {
+ m->pertag->nmasters[i] = m->nmaster;
+ m->pertag->mfacts[i] = m->mfact;
+
+ m->pertag->ltidxs[i][0] = m->lt[0];
+ m->pertag->ltidxs[i][1] = m->lt[1];
+ m->pertag->sellts[i] = m->sellt;
+
+ m->pertag->showbars[i] = m->showbar;
+ }
+
return m;
}
@@ -966,7 +992,16 @@ grabkeys(void)
void
incnmaster(const Arg *arg)
{
+ unsigned int i;
selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
+ for(i=0; i<LENGTH(tags); ++i)
+ if(selmon->tagset[selmon->seltags] & 1<<i)
+ selmon->pertag->nmasters[i+1] = selmon->nmaster;
+
+ if(selmon->pertag->curtag == 0)
+ {
+ selmon->pertag->nmasters[0] = selmon->nmaster;
+ }
arrange(selmon);
}
@@ -1500,11 +1535,26 @@ setfullscreen(Client *c, int fullscreen)
void
setlayout(const Arg *arg)
{
+ unsigned int i;
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
selmon->sellt ^= 1;
if (arg && arg->v)
selmon->lt[selmon->sellt] = (Layout *)arg->v;
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+
+ for(i=0; i<LENGTH(tags); ++i)
+ if(selmon->tagset[selmon->seltags] & 1<<i)
+ {
+ selmon->pertag->ltidxs[i+1][selmon->sellt] = selmon->lt[selmon->sellt];
+ selmon->pertag->sellts[i+1] = selmon->sellt;
+ }
+
+ if(selmon->pertag->curtag == 0)
+ {
+ selmon->pertag->ltidxs[0][selmon->sellt] = selmon->lt[selmon->sellt];
+ selmon->pertag->sellts[0] = selmon->sellt;
+ }
+
if (selmon->sel)
arrange(selmon);
else
@@ -1516,13 +1566,24 @@ void
setmfact(const Arg *arg)
{
float f;
+ unsigned int i;
if (!arg || !selmon->lt[selmon->sellt]->arrange)
return;
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
- if (f < 0.1 || f > 0.9)
+ if (arg->f == 0.0)
+ f = mfact;
+ if (f < 0.05 || f > 0.95)
return;
selmon->mfact = f;
+ for(i=0; i<LENGTH(tags); ++i)
+ if(selmon->tagset[selmon->seltags] & 1<<i)
+ selmon->pertag->mfacts[i+1] = f;
+
+ if(selmon->pertag->curtag == 0)
+ {
+ selmon->pertag->mfacts[0] = f;
+ }
arrange(selmon);
}
@@ -1699,7 +1760,16 @@ tile(Monitor *m)
void
togglebar(const Arg *arg)
{
+ unsigned int i;
selmon->showbar = !selmon->showbar;
+ for(i=0; i<LENGTH(tags); ++i)
+ if(selmon->tagset[selmon->seltags] & 1<<i)
+ selmon->pertag->showbars[i+1] = selmon->showbar;
+
+ if(selmon->pertag->curtag == 0)
+ {
+ selmon->pertag->showbars[0] = selmon->showbar;
+ }
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange(selmon);
@@ -1738,9 +1808,33 @@ void
toggleview(const Arg *arg)
{
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+ int i;
if (newtagset) {
selmon->tagset[selmon->seltags] = newtagset;
+
+ if (newtagset == ~0) {
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ selmon->pertag->curtag = 0;
+ }
+
+ /* test if the user did not select the same tag */
+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ for (i = 0; !(newtagset & 1 << i); i++) ;
+ selmon->pertag->curtag = i + 1;
+ }
+
+ /* apply settings for this view */
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
+
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ togglebar(NULL);
+
focus(NULL);
arrange(selmon);
}
@@ -2035,11 +2129,37 @@ updatewmhints(Client *c)
void
view(const Arg *arg)
{
+ int i;
+ unsigned int tmptag;
+
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
return;
selmon->seltags ^= 1; /* toggle sel tagset */
- if (arg->ui & TAGMASK)
+ if (arg->ui & TAGMASK) {
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+
+ if (arg->ui == ~0)
+ selmon->pertag->curtag = 0;
+ else {
+ for (i = 0; !(arg->ui & 1 << i); i++) ;
+ selmon->pertag->curtag = i + 1;
+ }
+ } else {
+ tmptag = selmon->pertag->prevtag;
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ selmon->pertag->curtag = tmptag;
+ }
+
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
+
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ togglebar(NULL);
+
focus(NULL);
arrange(selmon);
}

View File

@ -1,118 +0,0 @@
From 713fa8650f5a20006451ebcccf57a4512e83bae8 Mon Sep 17 00:00:00 2001
From: Arda Atci <arda@phytech.io>
Date: Wed, 18 May 2022 17:23:16 +0300
Subject: [PATCH] preserve clients on old tags when renewing dwm
By default, when dwm is recompiled-restarted all clients will
lose it's current tag and collapse to first tag. This patch preserves
clients on old tags, however note that layout order is not preserved.
---
dwm.c | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/dwm.c b/dwm.c
index a96f33c..a12e0bd 100644
--- a/dwm.c
+++ b/dwm.c
@@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+ NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
@@ -198,6 +198,7 @@ static void scan(void);
static int sendevent(Client *c, Atom proto);
static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
+static void setclienttagprop(Client *c);
static void setfocus(Client *c);
static void setfullscreen(Client *c, int fullscreen);
static void setlayout(const Arg *arg);
@@ -1060,6 +1061,26 @@ manage(Window w, XWindowAttributes *wa)
updatewindowtype(c);
updatesizehints(c);
updatewmhints(c);
+ {
+ int format;
+ unsigned long *data, n, extra;
+ Monitor *m;
+ Atom atom;
+ if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL,
+ &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) {
+ c->tags = *data;
+ for (m = mons; m; m = m->next) {
+ if (m->num == *(data+1)) {
+ c->mon = m;
+ break;
+ }
+ }
+ }
+ if (n > 0)
+ XFree(data);
+ }
+ setclienttagprop(c);
+
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
grabbuttons(c, 0);
if (!c->isfloating)
@@ -1423,6 +1444,7 @@ sendmon(Client *c, Monitor *m)
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
attach(c);
attachstack(c);
+ setclienttagprop(c);
focus(NULL);
arrange(NULL);
}
@@ -1566,6 +1588,7 @@ setup(void)
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1589,6 +1612,7 @@ setup(void)
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
PropModeReplace, (unsigned char *) netatom, NetLast);
XDeleteProperty(dpy, root, netatom[NetClientList]);
+ XDeleteProperty(dpy, root, netatom[NetClientInfo]);
/* select events */
wa.cursor = cursor[CurNormal]->cursor;
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
@@ -1656,11 +1680,22 @@ spawn(const Arg *arg)
}
}
+void
+setclienttagprop(Client *c)
+{
+ long data[] = { (long) c->tags, (long) c->mon->num };
+ XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) data, 2);
+}
+
void
tag(const Arg *arg)
{
+ Client *c;
if (selmon->sel && arg->ui & TAGMASK) {
+ c = selmon->sel;
selmon->sel->tags = arg->ui & TAGMASK;
+ setclienttagprop(c);
focus(NULL);
arrange(selmon);
}
@@ -1735,6 +1770,7 @@ toggletag(const Arg *arg)
newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
if (newtags) {
selmon->sel->tags = newtags;
+ setclienttagprop(selmon->sel);
focus(NULL);
arrange(selmon);
}
--
2.36.1

View File

@ -1,58 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 1c0b587..961a189 100644
--- a/config.def.h
+++ b/config.def.h
@@ -70,6 +70,7 @@ static Key keys[] = {
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY, XK_r, reorganizetags, {0} },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
diff --git a/dwm.c b/dwm.c
index 4465af1..723d675 100644
--- a/dwm.c
+++ b/dwm.c
@@ -188,6 +188,7 @@ static void pop(Client *);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h);
+static void reorganizetags(const Arg *arg);
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);
@@ -1265,6 +1266,33 @@ recttomon(int x, int y, int w, int h)
return r;
}
+void
+reorganizetags(const Arg *arg) {
+ Client *c;
+ unsigned int occ, unocc, i;
+ unsigned int tagdest[LENGTH(tags)];
+
+ occ = 0;
+ for (c = selmon->clients; c; c = c->next)
+ occ |= (1 << (ffs(c->tags)-1));
+ unocc = 0;
+ for (i = 0; i < LENGTH(tags); ++i) {
+ while (unocc < i && (occ & (1 << unocc)))
+ unocc++;
+ if (occ & (1 << i)) {
+ tagdest[i] = unocc;
+ occ &= ~(1 << i);
+ occ |= 1 << unocc;
+ }
+ }
+
+ for (c = selmon->clients; c; c = c->next)
+ c->tags = 1 << tagdest[ffs(c->tags)-1];
+ if (selmon->sel)
+ selmon->tagset[selmon->seltags] = selmon->sel->tags;
+ arrange(selmon);
+}
+
void
resize(Client *c, int x, int y, int w, int h, int interact)
{

View File

@ -1,65 +0,0 @@
From 4df827a2ec7820f41bdb8576cc39b55fbf35be44 Mon Sep 17 00:00:00 2001
From: Jack Bird <jack.bird@durham.ac.uk>
Date: Mon, 16 Aug 2021 23:25:16 +0100
Subject: [PATCH] Patch applies cleanly
---
config.def.h | 1 +
dwm.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/config.def.h b/config.def.h
index 1c0b587..5d118cf 100644
--- a/config.def.h
+++ b/config.def.h
@@ -70,6 +70,7 @@ static Key keys[] = {
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY, XK_r, resetlayout, {0} },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
diff --git a/dwm.c b/dwm.c
index 4465af1..77727ea 100644
--- a/dwm.c
+++ b/dwm.c
@@ -188,6 +188,7 @@ static void pop(Client *);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h);
+static void resetlayout(const Arg *arg);
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);
@@ -1265,6 +1266,16 @@ recttomon(int x, int y, int w, int h)
return r;
}
+void
+resetlayout(const Arg *arg)
+{
+ Arg default_layout = {.v = &layouts[0]};
+ Arg default_mfact = {.f = mfact + 1};
+
+ setlayout(&default_layout);
+ setmfact(&default_mfact);
+}
+
void
resize(Client *c, int x, int y, int w, int h, int interact)
{
@@ -1282,6 +1293,10 @@ resizeclient(Client *c, int x, int y, int w, int h)
c->oldw = c->w; c->w = wc.width = w;
c->oldh = c->h; c->h = wc.height = h;
wc.border_width = c->bw;
+
+ if ((nexttiled(c->mon->clients) == c) && !(nexttiled(c->next)))
+ resetlayout(NULL);
+
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);
--
2.32.0

View File

@ -1,36 +0,0 @@
diff -r -u a/config.def.h b/config.def.h
--- a/config.def.h 2022-01-07 06:42:18.000000000 -0500
+++ b/config.def.h 2022-01-23 16:03:42.521951418 -0500
@@ -69,6 +69,7 @@
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
+ { MODKEY, XK_o, resetnmaster, {0} },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_Return, zoom, {0} },
diff -r -u a/dwm.c b/dwm.c
--- a/dwm.c 2022-01-23 16:06:01.221948285 -0500
+++ b/dwm.c 2022-01-23 16:05:35.949948855 -0500
@@ -191,6 +191,7 @@
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h);
+static void resetnmaster(const Arg *arg);
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);
@@ -1296,6 +1297,13 @@
}
void
+resetnmaster(const Arg *arg)
+{
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = 1;
+ arrange(selmon);
+}
+
+void
resize(Client *c, int x, int y, int w, int h, int interact)
{
if (applysizehints(c, &x, &y, &w, &h, interact))

View File

@ -1,42 +0,0 @@
diff --git i/dwm.c w/dwm.c
index 4465af1..96b0b26 100644
--- i/dwm.c
+++ w/dwm.c
@@ -88,6 +88,7 @@ struct Client {
char name[256];
float mina, maxa;
int x, y, w, h;
+ int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */
int oldx, oldy, oldw, oldh;
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw;
@@ -1056,6 +1057,10 @@ manage(Window w, XWindowAttributes *wa)
updatewindowtype(c);
updatesizehints(c);
updatewmhints(c);
+ c->sfx = c->x;
+ c->sfy = c->y;
+ c->sfw = c->w;
+ c->sfh = c->h;
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
grabbuttons(c, 0);
if (!c->isfloating)
@@ -1714,8 +1719,16 @@ togglefloating(const Arg *arg)
return;
selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
if (selmon->sel->isfloating)
- resize(selmon->sel, selmon->sel->x, selmon->sel->y,
- selmon->sel->w, selmon->sel->h, 0);
+ /* restore last known float dimensions */
+ resize(selmon->sel, selmon->sel->sfx, selmon->sel->sfy,
+ selmon->sel->sfw, selmon->sel->sfh, False);
+ else {
+ /* save last known float dimensions */
+ selmon->sel->sfx = selmon->sel->x;
+ selmon->sel->sfy = selmon->sel->y;
+ selmon->sel->sfw = selmon->sel->w;
+ selmon->sel->sfh = selmon->sel->h;
+ }
arrange(selmon);
}

View File

@ -1,28 +0,0 @@
From 449324adbe53240a734cb5f8f72763bb3419829a Mon Sep 17 00:00:00 2001
From: Rizqi Nur Assyaufi <bandithijo@gmail.com>
Date: Sat, 5 Aug 2021 00:04:32 +0800
Subject: [PATCH] [sendmoncenter] Send floating window to another monitor will
centered
This patch will allows you to send floating window client to another monitor
will be centered position.
---
dwm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dwm.c b/dwm.c
index 5e4d494..c20023e 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1418,6 +1418,8 @@ sendmon(Client *c, Monitor *m)
detachstack(c);
c->mon = m;
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
+ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
attach(c);
attachstack(c);
focus(NULL);
--
2.31.1

View File

@ -1,412 +0,0 @@
From 0cf9a007511f7dfd7dd94171b172562ebac9b6d5 Mon Sep 17 00:00:00 2001
From: Tom Schwindl <schwindl@posteo.de>
Date: Sat, 10 Sep 2022 12:51:09 +0200
Subject: [PATCH] 6.3 swallow patch
---
config.def.h | 9 +-
config.mk | 3 +-
dwm.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 237 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 061ad662f82a..0b2b8ffd30d5 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,6 +3,7 @@
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
+static const int swallowfloating = 0; /* 1 means swallow floating windows by default */
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" };
@@ -26,9 +27,11 @@ 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 isterminal noswallow monitor */
+ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 },
+ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 },
+ { "St", NULL, NULL, 0, 0, 1, 0, -1 },
+ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
};
/* layout(s) */
diff --git a/config.mk b/config.mk
index 81c493ef4aff..52d1ebf30bec 100644
--- a/config.mk
+++ b/config.mk
@@ -20,10 +20,11 @@ FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = ${X11INC}/freetype2
#MANPREFIX = ${PREFIX}/man
+#KVMLIB = -lkvm
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC}
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB}
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
diff --git a/dwm.c b/dwm.c
index e5efb6a22806..e68294b6b679 100644
--- a/dwm.c
+++ b/dwm.c
@@ -40,6 +40,12 @@
#include <X11/extensions/Xinerama.h>
#endif /* XINERAMA */
#include <X11/Xft/Xft.h>
+#include <X11/Xlib-xcb.h>
+#include <xcb/res.h>
+#ifdef __OpenBSD__
+#include <sys/sysctl.h>
+#include <kvm.h>
+#endif /* __OpenBSD */
#include "drw.h"
#include "util.h"
@@ -92,9 +98,11 @@ 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, isterminal, noswallow;
+ pid_t pid;
Client *next;
Client *snext;
+ Client *swallowing;
Monitor *mon;
Window win;
};
@@ -138,6 +146,8 @@ typedef struct {
const char *title;
unsigned int tags;
int isfloating;
+ int isterminal;
+ int noswallow;
int monitor;
} Rule;
@@ -235,6 +245,12 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static pid_t getparentprocess(pid_t p);
+static int isdescprocess(pid_t p, pid_t c);
+static Client *swallowingclient(Window w);
+static Client *termforwin(const Client *c);
+static pid_t winpid(Window w);
+
/* variables */
static const char broken[] = "broken";
static char stext[256];
@@ -269,6 +285,8 @@ static Drw *drw;
static Monitor *mons, *selmon;
static Window root, wmcheckwin;
+static xcb_connection_t *xcon;
+
/* configuration, allows nested code to access above variables */
#include "config.h"
@@ -298,6 +316,8 @@ applyrules(Client *c)
&& (!r->class || strstr(class, r->class))
&& (!r->instance || strstr(instance, r->instance)))
{
+ c->isterminal = r->isterminal;
+ c->noswallow = r->noswallow;
c->isfloating = r->isfloating;
c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next);
@@ -416,6 +436,53 @@ attachstack(Client *c)
c->mon->stack = c;
}
+void
+swallow(Client *p, Client *c)
+{
+
+ if (c->noswallow || c->isterminal)
+ return;
+ if (c->noswallow && !swallowfloating && c->isfloating)
+ return;
+
+ detach(c);
+ detachstack(c);
+
+ setclientstate(c, WithdrawnState);
+ XUnmapWindow(dpy, p->win);
+
+ p->swallowing = c;
+ c->mon = p->mon;
+
+ Window w = p->win;
+ p->win = c->win;
+ c->win = w;
+ updatetitle(p);
+ XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
+ arrange(p->mon);
+ configure(p);
+ updateclientlist();
+}
+
+void
+unswallow(Client *c)
+{
+ c->win = c->swallowing->win;
+
+ free(c->swallowing);
+ c->swallowing = NULL;
+
+ /* unfullscreen the client */
+ setfullscreen(c, 0);
+ updatetitle(c);
+ arrange(c->mon);
+ XMapWindow(dpy, c->win);
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
+ setclientstate(c, NormalState);
+ focus(NULL);
+ arrange(c->mon);
+}
+
void
buttonpress(XEvent *e)
{
@@ -656,6 +723,9 @@ destroynotify(XEvent *e)
if ((c = wintoclient(ev->window)))
unmanage(c, 1);
+
+ else if ((c = swallowingclient(ev->window)))
+ unmanage(c->swallowing, 1);
}
void
@@ -1022,12 +1092,13 @@ killclient(const Arg *arg)
void
manage(Window w, XWindowAttributes *wa)
{
- Client *c, *t = NULL;
+ Client *c, *t = NULL, *term = NULL;
Window trans = None;
XWindowChanges wc;
c = ecalloc(1, sizeof(Client));
c->win = w;
+ c->pid = winpid(w);
/* geometry */
c->x = c->oldx = wa->x;
c->y = c->oldy = wa->y;
@@ -1042,6 +1113,7 @@ manage(Window w, XWindowAttributes *wa)
} else {
c->mon = selmon;
applyrules(c);
+ term = termforwin(c);
}
if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
@@ -1076,6 +1148,8 @@ manage(Window w, XWindowAttributes *wa)
c->mon->sel = c;
arrange(c->mon);
XMapWindow(dpy, c->win);
+ if (term)
+ swallow(term, c);
focus(NULL);
}
@@ -1763,6 +1837,20 @@ unmanage(Client *c, int destroyed)
Monitor *m = c->mon;
XWindowChanges wc;
+ if (c->swallowing) {
+ unswallow(c);
+ return;
+ }
+
+ Client *s = swallowingclient(c->win);
+ if (s) {
+ free(s->swallowing);
+ s->swallowing = NULL;
+ arrange(m);
+ focus(NULL);
+ return;
+ }
+
detach(c);
detachstack(c);
if (!destroyed) {
@@ -1778,9 +1866,12 @@ unmanage(Client *c, int destroyed)
XUngrabServer(dpy);
}
free(c);
- focus(NULL);
- updateclientlist();
- arrange(m);
+
+ if (!s) {
+ arrange(m);
+ focus(NULL);
+ updateclientlist();
+ }
}
void
@@ -2044,6 +2135,136 @@ view(const Arg *arg)
arrange(selmon);
}
+pid_t
+winpid(Window w)
+{
+
+ pid_t result = 0;
+
+#ifdef __linux__
+ xcb_res_client_id_spec_t spec = {0};
+ spec.client = w;
+ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
+
+ xcb_generic_error_t *e = NULL;
+ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
+ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
+
+ if (!r)
+ return (pid_t)0;
+
+ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
+ for (; i.rem; xcb_res_client_id_value_next(&i)) {
+ spec = i.data->spec;
+ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
+ uint32_t *t = xcb_res_client_id_value_value(i.data);
+ result = *t;
+ break;
+ }
+ }
+
+ free(r);
+
+ if (result == (pid_t)-1)
+ result = 0;
+
+#endif /* __linux__ */
+
+#ifdef __OpenBSD__
+ Atom type;
+ int format;
+ unsigned long len, bytes;
+ unsigned char *prop;
+ pid_t ret;
+
+ if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 0), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop)
+ return 0;
+
+ ret = *(pid_t*)prop;
+ XFree(prop);
+ result = ret;
+
+#endif /* __OpenBSD__ */
+ return result;
+}
+
+pid_t
+getparentprocess(pid_t p)
+{
+ unsigned int v = 0;
+
+#ifdef __linux__
+ FILE *f;
+ char buf[256];
+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
+
+ if (!(f = fopen(buf, "r")))
+ return 0;
+
+ fscanf(f, "%*u %*s %*c %u", &v);
+ fclose(f);
+#endif /* __linux__*/
+
+#ifdef __OpenBSD__
+ int n;
+ kvm_t *kd;
+ struct kinfo_proc *kp;
+
+ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
+ if (!kd)
+ return 0;
+
+ kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n);
+ v = kp->p_ppid;
+#endif /* __OpenBSD__ */
+
+ return (pid_t)v;
+}
+
+int
+isdescprocess(pid_t p, pid_t c)
+{
+ while (p != c && c != 0)
+ c = getparentprocess(c);
+
+ return (int)c;
+}
+
+Client *
+termforwin(const Client *w)
+{
+ Client *c;
+ Monitor *m;
+
+ if (!w->pid || w->isterminal)
+ return NULL;
+
+ for (m = mons; m; m = m->next) {
+ for (c = m->clients; c; c = c->next) {
+ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+Client *
+swallowingclient(Window w)
+{
+ Client *c;
+ Monitor *m;
+
+ for (m = mons; m; m = m->next) {
+ for (c = m->clients; c; c = c->next) {
+ if (c->swallowing && c->swallowing->win == w)
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
Client *
wintoclient(Window w)
{
@@ -2133,10 +2354,12 @@ main(int argc, char *argv[])
fputs("warning: no locale support\n", stderr);
if (!(dpy = XOpenDisplay(NULL)))
die("dwm: cannot open display");
+ if (!(xcon = XGetXCBConnection(dpy)))
+ die("dwm: cannot get xcb connection\n");
checkotherwm();
setup();
#ifdef __OpenBSD__
- if (pledge("stdio rpath proc exec", NULL) == -1)
+ if (pledge("stdio rpath proc exec ps", NULL) == -1)
die("pledge");
#endif /* __OpenBSD__ */
scan();
--
2.37.2

View File

@ -1,31 +0,0 @@
From efa326b2c71f0df1d097fd52a17684f5ccc5df6c Mon Sep 17 00:00:00 2001
From: Rizqi Nur Assyaufi <bandithijo@gmail.com>
Date: Sat, 7 Aug 2021 00:24:01 +0800
Subject: [PATCH] [dwm][patch][togglefloatingcenter] centered togglefloating
window
Default behaviour when togglefloating() is floating from top-left corner.
This patch will allows you to toggle floating window client will be centered
position.
---
dwm.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dwm.c b/dwm.c
index 5e4d494..cbedb09 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1719,6 +1719,10 @@ togglefloating(const Arg *arg)
if (selmon->sel->isfloating)
resize(selmon->sel, selmon->sel->x, selmon->sel->y,
selmon->sel->w, selmon->sel->h, 0);
+
+ selmon->sel->x = selmon->sel->mon->mx + (selmon->sel->mon->mw - WIDTH(selmon->sel)) / 2;
+ selmon->sel->y = selmon->sel->mon->my + (selmon->sel->mon->mh - HEIGHT(selmon->sel)) / 2;
+
arrange(selmon);
}
--
2.31.1

View File

@ -1,95 +0,0 @@
From 3867ef5a68e15a4faff377ddbc8371853de4a800 Mon Sep 17 00:00:00 2001
From: aleks <aleks.stier@icloud.com>
Date: Sat, 19 Oct 2019 00:56:21 +0200
Subject: [PATCH] Put master to exact position of zoomed client
The default behaviour when zooming a client is to put the previous
master on top of the client-stack. This patch puts the master to the
exact position of the zoomed client in the stack.
---
dwm.c | 44 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/dwm.c b/dwm.c
index 4465af1..1719b36 100644
--- a/dwm.c
+++ b/dwm.c
@@ -165,6 +165,7 @@ static void drawbar(Monitor *m);
static void drawbars(void);
static void enternotify(XEvent *e);
static void expose(XEvent *e);
+static Client *findbefore(Client *c);
static void focus(Client *c);
static void focusin(XEvent *e);
static void focusmon(const Arg *arg);
@@ -235,6 +236,7 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
/* variables */
+static Client *prevzoom = NULL;
static const char broken[] = "broken";
static char stext[256];
static int screen;
@@ -780,6 +782,16 @@ expose(XEvent *e)
drawbar(m);
}
+Client *
+findbefore(Client *c)
+{
+ Client *tmp;
+ if (c == selmon->clients)
+ return NULL;
+ for (tmp = selmon->clients; tmp && tmp->next != c; tmp = tmp->next);
+ return tmp;
+}
+
void
focus(Client *c)
{
@@ -2114,14 +2126,38 @@ void
zoom(const Arg *arg)
{
Client *c = selmon->sel;
+ Client *at = NULL, *cold, *cprevious = NULL;
if (!selmon->lt[selmon->sellt]->arrange
|| (selmon->sel && selmon->sel->isfloating))
return;
- if (c == nexttiled(selmon->clients))
- if (!c || !(c = nexttiled(c->next)))
- return;
- pop(c);
+ if (c == nexttiled(selmon->clients)) {
+ at = findbefore(prevzoom);
+ if (at)
+ cprevious = nexttiled(at->next);
+ if (!cprevious || cprevious != prevzoom) {
+ prevzoom = NULL;
+ if (!c || !(c = nexttiled(c->next)))
+ return;
+ } else
+ c = cprevious;
+ }
+ cold = nexttiled(selmon->clients);
+ if (c != cold && !at)
+ at = findbefore(c);
+ detach(c);
+ attach(c);
+ /* swap windows instead of pushing the previous one down */
+ if (c != cold && at) {
+ prevzoom = cold;
+ if (cold && at != cold) {
+ detach(cold);
+ cold->next = at->next;
+ at->next = cold;
+ }
+ }
+ focus(c);
+ arrange(c->mon);
}
int
--
2.23.0

View File

@ -1,68 +0,0 @@
From 17df87822b379ce47d0aba3c36c5ef0adf4a7c3e Mon Sep 17 00:00:00 2001
From: Miles Alan <m@milesalan.com>
Date: Sun, 8 Dec 2019 18:15:13 -0600
Subject: [PATCH] Mod + Right click / drag in tiling mode to resize mfact.
Works with multiple monitors.
---
dwm.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/dwm.c b/dwm.c
index c15f679..e273803 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1911,7 +1911,16 @@ resizemouse(const Arg *arg)
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
return;
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+
+ if (c->isfloating || NULL == c->mon->lt[c->mon->sellt]->arrange) {
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+ } else {
+ XWarpPointer(dpy, None, root, 0, 0, 0, 0,
+ selmon->mx + (selmon->ww * selmon->mfact),
+ selmon->my + (selmon->wh / 2)
+ );
+ }
+
do {
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
switch(ev.type) {
@@ -1927,19 +1936,24 @@ resizemouse(const Arg *arg)
nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
- if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
- && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
- {
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
- togglefloating(NULL);
- }
+
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
resize(c, c->x, c->y, nw, nh, 1);
break;
}
} while (ev.type != ButtonRelease);
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+
+ if (c->isfloating || NULL == c->mon->lt[c->mon->sellt]->arrange) {
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+ } else {
+ selmon->mfact = (double) (ev.xmotion.x_root - selmon->mx) / (double) selmon->ww;
+ arrange(selmon);
+ XWarpPointer(dpy, None, root, 0, 0, 0, 0,
+ selmon->mx + (selmon->ww * selmon->mfact),
+ selmon->my + (selmon->wh / 2)
+ );
+ }
+
XUngrabPointer(dpy, CurrentTime);
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
--
2.23.0

View File

@ -1,212 +0,0 @@
From 7ac106cad72c909fbb05d302f84191cdec8f2ac0 Mon Sep 17 00:00:00 2001
From: oxinosg <oxinosg@gmail.com>
Date: Sat, 10 Dec 2022 15:24:14 +0100
Subject: [PATCH] [dwm][moveresize]: fix for resize to edge
---
config.def.h | 16 ++++++
dwm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 170 insertions(+)
diff --git a/config.def.h b/config.def.h
index 9efa774..99049e7 100644
--- a/config.def.h
+++ b/config.def.h
@@ -79,6 +79,22 @@ static const Key keys[] = {
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } },
+ { MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } },
+ { MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } },
+ { MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } },
+ { MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } },
+ { MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } },
+ { MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } },
+ { MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } },
+ { MODKEY|ControlMask, XK_Up, moveresizeedge, {.v = "t"} },
+ { MODKEY|ControlMask, XK_Down, moveresizeedge, {.v = "b"} },
+ { MODKEY|ControlMask, XK_Left, moveresizeedge, {.v = "l"} },
+ { MODKEY|ControlMask, XK_Right, moveresizeedge, {.v = "r"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Up, moveresizeedge, {.v = "T"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Down, moveresizeedge, {.v = "B"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Left, moveresizeedge, {.v = "L"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Right, moveresizeedge, {.v = "R"} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
diff --git a/dwm.c b/dwm.c
index 03baf42..89ec70d 100644
--- a/dwm.c
+++ b/dwm.c
@@ -183,6 +183,8 @@ static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e);
static void monocle(Monitor *m);
static void motionnotify(XEvent *e);
+static void moveresize(const Arg *arg);
+static void moveresizeedge(const Arg *arg);
static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
static void pop(Client *c);
@@ -1203,6 +1205,158 @@ movemouse(const Arg *arg)
}
}
+void
+moveresize(const Arg *arg) {
+ /* only floating windows can be moved */
+ Client *c;
+ c = selmon->sel;
+ int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh;
+ char xAbs, yAbs, wAbs, hAbs;
+ int msx, msy, dx, dy, nmx, nmy;
+ unsigned int dui;
+ Window dummy;
+
+ if (!c || !arg)
+ return;
+ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
+ return;
+ if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8)
+ return;
+
+ /* compute new window position; prevent window from be positioned outside the current monitor */
+ nw = c->w + w;
+ if (wAbs == 'W')
+ nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw;
+
+ nh = c->h + h;
+ if (hAbs == 'H')
+ nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw;
+
+ nx = c->x + x;
+ if (xAbs == 'X') {
+ if (x < selmon->mx)
+ nx = selmon->mx;
+ else if (x > selmon->mx + selmon->mw)
+ nx = selmon->mx + selmon->mw - nw - 2 * c->bw;
+ else
+ nx = x;
+ }
+
+ ny = c->y + y;
+ if (yAbs == 'Y') {
+ if (y < selmon->my)
+ ny = selmon->my;
+ else if (y > selmon->my + selmon->mh)
+ ny = selmon->my + selmon->mh - nh - 2 * c->bw;
+ else
+ ny = y;
+ }
+
+ ox = c->x;
+ oy = c->y;
+ ow = c->w;
+ oh = c->h;
+
+ XRaiseWindow(dpy, c->win);
+ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
+ resize(c, nx, ny, nw, nh, True);
+
+ /* move cursor along with the window to avoid problems caused by the sloppy focus */
+ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy)
+ {
+ nmx = c->x - ox + c->w - ow;
+ nmy = c->y - oy + c->h - oh;
+ /* make sure the cursor stays inside the window */
+ if ((msx + nmx) > c->x && (msy + nmy) > c->y)
+ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
+ }
+}
+
+void
+moveresizeedge(const Arg *arg) {
+ /* move or resize floating window to edge of screen */
+ Client *c;
+ c = selmon->sel;
+ char e;
+ int nx, ny, nw, nh, ox, oy, ow, oh, bp;
+ int msx, msy, dx, dy, nmx, nmy;
+ int starty;
+ unsigned int dui;
+ Window dummy;
+
+ nx = c->x;
+ ny = c->y;
+ nw = c->w;
+ nh = c->h;
+
+ starty = selmon->showbar && topbar ? bh : 0;
+ bp = selmon->showbar && !topbar ? bh : 0;
+
+ if (!c || !arg)
+ return;
+ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
+ return;
+ if(sscanf((char *)arg->v, "%c", &e) != 1)
+ return;
+
+ if(e == 't')
+ ny = starty;
+
+ if(e == 'b')
+ ny = c->h > selmon->mh - 2 * c->bw ? c->h - bp : selmon->mh - c->h - 2 * c->bw - bp;
+
+ if(e == 'l')
+ nx = selmon->mx;
+
+ if(e == 'r')
+ nx = c->w > selmon->mw - 2 * c->bw ? selmon->mx + c->w : selmon->mx + selmon->mw - c->w - 2 * c->bw;
+
+ if(e == 'T') {
+ /* if you click to resize again, it will return to old size/position */
+ if(c->h + starty == c->oldh + c->oldy) {
+ nh = c->oldh;
+ ny = c->oldy;
+ } else {
+ nh = c->h + c->y - starty;
+ ny = starty;
+ }
+ }
+
+ if(e == 'B')
+ nh = c->h + c->y + 2 * c->bw + bp == selmon->mh ? c->oldh : selmon->mh - c->y - 2 * c->bw - bp;
+
+ if(e == 'L') {
+ if(selmon->mx + c->w == c->oldw + c->oldx) {
+ nw = c->oldw;
+ nx = c->oldx;
+ } else {
+ nw = c->w + c->x - selmon->mx;
+ nx = selmon->mx;
+ }
+ }
+
+ if(e == 'R')
+ nw = c->w + c->x + 2 * c->bw == selmon->mx + selmon->mw ? c->oldw : selmon->mx + selmon->mw - c->x - 2 * c->bw;
+
+ ox = c->x;
+ oy = c->y;
+ ow = c->w;
+ oh = c->h;
+
+ XRaiseWindow(dpy, c->win);
+ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
+ resizeclient(c, nx, ny, nw, nh);
+
+ /* move cursor along with the window to avoid problems caused by the sloppy focus */
+ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) {
+ nmx = c->x - ox + c->w - ow;
+ nmy = c->y - oy + c->h - oh;
+ /* make sure the cursor stays inside the window */
+ if ((msx + nmx) > c->x && (msy + nmy) > c->y)
+ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
+ }
+}
+
Client *
nexttiled(Client *c)
{
--
2.34.1

View File

@ -1,68 +0,0 @@
diff -r -u a/dwm.c b/dwm.c
--- a/dwm.c 2019-02-02 07:55:28.000000000 -0500
+++ b/dwm.c 2022-01-17 22:38:33.614493243 -0500
@@ -1291,9 +1291,14 @@
resizemouse(const Arg *arg)
{
int ocx, ocy, nw, nh;
+ int ocx2, ocy2, nx, ny;
Client *c;
Monitor *m;
XEvent ev;
+ int horizcorner, vertcorner;
+ int di;
+ unsigned int dui;
+ Window dummy;
Time lasttime = 0;
if (!(c = selmon->sel))
@@ -1303,10 +1308,18 @@
restack(selmon);
ocx = c->x;
ocy = c->y;
+ ocx2 = c->x + c->w;
+ ocy2 = c->y + c->h;
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
return;
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+ if (!XQueryPointer (dpy, c->win, &dummy, &dummy, &di, &di, &nx, &ny, &dui))
+ return;
+ horizcorner = nx < c->w / 2;
+ vertcorner = ny < c->h / 2;
+ XWarpPointer (dpy, None, c->win, 0, 0, 0, 0,
+ horizcorner ? (-c->bw) : (c->w + c->bw -1),
+ vertcorner ? (-c->bw) : (c->h + c->bw -1));
do {
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
switch(ev.type) {
@@ -1320,8 +1333,11 @@
continue;
lasttime = ev.xmotion.time;
- nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
- nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
+ nx = horizcorner ? ev.xmotion.x : c->x;
+ ny = vertcorner ? ev.xmotion.y : c->y;
+ nw = MAX(horizcorner ? (ocx2 - nx) : (ev.xmotion.x - ocx - 2 * c->bw + 1), 1);
+ nh = MAX(vertcorner ? (ocy2 - ny) : (ev.xmotion.y - ocy - 2 * c->bw + 1), 1);
+
if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
&& c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
{
@@ -1330,11 +1346,13 @@
togglefloating(NULL);
}
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
- resize(c, c->x, c->y, nw, nh, 1);
+ resize(c, nx, ny, nw, nh, 1);
break;
}
} while (ev.type != ButtonRelease);
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
+ horizcorner ? (-c->bw) : (c->w + c->bw - 1),
+ vertcorner ? (-c->bw) : (c->h + c->bw - 1));
XUngrabPointer(dpy, CurrentTime);
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {

View File

@ -1,83 +0,0 @@
From 427c5fef13676179621949f0a8a4036e49d4b74e Mon Sep 17 00:00:00 2001
From: Niki <>
Date: Sun, 10 Dec 2023 00:29:59 +0000
Subject: [PATCH] The function `movemouse` now doesn't force clients to be
floating.
Tiling clients when moved will swap with any existing clients that
overlap with the cursor, and snap to other monitors.
---
dwm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 53 insertions(+), 3 deletions(-)
diff --git a/dwm.c b/dwm.c
index d12be2d..b1023e0 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1189,11 +1189,60 @@ movemouse(const Arg *arg)
ny = selmon->wy;
else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
ny = selmon->wy + selmon->wh - HEIGHT(c);
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
- togglefloating(NULL);
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
resize(c, nx, ny, c->w, c->h, 1);
+ else if (selmon->lt[selmon->sellt]->arrange || !c->isfloating) {
+ if ((m = recttomon(ev.xmotion.x_root, ev.xmotion.y_root, 1, 1)) != selmon) {
+ sendmon(c, m);
+ selmon = m;
+ focus(NULL);
+ }
+
+ Client *cc = c->mon->clients;
+ while (1) {
+ if (cc == 0) break;
+ if(
+ cc != c && !cc->isfloating && ISVISIBLE(cc) &&
+ ev.xmotion.x_root > cc->x &&
+ ev.xmotion.x_root < cc->x + cc->w &&
+ ev.xmotion.y_root > cc->y &&
+ ev.xmotion.y_root < cc->y + cc->h ) {
+ break;
+ }
+
+ cc = cc->next;
+ }
+
+ if (cc) {
+ Client *cl1, *cl2, ocl1;
+
+ if (!selmon->lt[selmon->sellt]->arrange) return;
+
+ cl1 = c;
+ cl2 = cc;
+ ocl1 = *cl1;
+ strcpy(cl1->name, cl2->name);
+ cl1->win = cl2->win;
+ cl1->x = cl2->x;
+ cl1->y = cl2->y;
+ cl1->w = cl2->w;
+ cl1->h = cl2->h;
+
+ cl2->win = ocl1.win;
+ strcpy(cl2->name, ocl1.name);
+ cl2->x = ocl1.x;
+ cl2->y = ocl1.y;
+ cl2->w = ocl1.w;
+ cl2->h = ocl1.h;
+
+ selmon->sel = cl2;
+
+ c = cc;
+ focus(c);
+
+ arrange(cl1->mon);
+ }
+ }
break;
}
} while (ev.type != ButtonRelease);
--
2.43.0

View File

@ -1,162 +0,0 @@
From 0d52397649099000d154b65c077fe927608d8d0b Mon Sep 17 00:00:00 2001
From: Aidan Hall <aidan.hall202@gmail.com>
Date: Sun, 2 Oct 2022 18:13:36 +0100
Subject: [PATCH] window following for latest git version
---
config.def.h | 7 +++++++
dwm.1 | 6 +++++-
dwm.c | 24 ++++++++++++++++++++++--
3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 061ad66..5eb37ed 100644
--- a/config.def.h
+++ b/config.def.h
@@ -31,6 +31,11 @@ static const Rule rules[] = {
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
+/* window following */
+#define WFACTIVE '>'
+#define WFINACTIVE 'v'
+#define WFDEFAULT WFINACTIVE
+
/* 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 */
@@ -64,6 +69,7 @@ static const Key keys[] = {
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
+ { MODKEY, XK_n, togglefollow, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
@@ -102,6 +108,7 @@ static const Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkFollowSymbol, 0, Button1, togglefollow, {0} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
diff --git a/dwm.1 b/dwm.1
index ddc8321..67dfbc0 100644
--- a/dwm.1
+++ b/dwm.1
@@ -44,7 +44,8 @@ command.
.TP
.B Button1
click on a tag label to display all windows with that tag, click on the layout
-label toggles between tiled and floating layout.
+label toggles between tiled and floating layout, click on the window follow
+icon toggles it on and off.
.TP
.B Button3
click on a tag label adds/removes all windows with that tag to/from the view.
@@ -80,6 +81,9 @@ Send focused window to next screen, if any.
.B Mod1\-b
Toggles bar on and off.
.TP
+.B Mod1\-n
+Toggles window following on and off.
+.TP
.B Mod1\-t
Sets tiled layout.
.TP
diff --git a/dwm.c b/dwm.c
index e5efb6a..6d86a9c 100644
--- a/dwm.c
+++ b/dwm.c
@@ -65,7 +65,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+ ClkClientWin, ClkRootWin, ClkFollowSymbol, ClkLast }; /* clicks */
typedef union {
int i;
@@ -113,6 +113,7 @@ typedef struct {
struct Monitor {
char ltsymbol[16];
+ char wfsymbol[2];
float mfact;
int nmaster;
int num;
@@ -212,6 +213,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
+static void togglefollow(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
@@ -440,8 +442,10 @@ buttonpress(XEvent *e)
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
- } else if (ev->x < x + TEXTW(selmon->ltsymbol))
+ } else if (ev->x < (x = (x + TEXTW(selmon->ltsymbol))))
click = ClkLtSymbol;
+ else if (ev->x < x + TEXTW(selmon->wfsymbol))
+ click = ClkFollowSymbol;
else if (ev->x > selmon->ww - (int)TEXTW(stext))
click = ClkStatusText;
else
@@ -645,6 +649,8 @@ createmon(void)
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+ m->wfsymbol[0] = WFDEFAULT;
+ m->wfsymbol[1] = '\0';
return m;
}
@@ -735,6 +741,9 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+ w = TEXTW(m->wfsymbol);
+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->wfsymbol, 0);
+
if ((w = m->ww - tw - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
@@ -1656,6 +1665,8 @@ tag(const Arg *arg)
focus(NULL);
arrange(selmon);
}
+ if (selmon->wfsymbol[0] == WFACTIVE)
+ view(arg);
}
void
@@ -1664,6 +1675,8 @@ tagmon(const Arg *arg)
if (!selmon->sel || !mons->next)
return;
sendmon(selmon->sel, dirtomon(arg->i));
+ if (selmon->wfsymbol[0] == WFACTIVE)
+ focusmon(arg);
}
void
@@ -1703,6 +1716,13 @@ togglebar(const Arg *arg)
arrange(selmon);
}
+void
+togglefollow(const Arg *arg)
+{
+ selmon->wfsymbol[0] = (selmon->wfsymbol[0] == WFACTIVE) ? WFINACTIVE : WFACTIVE;
+ drawbars();
+}
+
void
togglefloating(const Arg *arg)
{
--
2.37.3

View File

@ -1,103 +0,0 @@
From 9cd160c4ba9c345c24644a7da77cc4f04fc93c4e Mon Sep 17 00:00:00 2001
From: Matt Quintanilla <matt@mattquintanilla.xyz>
Date: Fri, 13 Oct 2023 20:11:08 +0100
Subject: [PATCH] alwaysontop for all
---
config.def.h | 1 +
dwm.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..c3c7edd 100644
--- a/config.def.h
+++ b/config.def.h
@@ -78,6 +78,7 @@ static Key keys[] = {
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY|ShiftMask, XK_space, togglealwaysontop, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
diff --git a/dwm.c b/dwm.c
index 4465af1..8d54b26 100644
--- a/dwm.c
+++ b/dwm.c
@@ -92,7 +92,7 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw;
unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ int isfixed, iscentered, isfloating, isalwaysontop, isurgent, neverfocus, oldstate, isfullscreen;
Client *next;
Client *snext;
Monitor *mon;
@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
+static void togglealwaysontop(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
@@ -732,8 +733,11 @@ drawbar(Monitor *m)
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
- if (m->sel->isfloating)
+ if (m->sel->isfloating) {
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+ if (m->sel->isalwaysontop)
+ drw_rect(drw, x + boxs, bh - boxw, boxw, boxw, 0, 0);
+ }
} else {
drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, x, 0, w, bh, 1, 1);
@@ -1356,6 +1360,17 @@ restack(Monitor *m)
return;
if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
XRaiseWindow(dpy, m->sel->win);
+
+ /* raise the aot window */
+ for(Monitor *m_search = mons; m_search; m_search = m_search->next){
+ for(c = m_search->clients; c; c = c->next){
+ if(c->isalwaysontop){
+ XRaiseWindow(dpy, c->win);
+ }
+ }
+ }
+
if (m->lt[m->sellt]->arrange) {
wc.stack_mode = Below;
wc.sibling = m->barwin;
@@ -1716,6 +1731,32 @@ togglefloating(const Arg *arg)
if (selmon->sel->isfloating)
resize(selmon->sel, selmon->sel->x, selmon->sel->y,
selmon->sel->w, selmon->sel->h, 0);
+ else
+ selmon->sel->isalwaysontop = 0; /* disabled, turn this off too */
+ arrange(selmon);
+}
+
+void
+togglealwaysontop(const Arg *arg)
+{
+ if (!selmon->sel)
+ return;
+ if (selmon->sel->isfullscreen)
+ return;
+
+ if(selmon->sel->isalwaysontop){
+ selmon->sel->isalwaysontop = 0;
+ }else{
+ c->isalwaysontop = 0;
+
+ }
+
arrange(selmon);
}
--
2.31.1

View File

@ -1,68 +0,0 @@
From eea13010ffc3983392857ee1e3804e3aa1064d7a Mon Sep 17 00:00:00 2001
From: Soenke Lambert <s.lambert@mittwald.de>
Date: Wed, 13 Oct 2021 18:21:09 +0200
Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f]
This actually fullscreens a window, instead of just hiding the statusbar
and applying the monocle layout.
---
config.def.h | 1 +
dwm.1 | 3 +++
dwm.c | 8 ++++++++
3 files changed, 12 insertions(+)
diff --git a/config.def.h b/config.def.h
index 1c0b587..8cd3204 100644
--- a/config.def.h
+++ b/config.def.h
@@ -78,6 +78,7 @@ static Key keys[] = {
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
diff --git a/dwm.1 b/dwm.1
index 13b3729..a368d05 100644
--- a/dwm.1
+++ b/dwm.1
@@ -116,6 +116,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only).
.B Mod1\-Shift\-c
Close focused window.
.TP
+.B Mod1\-Shift\-f
+Toggle fullscreen for focused window.
+.TP
.B Mod1\-Shift\-space
Toggle focused window between tiled and floating state.
.TP
diff --git a/dwm.c b/dwm.c
index 4465af1..c1b899a 100644
--- a/dwm.c
+++ b/dwm.c
@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
+static void togglefullscr(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
@@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg)
arrange(selmon);
}
+void
+togglefullscr(const Arg *arg)
+{
+ if(selmon->sel)
+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
+}
+
void
toggletag(const Arg *arg)
{
--
2.30.2

View File

@ -1,133 +0,0 @@
From feeaa839d2c6c1d0e66649cb64c4added563d4e4 Mon Sep 17 00:00:00 2001
From: Son Phan Trung <phantrungson17@gmail.com>
Date: Tue, 12 Mar 2024 18:37:32 +0700
Subject: [PATCH] patches/cool-autostart: Update patch
Updated for the removal of the sigchld() function.
---
config.def.h | 5 +++++
dwm.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 9efa774..aba210d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -18,6 +18,11 @@ static const char *colors[][3] = {
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
+static const char *const autostart[] = {
+ "st", NULL,
+ NULL /* terminate */
+};
+
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
diff --git a/dwm.c b/dwm.c
index f1d86b2..c2eb07d 100644
--- a/dwm.c
+++ b/dwm.c
@@ -233,6 +233,7 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static void autostart_exec(void);
/* variables */
static const char broken[] = "broken";
@@ -274,6 +275,34 @@ static Window root, wmcheckwin;
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+/* dwm will keep pid's of processes from autostart array and kill them at quit */
+static pid_t *autostart_pids;
+static size_t autostart_len;
+
+/* execute command from autostart array */
+static void
+autostart_exec() {
+ const char *const *p;
+ size_t i = 0;
+
+ /* count entries */
+ for (p = autostart; *p; autostart_len++, p++)
+ while (*++p);
+
+ autostart_pids = malloc(autostart_len * sizeof(pid_t));
+ for (p = autostart; *p; i++, p++) {
+ if ((autostart_pids[i] = fork()) == 0) {
+ setsid();
+ execvp(*p, (char *const *)p);
+ fprintf(stderr, "dwm: execvp %s\n", *p);
+ perror(" failed");
+ _exit(EXIT_FAILURE);
+ }
+ /* skip arguments */
+ while (*++p);
+ }
+}
+
/* function implementations */
void
applyrules(Client *c)
@@ -1258,6 +1287,16 @@ propertynotify(XEvent *e)
void
quit(const Arg *arg)
{
+ size_t i;
+
+ /* kill child processes */
+ for (i = 0; i < autostart_len; i++) {
+ if (0 < autostart_pids[i]) {
+ kill(autostart_pids[i], SIGTERM);
+ waitpid(autostart_pids[i], NULL, 0);
+ }
+ }
+
running = 0;
}
@@ -1540,6 +1579,7 @@ void
setup(void)
{
int i;
+ pid_t pid;
XSetWindowAttributes wa;
Atom utf8string;
struct sigaction sa;
@@ -1551,7 +1591,21 @@ setup(void)
sigaction(SIGCHLD, &sa, NULL);
/* clean up any zombies (inherited from .xinitrc etc) immediately */
- while (waitpid(-1, NULL, WNOHANG) > 0);
+ while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
+ pid_t *p, *lim;
+
+ if (!(p = autostart_pids))
+ continue;
+ lim = &p[autostart_len];
+
+ for (; p < lim; p++) {
+ if (*p == pid) {
+ *p = -1;
+ break;
+ }
+ }
+
+ }
/* init screen */
screen = DefaultScreen(dpy);
@@ -2152,6 +2206,7 @@ main(int argc, char *argv[])
if (!(dpy = XOpenDisplay(NULL)))
die("dwm: cannot open display");
checkotherwm();
+ autostart_exec();
setup();
#ifdef __OpenBSD__
if (pledge("stdio rpath proc exec", NULL) == -1)
--
2.44.0

View File

@ -1,114 +0,0 @@
diff --git a/config.def.h b/config.def.h
index a2ac963..92a6a81 100644
--- a/config.def.h
+++ b/config.def.h
@@ -60,6 +60,7 @@ 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 "exitdwm.c"
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
@@ -94,7 +95,7 @@ static Key keys[] = {
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
+ { MODKEY|ShiftMask, XK_e, exitdwm, {0} },
};
/* button definitions */
diff --git a/exitdwm.c b/exitdwm.c
new file mode 100644
index 0000000..74c514f
--- /dev/null
+++ b/exitdwm.c
@@ -0,0 +1,87 @@
+# include <stdio.h>
+# include <string.h>
+
+void exitdwm ()
+{
+# if \
+ defined S_LOCK || \
+ defined S_RESTART_DWM || \
+ defined S_OFFSCREEN || \
+ defined S_EXIT || \
+ defined S_REBOOT || \
+ defined S_SHUTDOWN || \
+ defined S_LOCK_ICON || \
+ defined S_RESTART_DWM_ICON || \
+ defined S_OFFSCREEN_ICON || \
+ defined S_EXIT_ICON || \
+ defined S_REBOOT_ICON || \
+ defined S_SHUTDOWN_ICON || \
+ defined S_FORMAT || \
+ defined S_FORMAT_CLEAR
+# error (conflicting macro names)
+# endif
+
+# define S_LOCK "Lock"
+# define S_RESTART_DWM "restart Dwm"
+# define S_OFFSCREEN "Off-screen"
+# define S_EXIT "Exit"
+# define S_REBOOT "Reboot"
+# define S_SHUTDOWN "Shutdown"
+# define S_LOCK_ICON "\uf023" // <= FontAwesome icons
+# define S_RESTART_DWM_ICON "\uf01e"
+# define S_OFFSCREEN_ICON "\uf108"
+# define S_EXIT_ICON "\uf2f5"
+# define S_REBOOT_ICON "\uf021"
+# define S_SHUTDOWN_ICON "\uf011"
+
+# define S_FORMAT(ACTION) S_##ACTION##_ICON " " S_##ACTION
+# define S_FORMAT_CLEAR "sed 's/^..//'"
+
+ FILE * exit_menu = popen (
+ "echo \""
+ S_FORMAT (LOCK) "\n"
+ S_FORMAT (RESTART_DWM) "\n"
+ S_FORMAT (OFFSCREEN) "\n"
+ S_FORMAT (EXIT) "\n"
+ S_FORMAT (REBOOT) "\n"
+ S_FORMAT (SHUTDOWN)
+ "\" | dmenu -p exit: | " S_FORMAT_CLEAR
+ ,
+ "r"
+ );
+
+ char exit_action [16];
+
+ if (
+ exit_menu == NULL ||
+ fscanf (exit_menu, "%15[a-zA-Z -]", exit_action) == EOF
+ ) {
+ fputs ("Error. Failure in exit_dwm.", stderr);
+ goto close_streams;
+ }
+
+ if (strcmp (exit_action, S_LOCK) == 0) system ("slock & sleep .5; xset dpms force off");
+ else if (strcmp (exit_action, S_RESTART_DWM) == 0) quit (& (const Arg) {1});
+ else if (strcmp (exit_action, S_OFFSCREEN) == 0) system ("sleep .5; xset dpms force off");
+ else if (strcmp (exit_action, S_EXIT) == 0) quit (& (const Arg) {0});
+ else if (strcmp (exit_action, S_REBOOT) == 0) system ("systemctl reboot");
+ else if (strcmp (exit_action, S_SHUTDOWN) == 0) system ("systemctl poweroff -i");
+
+close_streams:
+ pclose (exit_menu);
+
+# undef S_LOCK
+# undef S_RESTART_DWM
+# undef S_OFFSCREEN
+# undef S_EXIT
+# undef S_REBOOT
+# undef S_SHUTDOWN
+# undef S_LOCK_ICON
+# undef S_RESTART_DWM_ICON
+# undef S_OFFSCREEN_ICON
+# undef S_EXIT_ICON
+# undef S_REBOOT_ICON
+# undef S_SHUTDOWN_ICON
+# undef S_FORMAT
+# undef S_FORMAT_CLEAR
+}

View File

@ -1,84 +0,0 @@
From 6b5e23cdf8108a9033acc7c21c8926c0c72647fc Mon Sep 17 00:00:00 2001
From: Adham Zahran <adhamzahranfms@gmail.com>
Date: Wed, 27 May 2020 18:07:57 +0200
Subject: [PATCH] Top bar now has buttons that launches programs
---
config.def.h | 8 ++++++++
dwm.c | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..9231cd5 100644
--- a/config.def.h
+++ b/config.def.h
@@ -21,6 +21,14 @@ static const char *colors[][3] = {
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+/* launcher commands (They must be NULL terminated) */
+static const char* surf[] = { "surf", "duckduckgo.com", NULL };
+
+static const Launcher launchers[] = {
+ /* command name to display */
+ { surf, "surf" },
+};
+
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
diff --git a/dwm.c b/dwm.c
index 9fd0286..79e7e20 100644
--- a/dwm.c
+++ b/dwm.c
@@ -141,6 +141,11 @@ typedef struct {
int monitor;
} Rule;
/* function declarations */
static void applyrules(Client *c);
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
@@ -438,9 +443,26 @@ buttonpress(XEvent *e)
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
- } else if (ev->x < x + blw)
+ goto execute_handler;
+ } else if (ev->x < x + blw) {
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - TEXTW(stext))
+ goto execute_handler;
+ }
+
+ if (ev->x > selmon->ww - TEXTW(stext))
click = ClkStatusText;
else
click = ClkWinTitle;
@@ -450,6 +472,9 @@ buttonpress(XEvent *e)
XAllowEvents(dpy, ReplayPointer, CurrentTime);
click = ClkClientWin;
}
+
+execute_handler:
+
for (i = 0; i < LENGTH(buttons); i++)
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
@@ -728,6 +753,13 @@ drawbar(Monitor *m)
w = blw = TEXTW(m->ltsymbol);
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+
+ for (i = 0; i < LENGTH(launchers); i++)
+ {
+ w = TEXTW(launchers[i].name);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i);
+ x += w;
+ }
if ((w = m->ww - tw - x) > bh) {
if (m->sel) {
--
2.17.1

View File

@ -1,89 +0,0 @@
From e45e286b3d639b90ef202996d87054cced1fd80e Mon Sep 17 00:00:00 2001
From: tdu <tdukv@protonmail.com>
Date: Mon, 31 Aug 2020 00:07:32 +0300
Subject: [PATCH] Right clicking the layout symbol opens an xmenu prompt to
select layout.
Xmenu need to be installed for this to work.
Edit layoutmenu.sh with the correct layout table, and place in PATH.
---
config.def.h | 3 ++-
dwm.c | 19 +++++++++++++++++++
layoutmenu.sh | 7 +++++++
3 files changed, 28 insertions(+), 1 deletion(-)
create mode 100755 layoutmenu.sh
diff --git a/config.def.h b/config.def.h
index 1c0b587..c9e0833 100644
--- a/config.def.h
+++ b/config.def.h
@@ -58,6 +58,7 @@ static const Layout layouts[] = {
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 };
+static const char *layoutmenu_cmd = "layoutmenu.sh";
static Key keys[] = {
/* modifier key function argument */
@@ -101,7 +102,7 @@ static Key keys[] = {
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkLtSymbol, 0, Button3, layoutmenu, {0} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
diff --git a/dwm.c b/dwm.c
index 4465af1..2508a0a 100644
--- a/dwm.c
+++ b/dwm.c
@@ -177,6 +177,7 @@ static void grabkeys(void);
static void incnmaster(const Arg *arg);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
+static void layoutmenu(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa);
static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e);
@@ -1014,6 +1015,24 @@ killclient(const Arg *arg)
}
}
+void
+layoutmenu(const Arg *arg) {
+ FILE *p;
+ char c[3], *s;
+ int i;
+
+ if (!(p = popen(layoutmenu_cmd, "r")))
+ return;
+ s = fgets(c, sizeof(c), p);
+ pclose(p);
+
+ if (!s || *s == '\0' || c[0] == '\0')
+ return;
+
+ i = atoi(c);
+ setlayout(&((Arg) { .v = &layouts[i] }));
+}
+
void
manage(Window w, XWindowAttributes *wa)
{
diff --git a/layoutmenu.sh b/layoutmenu.sh
new file mode 100755
index 0000000..1bf95f2
--- /dev/null
+++ b/layoutmenu.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+cat <<EOF | xmenu
+[]= Tiled Layout 0
+><> Floating Layout 1
+[M] Monocle Layout 2
+EOF
--
2.28.0

View File

@ -1,95 +0,0 @@
From 9a4037dc0ef56f91c009317e78e9e3790dafbb58 Mon Sep 17 00:00:00 2001
From: BrunoCooper17 <BrunoCooper17@outlook.com>
Date: Mon, 15 Nov 2021 14:04:53 -0600
Subject: [PATCH] MoveStack patch
This plugin allows you to move clients around in the stack and swap them
with the master. It emulates the behavior off mod+shift+j and mod+shift+k
in Xmonad. movestack(+1) will swap the client with the current focus with
the next client. movestack(-1) will swap the client with the current focus
with the previous client.
---
config.def.h | 3 +++
movestack.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
create mode 100644 movestack.c
diff --git a/config.def.h b/config.def.h
index a2ac963..33efa5b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -60,6 +60,7 @@ 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 "movestack.c"
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
@@ -71,6 +72,8 @@ static Key keys[] = {
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
diff --git a/movestack.c b/movestack.c
new file mode 100644
index 0000000..520f4ae
--- /dev/null
+++ b/movestack.c
@@ -0,0 +1,48 @@
+void
+movestack(const Arg *arg) {
+ Client *c = NULL, *p = NULL, *pc = NULL, *i;
+
+ if(arg->i > 0) {
+ /* find the client after selmon->sel */
+ for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
+ if(!c)
+ for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
+
+ }
+ else {
+ /* find the client before selmon->sel */
+ for(i = selmon->clients; i != selmon->sel; i = i->next)
+ if(ISVISIBLE(i) && !i->isfloating)
+ c = i;
+ if(!c)
+ for(; i; i = i->next)
+ if(ISVISIBLE(i) && !i->isfloating)
+ c = i;
+ }
+ /* find the client before selmon->sel and c */
+ for(i = selmon->clients; i && (!p || !pc); i = i->next) {
+ if(i->next == selmon->sel)
+ p = i;
+ if(i->next == c)
+ pc = i;
+ }
+
+ /* swap c and selmon->sel selmon->clients in the selmon->clients list */
+ if(c && c != selmon->sel) {
+ Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
+ selmon->sel->next = c->next==selmon->sel?c:c->next;
+ c->next = temp;
+
+ if(p && p != c)
+ p->next = c;
+ if(pc && pc != selmon->sel)
+ pc->next = selmon->sel;
+
+ if(selmon->sel == selmon->clients)
+ selmon->clients = c;
+ else if(c == selmon->clients)
+ selmon->clients = selmon->sel;
+
+ arrange(selmon);
+ }
+}
\ No newline at end of file
--
2.33.1

View File

@ -1,139 +0,0 @@
From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001
From: Christopher Drelich <cd@cdrakka.com>
Date: Wed, 23 May 2018 22:50:38 -0400
Subject: [PATCH] Modifies quit to handle restarts and adds SIGHUP and SIGTERM
handlers.
Modified quit() to restart if it receives arg .i = 1
MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that.
Signal handlers were handled for SIGHUP and SIGTERM.
If dwm receives these signals it calls quit() with
arg .i = to 1 or 0, respectively.
To restart dwm:
MOD+CTRL+SHIFT+Q
or
kill -HUP dwmpid
To quit dwm cleanly:
MOD+SHIFT+Q
or
kill -TERM dwmpid
---
config.def.h | 1 +
dwm.1 | 10 ++++++++++
dwm.c | 22 ++++++++++++++++++++++
3 files changed, 33 insertions(+)
diff --git a/config.def.h b/config.def.h
index a9ac303..e559429 100644
--- a/config.def.h
+++ b/config.def.h
@@ -94,6 +94,7 @@ static Key keys[] = {
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
+ { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} },
};
/* button definitions */
diff --git a/dwm.1 b/dwm.1
index 13b3729..36a331c 100644
--- a/dwm.1
+++ b/dwm.1
@@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view.
.TP
.B Mod1\-Shift\-q
Quit dwm.
+.TP
+.B Mod1\-Control\-Shift\-q
+Restart dwm.
.SS Mouse commands
.TP
.B Mod1\-Button1
@@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float
.SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.
+.SH SIGNALS
+.TP
+.B SIGHUP - 1
+Restart the dwm process.
+.TP
+.B SIGTERM - 15
+Cleanly terminate the dwm process.
.SH SEE ALSO
.BR dmenu (1),
.BR st (1)
diff --git a/dwm.c b/dwm.c
index bb95e26..286eecd 100644
--- a/dwm.c
+++ b/dwm.c
@@ -205,6 +205,8 @@ static void setup(void);
static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
+static void sighup(int unused);
+static void sigterm(int unused);
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
@@ -260,6 +262,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[UnmapNotify] = unmapnotify
};
static Atom wmatom[WMLast], netatom[NetLast];
+static int restart = 0;
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
@@ -1248,6 +1251,7 @@ propertynotify(XEvent *e)
void
quit(const Arg *arg)
{
+ if(arg->i) restart = 1;
running = 0;
}
@@ -1536,6 +1540,9 @@ setup(void)
/* clean up any zombies immediately */
sigchld(0);
+ signal(SIGHUP, sighup);
+ signal(SIGTERM, sigterm);
+
/* init screen */
screen = DefaultScreen(dpy);
sw = DisplayWidth(dpy, screen);
@@ -1637,6 +1644,20 @@ sigchld(int unused)
}
void
+sighup(int unused)
+{
+ Arg a = {.i = 1};
+ quit(&a);
+}
+
+void
+sigterm(int unused)
+{
+ Arg a = {.i = 0};
+ quit(&a);
+}
+
+void
spawn(const Arg *arg)
{
if (arg->v == dmenucmd)
@@ -2139,6 +2160,7 @@ main(int argc, char *argv[])
setup();
scan();
run();
+ if(restart) execvp(argv[0], argv);
cleanup();
XCloseDisplay(dpy);
return EXIT_SUCCESS;
--
2.7.4

View File

@ -1,145 +0,0 @@
From 7b7230cba4a3b886aa4239edecb86665dffcd9d8 Mon Sep 17 00:00:00 2001
From: Francisco Tapia <link_1232@yahoo.com.mx>
Date: Mon, 30 Nov 2020 12:43:18 -0600
Subject: [PATCH] Fix for selectivefakefullscreen resize issue
Fixed a problem where entering a fake full screen caused the client
to resize incorrectly, resulting in a truncated window, and
requiring the user to force a whole screen update, e.g. toggling
on and off the bar, to correctly draw the whole window.
---
config.def.h | 6 +++---
dwm.c | 30 +++++++++++++++++++++++-------
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..b7a445b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -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 isfloating isfakefullscreen monitor */
+ { "Gimp", NULL, NULL, 0, 1, 0, -1 },
+ { "Firefox", NULL, NULL, 1 << 8, 0, 1, -1 },
};
/* layout(s) */
diff --git a/dwm.c b/dwm.c
index 664c527..a7418aa 100644
--- a/dwm.c
+++ b/dwm.c
@@ -92,7 +92,7 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw;
unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isfakefullscreen;
Client *next;
Client *snext;
Monitor *mon;
@@ -138,6 +138,7 @@ typedef struct {
const char *title;
unsigned int tags;
int isfloating;
+ int isfakefullscreen;
int monitor;
} Rule;
@@ -299,6 +300,7 @@ applyrules(Client *c)
&& (!r->instance || strstr(instance, r->instance)))
{
c->isfloating = r->isfloating;
+ c->isfakefullscreen = r->isfakefullscreen;
c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next);
if (m)
@@ -522,7 +524,8 @@ clientmessage(XEvent *e)
if (cme->data.l[1] == netatom[NetWMFullscreen]
|| cme->data.l[2] == netatom[NetWMFullscreen])
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
+ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */
+ && (!c->isfullscreen || c->isfakefullscreen))));
} else if (cme->message_type == netatom[NetActiveWindow]) {
if (c != selmon->sel && !c->isurgent)
seturgent(c, 1);
@@ -566,7 +569,8 @@ configurenotify(XEvent *e)
updatebars();
for (m = mons; m; m = m->next) {
for (c = m->clients; c; c = c->next)
- if (c->isfullscreen)
+ if (c->isfullscreen
+ && !c->isfakefullscreen)
resizeclient(c, m->mx, m->my, m->mw, m->mh);
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
}
@@ -1144,7 +1148,8 @@ movemouse(const Arg *arg)
if (!(c = selmon->sel))
return;
- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
+ if (c->isfullscreen
+ && !c->isfakefullscreen) /* no support moving fullscreen windows by mouse */
return;
restack(selmon);
ocx = c->x;
@@ -1299,7 +1304,8 @@ resizemouse(const Arg *arg)
if (!(c = selmon->sel))
return;
- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
+ if (c->isfullscreen
+ && !c->isfakefullscreen) /* no support resizing fullscreen windows by mouse */
return;
restack(selmon);
ocx = c->x;
@@ -1477,6 +1483,10 @@ setfullscreen(Client *c, int fullscreen)
XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
c->isfullscreen = 1;
+ if (c->isfakefullscreen) {
+ resizeclient(c, c->x, c->y, c->w, c->h);
+ return;
+ }
c->oldstate = c->isfloating;
c->oldbw = c->bw;
c->bw = 0;
@@ -1487,6 +1497,10 @@ setfullscreen(Client *c, int fullscreen)
XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
PropModeReplace, (unsigned char*)0, 0);
c->isfullscreen = 0;
+ if (c->isfakefullscreen) {
+ resizeclient(c, c->x, c->y, c->w, c->h);
+ return;
+ }
c->isfloating = c->oldstate;
c->bw = c->oldbw;
c->x = c->oldx;
@@ -1619,7 +1633,8 @@ showhide(Client *c)
if (ISVISIBLE(c)) {
/* show clients top down */
XMoveWindow(dpy, c->win, c->x, c->y);
- if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
+ if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating)
+ && (!c->isfullscreen || c->isfakefullscreen))
resize(c, c->x, c->y, c->w, c->h, 0);
showhide(c->snext);
} else {
@@ -1713,7 +1728,8 @@ togglefloating(const Arg *arg)
{
if (!selmon->sel)
return;
- if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
+ if (selmon->sel->isfullscreen
+ && !selmon->sel->isfakefullscreen) /* no support for fullscreen windows */
return;
selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
if (selmon->sel->isfloating)
--
2.20.1

View File

@ -1,68 +0,0 @@
From 9513cc776dc8114967988d4abc32fd7f37446ddb Mon Sep 17 00:00:00 2001
From: fossy <fossy@dnmx.org>
Date: Sun, 28 Nov 2021 21:34:37 +0100
Subject: [PATCH] Move function and it's prototype from config.def.h to dwm.c
---
config.def.h | 3 ++-
dwm.c | 23 +++++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index a2ac963..f31a66d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -50,7 +50,8 @@ static const Layout layouts[] = {
{ 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} },
+ { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, \
+ { Mod4Mask|ShiftMask, KEY, swaptags, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
diff --git a/dwm.c b/dwm.c
index 5e4d494..d11addd 100644
--- a/dwm.c
+++ b/dwm.c
@@ -234,6 +234,7 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static void swaptags(const Arg *arg);
/* variables */
static const char broken[] = "broken";
@@ -2127,6 +2128,28 @@ zoom(const Arg *arg)
pop(c);
}
+void
+swaptags(const Arg *arg)
+{
+ unsigned int newtag = arg->ui & TAGMASK;
+ unsigned int curtag = selmon->tagset[selmon->seltags];
+
+ if (newtag == curtag || !curtag || (curtag & (curtag-1)))
+ return;
+
+ for (Client *c = selmon->clients; c != NULL; c = c->next) {
+ if((c->tags & newtag) || (c->tags & curtag))
+ c->tags ^= curtag ^ newtag;
+
+ if(!c->tags) c->tags = newtag;
+ }
+
+ selmon->tagset[selmon->seltags] = newtag;
+
+ focus(NULL);
+ arrange(selmon);
+}
+
int
main(int argc, char *argv[])
{
--
2.34.1

View File

@ -1,77 +0,0 @@
From a071b060a1b9b94bcb167b988cf7774ceb870aad Mon Sep 17 00:00:00 2001
From: Jack Bird <jack.bird@durham.ac.uk>
Date: Mon, 2 Aug 2021 18:44:05 +0100
Subject: [PATCH] deck patch works with 6.2
---
config.def.h | 2 ++
dwm.c | 26 ++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/config.def.h b/config.def.h
index a2ac963..d865e18 100644
--- a/config.def.h
+++ b/config.def.h
@@ -42,6 +42,7 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "[D]", deck },
};
/* key definitions */
@@ -77,6 +78,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_r, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
diff --git a/dwm.c b/dwm.c
index 5e4d494..c67ff91 100644
--- a/dwm.c
+++ b/dwm.c
@@ -157,6 +157,7 @@ static void configure(Client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
static Monitor *createmon(void);
+static void deck(Monitor *m);
static void destroynotify(XEvent *e);
static void detach(Client *c);
static void detachstack(Client *c);
@@ -655,6 +656,31 @@ destroynotify(XEvent *e)
unmanage(c, 1);
}
+void
+deck(Monitor *m) {
+ unsigned int i, n, h, mw, my;
+ Client *c;
+
+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if(n == 0)
+ return;
+
+ if(n > m->nmaster) {
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n - m->nmaster);
+ }
+ else
+ mw = m->ww;
+ for(i = my = 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), False);
+ my += HEIGHT(c);
+ }
+ else
+ resize(c, m->wx + mw, m->wy, m->ww - mw - (2*c->bw), m->wh - (2*c->bw), False);
+}
+
void
detach(Client *c)
{
--
2.32.0

View File

@ -1,55 +0,0 @@
From a9e442ec18683e2255ffef74404c283bbb0b6381 Mon Sep 17 00:00:00 2001
From: aleks <aleks.stier@icloud.com>
Date: Thu, 23 May 2019 23:27:59 +0200
Subject: [PATCH] Make deck-patch work with the tilegap-patch
Apply this patch on top of the deck-patch to make it work with the
tilegap-patch.
---
dwm.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/dwm.c b/dwm.c
index 5b68242..1c17891 100644
--- a/dwm.c
+++ b/dwm.c
@@ -656,7 +656,7 @@ createmon(void)
void
deck(Monitor *m) {
- unsigned int i, n, h, mw, my;
+ unsigned int i, n, h, mw, my, ns;
Client *c;
for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
@@ -665,18 +665,20 @@ deck(Monitor *m) {
if(n > m->nmaster) {
mw = m->nmaster ? m->ww * m->mfact : 0;
+ ns = m->nmaster > 0 ? 2 : 1;
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n - m->nmaster);
- }
- else
+ } else {
mw = m->ww;
- for(i = my = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ ns = 1;
+ }
+ for(i = 0, my = gappx, 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), False);
- my += HEIGHT(c);
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - gappx;
+ resize(c, m->wx + gappx, m->wy + my, mw - (2*c->bw) - gappx*(5-ns)/2, h - (2*c->bw), False);
+ my += HEIGHT(c) + gappx;
}
else
- resize(c, m->wx + mw, m->wy, m->ww - mw - (2*c->bw), m->wh - (2*c->bw), False);
+ resize(c, m->wx + mw + gappx/ns, m->wy + gappx, m->ww - mw - (2*c->bw) - gappx*(5-ns)/2, m->wh - (2*c->bw) - 2*gappx, False);
}
void
--
2.21.0

View File

@ -1,8 +0,0 @@
#!/bin/sh
cat <<EOF | xmenu
[]= Tiled Layout 0
><> Floating Layout 1
[M] Monocle Layout 2
[D] Deck Layout 3
EOF

View File

@ -1,6 +0,0 @@
# DWM Todo
## Bar
- [ ] add `config.def.h` options for window name & tag underline colors and
widths
- [ ] and drawbar is a mess from that ^ so clean it up