2 * tasklist.c - task list widget
4 * Copyright © 2008 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.
34 #define ISVISIBLE_ON_TB(c, nscreen, show_all) ((!show_all && client_isvisible(c, nscreen) && !c->skiptb) \
35 || (show_all && c->screen == nscreen && !c->skiptb))
37 extern AwesomeConf globalconf
;
51 tasklist_draw(Widget
*widget
, DrawCtx
*ctx
, int offset
, int used
)
54 Data
*d
= widget
->data
;
55 Client
*sel
= focus_get_current_client(widget
->statusbar
->screen
);
58 int n
= 0, i
= 0, box_width
= 0, icon_width
= 0;
61 for(c
= globalconf
.clients
; c
; c
= c
->next
)
62 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
))
67 widget
->area
.width
= 0;
68 return widget
->area
.width
;
71 box_width
= (widget
->statusbar
->width
- used
) / n
;
73 if(!widget
->user_supplied_x
)
74 widget
->area
.x
= widget_calculate_offset(widget
->statusbar
->width
,
79 if(!widget
->user_supplied_y
)
80 widget
->area
.y
= widget
->area
.y
= 0;
82 for(c
= globalconf
.clients
; c
; c
= c
->next
)
83 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
))
89 if((r
= rule_matching_client(c
)) && r
->icon
)
91 area
= draw_get_image_size(r
->icon
);
92 icon_width
= ((double) widget
->statusbar
->height
/ (double) area
.height
) * area
.width
;
94 widget
->area
.x
+ box_width
* i
,
96 widget
->statusbar
->height
,
100 if(!icon_width
&& (icon
= ewmh_get_window_icon(c
->win
)))
102 icon_width
= ((double) widget
->statusbar
->height
/ (double) icon
->height
)
104 draw_image_from_argb_data(ctx
,
105 widget
->area
.x
+ box_width
* i
,
107 icon
->width
, icon
->height
,
108 widget
->statusbar
->height
, icon
->image
);
109 p_delete(&icon
->image
);
114 area
.x
= widget
->area
.x
+ icon_width
+ box_width
* i
;
115 area
.y
= widget
->area
.y
;
116 area
.width
= box_width
- icon_width
;
117 area
.height
= widget
->statusbar
->height
;
119 draw_text(ctx
, area
, d
->align
,
120 widget
->font
->height
/ 2, widget
->font
, c
->name
,
121 d
->fg_sel
, d
->bg_sel
);
123 draw_text(ctx
, area
, d
->align
,
124 widget
->font
->height
/ 2, widget
->font
, c
->name
,
127 if(c
->isfloating
|| c
->ismax
)
128 draw_circle(ctx
, widget
->area
.x
+ icon_width
+ box_width
* i
,
130 (widget
->font
->height
+ 2) / 4,
135 widget
->area
.width
= widget
->statusbar
->width
- used
;
136 widget
->area
.height
= widget
->statusbar
->height
;
138 return widget
->area
.width
;
142 tasklist_button_press(Widget
*widget
, XButtonPressedEvent
*ev
)
146 Data
*d
= widget
->data
;
148 int n
= 0, box_width
= 0, i
, ci
= 0;
150 /* button1 give focus */
151 if(ev
->button
== Button1
&& CLEANMASK(ev
->state
) == NoSymbol
)
153 for(c
= globalconf
.clients
; c
; c
= c
->next
)
154 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
))
160 box_width
= widget
->area
.width
/ n
;
162 if(ev
->button
== Button1
&& CLEANMASK(ev
->state
) == NoSymbol
)
164 switch(widget
->statusbar
->position
)
168 ci
= (ev
->x
- widget
->area
.x
) / box_width
;
171 ci
= (ev
->y
- widget
->area
.x
) / box_width
;
174 ci
= ((widget
->statusbar
->width
- ev
->y
) - widget
->area
.x
) / box_width
;
177 /* found first visible client */
178 for(c
= globalconf
.clients
;
179 c
&& !ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
);
181 /* found ci-th visible client */
182 for(i
= 0; c
; c
= c
->next
)
183 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
))
189 /* first switch tag if client not visible */
190 if(!client_isvisible(c
, widget
->statusbar
->screen
))
191 for(i
= 0, tag
= globalconf
.screens
[c
->screen
].tags
; tag
; tag
= tag
->next
, i
++)
192 if(is_client_tagged(c
, tag
))
193 tag_view_only_byindex(c
->screen
, i
);
194 focus(c
, True
, widget
->statusbar
->screen
);
201 for(b
= widget
->buttons
; b
; b
= b
->next
)
202 if(ev
->button
== b
->button
&& CLEANMASK(ev
->state
) == b
->mod
&& b
->func
)
204 b
->func(widget
->statusbar
->screen
, b
->arg
);
210 tasklist_new(Statusbar
*statusbar
, cfg_t
*config
)
215 int phys_screen
= get_phys_screen(statusbar
->screen
);
217 w
= p_new(Widget
, 1);
218 widget_common_new(w
, statusbar
, config
);
219 w
->draw
= tasklist_draw
;
220 w
->button_press
= tasklist_button_press
;
221 w
->alignment
= AlignFlex
;
222 w
->data
= d
= p_new(Data
, 1);
224 if((buf
= cfg_getstr(config
, "fg")))
225 d
->fg
= initxcolor(phys_screen
, buf
);
227 d
->fg
= globalconf
.screens
[statusbar
->screen
].colors_normal
[ColFG
];
229 if((buf
= cfg_getstr(config
, "bg")))
230 d
->bg
= initxcolor(phys_screen
, buf
);
232 d
->bg
= globalconf
.screens
[statusbar
->screen
].colors_normal
[ColBG
];
234 if((buf
= cfg_getstr(config
, "focus_bg")))
235 d
->bg_sel
= initxcolor(phys_screen
, buf
);
237 d
->bg_sel
= globalconf
.screens
[statusbar
->screen
].colors_selected
[ColBG
];
239 if((buf
= cfg_getstr(config
, "focus_fg")))
240 d
->fg_sel
= initxcolor(phys_screen
, buf
);
242 d
->fg_sel
= globalconf
.screens
[statusbar
->screen
].colors_selected
[ColFG
];
244 d
->align
= draw_get_align(cfg_getstr(config
, "align"));
245 d
->show_icons
= cfg_getbool(config
, "show_icons");
246 d
->show_all
= cfg_getbool(config
, "show_all");
248 if((buf
= cfg_getstr(config
, "font")))
249 w
->font
= XftFontOpenName(globalconf
.display
, get_phys_screen(statusbar
->screen
), buf
);
252 w
->font
= globalconf
.screens
[statusbar
->screen
].font
;
254 /* Set cache property */
255 w
->cache
.flags
= WIDGET_CACHE_CLIENTS
;
260 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80