all repos — dwm @ 50be6c8b67c500ee4aa07919609fa80785fd389d

fork of suckless dynamic window manager

layout.c (view raw)

  1/* See LICENSE file for copyright and license details. */
  2#include "dwm.h"
  3#include <stdlib.h>
  4
  5/* static */
  6
  7typedef struct {
  8	const char *symbol;
  9	void (*arrange)(void);
 10} Layout;
 11
 12unsigned int blw = 0;
 13static unsigned int ltidx = 0; /* default */
 14
 15static void
 16floating(void) { /* default floating layout */
 17	Client *c;
 18
 19	for(c = clients; c; c = c->next)
 20		if(isvisible(c))
 21			resize(c, c->x, c->y, c->w, c->h, True);
 22}
 23
 24static unsigned int nlayouts = 0;
 25
 26LAYOUTS
 27
 28/* extern */
 29
 30void
 31arrange(void) {
 32	Client *c;
 33
 34	for(c = clients; c; c = c->next)
 35		if(isvisible(c))
 36			unban(c);
 37		else
 38			ban(c);
 39	layouts[ltidx].arrange();
 40	focus(NULL);
 41	restack();
 42}
 43
 44void
 45focusnext(const char *arg) {
 46	Client *c;
 47
 48	if(!sel)
 49		return;
 50	for(c = sel->next; c && !isvisible(c); c = c->next);
 51	if(!c)
 52		for(c = clients; c && !isvisible(c); c = c->next);
 53	if(c) {
 54		focus(c);
 55		restack();
 56	}
 57}
 58
 59void
 60focusprev(const char *arg) {
 61	Client *c;
 62
 63	if(!sel)
 64		return;
 65	for(c = sel->prev; c && !isvisible(c); c = c->prev);
 66	if(!c) {
 67		for(c = clients; c && c->next; c = c->next);
 68		for(; c && !isvisible(c); c = c->prev);
 69	}
 70	if(c) {
 71		focus(c);
 72		restack();
 73	}
 74}
 75
 76const char *
 77getsymbol(void)
 78{
 79	return layouts[ltidx].symbol;
 80}
 81
 82Bool
 83isfloating(void) {
 84	return layouts[ltidx].arrange == floating;
 85}
 86
 87Bool
 88isarrange(void (*func)())
 89{
 90	return func == layouts[ltidx].arrange;
 91}
 92
 93void
 94initlayouts(void) {
 95	unsigned int i, w;
 96
 97	/* TODO deserialize ltidx if present */
 98	nlayouts = sizeof layouts / sizeof layouts[0];
 99	for(blw = i = 0; i < nlayouts; i++) {
100		w = textw(layouts[i].symbol);
101		if(w > blw)
102			blw = w;
103	}
104}
105
106Client *
107nexttiled(Client *c) {
108	for(; c && (c->isfloating || !isvisible(c)); c = c->next);
109	return c;
110}
111
112void
113restack(void) {
114	Client *c;
115	XEvent ev;
116	XWindowChanges wc;
117
118	drawstatus();
119	if(!sel)
120		return;
121	if(sel->isfloating || isfloating())
122		XRaiseWindow(dpy, sel->win);
123	if(!isfloating()) {
124		wc.stack_mode = Below;
125		wc.sibling = barwin;
126		if(!sel->isfloating) {
127			XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc);
128			wc.sibling = sel->win;
129		}
130		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
131			if(c == sel)
132				continue;
133			XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
134			wc.sibling = c->win;
135		}
136	}
137	XSync(dpy, False);
138	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
139}
140
141void
142setlayout(const char *arg) {
143	int i;
144
145	if(!arg) {
146		if(++ltidx == nlayouts)
147			ltidx = 0;;
148	}
149	else {
150		i = atoi(arg);
151		if(i < 0 || i >= nlayouts)
152			return;
153		ltidx = i;
154	}
155	if(sel)
156		arrange();
157	else
158		drawstatus();
159}
160
161void
162togglebar(const char *arg) {
163	if(bpos == BarOff)
164		bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
165	else
166		bpos = BarOff;
167	updatebarpos();
168	arrange();
169}
170
171void
172togglemax(const char *arg) {
173	XEvent ev;
174
175	if(!sel || (!isfloating() && !sel->isfloating) || sel->isfixed)
176		return;
177	if((sel->ismax = !sel->ismax)) {
178		sel->rx = sel->x;
179		sel->ry = sel->y;
180		sel->rw = sel->w;
181		sel->rh = sel->h;
182		resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
183	}
184	else
185		resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
186	drawstatus();
187	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
188}