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 * \return index of tag
39 idxoftag(const char *tag_to_find
, char **tags
, int ntags
)
46 for(i
= 0; i
< ntags
; i
++)
47 if(!strcmp(tags
[i
], tag_to_find
))
54 applyrules(Client
* c
, awesome_config
*awesomeconf
)
59 XClassHint ch
= { 0, 0 };
62 len
+= a_strlen(ch
.res_class
) + a_strlen(ch
.res_name
) + a_strlen(c
->name
);
64 prop
= p_new(char, len
+ 1);
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))
87 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
88 c
->tags
[i
] = awesomeconf
->selected_tags
[i
];
92 compileregs(Rule
* rules
, int nrules
)
99 regs
= p_new(Regs
, nrules
);
100 for(i
= 0; i
< nrules
; i
++)
104 reg
= p_new(regex_t
, 1);
105 if(regcomp(reg
, rules
[i
].prop
, REG_EXTENDED
))
108 regs
[i
].propregex
= reg
;
112 reg
= p_new(regex_t
, 1);
113 if(regcomp(reg
, rules
[i
].tags
, REG_EXTENDED
))
116 regs
[i
].tagregex
= reg
;
122 /** Returns True if a client is tagged
123 * with one of the tags
125 * \param tags tag to check
126 * \param ntags number of tags in *tags
127 * \return True or False
130 isvisible(Client
* c
, int screen
, Bool
* tags
, int ntags
)
134 for(i
= 0; i
< ntags
; i
++)
135 if(c
->tags
[i
] && tags
[i
] && c
->screen
== screen
)
141 /** Tag selected window with tag
142 * \param disp Display ref
143 * \param arg Tag name
144 * \ingroup ui_callback
147 uicb_tag(Display
*disp
,
149 awesome_config
*awesomeconf
,
156 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
157 sel
->tags
[i
] = arg
== NULL
;
158 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
159 if(i
>= 0 && i
< awesomeconf
->ntags
)
161 saveprops(sel
, awesomeconf
->ntags
);
162 arrange(disp
, drawcontext
, awesomeconf
);
165 /** Toggle floating state of a client
166 * \param disp Display ref
168 * \ingroup ui_callback
171 uicb_togglefloating(Display
*disp
,
173 awesome_config
* awesomeconf
,
174 const char *arg
__attribute__ ((unused
)))
178 sel
->isfloating
= !sel
->isfloating
;
180 /*restore last known float dimensions*/
181 resize(sel
, sel
->rx
, sel
->ry
, sel
->rw
, sel
->rh
, True
);
184 /*save last known float dimensions*/
190 saveprops(sel
, awesomeconf
->ntags
);
191 arrange(disp
, drawcontext
, awesomeconf
);
195 * \param disp Display ref
196 * \param arg Tag name
197 * \ingroup ui_callback
200 uicb_toggletag(Display
*disp
,
202 awesome_config
*awesomeconf
,
210 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
211 sel
->tags
[i
] = !sel
->tags
[i
];
212 for(j
= 0; j
< awesomeconf
->ntags
&& !sel
->tags
[j
]; j
++);
213 if(j
== awesomeconf
->ntags
)
215 saveprops(sel
, awesomeconf
->ntags
);
216 arrange(disp
, drawcontext
, awesomeconf
);
219 /** Add a tag to viewed tags
220 * \param disp Display ref
221 * \param arg Tag name
222 * \ingroup ui_callback
225 uicb_toggleview(Display
*disp
,
227 awesome_config
*awesomeconf
,
233 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
234 awesomeconf
->selected_tags
[i
] = !awesomeconf
->selected_tags
[i
];
235 for(j
= 0; j
< awesomeconf
->ntags
&& !awesomeconf
->selected_tags
[j
]; j
++);
236 if(j
== awesomeconf
->ntags
)
237 awesomeconf
->selected_tags
[i
] = True
; /* cannot toggle last view */
238 saveawesomeprops(disp
, awesomeconf
);
239 arrange(disp
, drawcontext
, awesomeconf
);
243 * \param disp Display ref
244 * \param awesomeconf awesome config ref
245 * \param arg tag to view
246 * \ingroup ui_callback
249 uicb_view(Display
*disp
,
251 awesome_config
*awesomeconf
,
256 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
258 awesomeconf
->prev_selected_tags
[i
] = awesomeconf
->selected_tags
[i
];
259 awesomeconf
->selected_tags
[i
] = arg
== NULL
;
261 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
262 if(i
>= 0 && i
< awesomeconf
->ntags
)
264 awesomeconf
->selected_tags
[i
] = True
;
265 awesomeconf
->current_layout
= awesomeconf
->tag_layouts
[i
];
267 saveawesomeprops(disp
, awesomeconf
);
268 arrange(disp
, drawcontext
, awesomeconf
);
271 /** View previously selected tags
272 * \param disp Display ref
273 * \param awesomeconf awesome config ref
275 * \ingroup ui_callback
278 uicb_viewprevtags(Display
* disp
,
280 awesome_config
*awesomeconf
,
281 const char *arg
__attribute__ ((unused
)))
286 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
288 t
= awesomeconf
->selected_tags
[i
];
289 awesomeconf
->selected_tags
[i
] = awesomeconf
->prev_selected_tags
[i
];
290 awesomeconf
->prev_selected_tags
[i
] = t
;
292 arrange(disp
, drawcontext
, awesomeconf
);
296 * \param disp Display ref
298 * \ingroup ui_callback
301 uicb_tag_viewnext(Display
*disp
,
303 awesome_config
*awesomeconf
,
304 const char *arg
__attribute__ ((unused
)))
309 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
311 if(firsttag
< 0 && awesomeconf
->selected_tags
[i
])
313 awesomeconf
->selected_tags
[i
] = False
;
315 if(++firsttag
>= awesomeconf
->ntags
)
317 awesomeconf
->selected_tags
[firsttag
] = True
;
318 saveawesomeprops(disp
, awesomeconf
);
319 arrange(disp
, drawcontext
, awesomeconf
);
322 /** View previous tag
323 * \param disp Display ref
325 * \ingroup ui_callback
328 uicb_tag_viewprev(Display
*disp
,
330 awesome_config
*awesomeconf
,
331 const char *arg
__attribute__ ((unused
)))
336 for(i
= awesomeconf
->ntags
- 1; i
>= 0; i
--)
338 if(firsttag
< 0 && awesomeconf
->selected_tags
[i
])
340 awesomeconf
->selected_tags
[i
] = False
;
343 firsttag
= awesomeconf
->ntags
- 1;
344 awesomeconf
->selected_tags
[firsttag
] = True
;
345 saveawesomeprops(disp
, awesomeconf
);
346 arrange(disp
, drawcontext
, awesomeconf
);