enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
enum { NetSupported, NetWMName, NetWMState,
- NetWMFullscreen, NetActiveWindow, NetLast }; /* EWMH atoms */
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
struct Monitor {
char ltsymbol[16];
float mfact;
+ int nmaster;
int num;
int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, Bool focused);
static void grabkeys(void);
+static void incnmaster(const Arg *arg);
static void initfont(const char *fontstr);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static void updatestatus(void);
+static void updatewindowtype(Client *c);
static void updatetitle(Client *c);
static void updatewmhints(Client *c);
static void view(const Arg *arg);
*h = bh;
if(*w < bh)
*w = bh;
- if(resizehints || c->isfloating) {
+ if(resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
/* 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 */
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
+ m->nmaster = nmaster;
m->showbar = showbar;
m->topbar = topbar;
m->lt[0] = &layouts[0];
}
}
+void
+incnmaster(const Arg *arg) {
+ selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
+ arrange(selmon);
+}
+
void
initfont(const char *fontstr) {
char *def, **missing;
XConfigureWindow(dpy, w, CWBorderWidth, &wc);
XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
configure(c); /* propagates border_width, if size doesn't change */
+ updatewindowtype(c);
updatesizehints(c);
updatewmhints(c);
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
if(c == c->mon->sel)
drawbar(c->mon);
}
+ if(ev->atom == netatom[NetWMWindowType])
+ updatewindowtype(c);
}
}
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+ netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+ netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
/* init cursors */
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
}
else { /* hide clients bottom up */
showhide(c->snext);
- XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
+ XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
}
}
void
tile(Monitor *m) {
- int x, y, h, w, mw;
- unsigned int i, n;
+ unsigned int i, n, h, mw, my, ty;
Client *c;
for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
if(n == 0)
return;
- /* master */
- c = nexttiled(m->clients);
- mw = m->mfact * m->ww;
- resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw, False);
- if(--n == 0)
- return;
- /* tile stack */
- x = (m->wx > c->x) ? c->x + mw + 2 * c->bw : m->wx + mw;
- y = m->wy;
- w = (m->wx > c->x) ? m->wx + m->ww - x : m->ww - mw;
- h = m->wh / n;
- if(h < bh)
- h = m->wh;
- for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
- resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n)
- ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False);
- if(h != m->wh)
- y = c->y + HEIGHT(c);
- }
+
+ 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), False);
+ 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), False);
+ ty += HEIGHT(c);
+ }
}
void
drawbar(selmon);
}
+void
+updatewindowtype(Client *c)
+{
+ Atom wtype, real;
+ int format;
+ unsigned long n, extra;
+ unsigned char *p = NULL;
+
+ if(XGetWindowProperty(dpy, c->win, netatom[NetWMWindowType], 0L,
+ sizeof(Atom), False, XA_ATOM, &real, &format,
+ &n, &extra, (unsigned char **)&p) == Success && p) {
+ wtype = *(Atom *)p;
+ XFree(p);
+
+ if(wtype == netatom[NetWMWindowTypeDialog])
+ c->isfloating = True;
+ }
+}
+
void
updatewmhints(Client *c) {
XWMHints *wmh;