Compare commits

..

1 Commits

Author SHA1 Message Date
aa97ffdf35 status2d patch 2024-07-07 21:47:00 -04:00
15 changed files with 613 additions and 1142 deletions

View File

@ -12,8 +12,8 @@ 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 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 vertpad = 10; /* vertical padding of bar */
static const int sidepad = 10; /* horizontal padding of bar */ static const int sidepad = 10; /* horizontal padding of bar */
static const char *fonts[] = { "Hack Nerd Font:size=10" }; static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "Hack Nerd Font:size=10"; static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222"; static const char col_gray1[] = "#222222";
static const char col_gray2[] = "#444444"; static const char col_gray2[] = "#444444";
static const char col_gray3[] = "#bbbbbb"; static const char col_gray3[] = "#bbbbbb";
@ -26,16 +26,12 @@ static const char *colors[][3] = {
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, [SchemeSel] = { col_gray4, col_cyan, col_cyan },
[SchemeHid] = { col_cyan, col_gray1, 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] = { static const unsigned int alphas[][3] = {
/* fg bg border*/ /* fg bg border*/
[SchemeNorm] = { OPAQUE, baralpha, borderalpha }, [SchemeNorm] = { OPAQUE, baralpha, borderalpha },
[SchemeSel] = { OPAQUE, baralpha, borderalpha }, [SchemeSel] = { OPAQUE, baralpha, borderalpha },
[SchemeHid] = { OPAQUE, baralpha, borderalpha }, [SchemeHid] = { OPAQUE, baralpha, borderalpha },
[SchemeLay] = { OPAQUE, baralpha, borderalpha },
[SchemeWf] = { OPAQUE, baralpha, borderalpha },
}; };
static const char *const autostart[] = { static const char *const autostart[] = {
@ -62,35 +58,18 @@ static const unsigned int ulinestroke = 2; /* thickness / height of the underlin
static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */ 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 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[] = { static const Rule rules[] = {
/* xprop(1): /* xprop(1):
* WM_CLASS(STRING) = instance, class * WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title * WM_NAME(STRING) = title
*/ */
/* class instance title tags mask isfloating isfakefullscreen isterminal noswallow monitor */ /* class instance title tags mask isfloating isterminal noswallow monitor */
{ "Gimp", NULL, NULL, 0, 1, 0, 0, 0, -1 }, { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, -1, -1 }, { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 },
{ "St", NULL, NULL, 0, 0, 0, 1, 0, -1 }, { "St", NULL, NULL, 0, 0, 1, 0, -1 },
{ NULL, NULL, "Event Tester", 0, 0, 0, 0, 1, -1 }, /* xev */ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
}; };
static const char topicon[128] = "\uf435";
/* icon to indicate always on top floating windows */
/* window following */ /* window following */
#define WFACTIVE '>' #define WFACTIVE '>'
#define WFINACTIVE 'v' #define WFINACTIVE 'v'
@ -107,17 +86,16 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */ { "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */ { "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle }, { "[M]", monocle },
{ "[D]", deck },
}; };
/* 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} }, \
{ MODKEY|ShiftMask, KEY, tag, {.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} }, \
{ Mod1Mask|ShiftMask, KEY, swaptags, {.ui = 1 << TAG} }, { Mod4Mask|ShiftMask, KEY, swaptags, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
@ -126,7 +104,6 @@ static const Layout layouts[] = {
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_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, 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[] = { "st", NULL }; static const char *termcmd[] = { "st", NULL };
static const char *layoutmenu_cmd = "layoutmenu.sh";
#include "exitdwm.c" #include "exitdwm.c"
static const Key keys[] = { static const Key keys[] = {
/* modifier key function argument */ /* modifier key function argument */
@ -152,28 +129,9 @@ static const Key keys[] = {
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_r, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_space, setlayout, {0} }, { MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {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|ShiftMask, XK_f, togglefullscr, {0} },
{ MODKEY|Mod1Mask, XK_f, togglefakefullscr, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } }, { MODKEY, XK_comma, focusmon, {.i = -1 } },
@ -201,7 +159,7 @@ static const Key keys[] = {
static const Button buttons[] = { static const Button buttons[] = {
/* click event mask button function argument */ /* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, layoutmenu, {0} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkFollowSymbol, 0, Button1, togglefollow, {0} }, { ClkFollowSymbol, 0, Button1, togglefollow, {0} },
{ ClkWinTitle, 0, Button1, togglewin, {0} }, { ClkWinTitle, 0, Button1, togglewin, {0} },
{ ClkWinTitle, 0, Button2, zoom, {0} }, { ClkWinTitle, 0, Button2, zoom, {0} },

575
dwm.c
View File

@ -67,7 +67,7 @@
/* enums */ /* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel, SchemeHid, SchemeLay, SchemeWf }; /* color schemes */ enum { SchemeNorm, SchemeSel, SchemeHid }; /* 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, NetClientInfo, NetLast }; /* EWMH atoms */
@ -102,7 +102,7 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
int bw, oldbw; int bw, oldbw;
unsigned int tags; unsigned int tags;
int isfixed, isfloating, isalwaysontop, isurgent, neverfocus, oldstate, isfullscreen, isfakefullscreen, isterminal, noswallow; int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
pid_t pid; pid_t pid;
Client *next; Client *next;
Client *snext; Client *snext;
@ -158,7 +158,6 @@ typedef struct {
const char *title; const char *title;
unsigned int tags; unsigned int tags;
int isfloating; int isfloating;
int isfakefullscreen;
int isterminal; int isterminal;
int noswallow; int noswallow;
int monitor; int monitor;
@ -187,13 +186,13 @@ static void configure(Client *c);
static void configurenotify(XEvent *e); static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e); static void configurerequest(XEvent *e);
static Monitor *createmon(void); static Monitor *createmon(void);
static void deck(Monitor *m);
static void destroynotify(XEvent *e); static void destroynotify(XEvent *e);
static void detach(Client *c); static void detach(Client *c);
static void detachstack(Client *c); static void detachstack(Client *c);
static Monitor *dirtomon(int dir); static Monitor *dirtomon(int dir);
static void drawbar(Monitor *m); static void drawbar(Monitor *m);
static void drawbars(void); static void drawbars(void);
static int drawstatusbar(Monitor *m, int bh, int extra, char* text);
static void enternotify(XEvent *e); static void enternotify(XEvent *e);
static void expose(XEvent *e); static void expose(XEvent *e);
static Client *findbefore(Client *c); static Client *findbefore(Client *c);
@ -214,14 +213,11 @@ static void hidewin(Client *c);
static void incnmaster(const Arg *arg); static void incnmaster(const Arg *arg);
static void keypress(XEvent *e); static void keypress(XEvent *e);
static void killclient(const Arg *arg); static void killclient(const Arg *arg);
static void layoutmenu(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa); static void manage(Window w, XWindowAttributes *wa);
static void mappingnotify(XEvent *e); static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e); static void maprequest(XEvent *e);
static void monocle(Monitor *m); static void monocle(Monitor *m);
static void motionnotify(XEvent *e); static void motionnotify(XEvent *e);
static void moveresize(const Arg *arg);
static void moveresizeedge(const Arg *arg);
static void movemouse(const Arg *arg); static void movemouse(const Arg *arg);
static void movestack(const Arg *arg); static void movestack(const Arg *arg);
static Client *nexttiled(Client *c); static Client *nexttiled(Client *c);
@ -242,7 +238,6 @@ 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 setclienttagprop(Client *c);
static void setfocus(Client *c); static void setfocus(Client *c);
static void setfakefullscreen(Client *c, int fullscreen);
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);
static void setmfact(const Arg *arg); static void setmfact(const Arg *arg);
@ -259,11 +254,9 @@ static void tag(const Arg *arg);
static void tagmon(const Arg *arg); static void tagmon(const Arg *arg);
static void tile(Monitor *m); static void tile(Monitor *m);
static void togglebar(const Arg *arg); static void togglebar(const Arg *arg);
static void togglefakefullscr(const Arg *arg);
static void togglefullscr(const Arg *arg); static void togglefullscr(const Arg *arg);
static void toggleextrabar(const Arg *arg); static void toggleextrabar(const Arg *arg);
static void togglefloating(const Arg *arg); static void togglefloating(const Arg *arg);
static void togglealwaysontop(const Arg *arg);
static void togglefollow(const Arg *arg); static void togglefollow(const Arg *arg);
static void toggletag(const Arg *arg); static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg); static void toggleview(const Arg *arg);
@ -282,6 +275,9 @@ static void updatetitle(Client *c);
static void updatewindowtype(Client *c); static void updatewindowtype(Client *c);
static void updatewmhints(Client *c); static void updatewmhints(Client *c);
static void view(const Arg *arg); static void view(const Arg *arg);
static void window_set_state(Display *dpy, Window win, long state);
static void window_map(Display *dpy, Client *c, int deiconify);
static void window_unmap(Display *dpy, Window win, Window root, int iconify);
static Client *wintoclient(Window w); static Client *wintoclient(Window w);
static Monitor *wintomon(Window w); static Monitor *wintomon(Window w);
static int xerror(Display *dpy, XErrorEvent *ee); static int xerror(Display *dpy, XErrorEvent *ee);
@ -301,8 +297,8 @@ static pid_t winpid(Window w);
/* variables */ /* variables */
static Client *prevzoom = NULL; static Client *prevzoom = NULL;
static const char broken[] = "broken"; static const char broken[] = "broken";
static char stext[256]; static char stext[1024];
static char estext[256]; static char estext[1024];
static char wfsymbol[2]; static char wfsymbol[2];
static int screen; static int screen;
static int sw, sh; /* X display screen geometry width, height */ static int sw, sh; /* X display screen geometry width, height */
@ -333,7 +329,6 @@ static int restart = 0;
static int running = 1; static int running = 1;
static Cur *cursor[CurLast]; static Cur *cursor[CurLast];
static Clr **scheme; static Clr **scheme;
static Clr **tagscheme;
static Display *dpy; static Display *dpy;
static Drw *drw; static Drw *drw;
static Monitor *mons, *selmon; static Monitor *mons, *selmon;
@ -415,7 +410,6 @@ applyrules(Client *c)
c->isterminal = r->isterminal; c->isterminal = r->isterminal;
c->noswallow = r->noswallow; c->noswallow = r->noswallow;
c->isfloating = r->isfloating; c->isfloating = r->isfloating;
c->isfakefullscreen = r->isfakefullscreen;
c->tags |= r->tags; c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next); for (m = mons; m && m->num != r->monitor; m = m->next);
if (m) if (m)
@ -607,9 +601,15 @@ buttonpress(XEvent *e)
} }
if (ev->window == selmon->barwin) { if (ev->window == selmon->barwin) {
i = x = 0; i = x = 0;
do unsigned int occ = 0;
for(c = m->clients; c; c=c->next)
occ |= c->tags == TAGMASK ? 0 : c->tags;
do {
/* Do not reserve space for vacant tags */
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
continue;
x += TEXTW(tags[i]); x += TEXTW(tags[i]);
while (ev->x >= x && ++i < LENGTH(tags)); } while (ev->x >= x && ++i < LENGTH(tags));
if (i < LENGTH(tags)) { if (i < LENGTH(tags)) {
click = ClkTagBar; click = ClkTagBar;
arg.ui = 1 << i; arg.ui = 1 << i;
@ -689,7 +689,7 @@ cleanup(void)
cleanupmon(mons); cleanupmon(mons);
for (i = 0; i < CurLast; i++) for (i = 0; i < CurLast; i++)
drw_cur_free(drw, cursor[i]); drw_cur_free(drw, cursor[i]);
for (i = 0; i < LENGTH(colors); i++) for (i = 0; i < LENGTH(colors) + 1; i++)
free(scheme[i]); free(scheme[i]);
free(scheme); free(scheme);
XDestroyWindow(dpy, wmcheckwin); XDestroyWindow(dpy, wmcheckwin);
@ -729,8 +729,7 @@ clientmessage(XEvent *e)
if (cme->data.l[1] == netatom[NetWMFullscreen] if (cme->data.l[1] == netatom[NetWMFullscreen]
|| cme->data.l[2] == netatom[NetWMFullscreen]) || cme->data.l[2] == netatom[NetWMFullscreen])
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
|| (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
&& (!c->isfullscreen || c->isfakefullscreen))));
} else if (cme->message_type == netatom[NetActiveWindow]) { } else if (cme->message_type == netatom[NetActiveWindow]) {
if (c != selmon->sel && !c->isurgent) if (c != selmon->sel && !c->isurgent)
seturgent(c, 1); seturgent(c, 1);
@ -774,8 +773,7 @@ configurenotify(XEvent *e)
updatebars(); updatebars();
for (m = mons; m; m = m->next) { for (m = mons; m; m = m->next) {
for (c = m->clients; c; c = c->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); resizeclient(c, m->mx, m->my, m->mw, m->mh);
XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh); XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh);
XMoveResizeWindow(dpy, m->extrabarwin, m->wx + sp, m->eby - vp, m->ww - 2 * sp, bh); XMoveResizeWindow(dpy, m->extrabarwin, m->wx + sp, m->eby - vp, m->ww - 2 * sp, bh);
@ -886,33 +884,6 @@ destroynotify(XEvent *e)
unmanage(c->swallowing, 1); unmanage(c->swallowing, 1);
} }
void
deck(Monitor *m) {
unsigned int i, n, h, mw, my, ns;
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;
ns = m->nmaster > 0 ? 2 : 1;
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n - m->nmaster);
} else {
mw = m->ww;
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) - 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 + gappx/ns, m->wy + gappx, m->ww - mw - (2*c->bw) - gappx*(5-ns)/2, m->wh - (2*c->bw) - 2*gappx, False);
}
void void
detach(Client *c) detach(Client *c)
{ {
@ -951,6 +922,127 @@ dirtomon(int dir)
return m; return m;
} }
int
drawstatusbar(Monitor *m, int bh, int extra, char* stext) {
int ret, i, w, x, len;
short isCode = 0;
char *text;
char *p;
Clr oldbg, oldfg;
len = strlen(stext) + 1 ;
if (!(text = (char*) malloc(sizeof(char)*len)))
die("malloc");
p = text;
memcpy(text, stext, len);
/* compute width of the status text */
w = 0;
i = -1;
while (text[++i]) {
if (text[i] == '^') {
if (!isCode) {
isCode = 1;
text[i] = '\0';
w += TEXTW(text) - lrpad;
text[i] = '^';
if (text[++i] == 'f')
w += atoi(text + ++i);
} else {
isCode = 0;
text = text + i + 1;
i = -1;
}
}
}
if (!isCode)
w += TEXTW(text) - lrpad;
else
isCode = 0;
text = p;
w += 2; /* 1px padding on both sides */
ret = x = m->ww - w - 2 * sp;
drw_setscheme(drw, scheme[LENGTH(colors)]);
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
drw_rect(drw, x, 0, w, bh, 1, 1);
x++;
/* process status text */
i = -1;
while (text[++i]) {
if (text[i] == '^' && !isCode) {
isCode = 1;
text[i] = '\0';
w = TEXTW(text) - lrpad;
drw_text(drw, x, 0, w, bh, 0, text, 0);
x += w;
/* process code */
while (text[++i] != '^') {
if (text[i] == 'c') {
char buf[8];
memcpy(buf, (char*)text+i+1, 7);
buf[7] = '\0';
drw_clr_create(drw, &drw->scheme[ColFg], buf, 230);
i += 7;
} else if (text[i] == 'b') {
char buf[8];
memcpy(buf, (char*)text+i+1, 7);
buf[7] = '\0';
drw_clr_create(drw, &drw->scheme[ColBg], buf, 230);
i += 7;
} else if (text[i] == 'd') {
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
} else if (text[i] == 'w') {
Clr swp;
swp = drw->scheme[ColFg];
drw->scheme[ColFg] = drw->scheme[ColBg];
drw->scheme[ColBg] = swp;
} else if (text[i] == 'v') {
oldfg = drw->scheme[ColFg];
oldbg = drw->scheme[ColBg];
} else if (text[i] == 't') {
drw->scheme[ColFg] = oldfg;
drw->scheme[ColBg] = oldbg;
} else if (text[i] == 'r') {
int rx = atoi(text + ++i);
while (text[++i] != ',');
int ry = atoi(text + ++i);
while (text[++i] != ',');
int rw = atoi(text + ++i);
while (text[++i] != ',');
int rh = atoi(text + ++i);
drw_rect(drw, rx + x, ry, rw, rh, 1, 0);
} else if (text[i] == 'f') {
x += atoi(text + ++i);
}
}
text = text + i + 1;
i=-1;
isCode = 0;
}
}
if (!isCode) {
w = TEXTW(text) - lrpad;
drw_text(drw, x, 0, w, bh, 0, text, 0);
}
drw_setscheme(drw, scheme[SchemeNorm]);
free(p);
return ret;
}
void void
drawbar(Monitor *m) drawbar(Monitor *m)
{ {
@ -965,34 +1057,45 @@ drawbar(Monitor *m)
return; return;
/* draw status first so it can be overdrawn by tags later */ /* draw status first so it can be overdrawn by tags later */
drw_setscheme(drw, scheme[SchemeNorm]); /* drw_setscheme(drw, scheme[SchemeNorm]); */
tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ /* tw = TEXTW(stext) - lrpad + 2; */ /* 2px right padding */
drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0); /* drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0); */
tw = m->ww - drawstatusbar(m, bh, 0, stext);
for (c = m->clients; c; c = c->next) { for (c = m->clients; c; c = c->next) {
if (ISVISIBLE(c)) if (ISVISIBLE(c))
n++; n++;
occ |= c->tags; occ |= c->tags == TAGMASK ? 0 : c->tags;
if (c->isurgent) if (c->isurgent)
urg |= c->tags; urg |= c->tags;
} }
x = 0; x = 0;
for (i = 0; i < LENGTH(tags); i++) { for (i = 0; i < LENGTH(tags); i++) {
/* Do not draw vacant tags */
if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
continue;
w = TEXTW(tags[i]); w = TEXTW(tags[i]);
drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm])); drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeNorm : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); 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, if (ulineall || m->tagset[m->seltags] & 1 << i) { /* if there are conflicts, just move these lines directly underneath both 'drw_setscheme' and 'drw_text' :) */
m == selmon && selmon->sel && selmon->sel->tags & 1 << i, if (m == selmon)
urg & 1 << i); drw_setscheme(drw, scheme[SchemeHid]);
drw_rect(drw, x + w * 0.0675, bh - ulinestroke - ulinevoffset, w * 0.875, ulinestroke, 1, 0);
} else if (occ & 1 << i) {
drw_setscheme(drw, scheme[SchemeNorm]);
if (urg)
drw_rect(drw, x + boxs, boxs, boxw, boxw, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, 1);
else
drw_rect(drw, x + w * 0.375, bh - ulinestroke - ulinevoffset, w * 0.25, ulinestroke, 1, 0);
}
x += w; x += w;
} }
w = TEXTW(m->ltsymbol); w = TEXTW(m->ltsymbol);
drw_setscheme(drw, scheme[SchemeLay]); drw_setscheme(drw, scheme[SchemeSel]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
w = TEXTW(wfsymbol); w = TEXTW(wfsymbol);
drw_setscheme(drw, scheme[SchemeWf]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, wfsymbol, 0); x = drw_text(drw, x, 0, w, bh, lrpad / 2, wfsymbol, 0);
if ((w = m->ww - tw - x) > bh) { if ((w = m->ww - tw - x) > bh) {
@ -1002,13 +1105,11 @@ drawbar(Monitor *m)
for (c = m->clients; c; c = c->next) { for (c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c)) if (!ISVISIBLE(c))
continue; continue;
if (HIDDEN(c))
if (m->sel == c && m == selmon) scm = SchemeHid;
drw_setscheme(drw, scheme[SchemeSel]);
else if (HIDDEN(c))
drw_setscheme(drw, scheme[SchemeHid]);
else else
drw_setscheme(drw, scheme[SchemeNorm]); scm = SchemeNorm;
drw_setscheme(drw, scheme[scm]);
if (remainder >= 0) { if (remainder >= 0) {
if (remainder == 0) { if (remainder == 0) {
@ -1016,19 +1117,20 @@ drawbar(Monitor *m)
} }
remainder--; remainder--;
} }
mid = (tabw - (int)TEXTW(c->name)) / 2;
mid = mid >= lrpad / 2 ? mid : lrpad / 2;
drw_text(drw, x, 0, tabw - 2 * sp, bh, mid, c->name, 0);
char name[512]; if (!HIDDEN(c)) {
if (m->sel == c) {
if (m == selmon)
drw_setscheme(drw, scheme[SchemeHid]);
drw_rect(drw, x + tabw * 0.0675, bh - ulinestroke - ulinevoffset, tabw * 0.875 - ulinepad * 2, ulinestroke, 1, 0);
} else {
drw_rect(drw, x + tabw * 0.375, bh - ulinestroke - ulinevoffset, tabw * 0.25 - ulinepad * 2, ulinestroke, 1, 0);
}
}
if (c->isalwaysontop && c->isfloating)
snprintf(name, sizeof name, "%s %s", topicon, c->name);
else
snprintf(name, sizeof name, c->name);
mid = ((tabw - (int)TEXTW(name)) / 2) + lrpad / 2;
if ( tabw < (int)TEXTW(name) + lrpad )
mid = lrpad / 2;
drw_text(drw, x, 0, tabw, bh, mid, name, 0);
x += tabw; x += tabw;
} }
} else { } else {
@ -1043,8 +1145,9 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
/* clear default bar draw buffer by drawing a blank rectangle */ /* clear default bar draw buffer by drawing a blank rectangle */
drw_rect(drw, 0, 0, m->ww, bh, 1, 1); drw_rect(drw, 0, 0, m->ww, bh, 1, 1);
w = TEXTW(estext) - lrpad + 2; /* 2px right padding */ /* w = TEXTW(estext) - lrpad + 2; */ /* 2px right padding */
drw_text(drw, m->ww - w - 2 * sp, 0, w, bh, 0, estext, 0); /* drw_text(drw, m->ww - w - 2 * sp, 0, w, bh, 0, estext, 0); */
w = drawstatusbar(m, bh, 1, estext);
x = 0; x = 0;
for (i = 0; i < LENGTH(launchers); i++) for (i = 0; i < LENGTH(launchers); i++)
@ -1421,24 +1524,6 @@ 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 void
manage(Window w, XWindowAttributes *wa) manage(Window w, XWindowAttributes *wa)
{ {
@ -1519,7 +1604,7 @@ manage(Window w, XWindowAttributes *wa)
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
if (!HIDDEN(c)) if (!HIDDEN(c))
setclientstate(c, NormalState); setclientstate(c, NormalState);
if (selmon->sel && selmon->sel->isfullscreen && !selmon->sel->isfakefullscreen) if (selmon->sel && selmon->sel->isfullscreen)
setfullscreen(selmon->sel, 0); setfullscreen(selmon->sel, 0);
if (c->mon == selmon) if (c->mon == selmon)
unfocus(selmon->sel, 0); unfocus(selmon->sel, 0);
@ -1600,8 +1685,7 @@ movemouse(const Arg *arg)
if (!(c = selmon->sel)) if (!(c = selmon->sel))
return; return;
if (c->isfullscreen if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
&& !c->isfakefullscreen) /* no support moving fullscreen windows by mouse */
return; return;
restack(selmon); restack(selmon);
ocx = c->x; ocx = c->x;
@ -1699,158 +1783,6 @@ 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 * Client *
nexttiled(Client *c) nexttiled(Client *c)
{ {
@ -1861,8 +1793,6 @@ nexttiled(Client *c)
void void
movestack(const Arg *arg) { movestack(const Arg *arg) {
Client *c = NULL, *p = NULL, *pc = NULL, *i; Client *c = NULL, *p = NULL, *pc = NULL, *i;
if (!selmon->sel)
return;
if(arg->i > 0) { if(arg->i > 0) {
/* find the client after selmon->sel */ /* find the client after selmon->sel */
@ -2091,8 +2021,7 @@ resizemouse(const Arg *arg)
if (!(c = selmon->sel)) if (!(c = selmon->sel))
return; return;
if (c->isfullscreen if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
&& !c->isfakefullscreen) /* no support resizing fullscreen windows by mouse */
return; return;
restack(selmon); restack(selmon);
ocx = c->x; ocx = c->x;
@ -2192,16 +2121,6 @@ restack(Monitor *m)
return; return;
if (m->sel->isfloating || !m->lt[m->sellt]->arrange) if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
XRaiseWindow(dpy, m->sel->win); 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) { if (m->lt[m->sellt]->arrange) {
wc.stack_mode = Below; wc.stack_mode = Below;
wc.sibling = m->barwin; wc.sibling = m->barwin;
@ -2318,48 +2237,13 @@ setfocus(Client *c)
sendevent(c, wmatom[WMTakeFocus]); sendevent(c, wmatom[WMTakeFocus]);
} }
void
setfakefullscreen(Client *c, int fakefullscreen)
{
if (fakefullscreen && !c->isfakefullscreen) {
c->isfakefullscreen = 1;
if (c->isfullscreen) {
c->isfloating = c->oldstate;
c->bw = c->oldbw;
c->x = c->oldx;
c->y = c->oldy;
c->w = c->oldw;
c->h = c->oldh;
resizeclient(c, c->x, c->y, c->w, c->h);
arrange(c->mon);
}
} else if (!fakefullscreen && c->isfakefullscreen){
c->isfakefullscreen = 0;
if (c->isfullscreen) {
c->oldstate = c->isfloating;
c->oldbw = c->bw;
c->bw = 0;
c->isfloating = 1;
resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
XRaiseWindow(dpy, c->win);
}
}
}
void void
setfullscreen(Client *c, int fullscreen) setfullscreen(Client *c, int fullscreen)
{ {
if (fullscreen && !c->isfullscreen) { if (fullscreen && !c->isfullscreen) {
// make non fs win a fs win
XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
c->isfullscreen = 1; c->isfullscreen = 1;
if (c->isfakefullscreen) {
resizeclient(c, c->x, c->y, c->w, c->h);
return;
}
c->oldstate = c->isfloating; c->oldstate = c->isfloating;
c->oldbw = c->bw; c->oldbw = c->bw;
c->bw = 0; c->bw = 0;
@ -2367,14 +2251,9 @@ setfullscreen(Client *c, int fullscreen)
resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
XRaiseWindow(dpy, c->win); XRaiseWindow(dpy, c->win);
} else if (!fullscreen && c->isfullscreen){ } else if (!fullscreen && c->isfullscreen){
// make a fs win a non fs win
XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
PropModeReplace, (unsigned char*)0, 0); PropModeReplace, (unsigned char*)0, 0);
c->isfullscreen = 0; c->isfullscreen = 0;
if (c->isfakefullscreen) {
resizeclient(c, c->x, c->y, c->w, c->h);
return;
}
c->isfloating = c->oldstate; c->isfloating = c->oldstate;
c->bw = c->oldbw; c->bw = c->oldbw;
c->x = c->oldx; c->x = c->oldx;
@ -2511,14 +2390,10 @@ setup(void)
cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurResize] = drw_cur_create(drw, XC_sizing);
cursor[CurMove] = drw_cur_create(drw, XC_fleur); cursor[CurMove] = drw_cur_create(drw, XC_fleur);
/* init appearance */ /* init appearance */
if (LENGTH(tags) > LENGTH(tagsel)) scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
die("too few color schemes for the tags"); scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], alphas[0], 3);
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
for (i = 0; i < LENGTH(colors); i++) for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3); scheme[i] = drw_scm_create(drw, colors[i], alphas[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 */ /* init bars */
updatebars(); updatebars();
updatestatus(); updatestatus();
@ -2602,14 +2477,12 @@ showhide(Client *c)
return; return;
if (ISVISIBLE(c)) { if (ISVISIBLE(c)) {
/* show clients top down */ /* show clients top down */
XMoveWindow(dpy, c->win, c->x, c->y); window_map(dpy, c, 1);
if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
resize(c, c->x, c->y, c->w, c->h, 0);
showhide(c->snext); showhide(c->snext);
} else { } else {
/* hide clients bottom up */ /* hide clients bottom up */
showhide(c->snext); showhide(c->snext);
XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); window_unmap(dpy, c->win, root, 1);
} }
} }
@ -2752,10 +2625,8 @@ togglefloating(const Arg *arg)
{ {
if (!selmon->sel) if (!selmon->sel)
return; return;
if (selmon->sel->isfullscreen if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
&& !selmon->sel->isfakefullscreen) /* no support for fullscreen windows */
return; return;
selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
if (selmon->sel->isfloating) if (selmon->sel->isfloating)
/* restore last known float dimensions */ /* restore last known float dimensions */
@ -2775,26 +2646,6 @@ togglefloating(const Arg *arg)
arrange(selmon); arrange(selmon);
} }
void
togglealwaysontop(const Arg *arg)
{
Client *c;
if (!selmon->sel)
return;
if (selmon->sel->isfullscreen)
return;
selmon->sel->isalwaysontop = !selmon->sel->isalwaysontop;
arrange(selmon);
}
void
togglefakefullscr(const Arg *arg)
{
if (selmon->sel)
setfakefullscreen(selmon->sel, !selmon->sel->isfakefullscreen);
}
void void
togglefullscr(const Arg *arg) togglefullscr(const Arg *arg)
{ {
@ -2802,7 +2653,6 @@ togglefullscr(const Arg *arg)
setfullscreen(selmon->sel, !selmon->sel->isfullscreen); setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
} }
void void
toggletag(const Arg *arg) toggletag(const Arg *arg)
{ {
@ -2869,7 +2719,7 @@ togglewin(const Arg *arg)
showwin(c); showwin(c);
focus(c); focus(c);
restack(selmon); restack(selmon);
/* XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); */ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
} }
} }
@ -3210,6 +3060,51 @@ updatewmhints(Client *c)
} }
} }
void
window_set_state(Display *dpy, Window win, long state)
{
long data[] = { state, None };
XChangeProperty(dpy, win, wmatom[WMState], wmatom[WMState], 32,
PropModeReplace, (unsigned char*)data, 2);
}
void
window_map(Display *dpy, Client *c, int deiconify)
{
Window win = c->win;
if (deiconify)
window_set_state(dpy, win, NormalState);
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
XMapWindow(dpy, win);
}
void
window_unmap(Display *dpy, Window win, Window root, int iconify)
{
static XWindowAttributes ca, ra;
XGrabServer(dpy);
XGetWindowAttributes(dpy, root, &ra);
XGetWindowAttributes(dpy, win, &ca);
/* Prevent UnmapNotify events */
XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
XSelectInput(dpy, win, ca.your_event_mask & ~StructureNotifyMask);
XUnmapWindow(dpy, win);
if (iconify)
window_set_state(dpy, win, IconicState);
XSelectInput(dpy, root, ra.your_event_mask);
XSelectInput(dpy, win, ca.your_event_mask);
XUngrabServer(dpy);
}
void void
view(const Arg *arg) view(const Arg *arg)
{ {

View File

@ -0,0 +1,48 @@
:100644 100644 f1d86b2 0000000 M dwm.c
diff --git a/dwm.c b/dwm.c
index f1d86b2..d41cc14 100644
--- a/dwm.c
+++ b/dwm.c
@@ -433,9 +433,15 @@ buttonpress(XEvent *e)
}
if (ev->window == selmon->barwin) {
i = x = 0;
- do
+ unsigned int occ = 0;
+ for(c = m->clients; c; c=c->next)
+ occ |= c->tags == TAGMASK ? 0 : c->tags;
+ do {
+ /* Do not reserve space for vacant tags */
+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
+ continue;
x += TEXTW(tags[i]);
- while (ev->x >= x && ++i < LENGTH(tags));
+ } while (ev->x >= x && ++i < LENGTH(tags));
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
@@ -715,19 +721,18 @@ drawbar(Monitor *m)
}
for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
+ occ |= c->tags == TAGMASK ? 0 : c->tags;
if (c->isurgent)
urg |= c->tags;
}
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
+ /* Do not draw vacant tags */
+ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
+ continue;
w = TEXTW(tags[i]);
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : 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,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
x += w;
}
w = TEXTW(m->ltsymbol);

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

