forked from mirror/dwm
Compare commits
No commits in common. "b6f968c9ff579691641d48ffc0cc19970ad1e519" and "8933ebcf50024f4378a78e556b1ac08091197206" have entirely different histories.
b6f968c9ff
...
8933ebcf50
7 changed files with 21 additions and 445 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
.cache
|
|
|
@ -1,44 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
"/nix/store/vh9fsdhgxcnab2qk7vdp2palkkn6j3cp-gcc-wrapper-13.3.0/bin/cc",
|
|
||||||
"-c",
|
|
||||||
"-std=c99",
|
|
||||||
"-pedantic",
|
|
||||||
"-Wall",
|
|
||||||
"-Wno-deprecated-declarations",
|
|
||||||
"-Os",
|
|
||||||
"-I/usr/X11R6/include",
|
|
||||||
"-I/usr/include/freetype2",
|
|
||||||
"-D_DEFAULT_SOURCE",
|
|
||||||
"-D_BSD_SOURCE",
|
|
||||||
"-D_XOPEN_SOURCE=700L",
|
|
||||||
"-DVERSION=\"6.5\"",
|
|
||||||
"-DXINERAMA",
|
|
||||||
"drw.c"
|
|
||||||
],
|
|
||||||
"directory": "/home/ravenshade/Documents/projects/dwm",
|
|
||||||
"file": "/home/ravenshade/Documents/projects/dwm/drw.c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
"/nix/store/vh9fsdhgxcnab2qk7vdp2palkkn6j3cp-gcc-wrapper-13.3.0/bin/cc",
|
|
||||||
"-c",
|
|
||||||
"-std=c99",
|
|
||||||
"-pedantic",
|
|
||||||
"-Wall",
|
|
||||||
"-Wno-deprecated-declarations",
|
|
||||||
"-Os",
|
|
||||||
"-I/usr/X11R6/include",
|
|
||||||
"-I/usr/include/freetype2",
|
|
||||||
"-D_DEFAULT_SOURCE",
|
|
||||||
"-D_BSD_SOURCE",
|
|
||||||
"-D_XOPEN_SOURCE=700L",
|
|
||||||
"-DVERSION=\"6.5\"",
|
|
||||||
"-DXINERAMA",
|
|
||||||
"dwm.c"
|
|
||||||
],
|
|
||||||
"directory": "/home/ravenshade/Documents/projects/dwm",
|
|
||||||
"file": "/home/ravenshade/Documents/projects/dwm/dwm.c"
|
|
||||||
}
|
|
||||||
]
|
|
38
config.def.h
38
config.def.h
|
@ -1,22 +1,21 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
/* appearance */
|
/* appearance */
|
||||||
static const unsigned int borderpx = 0; /* border pixel of windows */
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
static const unsigned int snap = 32; /* snap pixel */
|
static const unsigned int snap = 32; /* snap pixel */
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
static const int showbar = 1; /* 0 means no bar */
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
static const int topbar = 1; /* 0 means bottom bar */
|
||||||
static const char *fonts[] = { "JetBrainsMono Nerd Font:size=10" };
|
static const char *fonts[] = { "monospace:size=10" };
|
||||||
static const char dmenufont[] = "JetBrainsMono Nerd Font:size=10";
|
static const char dmenufont[] = "monospace:size=10";
|
||||||
static const char col_text[] = "#e0def4";
|
static const char col_gray1[] = "#222222";
|
||||||
static const char col_subtle[] = "#908caa";
|
static const char col_gray2[] = "#444444";
|
||||||
static const char col_muted[] = "#6e6a86";
|
static const char col_gray3[] = "#bbbbbb";
|
||||||
static const char col_base[] = "#191724";
|
static const char col_gray4[] = "#eeeeee";
|
||||||
static const char col_iris[] = "#c4a7e7";
|
static const char col_cyan[] = "#005577";
|
||||||
static const char col_h_low[] = "#21202e";
|
|
||||||
static const char *colors[][3] = {
|
static const char *colors[][3] = {
|
||||||
/* fg bg border */
|
/* fg bg border */
|
||||||
[SchemeNorm] = { col_muted, col_h_low, col_base },
|
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||||
[SchemeSel] = { col_text, col_base, col_iris },
|
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* tagging */
|
/* tagging */
|
||||||
|
@ -29,11 +28,7 @@ static const Rule rules[] = {
|
||||||
*/
|
*/
|
||||||
/* class instance title tags mask isfloating monitor */
|
/* class instance title tags mask isfloating monitor */
|
||||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||||
{ "discord", NULL, NULL, 1 << 1, 0, 1 },
|
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||||
{ "calendar", NULL, NULL, 1 << 4, 0, 1 },
|
|
||||||
{ "vesktop", NULL, NULL, 1 << 1, 0, 1 },
|
|
||||||
{ "obsidian", NULL, NULL, 1 << 3, 0, 1 },
|
|
||||||
{ "nannou", NULL, NULL, 0, 1, -1 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
|
@ -50,7 +45,7 @@ static const Layout layouts[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* key definitions */
|
/* key definitions */
|
||||||
#define MODKEY Mod4Mask
|
#define MODKEY Mod1Mask
|
||||||
#define TAGKEYS(KEY,TAG) \
|
#define TAGKEYS(KEY,TAG) \
|
||||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
|
@ -62,17 +57,13 @@ static const Layout layouts[] = {
|
||||||
|
|
||||||
/* commands */
|
/* commands */
|
||||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_h_low, "-nf", col_muted, "-sb", col_base, "-sf", col_text, NULL };
|
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[] = { "kitty", NULL };
|
static const char *termcmd[] = { "st", NULL };
|
||||||
static const char *scrnshotcmd[] = { "flameshot", "gui", NULL };
|
|
||||||
|
|
||||||
#include "selfrestart.c"
|
|
||||||
|
|
||||||
static const Key keys[] = {
|
static const Key keys[] = {
|
||||||
/* modifier key function argument */
|
/* modifier key function argument */
|
||||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||||
{ ControlMask, XK_Print, spawn, {.v = scrnshotcmd } },
|
|
||||||
{ MODKEY, XK_b, togglebar, {0} },
|
{ MODKEY, XK_b, togglebar, {0} },
|
||||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||||
|
@ -104,7 +95,6 @@ static const Key keys[] = {
|
||||||
TAGKEYS( XK_8, 7)
|
TAGKEYS( XK_8, 7)
|
||||||
TAGKEYS( XK_9, 8)
|
TAGKEYS( XK_9, 8)
|
||||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_r, self_restart, {0} },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* button definitions */
|
/* button definitions */
|
||||||
|
|
130
dwm.c
130
dwm.c
|
@ -61,8 +61,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||||
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||||
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
||||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
||||||
NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetLast }; /* EWMH atoms */
|
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
|
||||||
enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
|
|
||||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
||||||
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
||||||
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
||||||
|
@ -111,7 +110,6 @@ typedef struct {
|
||||||
void (*arrange)(Monitor *);
|
void (*arrange)(Monitor *);
|
||||||
} Layout;
|
} Layout;
|
||||||
|
|
||||||
typedef struct Pertag Pertag;
|
|
||||||
struct Monitor {
|
struct Monitor {
|
||||||
char ltsymbol[16];
|
char ltsymbol[16];
|
||||||
float mfact;
|
float mfact;
|
||||||
|
@ -131,7 +129,6 @@ struct Monitor {
|
||||||
Monitor *next;
|
Monitor *next;
|
||||||
Window barwin;
|
Window barwin;
|
||||||
const Layout *lt[2];
|
const Layout *lt[2];
|
||||||
Pertag *pertag;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -200,7 +197,6 @@ static void scan(void);
|
||||||
static int sendevent(Client *c, Atom proto);
|
static int sendevent(Client *c, Atom proto);
|
||||||
static void sendmon(Client *c, Monitor *m);
|
static void sendmon(Client *c, Monitor *m);
|
||||||
static void setclientstate(Client *c, long state);
|
static void setclientstate(Client *c, long state);
|
||||||
static void setclienttagprop(Client *c);
|
|
||||||
static void setfocus(Client *c);
|
static void setfocus(Client *c);
|
||||||
static void setfullscreen(Client *c, int fullscreen);
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
static void setlayout(const Arg *arg);
|
static void setlayout(const Arg *arg);
|
||||||
|
@ -274,15 +270,6 @@ static Window root, wmcheckwin;
|
||||||
/* configuration, allows nested code to access above variables */
|
/* configuration, allows nested code to access above variables */
|
||||||
#include "config.h"
|
#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. */
|
/* compile-time check if all tags fit into an unsigned int bit array. */
|
||||||
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
||||||
|
|
||||||
|
@ -646,7 +633,6 @@ Monitor *
|
||||||
createmon(void)
|
createmon(void)
|
||||||
{
|
{
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
m = ecalloc(1, sizeof(Monitor));
|
m = ecalloc(1, sizeof(Monitor));
|
||||||
m->tagset[0] = m->tagset[1] = 1;
|
m->tagset[0] = m->tagset[1] = 1;
|
||||||
|
@ -657,20 +643,6 @@ createmon(void)
|
||||||
m->lt[0] = &layouts[0];
|
m->lt[0] = &layouts[0];
|
||||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,7 +979,7 @@ grabkeys(void)
|
||||||
void
|
void
|
||||||
incnmaster(const Arg *arg)
|
incnmaster(const Arg *arg)
|
||||||
{
|
{
|
||||||
selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
|
selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,26 +1067,6 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
updatewindowtype(c);
|
updatewindowtype(c);
|
||||||
updatesizehints(c);
|
updatesizehints(c);
|
||||||
updatewmhints(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);
|
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||||
grabbuttons(c, 0);
|
grabbuttons(c, 0);
|
||||||
if (!c->isfloating)
|
if (!c->isfloating)
|
||||||
|
@ -1476,7 +1428,6 @@ sendmon(Client *c, Monitor *m)
|
||||||
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
|
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
|
||||||
attach(c);
|
attach(c);
|
||||||
attachstack(c);
|
attachstack(c);
|
||||||
setclienttagprop(c);
|
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
arrange(NULL);
|
arrange(NULL);
|
||||||
}
|
}
|
||||||
|
@ -1559,9 +1510,9 @@ void
|
||||||
setlayout(const Arg *arg)
|
setlayout(const Arg *arg)
|
||||||
{
|
{
|
||||||
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
||||||
selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
|
selmon->sellt ^= 1;
|
||||||
if (arg && arg->v)
|
if (arg && arg->v)
|
||||||
selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
|
selmon->lt[selmon->sellt] = (Layout *)arg->v;
|
||||||
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
|
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
|
||||||
if (selmon->sel)
|
if (selmon->sel)
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
|
@ -1580,7 +1531,7 @@ setmfact(const Arg *arg)
|
||||||
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
|
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
|
||||||
if (f < 0.05 || f > 0.95)
|
if (f < 0.05 || f > 0.95)
|
||||||
return;
|
return;
|
||||||
selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
|
selmon->mfact = f;
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1627,10 +1578,6 @@ setup(void)
|
||||||
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
|
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
|
||||||
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||||
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
|
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
|
||||||
xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
|
|
||||||
xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
|
|
||||||
xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
|
|
||||||
netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False);
|
|
||||||
/* init cursors */
|
/* init cursors */
|
||||||
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
|
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
|
||||||
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
||||||
|
@ -1654,7 +1601,6 @@ setup(void)
|
||||||
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
|
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
|
||||||
PropModeReplace, (unsigned char *) netatom, NetLast);
|
PropModeReplace, (unsigned char *) netatom, NetLast);
|
||||||
XDeleteProperty(dpy, root, netatom[NetClientList]);
|
XDeleteProperty(dpy, root, netatom[NetClientList]);
|
||||||
XDeleteProperty(dpy, root, netatom[NetClientInfo]);
|
|
||||||
/* select events */
|
/* select events */
|
||||||
wa.cursor = cursor[CurNormal]->cursor;
|
wa.cursor = cursor[CurNormal]->cursor;
|
||||||
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
|
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
|
||||||
|
@ -1719,22 +1665,11 @@ 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
|
void
|
||||||
tag(const Arg *arg)
|
tag(const Arg *arg)
|
||||||
{
|
{
|
||||||
Client *c;
|
|
||||||
if (selmon->sel && arg->ui & TAGMASK) {
|
if (selmon->sel && arg->ui & TAGMASK) {
|
||||||
c = selmon->sel;
|
|
||||||
selmon->sel->tags = arg->ui & TAGMASK;
|
selmon->sel->tags = arg->ui & TAGMASK;
|
||||||
setclienttagprop(c);
|
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
@ -1779,7 +1714,7 @@ tile(Monitor *m)
|
||||||
void
|
void
|
||||||
togglebar(const Arg *arg)
|
togglebar(const Arg *arg)
|
||||||
{
|
{
|
||||||
selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
|
selmon->showbar = !selmon->showbar;
|
||||||
updatebarpos(selmon);
|
updatebarpos(selmon);
|
||||||
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
|
@ -1809,7 +1744,6 @@ toggletag(const Arg *arg)
|
||||||
newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
|
newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
|
||||||
if (newtags) {
|
if (newtags) {
|
||||||
selmon->sel->tags = newtags;
|
selmon->sel->tags = newtags;
|
||||||
setclienttagprop(selmon->sel);
|
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
@ -1819,33 +1753,9 @@ void
|
||||||
toggleview(const Arg *arg)
|
toggleview(const Arg *arg)
|
||||||
{
|
{
|
||||||
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
|
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
|
||||||
int i;
|
|
||||||
|
|
||||||
if (newtagset) {
|
if (newtagset) {
|
||||||
selmon->tagset[selmon->seltags] = 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);
|
focus(NULL);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
@ -2142,37 +2052,11 @@ updatewmhints(Client *c)
|
||||||
void
|
void
|
||||||
view(const Arg *arg)
|
view(const Arg *arg)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
unsigned int tmptag;
|
|
||||||
|
|
||||||
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
||||||
return;
|
return;
|
||||||
selmon->seltags ^= 1; /* toggle sel tagset */
|
selmon->seltags ^= 1; /* toggle sel tagset */
|
||||||
if (arg->ui & TAGMASK) {
|
if (arg->ui & TAGMASK)
|
||||||
selmon->tagset[selmon->seltags] = 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);
|
focus(NULL);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
|
@ -1,101 +0,0 @@
|
||||||
# HG changeset patch
|
|
||||||
# User Barbu Paul - Gheorghe <barbu.paul.gheorghe@gmail.com>
|
|
||||||
# Date 1354650884 -7200
|
|
||||||
# Node ID 6c472a21a5887c5295a331c48c4da188ec2c8413
|
|
||||||
# Parent aaab44133a6830c9a00263731d098c01cc1d6fb5
|
|
||||||
selfrestart now magically locates the current dwm (no need to hardcode a path)
|
|
||||||
|
|
||||||
diff -r aaab44133a68 -r 6c472a21a588 config.def.h
|
|
||||||
--- a/config.def.h Tue Dec 04 21:54:44 2012 +0200
|
|
||||||
+++ b/config.def.h Tue Dec 04 21:54:44 2012 +0200
|
|
||||||
@@ -54,6 +54,8 @@
|
|
||||||
static const char *termcmd[] = { "urxvtc", NULL };
|
|
||||||
static const char *filemancmd[] = { "thunar", NULL };
|
|
||||||
|
|
||||||
+#include "selfrestart.c"
|
|
||||||
+
|
|
||||||
static Key keys[] = {
|
|
||||||
/* modifier key function argument */
|
|
||||||
{ MODKEY, XK_r, spawn, {.v = dmenucmd } },
|
|
||||||
@@ -89,6 +91,7 @@
|
|
||||||
TAGKEYS( XK_7, 6)
|
|
||||||
TAGKEYS( XK_8, 7)
|
|
||||||
TAGKEYS( XK_9, 8)
|
|
||||||
+ { MODKEY|ShiftMask, XK_r, self_restart, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -108,4 +111,3 @@
|
|
||||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
|
||||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
|
||||||
};
|
|
||||||
-
|
|
||||||
diff -r aaab44133a68 -r 6c472a21a588 selfrestart.c
|
|
||||||
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
|
||||||
+++ b/selfrestart.c Tue Dec 04 21:54:44 2012 +0200
|
|
||||||
@@ -0,0 +1,65 @@
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <sys/types.h>
|
|
||||||
+#include <sys/stat.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * Magically finds the current's executable path
|
|
||||||
+ *
|
|
||||||
+ * I'm doing the do{}while(); trick because Linux (what I'm running) is not
|
|
||||||
+ * POSIX compilant and so lstat() cannot be trusted on /proc entries
|
|
||||||
+ *
|
|
||||||
+ * @return char* the path of the current executable
|
|
||||||
+ */
|
|
||||||
+char *get_dwm_path(){
|
|
||||||
+ struct stat s;
|
|
||||||
+ int r, length, rate = 42;
|
|
||||||
+ char *path = NULL;
|
|
||||||
+
|
|
||||||
+ if(lstat("/proc/self/exe", &s) == -1){
|
|
||||||
+ perror("lstat:");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ length = s.st_size + 1 - rate;
|
|
||||||
+
|
|
||||||
+ do{
|
|
||||||
+ length+=rate;
|
|
||||||
+
|
|
||||||
+ free(path);
|
|
||||||
+ path = malloc(sizeof(char) * length);
|
|
||||||
+
|
|
||||||
+ if(path == NULL){
|
|
||||||
+ perror("malloc:");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ r = readlink("/proc/self/exe", path, length);
|
|
||||||
+
|
|
||||||
+ if(r == -1){
|
|
||||||
+ perror("readlink:");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ }while(r >= length);
|
|
||||||
+
|
|
||||||
+ path[r] = '\0';
|
|
||||||
+
|
|
||||||
+ return path;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * self-restart
|
|
||||||
+ *
|
|
||||||
+ * Initially inspired by: Yu-Jie Lin
|
|
||||||
+ * https://sites.google.com/site/yjlnotes/notes/dwm
|
|
||||||
+ */
|
|
||||||
+void self_restart(const Arg *arg) {
|
|
||||||
+ char *const argv[] = {get_dwm_path(), NULL};
|
|
||||||
+
|
|
||||||
+ if(argv[0] == NULL){
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ execv(argv[0], argv);
|
|
||||||
+}
|
|
|
@ -1,34 +0,0 @@
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Magically finds the current's executable path
|
|
||||||
*
|
|
||||||
* I'm doing the do{}while(); trick because Linux (what I'm running) is not
|
|
||||||
* POSIX compilant and so lstat() cannot be trusted on /proc entries
|
|
||||||
*
|
|
||||||
* @return char* the path of the current executable
|
|
||||||
*/
|
|
||||||
char *get_dwm_path(){
|
|
||||||
// Sorry non nixos users
|
|
||||||
return "/run/current-system/sw/bin/dwm";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* self-restart
|
|
||||||
*
|
|
||||||
* Initially inspired by: Yu-Jie Lin
|
|
||||||
* https://sites.google.com/site/yjlnotes/notes/dwm
|
|
||||||
*/
|
|
||||||
void self_restart(const Arg *arg) {
|
|
||||||
char *const argv[] = {get_dwm_path(), NULL};
|
|
||||||
|
|
||||||
if(argv[0] == NULL){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
execv(argv[0], argv);
|
|
||||||
}
|
|
Loading…
Reference in a new issue