fix toggle floating with Button2 in tileleft layout, and prefix layout functions...
[awesome.git] / tag.c
blobcaa457385f72d9d2ef26f314636d47ebcc009f22
1 /*
2 * tag.c - tag management
3 *
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
5 *
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 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 * \return index of tag
38 static int
39 idxoftag(const char *tag_to_find, char **tags, int ntags)
41 int i;
43 if(!tag_to_find)
44 return 0;
46 for(i = 0; i < ntags; i++)
47 if(!strcmp(tags[i], tag_to_find))
48 return i;
50 return 0;
53 void
54 applyrules(Client * c, awesome_config *awesomeconf)
56 int i, j, len = 0;
57 regmatch_t tmp;
58 Bool matched = False;
59 XClassHint ch = { 0, 0 };
60 char *prop;
62 len += a_strlen(ch.res_class) + a_strlen(ch.res_name) + a_strlen(c->name);
64 prop = p_new(char, len + 1);
66 /* rule matching */
67 XGetClassHint(c->display, c->win, &ch);
68 snprintf(prop, len + 1, "%s:%s:%s",
69 ch.res_class ? ch.res_class : "", ch.res_name ? ch.res_name : "", c->name);
70 for(i = 0; i < awesomeconf->nrules; i++)
71 if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0))
73 c->isfloating = awesomeconf->rules[i].isfloating;
74 for(j = 0; regs[i].tagregex && j < awesomeconf->ntags; j++)
75 if(!regexec(regs[i].tagregex, awesomeconf->tags[j], 1, &tmp, 0))
77 matched = True;
78 c->tags[j] = True;
81 p_delete(&prop);
82 if(ch.res_class)
83 XFree(ch.res_class);
84 if(ch.res_name)
85 XFree(ch.res_name);
86 if(!matched)
87 for(i = 0; i < awesomeconf->ntags; i++)
88 c->tags[i] = awesomeconf->selected_tags[i];
91 void
92 compileregs(Rule * rules, int nrules)
94 int i;
95 regex_t *reg;
97 if(regs)
98 return;
99 regs = p_new(Regs, nrules);
100 for(i = 0; i < nrules; i++)
102 if(rules[i].prop)
104 reg = p_new(regex_t, 1);
105 if(regcomp(reg, rules[i].prop, REG_EXTENDED))
106 p_delete(&reg);
107 else
108 regs[i].propregex = reg;
110 if(rules[i].tags)
112 reg = p_new(regex_t, 1);
113 if(regcomp(reg, rules[i].tags, REG_EXTENDED))
114 p_delete(&reg);
115 else
116 regs[i].tagregex = reg;
122 /** Returns True if a client is tagged
123 * with one of the tags
124 * \param c Client
125 * \param tags tag to check
126 * \param ntags number of tags in *tags
127 * \return True or False
129 Bool
130 isvisible(Client * c, int screen, Bool * tags, int ntags)
132 int i;
134 for(i = 0; i < ntags; i++)
135 if(c->tags[i] && tags[i] && c->screen == screen)
136 return True;
137 return False;
141 /** Tag selected window with tag
142 * \param disp Display ref
143 * \param drawcontext Drawcontext ref
144 * \param arg Tag name
145 * \ingroup ui_callback
147 void
148 uicb_tag(Display *disp,
149 DC *drawcontext,
150 awesome_config *awesomeconf,
151 const char *arg)
153 int i;
155 if(!sel)
156 return;
157 for(i = 0; i < awesomeconf->ntags; i++)
158 sel->tags[i] = arg == NULL;
159 i = idxoftag(arg, awesomeconf->tags, awesomeconf->ntags);
160 if(i >= 0 && i < awesomeconf->ntags)
161 sel->tags[i] = True;
162 saveprops(sel, awesomeconf->ntags);
163 arrange(disp, drawcontext, awesomeconf);
166 /** Toggle floating state of a client
167 * \param disp Display ref
168 * \param drawcontext Drawcontext ref
169 * \param arg unused
170 * \ingroup ui_callback
172 void
173 uicb_togglefloating(Display *disp,
174 DC *drawcontext,
175 awesome_config * awesomeconf,
176 const char *arg __attribute__ ((unused)))
178 if(!sel)
179 return;
180 sel->isfloating = !sel->isfloating;
181 if(sel->isfloating)
182 /*restore last known float dimensions*/
183 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
184 else
186 /*save last known float dimensions*/
187 sel->rx = sel->x;
188 sel->ry = sel->y;
189 sel->rw = sel->w;
190 sel->rh = sel->h;
192 saveprops(sel, awesomeconf->ntags);
193 arrange(disp, drawcontext, awesomeconf);
196 /** Toggle tag view
197 * \param disp Display ref
198 * \param drawcontext Drawcontext ref
199 * \param arg Tag name
200 * \ingroup ui_callback
202 void
203 uicb_toggletag(Display *disp,
204 DC *drawcontext,
205 awesome_config *awesomeconf,
206 const char *arg)
208 unsigned int i;
209 int j;
211 if(!sel)
212 return;
213 i = idxoftag(arg, awesomeconf->tags, awesomeconf->ntags);
214 sel->tags[i] = !sel->tags[i];
215 for(j = 0; j < awesomeconf->ntags && !sel->tags[j]; j++);
216 if(j == awesomeconf->ntags)
217 sel->tags[i] = True;
218 saveprops(sel, awesomeconf->ntags);
219 arrange(disp, drawcontext, awesomeconf);
222 /** Add a tag to viewed tags
223 * \param disp Display ref
224 * \param drawcontext Drawcontext ref
225 * \param arg Tag name
226 * \ingroup ui_callback
228 void
229 uicb_toggleview(Display *disp,
230 DC *drawcontext,
231 awesome_config *awesomeconf,
232 const char *arg)
234 unsigned int i;
235 int j;
237 i = idxoftag(arg, awesomeconf->tags, awesomeconf->ntags);
238 awesomeconf->selected_tags[i] = !awesomeconf->selected_tags[i];
239 for(j = 0; j < awesomeconf->ntags && !awesomeconf->selected_tags[j]; j++);
240 if(j == awesomeconf->ntags)
241 awesomeconf->selected_tags[i] = True; /* cannot toggle last view */
242 saveawesomeprops(disp, awesomeconf);
243 arrange(disp, drawcontext, awesomeconf);
246 /** View tag
247 * \param disp Display ref
248 * \param awesomeconf awesome config ref
249 * \param arg tag to view
250 * \ingroup ui_callback
252 void
253 uicb_view(Display *disp,
254 DC *drawcontext,
255 awesome_config *awesomeconf,
256 const char *arg)
258 int i;
260 for(i = 0; i < awesomeconf->ntags; i++)
262 awesomeconf->prev_selected_tags[i] = awesomeconf->selected_tags[i];
263 awesomeconf->selected_tags[i] = arg == NULL;
265 i = idxoftag(arg, awesomeconf->tags, awesomeconf->ntags);
266 if(i >= 0 && i < awesomeconf->ntags)
268 awesomeconf->selected_tags[i] = True;
269 awesomeconf->current_layout = awesomeconf->tag_layouts[i];
271 saveawesomeprops(disp, awesomeconf);
272 arrange(disp, drawcontext, awesomeconf);
275 /** View previously selected tags
276 * \param disp Display ref
277 * \param awesomeconf awesome config ref
278 * \param arg unused
279 * \ingroup ui_callback
281 void
282 uicb_viewprevtags(Display * disp,
283 DC *drawcontext,
284 awesome_config *awesomeconf,
285 const char *arg __attribute__ ((unused)))
287 int i;
288 Bool t;
290 for(i = 0; i < awesomeconf->ntags; i++)
292 t = awesomeconf->selected_tags[i];
293 awesomeconf->selected_tags[i] = awesomeconf->prev_selected_tags[i];
294 awesomeconf->prev_selected_tags[i] = t;
296 arrange(disp, drawcontext, awesomeconf);
299 /** View next tag
300 * \param disp Display ref
301 * \param drawcontext Drawcontext ref
302 * \param arg unused
303 * \ingroup ui_callback
305 void
306 uicb_tag_viewnext(Display *disp,
307 DC * drawcontext,
308 awesome_config *awesomeconf,
309 const char *arg __attribute__ ((unused)))
311 int i;
312 int firsttag = -1;
314 for(i = 0; i < awesomeconf->ntags; i++)
316 if(firsttag < 0 && awesomeconf->selected_tags[i])
317 firsttag = i;
318 awesomeconf->selected_tags[i] = False;
320 if(++firsttag >= awesomeconf->ntags)
321 firsttag = 0;
322 awesomeconf->selected_tags[firsttag] = True;
323 saveawesomeprops(disp, awesomeconf);
324 arrange(disp, drawcontext, awesomeconf);
327 /** View previous tag
328 * \param disp Display ref
329 * \param drawcontext Drawcontext ref
330 * \param arg unused
331 * \ingroup ui_callback
333 void
334 uicb_tag_viewprev(Display *disp,
335 DC *drawcontext,
336 awesome_config *awesomeconf,
337 const char *arg __attribute__ ((unused)))
339 int i;
340 int firsttag = -1;
342 for(i = awesomeconf->ntags - 1; i >= 0; i--)
344 if(firsttag < 0 && awesomeconf->selected_tags[i])
345 firsttag = i;
346 awesomeconf->selected_tags[i] = False;
348 if(--firsttag < 0)
349 firsttag = awesomeconf->ntags - 1;
350 awesomeconf->selected_tags[firsttag] = True;
351 saveawesomeprops(disp, awesomeconf);
352 arrange(disp, drawcontext, awesomeconf);