@ -0,0 +1,27 @@
diff -pu dwm.git/config.def.h dwm.underlinetags/config.def.h
--- dwm.git/config.def.h 2021-02-27 20:04:32.030570909 -0600
+++ dwm.underlinetags/config.def.h 2021-03-16 16:42:26.278703624 -0500
@@ -21,6 +21,11 @@ static const char *colors[][3] = {
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+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 Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
diff -pu dwm.git/dwm.c dwm.underlinetags/dwm.c
--- dwm.git/dwm.c 2021-02-27 20:04:32.030570909 -0600
+++ dwm.underlinetags/dwm.c 2021-03-16 16:41:21.468077151 -0500
@@ -719,6 +719,8 @@ drawbar(Monitor *m)
w = TEXTW(tags[i]);
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+ if (ulineall || m->tagset[m->seltags] & 1 << i) /* if there are conflicts, just move these lines directly underneath both 'drw_setscheme' and 'drw_text' :) */
+ drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0);
if (occ & 1 << i)
drw_rect(drw, x + boxs, boxs, boxw, boxw,
m == selmon && selmon->sel && selmon->sel->tags & 1 << i,

View File

@ -0,0 +1,83 @@
diff --git a/dwm.c b/dwm.c
index e5efb6a..eaf0333 100644
--- a/dwm.c
+++ b/dwm.c
@@ -228,6 +228,9 @@ static void updatetitle(Client *c);
static void updatewindowtype(Client *c);
static void updatewmhints(Client *c);
static void view(const Arg *arg);
+static void window_set_state(Display *dpy, Window win, long state);
+static void window_map(Display *dpy, Client *c, int deiconify);
+static void window_unmap(Display *dpy, Window win, Window root, int iconify);
static Client *wintoclient(Window w);
static Monitor *wintomon(Window w);
static int xerror(Display *dpy, XErrorEvent *ee);
@@ -1617,14 +1620,12 @@ showhide(Client *c)
return;
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)
- resize(c, c->x, c->y, c->w, c->h, 0);
+ window_map(dpy, c, 1);
showhide(c->snext);
} else {
/* hide clients bottom up */
showhide(c->snext);
- XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
+ window_unmap(dpy, c->win, root, 1);
}
}
@@ -2032,6 +2033,51 @@ updatewmhints(Client *c)
}
}
+void
+window_set_state(Display *dpy, Window win, long state)
+{
+ long data[] = { state, None };
+
+ XChangeProperty(dpy, win, wmatom[WMState], wmatom[WMState], 32,
+ PropModeReplace, (unsigned char*)data, 2);
+}
+
+void
+window_map(Display *dpy, Client *c, int deiconify)
+{
+ Window win = c->win;
+
+ if (deiconify)
+ window_set_state(dpy, win, NormalState);
+
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
+ XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
+ XMapWindow(dpy, win);
+}
+
+void
+window_unmap(Display *dpy, Window win, Window root, int iconify)
+{
+ static XWindowAttributes ca, ra;
+
+ XGrabServer(dpy);
+ XGetWindowAttributes(dpy, root, &ra);
+ XGetWindowAttributes(dpy, win, &ca);
+
+ /* Prevent UnmapNotify events */
+ XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
+ XSelectInput(dpy, win, ca.your_event_mask & ~StructureNotifyMask);
+
+ XUnmapWindow(dpy, win);
+
+ if (iconify)
+ window_set_state(dpy, win, IconicState);
+
+ XSelectInput(dpy, root, ra.your_event_mask);
+ XSelectInput(dpy, win, ca.your_event_mask);
+ XUngrabServer(dpy);
+}
+
void
view(const Arg *arg)
{

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,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,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,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

@ -0,0 +1,166 @@
diff --git a/dwm.c b/dwm.c
index a96f33c..24b1eeb 100644
--- a/dwm.c
+++ b/dwm.c
@@ -163,6 +163,7 @@ static void detachstack(Client *c);
static Monitor *dirtomon(int dir);
static void drawbar(Monitor *m);
static void drawbars(void);
+static int drawstatusbar(Monitor *m, int bh, char* text);
static void enternotify(XEvent *e);
static void expose(XEvent *e);
static void focus(Client *c);
@@ -237,7 +238,7 @@ static void zoom(const Arg *arg);
/* variables */
static const char broken[] = "broken";
-static char stext[256];
+static char stext[1024];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -485,7 +486,7 @@ cleanup(void)
cleanupmon(mons);
for (i = 0; i < CurLast; i++)
drw_cur_free(drw, cursor[i]);
- for (i = 0; i < LENGTH(colors); i++)
+ for (i = 0; i < LENGTH(colors) + 1; i++)
free(scheme[i]);
XDestroyWindow(dpy, wmcheckwin);
drw_free(drw);
@@ -693,6 +694,114 @@ dirtomon(int dir)
return m;
}
+int
+drawstatusbar(Monitor *m, int bh, char* stext) {
+ int ret, i, w, x, len;
+ short isCode = 0;
+ char *text;
+ char *p;
+
+ len = strlen(stext) + 1 ;
+ if (!(text = (char*) malloc(sizeof(char)*len)))
+ die("malloc");
+ p = text;
+ memcpy(text, stext, len);
+
+ /* compute width of the status text */
+ w = 0;
+ i = -1;
+ while (text[++i]) {
+ if (text[i] == '^') {
+ if (!isCode) {
+ isCode = 1;
+ text[i] = '\0';
+ w += TEXTW(text) - lrpad;
+ text[i] = '^';
+ if (text[++i] == 'f')
+ w += atoi(text + ++i);
+ } else {
+ isCode = 0;
+ text = text + i + 1;
+ i = -1;
+ }
+ }
+ }
+ if (!isCode)
+ w += TEXTW(text) - lrpad;
+ else
+ isCode = 0;
+ text = p;
+
+ w += 2; /* 1px padding on both sides */
+ ret = x = m->ww - w;
+
+ drw_setscheme(drw, scheme[LENGTH(colors)]);
+ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
+ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
+ drw_rect(drw, x, 0, w, bh, 1, 1);
+ x++;
+
+ /* process status text */
+ i = -1;
+ while (text[++i]) {
+ if (text[i] == '^' && !isCode) {
+ isCode = 1;
+
+ text[i] = '\0';
+ w = TEXTW(text) - lrpad;
+ drw_text(drw, x, 0, w, bh, 0, text, 0);
+
+ x += w;
+
+ /* process code */
+ while (text[++i] != '^') {
+ if (text[i] == 'c') {
+ char buf[8];
+ memcpy(buf, (char*)text+i+1, 7);
+ buf[7] = '\0';
+ drw_clr_create(drw, &drw->scheme[ColFg], buf);
+ i += 7;
+ } else if (text[i] == 'b') {
+ char buf[8];
+ memcpy(buf, (char*)text+i+1, 7);
+ buf[7] = '\0';
+ drw_clr_create(drw, &drw->scheme[ColBg], buf);
+ i += 7;
+ } else if (text[i] == 'd') {
+ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
+ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
+ } else if (text[i] == 'r') {
+ int rx = atoi(text + ++i);
+ while (text[++i] != ',');
+ int ry = atoi(text + ++i);
+ while (text[++i] != ',');
+ int rw = atoi(text + ++i);
+ while (text[++i] != ',');
+ int rh = atoi(text + ++i);
+
+ drw_rect(drw, rx + x, ry, rw, rh, 1, 0);
+ } else if (text[i] == 'f') {
+ x += atoi(text + ++i);
+ }
+ }
+
+ text = text + i + 1;
+ i=-1;
+ isCode = 0;
+ }
+ }
+
+ if (!isCode) {
+ w = TEXTW(text) - lrpad;
+ drw_text(drw, x, 0, w, bh, 0, text, 0);
+ }
+
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ free(p);
+
+ return ret;
+}
+
void
drawbar(Monitor *m)
{
@@ -707,9 +816,7 @@ drawbar(Monitor *m)
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ tw = m->ww - drawstatusbar(m, bh, stext);
}
for (c = m->clients; c; c = c->next) {
@@ -1571,7 +1678,8 @@ setup(void)
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
/* init appearance */
- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
+ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
+ scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3);
for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], 3);
/* init bars */

