2 * tag.c - tag management
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <X11/Xutil.h>
29 extern Client
*sel
; /* global client list */
31 static Regs
*regs
= NULL
;
33 /** This function returns the index of
34 * the tag given un argument in *tags
35 * \param tag_to_find tag name
36 * \param tags tag list
37 * \param ntags number of tags in tag list
38 * \return index of tag
41 idxoftag(const char *tag_to_find
, Tag
*tags
, int ntags
)
48 for(i
= 0; i
< ntags
; i
++)
49 if(!a_strcmp(tags
[i
].name
, tag_to_find
))
56 applyrules(Client
* c
, awesome_config
*awesomeconf
)
61 XClassHint ch
= { 0, 0 };
64 len
+= a_strlen(ch
.res_class
) + a_strlen(ch
.res_name
) + a_strlen(c
->name
);
66 prop
= p_new(char, len
+ 1);
69 XGetClassHint(c
->display
, c
->win
, &ch
);
70 snprintf(prop
, len
+ 1, "%s:%s:%s",
71 ch
.res_class
? ch
.res_class
: "", ch
.res_name
? ch
.res_name
: "", c
->name
);
72 for(i
= 0; i
< awesomeconf
->nrules
; i
++)
73 if(regs
[i
].propregex
&& !regexec(regs
[i
].propregex
, prop
, 1, &tmp
, 0))
75 c
->isfloating
= awesomeconf
->rules
[i
].isfloating
;
76 for(j
= 0; regs
[i
].tagregex
&& j
< awesomeconf
->ntags
; j
++)
77 if(!regexec(regs
[i
].tagregex
, awesomeconf
->tags
[j
].name
, 1, &tmp
, 0))
89 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
90 c
->tags
[i
] = awesomeconf
->tags
[i
].selected
;
94 compileregs(Rule
* rules
, int nrules
)
101 regs
= p_new(Regs
, nrules
);
102 for(i
= 0; i
< nrules
; i
++)
106 reg
= p_new(regex_t
, 1);
107 if(regcomp(reg
, rules
[i
].prop
, REG_EXTENDED
))
110 regs
[i
].propregex
= reg
;
114 reg
= p_new(regex_t
, 1);
115 if(regcomp(reg
, rules
[i
].tags
, REG_EXTENDED
))
118 regs
[i
].tagregex
= reg
;
124 /** Returns True if a client is tagged
125 * with one of the tags
127 * \param tags tag to check
128 * \param ntags number of tags in *tags
129 * \return True or False
132 isvisible(Client
* c
, int screen
, Tag
* tags
, int ntags
)
136 for(i
= 0; i
< ntags
; i
++)
137 if(c
->tags
[i
] && tags
[i
].selected
&& c
->screen
== screen
)
143 /** Tag selected window with tag
144 * \param disp Display ref
145 * \param drawcontext Drawcontext ref
146 * \param arg Tag name
147 * \ingroup ui_callback
150 uicb_tag(Display
*disp
,
152 awesome_config
*awesomeconf
,
159 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
160 sel
->tags
[i
] = arg
== NULL
;
161 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
162 if(i
>= 0 && i
< awesomeconf
->ntags
)
164 saveprops(sel
, awesomeconf
->ntags
);
165 arrange(disp
, drawcontext
, awesomeconf
);
168 /** Toggle floating state of a client
169 * \param disp Display ref
170 * \param drawcontext Drawcontext ref
172 * \ingroup ui_callback
175 uicb_togglefloating(Display
*disp
,
177 awesome_config
* awesomeconf
,
178 const char *arg
__attribute__ ((unused
)))
182 sel
->isfloating
= !sel
->isfloating
;
184 /*restore last known float dimensions*/
185 resize(sel
, sel
->rx
, sel
->ry
, sel
->rw
, sel
->rh
, True
);
188 /*save last known float dimensions*/
194 saveprops(sel
, awesomeconf
->ntags
);
195 arrange(disp
, drawcontext
, awesomeconf
);
199 * \param disp Display ref
200 * \param drawcontext Drawcontext ref
201 * \param arg Tag name
202 * \ingroup ui_callback
205 uicb_toggletag(Display
*disp
,
207 awesome_config
*awesomeconf
,
215 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
216 sel
->tags
[i
] = !sel
->tags
[i
];
217 for(j
= 0; j
< awesomeconf
->ntags
&& !sel
->tags
[j
]; j
++);
218 if(j
== awesomeconf
->ntags
)
220 saveprops(sel
, awesomeconf
->ntags
);
221 arrange(disp
, drawcontext
, awesomeconf
);
224 /** Add a tag to viewed tags
225 * \param disp Display ref
226 * \param drawcontext Drawcontext ref
227 * \param arg Tag name
228 * \ingroup ui_callback
231 uicb_toggleview(Display
*disp
,
233 awesome_config
*awesomeconf
,
239 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
240 awesomeconf
->tags
[i
].selected
= !awesomeconf
->tags
[i
].selected
;
241 for(j
= 0; j
< awesomeconf
->ntags
&& !awesomeconf
->tags
[j
].selected
; j
++);
242 if(j
== awesomeconf
->ntags
)
243 awesomeconf
->tags
[i
].selected
= True
;
244 saveawesomeprops(disp
, awesomeconf
);
245 arrange(disp
, drawcontext
, awesomeconf
);
249 * \param disp Display ref
250 * \param awesomeconf awesome config ref
251 * \param arg tag to view
252 * \ingroup ui_callback
255 uicb_view(Display
*disp
,
257 awesome_config
*awesomeconf
,
262 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
264 awesomeconf
->tags
[i
].was_selected
= awesomeconf
->tags
[i
].selected
;
265 awesomeconf
->tags
[i
].selected
= arg
== NULL
;
267 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
268 if(i
>= 0 && i
< awesomeconf
->ntags
)
270 awesomeconf
->tags
[i
].selected
= True
;
271 awesomeconf
->current_layout
= awesomeconf
->tags
[i
].layout
;
273 saveawesomeprops(disp
, awesomeconf
);
274 arrange(disp
, drawcontext
, awesomeconf
);
277 /** View previously selected tags
278 * \param disp Display ref
279 * \param awesomeconf awesome config ref
281 * \ingroup ui_callback
284 uicb_tag_prev_selected(Display
* disp
,
286 awesome_config
*awesomeconf
,
287 const char *arg
__attribute__ ((unused
)))
292 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
294 t
= awesomeconf
->tags
[i
].selected
;
295 awesomeconf
->tags
[i
].selected
= awesomeconf
->tags
[i
].was_selected
;
296 awesomeconf
->tags
[i
].was_selected
= t
;
298 arrange(disp
, drawcontext
, awesomeconf
);
302 * \param disp Display ref
303 * \param drawcontext Drawcontext ref
305 * \ingroup ui_callback
308 uicb_tag_viewnext(Display
*disp
,
310 awesome_config
*awesomeconf
,
311 const char *arg
__attribute__ ((unused
)))
316 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
318 if(firsttag
< 0 && awesomeconf
->tags
[i
].selected
)
320 awesomeconf
->tags
[i
].selected
= False
;
322 if(++firsttag
>= awesomeconf
->ntags
)
324 awesomeconf
->tags
[firsttag
].selected
= True
;
325 saveawesomeprops(disp
, awesomeconf
);
326 arrange(disp
, drawcontext
, awesomeconf
);
329 /** View previous tag
330 * \param disp Display ref
331 * \param drawcontext Drawcontext ref
333 * \ingroup ui_callback
336 uicb_tag_viewprev(Display
*disp
,
338 awesome_config
*awesomeconf
,
339 const char *arg
__attribute__ ((unused
)))
344 for(i
= awesomeconf
->ntags
- 1; i
>= 0; i
--)
346 if(firsttag
< 0 && awesomeconf
->tags
[i
].selected
)
348 awesomeconf
->tags
[i
].selected
= False
;
351 firsttag
= awesomeconf
->ntags
- 1;
352 awesomeconf
->tags
[firsttag
].selected
= True
;
353 saveawesomeprops(disp
, awesomeconf
);
354 arrange(disp
, drawcontext
, awesomeconf
);