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 for(r
= globalconf
.rules
; r
; r
= r
->next
)
90 if(r
->icon
&& client_match_rule(c
, r
))
92 area
= draw_get_image_size(r
->icon
);
93 icon_width
= ((double) widget
->statusbar
->height
/ (double) area
.height
) * area
.width
;
95 widget
->area
.x
+ box_width
* i
,
97 widget
->statusbar
->height
,
101 if(!icon_width
&& (icon
= ewmh_get_window_icon(c
->win
)))
103 icon_width
= ((double) widget
->statusbar
->height
/ (double) icon
->height
)
105 draw_image_from_argb_data(ctx
,
106 widget
->area
.x
+ box_width
* i
,
108 icon
->width
, icon
->height
,
109 widget
->statusbar
->height
, icon
->image
);
110 p_delete(&icon
->image
);
117 draw_text(ctx
, widget
->area
.x
+ icon_width
+ box_width
* i
,
119 box_width
- icon_width
,
120 widget
->statusbar
->height
,
122 widget
->font
->height
/ 2, widget
->font
, c
->name
,
123 d
->fg_sel
, d
->bg_sel
);
126 draw_text(ctx
, widget
->area
.x
+ icon_width
+ box_width
* i
,
128 box_width
- icon_width
,
129 widget
->statusbar
->height
,
131 widget
->font
->height
/ 2, widget
->font
, c
->name
,
134 draw_circle(ctx
, widget
->area
.x
+ icon_width
+ box_width
* i
,
136 (widget
->font
->height
+ 2) / 4,
141 widget
->area
.width
= widget
->statusbar
->width
- used
;
142 widget
->area
.height
= widget
->statusbar
->height
;
144 return widget
->area
.width
;
148 tasklist_button_press(Widget
*widget
, XButtonPressedEvent
*ev
)
152 Data
*d
= widget
->data
;
154 int n
= 0, box_width
= 0, i
= 0, ci
= 0;
156 /* button1 give focus */
157 if(ev
->button
== Button1
&& CLEANMASK(ev
->state
) == NoSymbol
)
159 for(c
= globalconf
.clients
; c
; c
= c
->next
)
160 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
))
166 box_width
= widget
->area
.width
/ n
;
168 if(ev
->button
== Button1
&& CLEANMASK(ev
->state
) == NoSymbol
)
170 switch(widget
->statusbar
->position
)
174 ci
= (ev
->x
- widget
->area
.x
) / box_width
;
177 ci
= (ev
->y
- widget
->area
.x
) / box_width
;
180 ci
= ((widget
->statusbar
->width
- ev
->y
) - widget
->area
.x
) / box_width
;
183 /* found first visible client */
184 for(c
= globalconf
.clients
;
185 c
&& !ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
);
187 /* found ci-th visible client */
188 for(; c
&& i
< ci
; c
= c
->next
)
189 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
, d
->show_all
))
192 /* first switch tag if client not visible */
193 if(!client_isvisible(c
, widget
->statusbar
->screen
))
194 for(i
= 0, tag
= globalconf
.screens
[c
->screen
].tags
; tag
; tag
= tag
->next
, i
++)
195 if(is_client_tagged(c
, tag
))
196 tag_view(c
->screen
, i
);
197 focus(c
, True
, widget
->statusbar
->screen
);
203 for(b
= widget
->buttons
; b
; b
= b
->next
)
204 if(ev
->button
== b
->button
&& CLEANMASK(ev
->state
) == b
->mod
&& b
->func
)
206 b
->func(widget
->statusbar
->screen
, b
->arg
);
212 tasklist_new(Statusbar
*statusbar
, cfg_t
*config
)
217 int phys_screen
= get_phys_screen(statusbar
->screen
);
219 w
= p_new(Widget
, 1);
220 widget_common_new(w
, statusbar
, config
);
221 w
->draw
= tasklist_draw
;
222 w
->button_press
= tasklist_button_press
;
223 w
->alignment
= AlignFlex
;
224 w
->data
= d
= p_new(Data
, 1);
226 if((buf
= cfg_getstr(config
, "fg")))
227 d
->fg
= initxcolor(phys_screen
, buf
);
229 d
->fg
= globalconf
.screens
[statusbar
->screen
].colors_normal
[ColFG
];
231 if((buf
= cfg_getstr(config
, "bg")))
232 d
->bg
= initxcolor(phys_screen
, buf
);
234 d
->bg
= globalconf
.screens
[statusbar
->screen
].colors_normal
[ColBG
];
236 if((buf
= cfg_getstr(config
, "focus_bg")))
237 d
->bg_sel
= initxcolor(phys_screen
, buf
);
239 d
->bg_sel
= globalconf
.screens
[statusbar
->screen
].colors_selected
[ColBG
];
241 if((buf
= cfg_getstr(config
, "focus_fg")))
242 d
->fg_sel
= initxcolor(phys_screen
, buf
);
244 d
->fg_sel
= globalconf
.screens
[statusbar
->screen
].colors_selected
[ColFG
];
246 d
->align
= draw_get_align(cfg_getstr(config
, "align"));
247 d
->show_icons
= cfg_getbool(config
, "show_icons");
248 d
->show_all
= cfg_getbool(config
, "show_all");
250 if((buf
= cfg_getstr(config
, "font")))
251 w
->font
= XftFontOpenName(globalconf
.display
, get_phys_screen(statusbar
->screen
), buf
);
254 w
->font
= globalconf
.screens
[statusbar
->screen
].font
;
259 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80