View File

@ -0,0 +1,44 @@
From dfd158c8dea87a0a4dbc5b2eda7c096069d1484a Mon Sep 17 00:00:00 2001
From: tdu <tdukv@protonmail.com>
Date: Wed, 26 Aug 2020 18:50:09 +0300
Subject: [PATCH] Add the following tags for the status2d patch: ^w^ -
Swaps bg/fg color. ^v^ - Saves the current fg/bg color. ^t^ - Restores
the previously saved bg/fg color.
---
dwm.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/dwm.c b/dwm.c
index 931044f..de07b66 100644
--- a/dwm.c
+++ b/dwm.c
@@ -699,6 +699,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) {
short isCode = 0;
char *text;
char *p;
+ Clr oldbg, oldfg;
len = strlen(stext) + 1 ;
if (!(text = (char*) malloc(sizeof(char)*len)))
@@ -769,6 +770,17 @@ drawstatusbar(Monitor *m, int bh, char* stext) {
} else if (text[i] == 'd') {
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
+ } else if (text[i] == 'w') {
+ Clr swp;
+ swp = drw->scheme[ColFg];
+ drw->scheme[ColFg] = drw->scheme[ColBg];
+ drw->scheme[ColBg] = swp;
+ } else if (text[i] == 'v') {
+ oldfg = drw->scheme[ColFg];
+ oldbg = drw->scheme[ColBg];
+ } else if (text[i] == 't') {
+ drw->scheme[ColFg] = oldfg;
+ drw->scheme[ColBg] = oldbg;
} else if (text[i] == 'r') {
int rx = atoi(text + ++i);
while (text[++i] != ',');
--
2.28.0

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