factorize mouse button press event handling for status bar
[awesome.git] / tag.c
blob7a2645ecc7eefb663bf4a5811a83f6a56a4b5ddb
1 /*
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.
22 #include <stdio.h>
23 #include <X11/Xutil.h>
25 #include "layout.h"
26 #include "tag.h"
27 #include "util.h"
29 void
30 applyrules(Client * c, awesome_config *awesomeconf)
32 int i, j, len = 0;
33 regmatch_t tmp;
34 Bool matched = False;
35 XClassHint ch = { 0, 0 };
36 char *prop;
38 XGetClassHint(c->display, c->win, &ch);
40 len = a_strlen(ch.res_class) + a_strlen(ch.res_name) + a_strlen(c->name);
42 prop = p_new(char, len + 3);
44 /* rule matching */
45 snprintf(prop, len + 3, "%s:%s:%s",
46 ch.res_class ? ch.res_class : "", ch.res_name ? ch.res_name : "", c->name);
47 for(i = 0; i < awesomeconf->nrules; i++)
48 if(awesomeconf->rules[i].propregex && !regexec(awesomeconf->rules[i].propregex, prop, 1, &tmp, 0))
50 c->isfloating = awesomeconf->rules[i].isfloating;
51 for(j = 0; awesomeconf->rules[i].tagregex && j < awesomeconf->ntags; j++)
52 if(!regexec(awesomeconf->rules[i].tagregex, awesomeconf->tags[j].name, 1, &tmp, 0))
54 matched = True;
55 c->tags[j] = True;
57 else
58 c->tags[j] = False;
60 p_delete(&prop);
61 if(ch.res_class)
62 XFree(ch.res_class);
63 if(ch.res_name)
64 XFree(ch.res_name);
65 if(!matched)
66 for(i = 0; i < awesomeconf->ntags; i++)
67 c->tags[i] = awesomeconf->tags[i].selected;
70 void
71 compileregs(Rule * rules, int nrules)
73 int i;
74 regex_t *reg;
76 for(i = 0; i < nrules; i++)
78 if(rules[i].prop)
80 reg = p_new(regex_t, 1);
81 if(regcomp(reg, rules[i].prop, REG_EXTENDED))
82 p_delete(&reg);
83 else
84 rules[i].propregex = reg;
86 if(rules[i].tags)
88 reg = p_new(regex_t, 1);
89 if(regcomp(reg, rules[i].tags, REG_EXTENDED))
90 p_delete(&reg);
91 else
92 rules[i].tagregex = reg;
98 /** Returns True if a client is tagged
99 * with one of the tags
100 * \param c Client
101 * \param tags tag to check
102 * \param ntags number of tags in *tags
103 * \return True or False
105 Bool
106 isvisible(Client * c, int screen, Tag * tags, int ntags)
108 int i;
110 if(c->screen != screen)
111 return False;
113 for(i = 0; i < ntags; i++)
114 if(c->tags[i] && tags[i].selected)
115 return True;
116 return False;
120 /** Tag selected window with tag
121 * \param arg Tag name
122 * \ingroup ui_callback
124 void
125 uicb_tag(awesome_config *awesomeconf,
126 const char *arg)
128 int i;
129 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
131 if(!sel)
132 return;
134 for(i = 0; i < awesomeconf->ntags; i++)
135 sel->tags[i] = arg == NULL;
137 i = arg ? atoi(arg) - 1 : 0;
139 if(i >= 0 && i < awesomeconf->ntags)
140 sel->tags[i] = True;
142 saveprops(sel, awesomeconf->ntags);
143 arrange(awesomeconf);
146 /** Toggle floating state of a client
147 * \param arg unused
148 * \ingroup ui_callback
150 void
151 uicb_togglefloating(awesome_config * awesomeconf,
152 const char *arg __attribute__ ((unused)))
154 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
156 if(!sel)
157 return;
159 sel->isfloating = !sel->isfloating;
161 if (arg == NULL)
162 client_resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, awesomeconf, True, False);
163 else
164 client_resize(sel, sel->x, sel->y, sel->w, sel->h, awesomeconf, True, True);
166 saveprops(sel, awesomeconf->ntags);
167 arrange(awesomeconf);
170 /** Toggle tag view
171 * \param arg Tag name
172 * \ingroup ui_callback
174 void
175 uicb_toggletag(awesome_config *awesomeconf,
176 const char *arg)
178 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
179 unsigned int i;
180 int j;
182 if(!sel)
183 return;
184 i = arg ? atoi(arg) - 1 : 0;
185 sel->tags[i] = !sel->tags[i];
186 for(j = 0; j < awesomeconf->ntags && !sel->tags[j]; j++);
187 if(j == awesomeconf->ntags)
188 sel->tags[i] = True;
189 saveprops(sel, awesomeconf->ntags);
190 arrange(awesomeconf);
193 /** Add a tag to viewed tags
194 * \param arg Tag name
195 * \ingroup ui_callback
197 void
198 uicb_toggleview(awesome_config *awesomeconf,
199 const char *arg)
201 unsigned int i;
202 int j;
204 i = arg ? atoi(arg) - 1: 0;
205 awesomeconf->tags[i].selected = !awesomeconf->tags[i].selected;
206 for(j = 0; j < awesomeconf->ntags && !awesomeconf->tags[j].selected; j++);
207 if(j == awesomeconf->ntags)
208 awesomeconf->tags[i].selected = True;
209 saveawesomeprops(awesomeconf);
210 arrange(awesomeconf);
213 /** View tag
214 * \param awesomeconf awesome config ref
215 * \param arg tag to view
216 * \ingroup ui_callback
218 void
219 uicb_view(awesome_config *awesomeconf,
220 const char *arg)
222 int i;
224 for(i = 0; i < awesomeconf->ntags; i++)
226 awesomeconf->tags[i].was_selected = awesomeconf->tags[i].selected;
227 awesomeconf->tags[i].selected = arg == NULL;
230 if(arg)
232 i = atoi(arg) - 1;
233 if(i >= 0 && i < awesomeconf->ntags)
234 awesomeconf->tags[i].selected = True;
237 saveawesomeprops(awesomeconf);
238 arrange(awesomeconf);
241 /** View previously selected tags
242 * \param awesomeconf awesome config ref
243 * \param arg unused
244 * \ingroup ui_callback
246 void
247 uicb_tag_prev_selected(awesome_config *awesomeconf,
248 const char *arg __attribute__ ((unused)))
250 int i;
251 Bool t;
253 for(i = 0; i < awesomeconf->ntags; i++)
255 t = awesomeconf->tags[i].selected;
256 awesomeconf->tags[i].selected = awesomeconf->tags[i].was_selected;
257 awesomeconf->tags[i].was_selected = t;
259 arrange(awesomeconf);
262 /** View next tag
263 * \param arg unused
264 * \ingroup ui_callback
266 void
267 uicb_tag_viewnext(awesome_config *awesomeconf,
268 const char *arg __attribute__ ((unused)))
270 int i;
271 int firsttag = -1;
273 for(i = 0; i < awesomeconf->ntags; i++)
275 if(firsttag < 0 && awesomeconf->tags[i].selected)
276 firsttag = i;
277 awesomeconf->tags[i].selected = False;
279 if(++firsttag >= awesomeconf->ntags)
280 firsttag = 0;
281 awesomeconf->tags[firsttag].selected = True;
282 saveawesomeprops(awesomeconf);
283 arrange(awesomeconf);
286 /** View previous tag
287 * \param arg unused
288 * \ingroup ui_callback
290 void
291 uicb_tag_viewprev(awesome_config *awesomeconf,
292 const char *arg __attribute__ ((unused)))
294 int i;
295 int firsttag = -1;
297 for(i = awesomeconf->ntags - 1; i >= 0; i--)
299 if(firsttag < 0 && awesomeconf->tags[i].selected)
300 firsttag = i;
301 awesomeconf->tags[i].selected = False;
303 if(--firsttag < 0)
304 firsttag = awesomeconf->ntags - 1;
305 awesomeconf->tags[firsttag].selected = True;
306 saveawesomeprops(awesomeconf);
307 arrange(awesomeconf);
309 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99