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>
28 extern Client
*sel
; /* global client list */
30 static Regs
*regs
= NULL
;
32 /** This function returns the index of
33 * the tag given un argument in *tags
34 * \param tag_to_find tag name
35 * \return index of tag
38 idxoftag(const char *tag_to_find
, const char **tags
, int ntags
)
45 for(i
= 0; i
< ntags
; i
++)
46 if(!strcmp(tags
[i
], tag_to_find
))
53 applyrules(Client
* c
, awesome_config
*awesomeconf
)
58 XClassHint ch
= { 0, 0 };
61 len
+= a_strlen(ch
.res_class
) + a_strlen(ch
.res_name
) + a_strlen(c
->name
);
63 prop
= p_new(char, len
+ 1);
66 XGetClassHint(c
->display
, c
->win
, &ch
);
67 snprintf(prop
, len
+ 1, "%s:%s:%s",
68 ch
.res_class
? ch
.res_class
: "", ch
.res_name
? ch
.res_name
: "", c
->name
);
69 for(i
= 0; i
< awesomeconf
->nrules
; i
++)
70 if(regs
[i
].propregex
&& !regexec(regs
[i
].propregex
, prop
, 1, &tmp
, 0))
72 c
->isfloating
= awesomeconf
->rules
[i
].isfloating
;
73 for(j
= 0; regs
[i
].tagregex
&& j
< awesomeconf
->ntags
; j
++)
74 if(!regexec(regs
[i
].tagregex
, awesomeconf
->tags
[j
], 1, &tmp
, 0))
86 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
87 c
->tags
[i
] = awesomeconf
->selected_tags
[i
];
91 compileregs(Rule
* rules
, int nrules
)
98 regs
= p_new(Regs
, nrules
);
99 for(i
= 0; i
< nrules
; i
++)
103 reg
= p_new(regex_t
, 1);
104 if(regcomp(reg
, rules
[i
].prop
, REG_EXTENDED
))
107 regs
[i
].propregex
= reg
;
111 reg
= p_new(regex_t
, 1);
112 if(regcomp(reg
, rules
[i
].tags
, REG_EXTENDED
))
115 regs
[i
].tagregex
= reg
;
121 /** Returns True if a client is tagged
122 * with one of the tags
124 * \param tags tag to check
125 * \param ntags number of tags in *tags
126 * \return True or False
129 isvisible(Client
* c
, Bool
* tags
, int ntags
)
133 for(i
= 0; i
< ntags
; i
++)
134 if(c
->tags
[i
] && tags
[i
])
140 /** Tag selected window with tag
141 * \param disp Display ref
142 * \param arg Tag name
143 * \ingroup ui_callback
146 uicb_tag(Display
*disp
,
148 awesome_config
*awesomeconf
,
155 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
156 sel
->tags
[i
] = arg
== NULL
;
157 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
158 if(i
>= 0 && i
< awesomeconf
->ntags
)
160 saveprops(sel
, awesomeconf
->ntags
);
161 arrange(disp
, drawcontext
, awesomeconf
);
164 /** Toggle floating state of a client
165 * \param disp Display ref
167 * \ingroup ui_callback
170 uicb_togglefloating(Display
*disp
,
172 awesome_config
* awesomeconf
,
173 const char *arg
__attribute__ ((unused
)))
177 sel
->isfloating
= !sel
->isfloating
;
179 /*restore last known float dimensions*/
180 resize(sel
, sel
->rx
, sel
->ry
, sel
->rw
, sel
->rh
, True
);
183 /*save last known float dimensions*/
189 saveprops(sel
, awesomeconf
->ntags
);
190 arrange(disp
, drawcontext
, awesomeconf
);
194 * \param disp Display ref
195 * \param arg Tag name
196 * \ingroup ui_callback
199 uicb_toggletag(Display
*disp
,
201 awesome_config
*awesomeconf
,
209 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
210 sel
->tags
[i
] = !sel
->tags
[i
];
211 for(j
= 0; j
< awesomeconf
->ntags
&& !sel
->tags
[j
]; j
++);
212 if(j
== awesomeconf
->ntags
)
214 saveprops(sel
, awesomeconf
->ntags
);
215 arrange(disp
, drawcontext
, awesomeconf
);
218 /** Add a tag to viewed tags
219 * \param disp Display ref
220 * \param arg Tag name
221 * \ingroup ui_callback
224 uicb_toggleview(Display
*disp
,
226 awesome_config
*awesomeconf
,
232 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
233 awesomeconf
->selected_tags
[i
] = !awesomeconf
->selected_tags
[i
];
234 for(j
= 0; j
< awesomeconf
->ntags
&& !awesomeconf
->selected_tags
[j
]; j
++);
235 if(j
== awesomeconf
->ntags
)
236 awesomeconf
->selected_tags
[i
] = True
; /* cannot toggle last view */
237 saveawesomeprops(disp
, awesomeconf
);
238 arrange(disp
, drawcontext
, awesomeconf
);
242 * \param disp Display ref
243 * \param awesomeconf awesome config ref
244 * \param arg tag to view
245 * \ingroup ui_callback
248 uicb_view(Display
*disp
,
250 awesome_config
*awesomeconf
,
255 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
257 awesomeconf
->prev_selected_tags
[i
] = awesomeconf
->selected_tags
[i
];
258 awesomeconf
->selected_tags
[i
] = arg
== NULL
;
260 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
261 if(i
>= 0 && i
< awesomeconf
->ntags
)
263 awesomeconf
->selected_tags
[i
] = True
;
264 awesomeconf
->current_layout
= awesomeconf
->tag_layouts
[i
];
266 saveawesomeprops(disp
, awesomeconf
);
267 arrange(disp
, drawcontext
, awesomeconf
);
270 /** View previously selected tags
271 * \param disp Display ref
272 * \param awesomeconf awesome config ref
274 * \ingroup ui_callback
277 uicb_viewprevtags(Display
* disp
,
279 awesome_config
*awesomeconf
,
280 const char *arg
__attribute__ ((unused
)))
285 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
287 t
= awesomeconf
->selected_tags
[i
];
288 awesomeconf
->selected_tags
[i
] = awesomeconf
->prev_selected_tags
[i
];
289 awesomeconf
->prev_selected_tags
[i
] = t
;
291 arrange(disp
, drawcontext
, awesomeconf
);
295 * \param disp Display ref
297 * \ingroup ui_callback
300 uicb_tag_viewnext(Display
*disp
,
302 awesome_config
*awesomeconf
,
303 const char *arg
__attribute__ ((unused
)))
308 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
310 if(firsttag
< 0 && awesomeconf
->selected_tags
[i
])
312 awesomeconf
->selected_tags
[i
] = False
;
314 if(++firsttag
>= awesomeconf
->ntags
)
316 awesomeconf
->selected_tags
[firsttag
] = True
;
317 saveawesomeprops(disp
, awesomeconf
);
318 arrange(disp
, drawcontext
, awesomeconf
);
321 /** View previous tag
322 * \param disp Display ref
324 * \ingroup ui_callback
327 uicb_tag_viewprev(Display
*disp
,
329 awesome_config
*awesomeconf
,
330 const char *arg
__attribute__ ((unused
)))
335 for(i
= awesomeconf
->ntags
- 1; i
>= 0; i
--)
337 if(firsttag
< 0 && awesomeconf
->selected_tags
[i
])
339 awesomeconf
->selected_tags
[i
] = False
;
342 firsttag
= awesomeconf
->ntags
- 1;
343 awesomeconf
->selected_tags
[firsttag
] = True
;
344 saveawesomeprops(disp
, awesomeconf
);
345 arrange(disp
, drawcontext
, awesomeconf
);