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
, const 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
,
150 awesome_config
*awesomeconf
,
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
)
162 saveprops(sel
, awesomeconf
->ntags
);
163 arrange(disp
, screen
, drawcontext
, awesomeconf
);
166 /** Toggle floating state of a client
167 * \param disp Display ref
169 * \ingroup ui_callback
172 uicb_togglefloating(Display
*disp
,
175 awesome_config
* awesomeconf
,
176 const char *arg
__attribute__ ((unused
)))
180 sel
->isfloating
= !sel
->isfloating
;
182 /*restore last known float dimensions*/
183 resize(sel
, sel
->rx
, sel
->ry
, sel
->rw
, sel
->rh
, True
);
186 /*save last known float dimensions*/
192 saveprops(sel
, awesomeconf
->ntags
);
193 arrange(disp
, screen
, drawcontext
, awesomeconf
);
197 * \param disp Display ref
198 * \param arg Tag name
199 * \ingroup ui_callback
202 uicb_toggletag(Display
*disp
,
205 awesome_config
*awesomeconf
,
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
)
218 saveprops(sel
, awesomeconf
->ntags
);
219 arrange(disp
, screen
, drawcontext
, awesomeconf
);
222 /** Add a tag to viewed tags
223 * \param disp Display ref
224 * \param arg Tag name
225 * \ingroup ui_callback
228 uicb_toggleview(Display
*disp
,
231 awesome_config
*awesomeconf
,
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
, screen
, awesomeconf
);
243 arrange(disp
, screen
, drawcontext
, awesomeconf
);
247 * \param disp Display ref
248 * \param awesomeconf awesome config ref
249 * \param arg tag to view
250 * \ingroup ui_callback
253 uicb_view(Display
*disp
,
256 awesome_config
*awesomeconf
,
261 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
263 awesomeconf
->prev_selected_tags
[i
] = awesomeconf
->selected_tags
[i
];
264 awesomeconf
->selected_tags
[i
] = arg
== NULL
;
266 i
= idxoftag(arg
, awesomeconf
->tags
, awesomeconf
->ntags
);
267 if(i
>= 0 && i
< awesomeconf
->ntags
)
269 awesomeconf
->selected_tags
[i
] = True
;
270 awesomeconf
->current_layout
= awesomeconf
->tag_layouts
[i
];
272 saveawesomeprops(disp
, screen
, awesomeconf
);
273 arrange(disp
, screen
, drawcontext
, awesomeconf
);
276 /** View previously selected tags
277 * \param disp Display ref
278 * \param awesomeconf awesome config ref
280 * \ingroup ui_callback
283 uicb_viewprevtags(Display
* disp
,
286 awesome_config
*awesomeconf
,
287 const char *arg
__attribute__ ((unused
)))
292 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
294 t
= awesomeconf
->selected_tags
[i
];
295 awesomeconf
->selected_tags
[i
] = awesomeconf
->prev_selected_tags
[i
];
296 awesomeconf
->prev_selected_tags
[i
] = t
;
298 arrange(disp
, screen
, drawcontext
, awesomeconf
);
302 * \param disp Display ref
304 * \ingroup ui_callback
307 uicb_tag_viewnext(Display
*disp
,
310 awesome_config
*awesomeconf
,
311 const char *arg
__attribute__ ((unused
)))
316 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
318 if(firsttag
< 0 && awesomeconf
->selected_tags
[i
])
320 awesomeconf
->selected_tags
[i
] = False
;
322 if(++firsttag
>= awesomeconf
->ntags
)
324 awesomeconf
->selected_tags
[firsttag
] = True
;
325 saveawesomeprops(disp
, screen
, awesomeconf
);
326 arrange(disp
, screen
, drawcontext
, awesomeconf
);
329 /** View previous tag
330 * \param disp Display ref
332 * \ingroup ui_callback
335 uicb_tag_viewprev(Display
*disp
,
336 int screen
__attribute__ ((unused
)),
338 awesome_config
*awesomeconf
,
339 const char *arg
__attribute__ ((unused
)))
344 for(i
= awesomeconf
->ntags
- 1; i
>= 0; i
--)
346 if(firsttag
< 0 && awesomeconf
->selected_tags
[i
])
348 awesomeconf
->selected_tags
[i
] = False
;
351 firsttag
= awesomeconf
->ntags
- 1;
352 awesomeconf
->selected_tags
[firsttag
] = True
;
353 saveawesomeprops(disp
, screen
, awesomeconf
);
354 arrange(disp
, screen
, drawcontext
, awesomeconf
);