diff options
| author | ozpv <39195175+ozpv@users.noreply.github.com> | 2022-05-15 17:44:14 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-15 17:44:14 -0500 |
| commit | ab944fffbc9882fb2f3b4b4fa6532448a2886e87 (patch) | |
| tree | 78b174af05c2e929b6d379049adc43055c18aba0 | |
| parent | 2c7a9cd77ef4ecd8750e4d970187bd2baa92c48b (diff) | |
update dwm
| -rw-r--r-- | config.h | 110 | ||||
| -rw-r--r-- | config.mk | 5 | ||||
| -rw-r--r-- | drw.c | 91 | ||||
| -rw-r--r-- | drw.h | 1 | ||||
| -rw-r--r-- | dwm.1 | 15 | ||||
| -rw-r--r-- | dwm.c | 364 |
6 files changed, 240 insertions, 346 deletions
@@ -2,15 +2,11 @@ /* appearance */ static const unsigned int borderpx = 2; /* border pixel of windows */ -static const unsigned int gappx = 12; /* gaps between windows */ +static const unsigned int gappx = 12; /* gaps between windows */ static const unsigned int snap = 32; /* snap pixel */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ -static const int user_bh = 22; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ -static const int usealtbar = 0; /* 1 means use non-dwm status bar */ -static const char *altbarclass = "Polybar";/* Alternate bar class name */ -static const char *alttrayname = "tray"; /* Polybar tray instance name */ -static const char *altbarcmd = ""; /* Alternate bar launch command */ +static const int user_bh = 22; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ static const char *fonts[] = { "FiraCode Nerd Font Mono:style=Regular:size=10" }; static const char dmenufont[] = "FiraCode Nerd Font Mono:style=Regular:size=10"; static const char col_gray1[] = "#282828"; @@ -41,6 +37,7 @@ static const Rule rules[] = { static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ static const Layout layouts[] = { /* symbol arrange function */ @@ -63,8 +60,8 @@ static const Layout layouts[] = { /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; -static const char *dmenunmcmd[] = { "networkmanager_dmenu", NULL }; static const char *termcmd[] = { "st", NULL }; +static const char *dmenunmcmd[] = { "networkmanager_dmenu", NULL }; static const char *browsercmd[] = { "firefox", NULL }; static const char *volup[] = { "pactl", "set-sink-volume", "0", "+10%", NULL }; static const char *voldown[] = { "pactl", "set-sink-volume", "0", "-10%", NULL }; @@ -72,69 +69,56 @@ static const char *volmax[] = { "pactl", "set-sink-volume", "0", "100%", NULL }; static const char *volmute[] = { "pactl", "set-sink-volume", "0", "0%", NULL }; static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_space, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_space, spawn, {.v = dmenunmcmd } }, - { MODKEY, XK_a, spawn, {.v = termcmd } }, - { MODKEY, XK_f, spawn, {.v = browsercmd } }, - { MODKEY, XK_j, spawn, {.v = volup } }, - { MODKEY, XK_k, spawn, {.v = voldown } }, - { MODKEY, XK_l, spawn, {.v = volmax } }, - { MODKEY|ShiftMask, XK_l, spawn, {.v = volmute } }, + /* modifier key function argument */ + { MODKEY, XK_space, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_space, spawn, {.v = dmenunmcmd } }, + { MODKEY, XK_a, spawn, {.v = termcmd } }, + { MODKEY, XK_f, spawn, {.v = browsercmd } }, + { MODKEY, XK_j, spawn, {.v = volup } }, + { MODKEY, XK_k, spawn, {.v = voldown } }, + { MODKEY, XK_l, spawn, {.v = volmax } }, + { MODKEY|ShiftMask, XK_l, spawn, {.v = volmute } }, - { MODKEY, XK_b, togglebar, {0} }, - //{ MODKEY, XK_j, focusstack, {.i = +1 } }, - //{ MODKEY, XK_k, focusstack, {.i = -1 } }, - //{ MODKEY, XK_i, incnmaster, {.i = +1 } }, - //{ MODKEY, XK_d, incnmaster, {.i = -1 } }, - //{ MODKEY, XK_h, setmfact, {.f = -0.05} }, - //{ MODKEY, XK_l, setmfact, {.f = +0.05} }, - //{ MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY, XK_w, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - //{ MODKEY, XK_o, setlayout, {.v = &layouts[1]} }, - //{ MODKEY|ShiftMask, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_m, fullscreen, {0} }, - //{ MODKEY, XK_p, setlayout, {0} }, - { MODKEY|ShiftMask, XK_f, togglefloating, {0} }, - //{ MODKEY, XK_0, view, {.ui = ~0 } }, - //{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY, XK_w, killclient, {0} }, + { MODKEY|ShiftMask, XK_m, togglefullscr, {0} }, + { MODKEY|ShiftMask, XK_f, togglefloating, {0} }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - { MODKEY, XK_minus, setgaps, {.i = -1 } }, - { MODKEY, XK_equal, setgaps, {.i = +1 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, + { MODKEY, XK_minus, setgaps, {.i = -1 } }, + { MODKEY, XK_equal, setgaps, {.i = +1 } }, + { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, + { MODKEY|ShiftMask, XK_q, quit, {0} }, }; /* button definitions */ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; @@ -1,5 +1,5 @@ # dwm version -VERSION = 6.2 +VERSION = 6.3 # Customize below to fit your system @@ -19,13 +19,14 @@ FREETYPELIBS = -lfontconfig -lXft FREETYPEINC = /usr/include/freetype2 # OpenBSD (uncomment) #FREETYPEINC = ${X11INC}/freetype2 +#MANPREFIX = ${PREFIX}/man # includes and libs INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} LDFLAGS = ${LIBS} @@ -95,6 +95,7 @@ drw_free(Drw *drw) { XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); free(drw); } @@ -202,8 +203,6 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname) DefaultColormap(drw->dpy, drw->screen), clrname, dest)) die("error, cannot allocate color '%s'", clrname); - - dest->pixel |= 0xff << 24; } /* Wrapper to create color schemes. The caller has to call free(3) on the @@ -252,12 +251,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) { - char buf[1024]; - int ty; - unsigned int ew; + int i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; XftDraw *d = NULL; Fnt *usedfont, *curfont, *nextfont; - size_t i, len; int utf8strlen, utf8charlen, render = x || y || w || h; long utf8codepoint = 0; const char *utf8str; @@ -265,13 +262,17 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp FcPattern *fcpattern; FcPattern *match; XftResult result; - int charexists = 0; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) return 0; if (!render) { - w = ~w; + w = invert ? invert : ~invert; } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); @@ -283,8 +284,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); while (1) { - utf8strlen = 0; + ew = ellipsis_len = utf8strlen = 0; utf8str = text; nextfont = NULL; while (*text) { @@ -292,9 +295,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp for (curfont = drw->fonts; curfont; curfont = curfont->next) { charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); if (charexists) { - if (curfont == usedfont) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { utf8strlen += utf8charlen; text += utf8charlen; + ew += tmpw; } else { nextfont = curfont; } @@ -302,36 +323,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } } - if (!charexists || nextfont) + if (overflow || !charexists || nextfont) break; else charexists = 0; } if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - - if (len) { - memcpy(buf, utf8str, len); - buf[len] = '\0'; - if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)buf, len); - } - x += ew; - w -= ew; + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); } + x += ew; + w -= ew; } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); - if (!*text) { + if (!*text || overflow) { break; } else if (nextfont) { charexists = 0; @@ -341,6 +351,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp * character must be drawn. */ charexists = 1; + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + goto no_match; + } + fccharset = FcCharSetCreate(); FcCharSetAddChar(fccharset, utf8codepoint); @@ -369,6 +385,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp curfont->next = usedfont; } else { xfont_free(usedfont); + nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; +no_match: usedfont = drw->fonts; } } @@ -398,6 +416,15 @@ drw_fontset_getwidth(Drw *drw, const char *text) return drw_text(drw, 0, 0, 0, 0, 0, text, 0); } +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { @@ -35,6 +35,7 @@ void drw_free(Drw *drw); Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); void drw_fontset_free(Fnt* set); unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); /* Colorscheme abstraction */ @@ -33,7 +33,7 @@ dwm draws a small border around windows to indicate the focus state. .SH OPTIONS .TP .B \-v -prints version information to standard output, then exits. +prints version information to stderr, then exits. .SH USAGE .SS Status bar .TP @@ -116,6 +116,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only). .B Mod1\-Shift\-c Close focused window. .TP +.B Mod1\-Shift\-f +Toggle fullscreen for focused window. +.TP .B Mod1\-Shift\-space Toggle focused window between tiled and floating state. .TP @@ -140,16 +143,6 @@ View all windows with any tag. .B Mod1\-Control\-[1..n] Add/remove all windows with nth tag to/from the view. .TP -.B Mod1\-- -Decrease the gaps around windows. -.TP -.B Mod1\-= -Increase the gaps around windows. -.TP -.B Mod1\-Shift-= -Reset the gaps around windows to -.BR 0 . -.TP .B Mod1\-Shift\-q Quit dwm. .SS Mouse commands @@ -47,8 +47,8 @@ /* macros */ #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) -#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \ - * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my))) +#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) #define MOUSEMASK (BUTTONMASK|PointerMotionMask) @@ -89,7 +89,7 @@ struct Client { float mina, maxa; int x, y, w, h; int oldx, oldy, oldw, oldh; - int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; int bw, oldbw; unsigned int tags; int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; @@ -116,8 +116,7 @@ struct Monitor { float mfact; int nmaster; int num; - int by, bh; /* bar geometry */ - int tx, tw; /* bar tray geometry */ + int by; /* bar geometry */ int mx, my, mw, mh; /* screen size */ int wx, wy, ww, wh; /* window area */ int gappx; /* gaps between windows */ @@ -131,7 +130,6 @@ struct Monitor { Client *stack; Monitor *next; Window barwin; - Window traywin; const Layout *lt[2]; }; @@ -171,16 +169,17 @@ static void expose(XEvent *e); static void focus(Client *c); static void focusin(XEvent *e); static void focusmon(const Arg *arg); +static void focusstack(const Arg *arg); +static Atom getatomprop(Client *c, Atom prop); static int getrootptr(int *x, int *y); static long getstate(Window w); static int gettextprop(Window w, Atom atom, char *text, unsigned int size); static void grabbuttons(Client *c, int focused); static void grabkeys(void); +static void incnmaster(const Arg *arg); static void keypress(XEvent *e); static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); -static void managealtbar(Window win, XWindowAttributes *wa); -static void managetray(Window win, XWindowAttributes *wa); static void mappingnotify(XEvent *e); static void maprequest(XEvent *e); static void monocle(Monitor *m); @@ -197,32 +196,29 @@ static void resizemouse(const Arg *arg); static void restack(Monitor *m); static void run(void); static void scan(void); -static void scantray(void); static int sendevent(Client *c, Atom proto); static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); -static void fullscreen(const Arg *arg); static void setgaps(const Arg *arg); static void setlayout(const Arg *arg); +static void setmfact(const Arg *arg); static void setup(void); static void seturgent(Client *c, int urg); static void showhide(Client *c); static void sigchld(int unused); static void spawn(const Arg *arg); -static void spawnbar(); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *); static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); +static void togglefullscr(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); static void unfocus(Client *c, int setfocus); static void unmanage(Client *c, int destroyed); -static void unmanagealtbar(Window w); -static void unmanagetray(Window w); static void unmapnotify(XEvent *e); static void updatebarpos(Monitor *m); static void updatebars(void); @@ -237,7 +233,6 @@ static void updatewmhints(Client *c); static void view(const Arg *arg); static Client *wintoclient(Window w); static Monitor *wintomon(Window w); -static int wmclasscontains(Window win, const char *class, const char *name); static int xerror(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); @@ -353,6 +348,8 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) if (*w < bh) *w = bh; if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { + if (!c->hintsvalid) + updatesizehints(c); /* see last two sentences in ICCCM 4.1.2.3 */ baseismin = c->basew == c->minw && c->baseh == c->minh; if (!baseismin) { /* temporarily remove base dimensions */ @@ -448,7 +445,7 @@ buttonpress(XEvent *e) arg.ui = 1 << i; } else if (ev->x < x + blw) click = ClkLtSymbol; - else if (ev->x > selmon->ww - TEXTW(stext)) + else if (ev->x > selmon->ww - (int)TEXTW(stext)) click = ClkStatusText; else click = ClkWinTitle; @@ -495,6 +492,7 @@ cleanup(void) drw_cur_free(drw, cursor[i]); for (i = 0; i < LENGTH(colors); i++) free(scheme[i]); + free(scheme); XDestroyWindow(dpy, wmcheckwin); drw_free(drw); XSync(dpy, False); @@ -513,10 +511,8 @@ cleanupmon(Monitor *mon) for (m = mons; m && m->next != mon; m = m->next); m->next = mon->next; } - if (!usealtbar) { - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - } + XUnmapWindow(dpy, mon->barwin); + XDestroyWindow(dpy, mon->barwin); free(mon); } @@ -578,7 +574,7 @@ configurenotify(XEvent *e) for (c = m->clients; c; c = c->next) if (c->isfullscreen) resizeclient(c, m->mx, m->my, m->mw, m->mh); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); } focus(NULL); arrange(NULL); @@ -648,9 +644,8 @@ createmon(void) m->mfact = mfact; m->nmaster = nmaster; m->showbar = showbar; - m->gappx = gappx; m->topbar = topbar; - m->bh = bh; + m->gappx = gappx; m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); @@ -661,15 +656,10 @@ void destroynotify(XEvent *e) { Client *c; - Monitor *m; XDestroyWindowEvent *ev = &e->xdestroywindow; if ((c = wintoclient(ev->window))) unmanage(c, 1); - else if ((m = wintomon(ev->window)) && m->barwin == ev->window) - unmanagealtbar(ev->window); - else if (m->traywin == ev->window) - unmanagetray(ev->window); } void @@ -713,20 +703,20 @@ dirtomon(int dir) void drawbar(Monitor *m) { - if (usealtbar) - return; - - int x, w, sw = 0; + int x, w, tw = 0; int boxs = drw->fonts->h / 9; int boxw = drw->fonts->h / 6 + 2; unsigned int i, occ = 0, urg = 0; Client *c; + if (!m->showbar) + return; + /* 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]); - sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); + tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ + drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); } for (c = m->clients; c; c = c->next) { @@ -749,7 +739,7 @@ drawbar(Monitor *m) drw_setscheme(drw, scheme[SchemeNorm]); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - if ((w = m->ww - sw - x) > bh) { + if ((w = m->ww - tw - x) > bh) { if (m->sel) { drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); @@ -850,6 +840,32 @@ focusmon(const Arg *arg) focus(NULL); } +void +focusstack(const Arg *arg) +{ + Client *c = NULL, *i; + + if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) + return; + if (arg->i > 0) { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); + if (!c) + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); + } else { + for (i = selmon->clients; i != selmon->sel; i = i->next) + if (ISVISIBLE(i)) + c = i; + if (!c) + for (; i; i = i->next) + if (ISVISIBLE(i)) + c = i; + } + if (c) { + focus(c); + restack(selmon); + } +} + Atom getatomprop(Client *c, Atom prop) { @@ -958,6 +974,13 @@ grabkeys(void) } } +void +incnmaster(const Arg *arg) +{ + selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); +} + #ifdef XINERAMA static int isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) @@ -1067,45 +1090,6 @@ manage(Window w, XWindowAttributes *wa) } void -managealtbar(Window win, XWindowAttributes *wa) -{ - Monitor *m; - if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height))) - return; - - m->barwin = win; - m->by = wa->y; - bh = m->bh = wa->height; - updatebarpos(m); - arrange(m); - XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height); - XMapWindow(dpy, win); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &win, 1); -} - -void -managetray(Window win, XWindowAttributes *wa) -{ - Monitor *m; - if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height))) - return; - - m->traywin = win; - m->tx = wa->x; - m->tw = wa->width; - updatebarpos(m); - arrange(m); - XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height); - XMapWindow(dpy, win); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &win, 1); -} - - -void mappingnotify(XEvent *e) { XMappingEvent *ev = &e->xmapping; @@ -1125,9 +1109,7 @@ maprequest(XEvent *e) return; if (wa.override_redirect) return; - if (wmclasscontains(ev->window, altbarclass, "")) - managealtbar(ev->window, &wa); - else if (!wintoclient(ev->window)) + if (!wintoclient(ev->window)) manage(ev->window, &wa); } @@ -1259,7 +1241,7 @@ propertynotify(XEvent *e) arrange(c->mon); break; case XA_WM_NORMAL_HINTS: - updatesizehints(c); + c->hintsvalid = 0; break; case XA_WM_HINTS: updatewmhints(c); @@ -1423,9 +1405,7 @@ scan(void) if (!XGetWindowAttributes(dpy, wins[i], &wa) || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) continue; - if (wmclasscontains(wins[i], altbarclass, "")) - managealtbar(wins[i], &wa); - else if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) manage(wins[i], &wa); } for (i = 0; i < num; i++) { /* now the transients */ @@ -1441,29 +1421,6 @@ scan(void) } void -scantray(void) -{ - unsigned int num; - Window d1, d2, *wins = NULL; - XWindowAttributes wa; - - if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { - for (unsigned int i = 0; i < num; i++) { - if (wmclasscontains(wins[i], altbarclass, alttrayname)) { - if (!XGetWindowAttributes(dpy, wins[i], &wa)) - break; - managetray(wins[i], &wa); - } - } - } - - if (wins) - XFree(wins); -} - - - -void sendmon(Client *c, Monitor *m) { if (c->mon == m) @@ -1563,19 +1520,6 @@ setgaps(const Arg *arg) arrange(selmon); } -Layout *last_layout; -void -fullscreen(const Arg *arg) -{ - if (selmon->showbar) { - for(last_layout = (Layout *)layouts; last_layout != selmon->lt[selmon->sellt]; last_layout++); - setlayout(&((Arg) { .v = &layouts[2] })); - } else { - setlayout(&((Arg) { .v = last_layout })); - } - togglebar(arg); -} - void setlayout(const Arg *arg) { @@ -1590,6 +1534,21 @@ setlayout(const Arg *arg) drawbar(selmon); } +/* arg > 1.0 will set mfact absolutely */ +void +setmfact(const Arg *arg) +{ + float f; + + if (!arg || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.05 || f > 0.95) + return; + selmon->mfact = f; + arrange(selmon); +} + void setup(void) { @@ -1609,8 +1568,7 @@ setup(void) if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); lrpad = drw->fonts->h; - bh = user_bh ? user_bh : drw->fonts->h + 2; - //bh = usealtbar ? 0 : drw->fonts->h + 2; + bh = user_bh ? user_bh : drw->fonts->h + 2; updategeom(); /* init atoms */ utf8string = XInternAtom(dpy, "UTF8_STRING", False); @@ -1659,7 +1617,6 @@ setup(void) XSelectInput(dpy, root, wa.event_mask); grabkeys(); focus(NULL); - spawnbar(); } @@ -1719,13 +1676,6 @@ spawn(const Arg *arg) } void -spawnbar() -{ - if (*altbarcmd) - system(altbarcmd); -} - -void tag(const Arg *arg) { if (selmon->sel && arg->ui & TAGMASK) { @@ -1761,31 +1711,20 @@ tile(Monitor *m) if (i < m->nmaster) { h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); - if (my + HEIGHT(c) + m->gappx < m->wh) - my += HEIGHT(c) + m->gappx; + my += HEIGHT(c) + m->gappx; } else { h = (m->wh - ty) / (n - i) - m->gappx; resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); - if (ty + HEIGHT(c) + m->gappx < m->wh) - ty += HEIGHT(c) + m->gappx; + ty += HEIGHT(c) + m->gappx; } } void togglebar(const Arg *arg) { - /** - * Polybar tray does not raise maprequest event. It must be manually scanned - * for. Scanning it too early while the tray is being populated would give - * wrong dimensions. - */ - if (!selmon->traywin) - scantray(); - selmon->showbar = !selmon->showbar; updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh); - XMoveResizeWindow(dpy, selmon->traywin, selmon->tx, selmon->by, selmon->tw, selmon->bh); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); arrange(selmon); } @@ -1804,6 +1743,13 @@ togglefloating(const Arg *arg) } void +togglefullscr(const Arg *arg) +{ + if(selmon->sel) + setfullscreen(selmon->sel, !selmon->sel->isfullscreen); +} + +void toggletag(const Arg *arg) { unsigned int newtags; @@ -1869,40 +1815,9 @@ unmanage(Client *c, int destroyed) } void -unmanagealtbar(Window w) -{ - Monitor *m = wintomon(w); - - if (!m) - return; - - m->barwin = 0; - m->by = 0; - m->bh = 0; - updatebarpos(m); - arrange(m); -} - -void -unmanagetray(Window w) -{ - Monitor *m = wintomon(w); - - if (!m) - return; - - m->traywin = 0; - m->tx = 0; - m->tw = 0; - updatebarpos(m); - arrange(m); -} - -void unmapnotify(XEvent *e) { Client *c; - Monitor *m; XUnmapEvent *ev = &e->xunmap; if ((c = wintoclient(ev->window))) { @@ -1910,18 +1825,12 @@ unmapnotify(XEvent *e) setclientstate(c, WithdrawnState); else unmanage(c, 0); - } else if ((m = wintomon(ev->window)) && m->barwin == ev->window) - unmanagealtbar(ev->window); - else if (m->traywin == ev->window) - unmanagetray(ev->window); + } } void updatebars(void) { - if (usealtbar) - return; - Monitor *m; XSetWindowAttributes wa = { .override_redirect = True, @@ -1947,11 +1856,11 @@ updatebarpos(Monitor *m) m->wy = m->my; m->wh = m->mh; if (m->showbar) { - m->wh -= m->bh; + m->wh -= bh; m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + m->bh : m->wy; + m->wy = m->topbar ? m->wy + bh : m->wy; } else - m->by = -m->bh; + m->by = -bh; } void @@ -1989,42 +1898,42 @@ updategeom(void) memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); XFree(info); nn = j; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); + + /* new monitors if nn > n */ + for (i = n; i < nn; i++) { + for (m = mons; m && m->next; m = m->next); + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n + || unique[i].x_org != m->mx || unique[i].y_org != m->my + || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); + /* removed monitors if n > nn */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); + while ((c = m->clients)) { + dirty = 1; + m->clients = c->next; + detachstack(c); + c->mon = mons; + attach(c); + attachstack(c); } + if (m == selmon) + selmon = mons; + cleanupmon(m); } free(unique); } else @@ -2103,6 +2012,7 @@ updatesizehints(Client *c) } else c->maxa = c->mina = 0.0; c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); + c->hintsvalid = 1; } void @@ -2188,35 +2098,13 @@ wintomon(Window w) if (w == root && getrootptr(&x, &y)) return recttomon(x, y, 1, 1); for (m = mons; m; m = m->next) - if (w == m->barwin || w == m->traywin) + if (w == m->barwin) return m; if ((c = wintoclient(w))) return c->mon; return selmon; } -int -wmclasscontains(Window win, const char *class, const char *name) -{ - XClassHint ch = { NULL, NULL }; - int res = 1; - - if (XGetClassHint(dpy, win, &ch)) { - if (ch.res_name && strstr(ch.res_name, name) == NULL) - res = 0; - if (ch.res_class && strstr(ch.res_class, class) == NULL) - res = 0; - } else - res = 0; - - if (ch.res_class) - XFree(ch.res_class); - if (ch.res_name) - XFree(ch.res_name); - - return res; -} - /* There's no way to check accesses to destroyed windows, thus those cases are * ignored (especially on UnmapNotify's). Other types of errors call Xlibs * default error handler, which may call exit. */ |
