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