Compare commits

...

16 Commits

Author SHA1 Message Date
celso 3316a5d530 added whitespace for nicer reading and modified screenshot keybinds 2023-11-15 03:35:07 -03:00
celso adf24afdac changed fontsize 2023-11-15 03:35:07 -03:00
celso d45803b289 fixed tag ref format (must use << for numbers above 2 for some reason) 2023-11-15 03:35:07 -03:00
celso a178d341ff added keepassxc and renamed some tag refs 2023-11-15 03:35:07 -03:00
celso 6a12c68259 changed font and fontsize dmenu spawns with 2023-11-15 03:35:07 -03:00
celso 04879dcaf8 added commands and paths related to dell_laptop 2023-11-15 03:35:07 -03:00
celso 604f165a0e modified config.mk for dell_laptop 2023-11-15 03:35:07 -03:00
celso 3bea588c60 changed MODKEY from alt to meta 2023-11-15 03:35:07 -03:00
celso dfe6987203 applied hardware volume keys patch 2023-11-15 03:35:07 -03:00
celso 434e08b969 added movekeyboard patch 2023-11-15 03:35:07 -03:00
celso 706ac15a9c applied focusonclick patch 2023-11-15 03:35:07 -03:00
celso 413af24edb applied gridmode patch 2023-11-15 03:35:07 -03:00
celso d916c568a1 applied resizecorners patch 2023-11-15 03:35:07 -03:00
celso 275a0658d0 applied adjacenttag-spikvacant patch 2023-11-15 03:35:07 -03:00
celso 3d6977ed76 applied hide vacant tags patch 2023-11-15 03:35:07 -03:00
Hiltjo Posthuma 9f8855343c Makefile: remove the options target
The Makefile used to suppress output (by using @), so this target made sense at
the time.

But the Makefile should be simple and make debugging with less abstractions or
fancy printing.  The Makefile was made verbose and doesn't hide the build
output, so remove this target.

Prompted by a question on the mailing list about the options target.
2023-09-22 15:13:29 +02:00
5 changed files with 314 additions and 72 deletions

View File

