Compare commits

..

25 Commits

Author SHA1 Message Date
281a9ec38d Merge branch 'baseconf'
# Conflicts:
#	config.def.h
2020-12-15 10:30:39 +01:00
87b7de3d09 changed borderpx to 2px 2020-12-15 10:20:03 +01:00
f440537c22 Merge remote-tracking branch 'upstream/master'
merging updates from upstream
2020-08-05 19:07:47 +02:00
9edcca1eec made patch configuration 2020-06-25 15:57:20 +02:00
1bfedd8be1 Merge branch 'allpatch'
# Conflicts:
#	config.def.h
2020-06-25 15:53:33 +02:00
894dc6fb87 Merge branch 'baseconf' 2020-06-25 15:52:30 +02:00
06e45c2129 added back firefox rule, but removed tags mask 2020-06-25 15:50:38 +02:00
356c806404 Merge branch 'center' into allpatch 2020-06-25 15:19:08 +02:00
f942d4d2ea applied center patch 2020-06-25 14:35:40 +02:00
245738e087 Merge branch 'baseconf' 2020-06-24 19:32:08 +02:00
2ccccae4fe Merge branch 'fibonacci' into allpatch
# Conflicts:
#	config.def.h
2020-06-24 19:30:50 +02:00
14599d057e Merge branch 'deck-layout' into allpatch 2020-06-24 19:30:02 +02:00
9a327dea20 Merge branch 'pertag' into allpatch 2020-06-24 19:29:54 +02:00
16936e93ba Merge branch 'uselessgap' into allpatch 2020-06-24 19:29:51 +02:00
3869a717bc Merge branch 'autostart' into allpatch 2020-06-24 19:29:46 +02:00
68b8fdb8ae Merge branch 'attachbelow' into allpatch 2020-06-24 19:29:39 +02:00
044fa86b05 applied fibonacci patch 2020-06-24 14:28:51 +02:00
caaf1ff8e1 applied dwm deck patch 2020-06-24 14:23:50 +02:00
efb0765d16 applied attachbelow patch 2020-06-24 13:13:50 +02:00
19ab95da81 change default MODKEY to Mod4Mask i.e. super 2020-06-24 00:07:33 +02:00
e5bdde4c77 removed default firefox rule (useless IMO) 2020-06-24 00:06:47 +02:00
b1b52608ff applied uselessgap patch 2020-06-23 23:14:15 +02:00
19c8ed5228 applied alpha patch 2020-06-16 18:17:30 +02:00
9751458b05 applied pertag patch 2020-06-09 17:45:57 +02:00
3db3255eaf added autostart patch 2020-06-09 17:42:58 +02:00
4 changed files with 125 additions and 332 deletions

View File

