Xinqi Bao's Git
1 /* See LICENSE file for copyright and license details. */
14 void (*arrange
)(void);
31 static char prop
[512];
32 static unsigned int nrules
= 0;
33 static unsigned int nlayouts
= 0;
34 static unsigned int ltidx
= 0; /* default */
35 static Regs
*regs
= NULL
;
38 idxoftag(const char *tag
) {
41 for(i
= 0; i
< ntags
; i
++)
48 floating(void) { /* default floating layout */
51 for(c
= clients
; c
; c
= c
->next
)
53 resize(c
, c
->x
, c
->y
, c
->w
, c
->h
, True
);
60 for(i
= 0; i
< ntags
&& i
< sizeof prop
- 1; i
++)
61 prop
[i
] = seltags
[i
] ? '1' : '0';
62 if(i
< sizeof prop
- 1)
63 prop
[i
++] = (char)ltidx
;
65 XChangeProperty(dpy
, root
, dwmprops
, XA_STRING
, 8,
66 PropModeReplace
, (unsigned char *)prop
, i
);
76 applyrules(Client
*c
) {
80 XClassHint ch
= { 0 };
83 XGetClassHint(dpy
, c
->win
, &ch
);
84 snprintf(prop
, sizeof prop
, "%s:%s:%s",
85 ch
.res_class
? ch
.res_class
: "",
86 ch
.res_name
? ch
.res_name
: "", c
->name
);
87 for(i
= 0; i
< nrules
; i
++)
88 if(regs
[i
].propregex
&& !regexec(regs
[i
].propregex
, prop
, 1, &tmp
, 0)) {
89 c
->isfloating
= rules
[i
].isfloating
;
90 for(j
= 0; regs
[i
].tagregex
&& j
< ntags
; j
++) {
91 if(!regexec(regs
[i
].tagregex
, tags
[j
], 1, &tmp
, 0)) {
102 for(i
= 0; i
< ntags
; i
++)
103 c
->tags
[i
] = seltags
[i
];
110 for(c
= clients
; c
; c
= c
->next
)
115 layouts
[ltidx
].arrange();
127 nrules
= sizeof rules
/ sizeof rules
[0];
128 regs
= emallocz(nrules
* sizeof(Regs
));
129 for(i
= 0; i
< nrules
; i
++) {
131 reg
= emallocz(sizeof(regex_t
));
132 if(regcomp(reg
, rules
[i
].prop
, REG_EXTENDED
))
135 regs
[i
].propregex
= reg
;
138 reg
= emallocz(sizeof(regex_t
));
139 if(regcomp(reg
, rules
[i
].tags
, REG_EXTENDED
))
142 regs
[i
].tagregex
= reg
;
148 focusnext(const char *arg
) {
153 for(c
= sel
->next
; c
&& !isvisible(c
); c
= c
->next
);
155 for(c
= clients
; c
&& !isvisible(c
); c
= c
->next
);
163 focusprev(const char *arg
) {
168 for(c
= sel
->prev
; c
&& !isvisible(c
); c
= c
->prev
);
170 for(c
= clients
; c
&& c
->next
; c
= c
->next
);
171 for(; c
&& !isvisible(c
); c
= c
->prev
);
182 return layouts
[ltidx
].symbol
;
189 nlayouts
= sizeof layouts
/ sizeof layouts
[0];
190 for(blw
= i
= 0; i
< nlayouts
; i
++) {
191 w
= textw(layouts
[i
].symbol
);
199 return layouts
[ltidx
].arrange
== floating
;
203 isarrange(void (*func
)())
205 return func
== layouts
[ltidx
].arrange
;
209 isvisible(Client
*c
) {
212 for(i
= 0; i
< ntags
; i
++)
213 if(c
->tags
[i
] && seltags
[i
])
222 if(gettextprop(root
, dwmprops
, prop
, sizeof prop
)) {
223 for(i
= 0; i
< ntags
&& i
< sizeof prop
- 1 && prop
[i
] != '\0'; i
++)
224 seltags
[i
] = prop
[i
] == '1';
225 if(i
< sizeof prop
- 1 && prop
[i
] != '\0') {
226 if(prop
[i
] < nlayouts
)
233 nexttiled(Client
*c
) {
234 for(; c
&& (c
->isfloating
|| !isvisible(c
)); c
= c
->next
);
247 if(sel
->isfloating
|| isfloating())
248 XRaiseWindow(dpy
, sel
->win
);
250 wc
.stack_mode
= Below
;
252 if(!sel
->isfloating
) {
253 XConfigureWindow(dpy
, sel
->win
, CWSibling
| CWStackMode
, &wc
);
254 wc
.sibling
= sel
->win
;
256 for(c
= nexttiled(clients
); c
; c
= nexttiled(c
->next
)) {
259 XConfigureWindow(dpy
, c
->win
, CWSibling
| CWStackMode
, &wc
);
264 while(XCheckMaskEvent(dpy
, EnterWindowMask
, &ev
));
268 setlayout(const char *arg
) {
272 if(++ltidx
== nlayouts
)
277 if(i
< 0 || i
>= nlayouts
)
289 tag(const char *arg
) {
294 for(i
= 0; i
< ntags
; i
++)
295 sel
->tags
[i
] = arg
== NULL
;
297 if(i
>= 0 && i
< ntags
)
304 togglebar(const char *arg
) {
306 bpos
= (BARPOS
== BarOff
) ? BarTop
: BARPOS
;
314 togglefloating(const char *arg
) {
315 if(!sel
|| isfloating())
317 sel
->isfloating
= !sel
->isfloating
;
318 if(sel
->isfloating
) {
319 resize(sel
, sel
->x
, sel
->y
, sel
->w
, sel
->h
, True
);
326 togglemax(const char *arg
) {
329 if(!sel
|| (!isfloating() && !sel
->isfloating
) || sel
->isfixed
)
331 if((sel
->ismax
= !sel
->ismax
)) {
336 resize(sel
, wax
, way
, waw
- 2 * sel
->border
, wah
- 2 * sel
->border
, True
);
339 resize(sel
, sel
->rx
, sel
->ry
, sel
->rw
, sel
->rh
, True
);
341 while(XCheckMaskEvent(dpy
, EnterWindowMask
, &ev
));
345 toggletag(const char *arg
) {
351 sel
->tags
[i
] = !sel
->tags
[i
];
352 for(j
= 0; j
< ntags
&& !sel
->tags
[j
]; j
++);
360 toggleview(const char *arg
) {
364 seltags
[i
] = !seltags
[i
];
365 for(j
= 0; j
< ntags
&& !seltags
[j
]; j
++);
367 seltags
[i
] = True
; /* cannot toggle last view */
384 XMoveWindow(dpy
, barwin
, sx
, sy
);
388 XMoveWindow(dpy
, barwin
, sx
, sy
+ wah
);
391 XMoveWindow(dpy
, barwin
, sx
, sy
- bh
);
395 while(XCheckMaskEvent(dpy
, EnterWindowMask
, &ev
));
399 view(const char *arg
) {
402 for(i
= 0; i
< ntags
; i
++)
403 seltags
[i
] = arg
== NULL
;
405 if(i
>= 0 && i
< ntags
)