@ -6,13 +6,7 @@ include config.mk
SRC = drw.c dwm.c util.c SRC = drw.c dwm.c util.c
OBJ = ${SRC:.c=.o} OBJ = ${SRC:.c=.o}
all: options dwm all: dwm
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o: .c.o:
${CC} -c ${CFLAGS} $< ${CC} -c ${CFLAGS} $<
@ -48,4 +42,4 @@ uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwm\ rm -f ${DESTDIR}${PREFIX}/bin/dwm\
${DESTDIR}${MANPREFIX}/man1/dwm.1 ${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all options clean dist install uninstall .PHONY: all clean dist install uninstall

View File

@ -5,8 +5,9 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */ static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */ static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */ static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" }; static const int focusonwheel = 0;
static const char dmenufont[] = "monospace:size=10"; static const char *fonts[] = { "Liberation Sans:style=regular:size=11:antialias=true:autohint=true", "Font Awesome 5 Free:size=11:antialias=true:autohint=true" };
static const char dmenufont[] = "Liberation Mono:size=11";
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";
@ -19,7 +20,7 @@ static const char *colors[][3] = {
}; };
/* tagging */ /* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static const char *tags[] = { "", "", "", "", "", "", "7", "8", "" };
static const Rule rules[] = { static const Rule rules[] = {
/* xprop(1): /* xprop(1):
@ -28,9 +29,24 @@ static const Rule rules[] = {
*/ */
/* class instance title tags mask isfloating monitor */ /* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 }, { "Gimp", NULL, NULL, 0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 }, { "Pale moon", "Navigator", NULL, 2, 0, -1 },
{ "Pale moon", "Browser", NULL, 2, 1, -1 },
{ "Pale moon", "Places", NULL, 2, 1, -1 },
{ "Pale moon", "Toplevel", NULL, 2, 1, -1 },
{ "Pale moon", "Devtools", NULL, 2, 1, -1 },
{ "Pale moon", "DTA", NULL, 2, 1, -1 },
{ "Pale moon", "Global", NULL, 2, 1, -1 },
{ "Chromium-browser-chromium", "chromium-browser-chromium", NULL, 1<<5, 0, -1 },
{ "TelegramDesktop", "telegram-desktop", "Media viewer", 0, 1, -1 },
{ "TelegramDesktop", "telegram-desktop", NULL, 4, 0, -1 },
{ "keepassxc", "KeePassXC", NULL, 0, 1, -1 },
{ "mpv", NULL, NULL, 1<<3, 0, -1 },
{ "floatalsamxr", NULL, NULL, 0, 1, -1 },
{ "QjackCtl", "qjackctl", NULL, 0, 1, -1 },
{ "Nextcloud", "nextcloud", NULL, 0, 1, -1 },
}; };
#include "layouts.c"
/* layout(s) */ /* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ 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 nmaster = 1; /* number of clients in master area */
@ -42,10 +58,11 @@ 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 },
{ "HHH", grid },
}; };
/* key definitions */ /* key definitions */
#define MODKEY Mod1Mask #define MODKEY Mod4Mask
#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} }, \
@ -55,15 +72,44 @@ static const Layout layouts[] = {
/* 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 } }
#include <X11/XF86keysym.h>
/* commands */ /* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_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 };
/* alsa volume control */
static const char *alsacmd[] = { "st", "-c", "floatalsamxr", "-e", "alsamixer", NULL };
static const char *upvol[] = { "amixer", "set", "Master", "2+", NULL };
static const char *downvol[] = { "amixer", "set", "Master", "2-", NULL };
/* alsa muting/unmuting */
static const char *mute[] = { "amixer", "-q", "set", "Master", "toggle", NULL };
/* screenshot tools */
static const char *scrallcmd[] = { "/home/celso/sources/scripts/prtscr/prtscra.sh", NULL };
static const char *scrcurcmd[] = { "/home/celso/sources/scripts/prtscr/prtscrcr.sh", NULL };
static const char *scrselcmd[] = { "/home/celso/sources/scripts/prtscr/prtscrsel.sh", NULL };
/* browsers */
static const char *palemooncmd[] = { "palemoon", NULL };
static const char *chromiumcmd[] = { "chromium", NULL };
static const char *nextcloudcmd[] = { "nextcloud", NULL };
static const char *xfecmd[] = { "xfe", NULL };
static const char *keepassxccmd[] = { "keepassxc", NULL };
static const Key keys[] = { static const Key keys[] = {
/* modifier key function argument */ /* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol } },
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvol } },
{ 0, XF86XK_AudioMute, spawn, {.v = mute } },
{ 0, XK_Print, spawn, {.v = scrallcmd } },
{ ShiftMask, XK_Print, spawn, {.v = scrcurcmd } },
{ ControlMask, XK_Print, spawn, {.v = scrselcmd } },
{ MODKEY, XK_s, spawn, {.v = palemooncmd } },
{ MODKEY, XK_n, spawn, {.v = nextcloudcmd } },
{ MODKEY, XK_c, spawn, {.v = chromiumcmd } },
{ MODKEY|ShiftMask, XK_x, spawn, {.v = xfecmd } },
{ MODKEY, XK_x, spawn, {.v = keepassxccmd } },
{ MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } },
@ -77,6 +123,7 @@ 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_g, 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, XK_0, view, {.ui = ~0 } }, { MODKEY, XK_0, view, {.ui = ~0 } },
@ -85,6 +132,14 @@ static const Key keys[] = {
{ MODKEY, XK_period, focusmon, {.i = +1 } }, { MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
{ MODKEY|ControlMask, XK_l, movekeyboard_x, {.i = 20}},
{ MODKEY|ControlMask, XK_h, movekeyboard_x, {.i = -20}},
{ MODKEY|ControlMask, XK_j, movekeyboard_y, {.i = 20}},
{ MODKEY|ControlMask, XK_k, movekeyboard_y, {.i = -20}},
{ MODKEY, XK_Right, viewnext, {0} },
{ MODKEY, XK_Left, viewprev, {0} },
{ MODKEY|ShiftMask, XK_Right, tagtonext, {0} },
{ MODKEY|ShiftMask, XK_Left, tagtoprev, {0} },
TAGKEYS( XK_1, 0) TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1) TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2) TAGKEYS( XK_3, 2)
@ -105,6 +160,7 @@ static const Button buttons[] = {
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} }, { ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkStatusText, 0, Button1, spawn, {.v = alsacmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} },

View File

@ -4,11 +4,11 @@ VERSION = 6.4
# Customize below to fit your system # Customize below to fit your system
# paths # paths
PREFIX = /usr/local PREFIX = /usr
MANPREFIX = ${PREFIX}/share/man MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include X11INC = /usr/include/X11
X11LIB = /usr/X11R6/lib X11LIB = /usr/lib64
# Xinerama, comment if you don't want it # Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama XINERAMALIBS = -lXinerama

273
dwm.c
View File

@ -163,7 +163,6 @@ 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 void enternotify(XEvent *e);
static void expose(XEvent *e); static void expose(XEvent *e);
static void focus(Client *c); static void focus(Client *c);
static void focusin(XEvent *e); static void focusin(XEvent *e);
@ -182,10 +181,13 @@ 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 movemouse(const Arg *arg); static void movemouse(const Arg *arg);
static void movekeyboard_x(const Arg *arg);
static void movekeyboard_y(const Arg *arg);
static unsigned int nexttag(void);
static Client *nexttiled(Client *c); static Client *nexttiled(Client *c);
static void pop(Client *c); static void pop(Client *c);
static unsigned int prevtag(void);
static void propertynotify(XEvent *e); static void propertynotify(XEvent *e);
static void quit(const Arg *arg); static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h); static Monitor *recttomon(int x, int y, int w, int h);
@ -208,6 +210,8 @@ static void showhide(Client *c);
static void spawn(const Arg *arg); static void spawn(const Arg *arg);
static void tag(const Arg *arg); static void tag(const Arg *arg);
static void tagmon(const Arg *arg); static void tagmon(const Arg *arg);
static void tagtonext(const Arg *arg);
static void tagtoprev(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 togglefloating(const Arg *arg); static void togglefloating(const Arg *arg);
@ -227,6 +231,8 @@ 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 viewnext(const Arg *arg);
static void viewprev(const Arg *arg);
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);
@ -249,13 +255,11 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[ConfigureRequest] = configurerequest, [ConfigureRequest] = configurerequest,
[ConfigureNotify] = configurenotify, [ConfigureNotify] = configurenotify,
[DestroyNotify] = destroynotify, [DestroyNotify] = destroynotify,
[EnterNotify] = enternotify,
[Expose] = expose, [Expose] = expose,
[FocusIn] = focusin, [FocusIn] = focusin,
[KeyPress] = keypress, [KeyPress] = keypress,
[MappingNotify] = mappingnotify, [MappingNotify] = mappingnotify,
[MapRequest] = maprequest, [MapRequest] = maprequest,
[MotionNotify] = motionnotify,
[PropertyNotify] = propertynotify, [PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify [UnmapNotify] = unmapnotify
}; };
@ -426,16 +430,23 @@ buttonpress(XEvent *e)
click = ClkRootWin; click = ClkRootWin;
/* focus monitor if necessary */ /* focus monitor if necessary */
if ((m = wintomon(ev->window)) && m != selmon) { if ((m = wintomon(ev->window)) && m != selmon
&& (focusonwheel || (ev->button != Button4 && ev->button != Button5))) {
unfocus(selmon->sel, 1); unfocus(selmon->sel, 1);
selmon = m; selmon = m;
focus(NULL); focus(NULL);
} }
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;
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;
@ -446,8 +457,8 @@ buttonpress(XEvent *e)
else else
click = ClkWinTitle; click = ClkWinTitle;
} else if ((c = wintoclient(ev->window))) { } else if ((c = wintoclient(ev->window))) {
focus(c); if (focusonwheel || (ev->button != Button4 && ev->button != Button5))
restack(selmon); focus(c);
XAllowEvents(dpy, ReplayPointer, CurrentTime); XAllowEvents(dpy, ReplayPointer, CurrentTime);
click = ClkClientWin; click = ClkClientWin;
} }
@ -721,13 +732,12 @@ drawbar(Monitor *m)
} }
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, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); 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); 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; x += w;
} }
w = TEXTW(m->ltsymbol); w = TEXTW(m->ltsymbol);
@ -757,25 +767,6 @@ drawbars(void)
drawbar(m); drawbar(m);
} }
void
enternotify(XEvent *e)
{
Client *c;
Monitor *m;
XCrossingEvent *ev = &e->xcrossing;
if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
return;
c = wintoclient(ev->window);
m = c ? c->mon : wintomon(ev->window);
if (m != selmon) {
unfocus(selmon->sel, 1);
selmon = m;
} else if (!c || c == selmon->sel)
return;
focus(c);
}
void void
expose(XEvent *e) expose(XEvent *e)
{ {
@ -1125,23 +1116,6 @@ monocle(Monitor *m)
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
} }
void
motionnotify(XEvent *e)
{
static Monitor *mon = NULL;
Monitor *m;
XMotionEvent *ev = &e->xmotion;
if (ev->window != root)
return;
if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
unfocus(selmon->sel, 1);
selmon = m;
focus(NULL);
}
mon = m;
}
void void
movemouse(const Arg *arg) movemouse(const Arg *arg)
{ {
@ -1202,6 +1176,115 @@ movemouse(const Arg *arg)
} }
} }
unsigned int
nexttag(void)
{
unsigned int seltag = selmon->tagset[selmon->seltags];
unsigned int usedtags = 0;
Client *c = selmon->clients;
if (!c)
return seltag;
/* skip vacant tags */
do {
usedtags |= c->tags;
c = c->next;
} while (c);
do {
seltag = seltag == (1 << (LENGTH(tags) - 1)) ? 1 : seltag << 1;
} while (!(seltag & usedtags));
return seltag;
}
void
movekeyboard_x(const Arg *arg){
int ocx, ocy, nx, ny;
Client *c;
Monitor *m;
if (!(c = selmon->sel))
return;
if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
return;
restack(selmon);
ocx = c->x;
ocy = c->y;
nx = ocx + arg->i;
ny = ocy;
if (abs(selmon->wx - nx) < snap)
nx = selmon->wx;
else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
nx = selmon->wx + selmon->ww - WIDTH(c);
if (abs(selmon->wy - ny) < snap)
ny = selmon->wy;
else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
ny = selmon->wy + selmon->wh - HEIGHT(c);
if (!c->isfloating)
togglefloating(NULL);
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
resize(c, nx, ny, c->w, c->h, 1);
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
sendmon(c, m);
selmon = m;
focus(NULL);
}
}
void
movekeyboard_y(const Arg *arg){
int ocx, ocy, nx, ny;
Client *c;
Monitor *m;
if (!(c = selmon->sel))
return;
if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
return;
restack(selmon);
ocx = c->x;
ocy = c->y;
nx = ocx;
ny = ocy + arg->i;
if (abs(selmon->wx - nx) < snap)
nx = selmon->wx;
else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
nx = selmon->wx + selmon->ww - WIDTH(c);
if (abs(selmon->wy - ny) < snap)
ny = selmon->wy;
else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
ny = selmon->wy + selmon->wh - HEIGHT(c);
if (!c->isfloating)
togglefloating(NULL);
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
resize(c, nx, ny, c->w, c->h, 1);
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
sendmon(c, m);
selmon = m;
focus(NULL);
}
}
Client * Client *
nexttiled(Client *c) nexttiled(Client *c)
{ {
@ -1218,6 +1301,28 @@ pop(Client *c)
arrange(c->mon); arrange(c->mon);
} }
unsigned int
prevtag(void)
{
unsigned int seltag = selmon->tagset[selmon->seltags];
unsigned int usedtags = 0;
Client *c = selmon->clients;
if (!c)
return seltag;
/* skip vacant tags */
do {
usedtags |= c->tags;
c = c->next;
} while (c);
do {
seltag = seltag == 1 ? (1 << (LENGTH(tags) - 1)) : seltag >> 1;
} while (!(seltag & usedtags));
return seltag;
}
void void
propertynotify(XEvent *e) propertynotify(XEvent *e)
{ {
@ -1301,9 +1406,14 @@ void
resizemouse(const Arg *arg) resizemouse(const Arg *arg)
{ {
int ocx, ocy, nw, nh; int ocx, ocy, nw, nh;
int ocx2, ocy2, nx, ny;
Client *c; Client *c;
Monitor *m; Monitor *m;
XEvent ev; XEvent ev;
int horizcorner, vertcorner;
int di;
unsigned int dui;
Window dummy;
Time lasttime = 0; Time lasttime = 0;
if (!(c = selmon->sel)) if (!(c = selmon->sel))
@ -1313,10 +1423,18 @@ resizemouse(const Arg *arg)
restack(selmon); restack(selmon);
ocx = c->x; ocx = c->x;
ocy = c->y; ocy = c->y;
ocx2 = c->x + c->w;
ocy2 = c->y + c->h;
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
return; return;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); if (!XQueryPointer (dpy, c->win, &dummy, &dummy, &di, &di, &nx, &ny, &dui))
return;
horizcorner = nx < c->w / 2;
vertcorner = ny < c->h / 2;
XWarpPointer (dpy, None, c->win, 0, 0, 0, 0,
horizcorner ? (-c->bw) : (c->w + c->bw -1),
vertcorner ? (-c->bw) : (c->h + c->bw -1));
do { do {
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
switch(ev.type) { switch(ev.type) {
@ -1330,8 +1448,11 @@ resizemouse(const Arg *arg)
continue; continue;
lasttime = ev.xmotion.time; lasttime = ev.xmotion.time;
nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); nx = horizcorner ? ev.xmotion.x : c->x;
nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); ny = vertcorner ? ev.xmotion.y : c->y;
nw = MAX(horizcorner ? (ocx2 - nx) : (ev.xmotion.x - ocx - 2 * c->bw + 1), 1);
nh = MAX(vertcorner ? (ocy2 - ny) : (ev.xmotion.y - ocy - 2 * c->bw + 1), 1);
if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
&& c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
{ {
@ -1340,11 +1461,13 @@ resizemouse(const Arg *arg)
togglefloating(NULL); togglefloating(NULL);
} }
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
resize(c, c->x, c->y, nw, nh, 1); resize(c, nx, ny, nw, nh, 1);
break; break;
} }
} while (ev.type != ButtonRelease); } while (ev.type != ButtonRelease);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
horizcorner ? (-c->bw) : (c->w + c->bw - 1),
vertcorner ? (-c->bw) : (c->h + c->bw - 1));
XUngrabPointer(dpy, CurrentTime); XUngrabPointer(dpy, CurrentTime);
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
@ -1684,6 +1807,36 @@ tagmon(const Arg *arg)
sendmon(selmon->sel, dirtomon(arg->i)); sendmon(selmon->sel, dirtomon(arg->i));
} }
void
tagtonext(const Arg *arg)
{
unsigned int tmp;
if (selmon->sel == NULL)
return;
if ((tmp = nexttag()) == selmon->tagset[selmon->seltags])
return;
tag(&(const Arg){.ui = tmp });
view(&(const Arg){.ui = tmp });
}
void
tagtoprev(const Arg *arg)
{
unsigned int tmp;
if (selmon->sel == NULL)
return;
if ((tmp = prevtag()) == selmon->tagset[selmon->seltags])
return;
tag(&(const Arg){.ui = tmp });
view(&(const Arg){.ui = tmp });
}
void void
tile(Monitor *m) tile(Monitor *m)
{ {
@ -2062,6 +2215,18 @@ view(const Arg *arg)
arrange(selmon); arrange(selmon);
} }
void
viewnext(const Arg *arg)
{
view(&(const Arg){.ui = nexttag()});
}
void
viewprev(const Arg *arg)
{
view(&(const Arg){.ui = prevtag()});
}
Client * Client *
wintoclient(Window w) wintoclient(Window w)
{ {

27
layouts.c Normal file
View File

@ -0,0 +1,27 @@
void
grid(Monitor *m) {
unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
Client *c;
for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
n++;
/* grid dimensions */
for(rows = 0; rows <= n/2; rows++)
if(rows*rows >= n)
break;
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
/* window geoms (cell height/width) */
ch = m->wh / (rows ? rows : 1);
cw = m->ww / (cols ? cols : 1);
for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
cx = m->wx + (i / rows) * cw;
cy = m->wy + (i % rows) * ch;
/* adjust height/width of last row/column's windows */
ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
i++;
}
}