@ -2,8 +2,7 @@
/* appearance */
static const unsigned int borderpx = 2; /* border pixel of windows */
static const int startwithgaps[] = { 1 }; /* 1 means gaps are used by default, this can be customized for each tag */
static const unsigned int gappx[] = { 10 }; /* default gap between windows in pixels, this can be customized for each tag */
static const unsigned int gappx = 6; /* 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 */
@ -35,18 +34,19 @@ 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 iscentered isfloating monitor */
{ "Gimp", NULL, NULL, 0, 0, 1, -1 },
{ "Firefox", NULL, NULL, 0, 1, 0, -1 },
{ "firefox", NULL, NULL, 0, 1, 0, -1 },
{ "St", NULL, NULL, 0, 1, 0, -1 },
{ "Gcr-prompt", NULL, NULL, 0, 1, 0, -1 },
};
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
/* mouse scroll resize */
static const int scrollsensetivity = 30; /* 1 means resize window by 1 pixel for each scroll event */
static const int attachbelow = 1; /* 1 means attach after the currently active window */
#include "fibonacci.c"
static const Layout layouts[] = {
@ -54,9 +54,9 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
{ "[@]", spiral },
{ "[\\]", dwindle },
{ "DD", doubledeck },
{ "[D]", deck },
{ "[@]", spiral },
{ "[\\]", dwindle },
};
/* key definitions */
@ -92,9 +92,9 @@ 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|ShiftMask, XK_r, setlayout, {.v = &layouts[4]} },
{ MODKEY|ShiftMask, XK_d, setlayout, {.v = &layouts[5]} },
{ MODKEY, XK_c, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_r, setlayout, {.v = &layouts[4]} },
{ MODKEY|ShiftMask, XK_r, setlayout, {.v = &layouts[5]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
@ -103,10 +103,6 @@ static Key keys[] = {
{ 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 = -5 } },
{ MODKEY, XK_equal, setgaps, {.i = +5 } },
{ MODKEY|ShiftMask, XK_minus, setgaps, {.i = GAP_RESET } },
{ MODKEY|ShiftMask, XK_equal, setgaps, {.i = GAP_TOGGLE} },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
@ -119,15 +115,6 @@ static Key keys[] = {
{ MODKEY|ShiftMask, XK_q, quit, {0} },
};
/* resizemousescroll direction argument list */
static const int scrollargs[][2] = {
/* width change height change */
{ +scrollsensetivity, 0 },
{ -scrollsensetivity, 0 },
{ 0, +scrollsensetivity },
{ 0, -scrollsensetivity },
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
@ -139,10 +126,6 @@ static Button buttons[] = {
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkClientWin, MODKEY, Button4, resizemousescroll, {.v = &scrollargs[0]} },
{ ClkClientWin, MODKEY, Button5, resizemousescroll, {.v = &scrollargs[1]} },
{ ClkClientWin, MODKEY, Button6, resizemousescroll, {.v = &scrollargs[2]} },
{ ClkClientWin, MODKEY, Button7, resizemousescroll, {.v = &scrollargs[3]} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },

26
dwm.1
View File

@ -29,15 +29,10 @@ color. The tags of the focused window are indicated with a filled square in the
top left corner. The tags which are applied to one or more windows are
indicated with an empty square in the top left corner.
.P
The attach below patch makes newly spawned windows attach after the currently
selected window
.P
dwm draws a small border around windows to indicate the focus state.
.P
On start, dwm can start additional programs that may be specified in two special
shell scripts (see the FILES section below), autostart_blocking.sh and
autostart.sh. The former is executed first and dwm will wait for its
termination before starting. The latter is executed in the background before
dwm enters its handler loop.
.P
Either of these files may be omitted.
.SH OPTIONS
.TP
.B \-v
@ -160,21 +155,6 @@ Toggles focused window between floating and tiled state.
.TP
.B Mod1\-Button3
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
.SH FILES
The files containing programs to be started along with dwm are searched for in
the following directories:
.IP "1. $XDG_DATA_HOME/dwm"
.IP "2. $HOME/.local/share/dwm"
.IP "3. $HOME/.dwm"
.P
The first existing directory is scanned for any of the autostart files below.
.TP 15
autostart.sh
This file is started as a shell background process before dwm enters its handler
loop.
.TP 15
autostart_blocking.sh
This file is started before any autostart.sh; dwm waits for its termination.
.SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.

382
dwm.c
View File

@ -29,7 +29,6 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
@ -50,23 +49,15 @@
#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)->wx+(m)->ww) - MAX((x),(m)->wx)) \
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
#define ISVISIBLEONTAG(C, T) ((C->tags & T))
#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
#define LENGTH(X) (sizeof X / sizeof X[0])
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
#define HEIGHT(X) ((X)->h + 2 * (X)->bw + gappx)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
#define GAP_TOGGLE 100
#define GAP_RESET 0
#define OPAQUE 0xffU
/* Undefined in X11/X.h buttons that are actualy exist and correspond to
* horizontal scroll
*/
#define Button6 6
#define Button7 7
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
@ -103,7 +94,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, isurgent, neverfocus, oldstate, isfullscreen;
Client *next;
Client *snext;
Monitor *mon;
@ -123,7 +114,6 @@ typedef struct {
} Layout;
typedef struct Pertag Pertag;
struct Monitor {
char ltsymbol[16];
float mfact;
@ -151,6 +141,7 @@ typedef struct {
const char *instance;
const char *title;
unsigned int tags;
int iscentered;
int isfloating;
int monitor;
} Rule;
@ -172,11 +163,11 @@ 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);
static Monitor *dirtomon(int dir);
static void doubledeck(Monitor *m);
static void drawbar(Monitor *m);
static void drawbars(void);
static void enternotify(XEvent *e);
@ -200,7 +191,6 @@ static void maprequest(XEvent *e);
static void monocle(Monitor *m);
static void motionnotify(XEvent *e);
static void movemouse(const Arg *arg);
static Client *nexttagged(Client *c);
static Client *nexttiled(Client *c);
static void pop(Client *);
static void propertynotify(XEvent *e);
@ -209,17 +199,15 @@ static Monitor *recttomon(int x, int y, int w, int h);
static void resize(Client *c, int x, int y, int w, int h, int interact);
static void resizeclient(Client *c, int x, int y, int w, int h);
static void resizemouse(const Arg *arg);
static void resizemousescroll(const Arg *arg);
static void restack(Monitor *m);
static void run(void);
static void runautostart(void);
static void runAutostart(void);
static void scan(void);
static int sendevent(Client *c, Atom proto);
static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
static void setfocus(Client *c);
static void setfullscreen(Client *c, int fullscreen);
static void setgaps(const Arg *arg);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setup(void);
@ -257,11 +245,7 @@ static void xinitvisual();
static void zoom(const Arg *arg);
/* variables */
static const char autostartblocksh[] = "autostart_blocking.sh";
static const char autostartsh[] = "autostart.sh";
static const char broken[] = "broken";
static const char dwmdir[] = "dwm";
static const char localshare[] = ".local/share";
static char stext[256];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
@ -309,9 +293,6 @@ struct Pertag {
unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
int drawwithgaps[LENGTH(tags) + 1]; /* gaps toggle for each tag */
int gappx[LENGTH(tags) + 1]; /* gaps for each tag */
};
/* compile-time check if all tags fit into an unsigned int bit array. */
@ -328,6 +309,7 @@ applyrules(Client *c)
XClassHint ch = { NULL, NULL };
/* rule matching */
c->iscentered = 0;
c->isfloating = 0;
c->tags = 0;
XGetClassHint(dpy, c->win, &ch);
@ -340,6 +322,7 @@ applyrules(Client *c)
&& (!r->class || strstr(class, r->class))
&& (!r->instance || strstr(instance, r->instance)))
{
c->iscentered = r->iscentered;
c->isfloating = r->isfloating;
c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next);
@ -452,14 +435,8 @@ void
attachBelow(Client *c)
{
//If there is nothing on the monitor or the selected client is floating, attach as normal
if(c->mon->sel == NULL || c->mon->sel->isfloating) {
Client *at = nexttagged(c);
if(!at) {
attach(c);
return;
}
c->next = at->next;
at->next = c;
if(c->mon->sel == NULL || c->mon->sel == c || c->mon->sel->isfloating) {
attach(c);
return;
}
@ -503,7 +480,7 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
else if (ev->x > selmon->ww - (int)TEXTW(stext))
else if (ev->x > selmon->ww - TEXTW(stext))
click = ClkStatusText;
else
click = ClkWinTitle;
@ -718,14 +695,7 @@ createmon(void)
m->pertag->sellts[i] = m->sellt;
m->pertag->showbars[i] = m->showbar;
if (i > 0) {
m->pertag->drawwithgaps[i] = startwithgaps[(i - 1) % LENGTH(gappx)];
m->pertag->gappx[i] = gappx[(i - 1) % LENGTH(gappx)];
}
}
m->pertag->drawwithgaps[0] = startwithgaps[0];
m->pertag->gappx[0] = gappx[0];
return m;
}
@ -740,6 +710,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)
{
@ -778,27 +773,6 @@ dirtomon(int dir)
return m;
}
void
doubledeck(Monitor *m) {
unsigned int i, n, mw;
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;
else
mw = m->ww;
for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
if(i < m->nmaster)
resize(c, m->wx, m->wy, mw - (2*c->bw), m->wh - (2*c->bw), False);
else
resize(c, m->wx + mw, m->wy, m->ww - mw - (2*c->bw), m->wh - (2*c->bw), False);
}
void
drawbar(Monitor *m)
{
@ -903,12 +877,6 @@ focus(Client *c)
attachstack(c);
grabbuttons(c, 1);
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
if (!selmon->pertag->drawwithgaps[selmon->pertag->curtag] && !c->isfloating) {
XWindowChanges wc;
wc.sibling = selmon->barwin;
wc.stack_mode = Below;
XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
}
setfocus(c);
} else {
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
@ -947,7 +915,7 @@ focusstack(const Arg *arg)
{
Client *c = NULL, *i;
if (!selmon->sel || selmon->sel->isfullscreen)
if (!selmon->sel)
return;
if (arg->i > 0) {
for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
@ -1169,15 +1137,20 @@ manage(Window w, XWindowAttributes *wa)
updatewindowtype(c);
updatesizehints(c);
updatewmhints(c);
c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
if (c->iscentered) {
c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
}
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
grabbuttons(c, 0);
if (!c->isfloating)
c->isfloating = c->oldstate = trans != None || c->isfixed;
if (c->isfloating)
XRaiseWindow(dpy, c->win);
attachBelow(c);
if( attachbelow )
attachBelow(c);
else
attach(c);
attachstack(c);
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
@ -1227,10 +1200,7 @@ monocle(Monitor *m)
if (n > 0) /* override layout symbol */
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
if (selmon->pertag->drawwithgaps[selmon->pertag->curtag])
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
else
resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
}
void
@ -1310,16 +1280,6 @@ movemouse(const Arg *arg)
}
}
Client *
nexttagged(Client *c) {
Client *walked = c->mon->clients;
for(;
walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags));
walked = walked->next
);
return walked;
}
Client *
nexttiled(Client *c)
{
@ -1404,21 +1364,36 @@ void
resizeclient(Client *c, int x, int y, int w, int h)
{
XWindowChanges wc;
unsigned int n;
unsigned int gapoffset;
unsigned int gapincr;
Client *nbc;
c->oldx = c->x; c->x = wc.x = x;
c->oldy = c->y; c->y = wc.y = y;
c->oldw = c->w; c->w = wc.width = w;
c->oldh = c->h; c->h = wc.height = h;
wc.border_width = c->bw;
if (!selmon->pertag->drawwithgaps[selmon->pertag->curtag] && /* this is the noborderfloatingfix patch, slightly modified so that it will work if, and only if, gaps are disabled. */
(((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) /* these two first lines are the only ones changed. if you are manually patching and have noborder installed already, just change these lines; or conversely, just remove this section if the noborder patch is not desired;) */
|| &monocle == c->mon->lt[c->mon->sellt]->arrange))
&& !c->isfullscreen && !c->isfloating
&& NULL != c->mon->lt[c->mon->sellt]->arrange) {
c->w = wc.width += c->bw * 2;
c->h = wc.height += c->bw * 2;
wc.border_width = 0;
/* Get number of clients for the selected monitor */
for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++);
/* Do nothing if layout is floating */
if (c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) {
gapincr = gapoffset = 0;
} else {
/* Remove border and gap if layout is monocle or only one client */
if (selmon->lt[selmon->sellt]->arrange == monocle || n == 1) {
gapoffset = 0;
gapincr = -2 * borderpx;
wc.border_width = 0;
} else {
gapoffset = gappx;
gapincr = 2 * gappx;
}
}
c->oldx = c->x; c->x = wc.x = x + gapoffset;
c->oldy = c->y; c->y = wc.y = y + gapoffset;
c->oldw = c->w; c->w = wc.width = w - gapincr;
c->oldh = c->h; c->h = wc.height = h - gapincr;
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);
@ -1481,45 +1456,6 @@ resizemouse(const Arg *arg)
}
}
void
resizemousescroll(const Arg *arg)
{
int nw, nh;
Client *c;
Monitor *m;
XEvent ev;
int dw = *((int*)arg->v + 1);
int dh = *(int*)arg->v;
if (!(c = selmon->sel))
return;
if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
return;
restack(selmon);
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
return;
nw = MAX(c->w + dw, 1);
nh = MAX(c->h + dh, 1);
if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
&& c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
{
if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
&& (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
togglefloating(NULL);
}
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
resize(c, c->x, c->y, nw, nh, 1);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
XUngrabPointer(dpy, CurrentTime);
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
sendmon(c, m);
selmon = m;
focus(NULL);
}
}
void
restack(Monitor *m)
{
@ -1557,80 +1493,9 @@ run(void)
}
void
runautostart(void)
{
char *pathpfx;
char *path;
char *xdgdatahome;
char *home;
struct stat sb;
if ((home = getenv("HOME")) == NULL)
/* this is almost impossible */
return;
/* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
* otherwise use ~/.local/share/dwm as autostart script directory
*/
xdgdatahome = getenv("XDG_DATA_HOME");
if (xdgdatahome != NULL && *xdgdatahome != '\0') {
/* space for path segments, separators and nul */
pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
free(pathpfx);
return;
}
} else {
/* space for path segments, separators and nul */
pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
+ strlen(dwmdir) + 3);
if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
free(pathpfx);
return;
}
}
/* check if the autostart script directory exists */
if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
/* the XDG conformant path does not exist or is no directory
* so we try ~/.dwm instead
*/
char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
if(pathpfx_new == NULL) {
free(pathpfx);
return;
}
pathpfx = pathpfx_new;
if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
free(pathpfx);
return;
}
}
/* try the blocking script first */
path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
free(path);
free(pathpfx);
}
if (access(path, X_OK) == 0)
system(path);
/* now the non-blocking script */
if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
free(path);
free(pathpfx);
}
if (access(path, X_OK) == 0)
system(strcat(path, " &"));
free(pathpfx);
free(path);
runAutostart(void) {
system("cd ~/.dwm; ./autostart_blocking.sh");
system("cd ~/.dwm; ./autostart.sh &");
}
void
@ -1670,7 +1535,10 @@ sendmon(Client *c, Monitor *m)
detachstack(c);
c->mon = m;
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
attachBelow(c);
if( attachbelow )
attachBelow(c);
else
attach(c);
attachstack(c);
focus(NULL);
arrange(NULL);
@ -1750,29 +1618,6 @@ setfullscreen(Client *c, int fullscreen)
}
}
void
setgaps(const Arg *arg)
{
switch(arg->i)
{
case GAP_TOGGLE:
selmon->pertag->drawwithgaps[selmon->pertag->curtag] = !selmon->pertag->drawwithgaps[selmon->pertag->curtag];
break;
case GAP_RESET:
if (selmon->pertag->curtag > 0)
selmon->pertag->gappx[selmon->pertag->curtag] = gappx[selmon->pertag->curtag - 1 % LENGTH(gappx)];
else
selmon->pertag->gappx[0] = gappx[0];
break;
default:
if (selmon->pertag->gappx[selmon->pertag->curtag] + arg->i < 0)
selmon->pertag->gappx[selmon->pertag->curtag] = 0;
else
selmon->pertag->gappx[selmon->pertag->curtag] += arg->i;
}
arrange(selmon);
}
void
setlayout(const Arg *arg)
{
@ -1956,42 +1801,23 @@ tile(Monitor *m)
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
if (n == 0)
return;
if (m->pertag->drawwithgaps[m->pertag->curtag]) { /* draw with fullgaps logic */
if (n > m->nmaster)
mw = m->nmaster ? m->ww * m->mfact : 0;
else
mw = m->ww - m->pertag->gappx[m->pertag->curtag];
for (i = 0, my = ty = m->pertag->gappx[m->pertag->curtag], c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
if (i < m->nmaster) {
h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->pertag->gappx[m->pertag->curtag];
resize(c, m->wx + m->pertag->gappx[m->pertag->curtag], m->wy + my, mw - (2*c->bw) - m->pertag->gappx[m->pertag->curtag], h - (2*c->bw), 0);
if (my + HEIGHT(c) + m->pertag->gappx[m->pertag->curtag] < m->wh)
my += HEIGHT(c) + m->pertag->gappx[m->pertag->curtag];
} else {
h = (m->wh - ty) / (n - i) - m->pertag->gappx[m->pertag->curtag];
resize(c, m->wx + mw + m->pertag->gappx[m->pertag->curtag], m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->pertag->gappx[m->pertag->curtag], h - (2*c->bw), 0);
if (ty + HEIGHT(c) + m->pertag->gappx[m->pertag->curtag] < m->wh)
ty += HEIGHT(c) + m->pertag->gappx[m->pertag->curtag];
}
} else { /* draw with singularborders logic */
if (n > m->nmaster)
mw = m->nmaster ? m->ww * m->mfact : 0;
else
mw = m->ww;
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
if (i < m->nmaster) {
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
if (n == 1)
resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
else
resize(c, m->wx - c->bw, m->wy + my, mw - c->bw, h - c->bw, False);
my += HEIGHT(c) - c->bw;
} else {
h = (m->wh - ty) / (n - i);
resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww - mw, h - c->bw, False);
ty += HEIGHT(c) - c->bw;
}
}
if (n > m->nmaster)
mw = m->nmaster ? m->ww * m->mfact : 0;
else
mw = m->ww;
for (i = my = ty = 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), 0);
if (my + HEIGHT(c) < m->wh)
my += HEIGHT(c);
} else {
h = (m->wh - ty) / (n - i);
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
if (ty + HEIGHT(c) < m->wh)
ty += HEIGHT(c);
}
}
void
@ -2221,8 +2047,10 @@ updategeom(void)
m->clients = c->next;
detachstack(c);
c->mon = mons;
attach(c);
attachBelow(c);
if( attachbelow )
attachBelow(c);
else
attach(c);
attachstack(c);
}
if (m == selmon)
@ -2334,8 +2162,10 @@ updatewindowtype(Client *c)
if (state == netatom[NetWMFullscreen])
setfullscreen(c, 1);
if (wtype == netatom[NetWMWindowTypeDialog])
if (wtype == netatom[NetWMWindowTypeDialog]) {
c->iscentered = 1;
c->isfloating = 1;
}
}
void
@ -2530,7 +2360,7 @@ main(int argc, char *argv[])
die("pledge");
#endif /* __OpenBSD__ */
scan();
runautostart();
runAutostart();
run();
cleanup();
XCloseDisplay(dpy);

View File

@ -6,12 +6,12 @@ fibonacci(Monitor *mon, int s) {
for(n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++);
if(n == 0)
return;
nx = mon->wx;
ny = 0;
nw = mon->ww;
nh = mon->wh;
for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
if((i % 2 && nh / 2 > 2 * c->bw)
|| (!(i % 2) && nw / 2 > 2 * c->bw)) {