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 */
37 static Regs
*regs
= NULL
;
39 /** This function returns the index of
40 * the tag given un argument in *tags
41 * \param tag_to_find tag name
42 * \param tags tag list
43 * \param ntags number of tags in tag list
44 * \return index of tag
47 idxoftag(const char *tag_to_find
, Tag
*tags
, int ntags
)
54 for(i
= 0; i
< ntags
; i
++)
55 if(!a_strcmp(tags
[i
].name
, tag_to_find
))
62 applyrules(Client
* c
, awesome_config
*awesomeconf
)
67 XClassHint ch
= { 0, 0 };
70 XGetClassHint(c
->display
, c
->win
, &ch
);
72 len
= a_strlen(ch
.res_class
) + a_strlen(ch
.res_name
) + a_strlen(c
->name
);
74 prop
= p_new(char, len
+ 3);
77 snprintf(prop
, len
+ 3, "%s:%s:%s",
78 ch
.res_class
? ch
.res_class
: "", ch
.res_name
? ch
.res_name
: "", c
->name
);
79 for(i
= 0; i
< awesomeconf
->nrules
; i
++)
80 if(regs
[i
].propregex
&& !regexec(regs
[i
].propregex
, prop
, 1, &tmp
, 0))
82 c
->isfloating
= awesomeconf
->rules
[i
].isfloating
;
83 for(j
= 0; regs
[i
].tagregex
&& j
< awesomeconf
->ntags
; j
++)
84 if(!regexec(regs
[i
].tagregex
, awesomeconf
->tags
[j
].name
, 1, &tmp
, 0))
96 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
97 c
->tags
[i
] = awesomeconf
->tags
[i
].selected
;
101 compileregs(Rule
* rules
, int nrules
)
108 regs
= p_new(Regs
, nrules
);
109 for(i
= 0; i
< nrules
; i
++)
113 reg
= p_new(regex_t
, 1);
114 if(regcomp(reg
, rules
[i
].prop
, REG_EXTENDED
))
117 regs
[i
].propregex
= reg
;
121 reg
= p_new(regex_t
, 1);
122 if(regcomp(reg
, rules
[i
].tags
, REG_EXTENDED
))
125 regs
[i
].tagregex
= reg
;
131 /** Returns True if a client is tagged
132 * with one of the tags
134 * \param tags tag to check
135 * \param ntags number of tags in *tags
136 * \return True or False
139 isvisible(Client
* c
, int screen
, Tag
* tags
, int ntags
)
143 if(c
->screen
!= screen
)
146 for(i
= 0; i
< ntags
; i
++)
147 if(c
->tags
[i
] && tags
[i
].selected
)
153 /** Tag selected window with tag
154 * \param disp Display ref
155 * \param drawcontext Drawcontext ref
156 * \param arg Tag name
157 * \ingroup ui_callback
160 uicb_tag(Display
*disp
,
162 awesome_config
*awesomeconf
,
169 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
170 sel
->tags
[i
] = arg
== NULL
;
171 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
172 if(i
>= 0 && i
< awesomeconf
->ntags
)
174 saveprops(sel
, awesomeconf
->ntags
);
175 arrange(disp
, drawcontext
, awesomeconf
);
178 /** Toggle floating state of a client
179 * \param disp Display ref
180 * \param drawcontext Drawcontext ref
182 * \ingroup ui_callback
185 uicb_togglefloating(Display
*disp
,
187 awesome_config
* awesomeconf
,
188 const char *arg
__attribute__ ((unused
)))
192 sel
->isfloating
= !sel
->isfloating
;
194 /*restore last known float dimensions*/
195 resize(sel
, sel
->rx
, sel
->ry
, sel
->rw
, sel
->rh
, True
);
198 /*save last known float dimensions*/
204 saveprops(sel
, awesomeconf
->ntags
);
205 arrange(disp
, drawcontext
, awesomeconf
);
209 * \param disp Display ref
210 * \param drawcontext Drawcontext ref
211 * \param arg Tag name
212 * \ingroup ui_callback
215 uicb_toggletag(Display
*disp
,
217 awesome_config
*awesomeconf
,
225 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
226 sel
->tags
[i
] = !sel
->tags
[i
];
227 for(j
= 0; j
< awesomeconf
->ntags
&& !sel
->tags
[j
]; j
++);
228 if(j
== awesomeconf
->ntags
)
230 saveprops(sel
, awesomeconf
->ntags
);
231 arrange(disp
, drawcontext
, awesomeconf
);
234 /** Add a tag to viewed tags
235 * \param disp Display ref
236 * \param drawcontext Drawcontext ref
237 * \param arg Tag name
238 * \ingroup ui_callback
241 uicb_toggleview(Display
*disp
,
243 awesome_config
*awesomeconf
,
249 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
250 awesomeconf
->tags
[i
].selected
= !awesomeconf
->tags
[i
].selected
;
251 for(j
= 0; j
< awesomeconf
->ntags
&& !awesomeconf
->tags
[j
].selected
; j
++);
252 if(j
== awesomeconf
->ntags
)
253 awesomeconf
->tags
[i
].selected
= True
;
254 saveawesomeprops(disp
, awesomeconf
);
255 arrange(disp
, drawcontext
, awesomeconf
);
259 * \param disp Display ref
260 * \param awesomeconf awesome config ref
261 * \param arg tag to view
262 * \ingroup ui_callback
265 uicb_view(Display
*disp
,
267 awesome_config
*awesomeconf
,
272 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
274 awesomeconf
->tags
[i
].was_selected
= awesomeconf
->tags
[i
].selected
;
275 awesomeconf
->tags
[i
].selected
= arg
== NULL
;
277 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
278 if(i
>= 0 && i
< awesomeconf
->ntags
)
280 awesomeconf
->tags
[i
].selected
= True
;
281 awesomeconf
->current_layout
= awesomeconf
->tags
[i
].layout
;
283 saveawesomeprops(disp
, awesomeconf
);
284 arrange(disp
, drawcontext
, awesomeconf
);
287 /** View previously selected tags
288 * \param disp Display ref
289 * \param awesomeconf awesome config ref
291 * \ingroup ui_callback
294 uicb_tag_prev_selected(Display
* disp
,
296 awesome_config
*awesomeconf
,
297 const char *arg
__attribute__ ((unused
)))
302 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
304 t
= awesomeconf
->tags
[i
].selected
;
305 awesomeconf
->tags
[i
].selected
= awesomeconf
->tags
[i
].was_selected
;
306 awesomeconf
->tags
[i
].was_selected
= t
;
308 arrange(disp
, drawcontext
, awesomeconf
);
312 * \param disp Display ref
313 * \param drawcontext Drawcontext ref
315 * \ingroup ui_callback
318 uicb_tag_viewnext(Display
*disp
,
320 awesome_config
*awesomeconf
,
321 const char *arg
__attribute__ ((unused
)))
326 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
328 if(firsttag
< 0 && awesomeconf
->tags
[i
].selected
)
330 awesomeconf
->tags
[i
].selected
= False
;
332 if(++firsttag
>= awesomeconf
->ntags
)
334 awesomeconf
->tags
[firsttag
].selected
= True
;
335 awesomeconf
->current_layout
= awesomeconf
->tags
[firsttag
].layout
;
336 saveawesomeprops(disp
, awesomeconf
);
337 arrange(disp
, drawcontext
, awesomeconf
);
340 /** View previous tag
341 * \param disp Display ref
342 * \param drawcontext Drawcontext ref
344 * \ingroup ui_callback
347 uicb_tag_viewprev(Display
*disp
,
349 awesome_config
*awesomeconf
,
350 const char *arg
__attribute__ ((unused
)))
355 for(i
= awesomeconf
->ntags
- 1; i
>= 0; i
--)
357 if(firsttag
< 0 && awesomeconf
->tags
[i
].selected
)
359 awesomeconf
->tags
[i
].selected
= False
;
362 firsttag
= awesomeconf
->ntags
- 1;
363 awesomeconf
->tags
[firsttag
].selected
= True
;
364 awesomeconf
->current_layout
= awesomeconf
->tags
[firsttag
].layout
;
365 saveawesomeprops(disp
, awesomeconf
);
366 arrange(disp
, drawcontext
, awesomeconf
);