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.
33 #define ISVISIBLE_ON_TB(c, screen) (client_isvisible(c, screen) && !c->skiptb)
35 extern AwesomeConf globalconf
;
48 tasklist_draw(Widget
*widget
, DrawCtx
*ctx
, int offset
, int used
)
51 Data
*d
= widget
->data
;
52 Client
*sel
= focus_get_current_client(widget
->statusbar
->screen
);
55 int n
= 0, i
= 0, box_width
= 0, icon_width
= 0;
58 for(c
= globalconf
.clients
; c
; c
= c
->next
)
59 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
))
64 widget
->area
.width
= 0;
65 return widget
->area
.width
;
68 box_width
= (widget
->statusbar
->width
- used
) / n
;
70 if(!widget
->user_supplied_x
)
71 widget
->area
.x
= widget_calculate_offset(widget
->statusbar
->width
,
76 if(!widget
->user_supplied_y
)
77 widget
->area
.y
= widget
->area
.y
= 0;
79 for(c
= globalconf
.clients
; c
; c
= c
->next
)
80 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
))
86 for(r
= globalconf
.rules
; r
; r
= r
->next
)
87 if(r
->icon
&& client_match_rule(c
, r
))
89 area
= draw_get_image_size(r
->icon
);
90 icon_width
= ((double) widget
->statusbar
->height
/ (double) area
.height
) * area
.width
;
92 widget
->area
.x
+ box_width
* i
,
94 widget
->statusbar
->height
,
98 if(!icon_width
&& (icon
= ewmh_get_window_icon(c
->win
)))
100 icon_width
= ((double) widget
->statusbar
->height
/ (double) icon
->height
)
102 draw_image_from_argb_data(ctx
,
103 widget
->area
.x
+ box_width
* i
,
105 icon
->width
, icon
->height
,
106 widget
->statusbar
->height
, icon
->image
);
107 p_delete(&icon
->image
);
114 draw_text(ctx
, widget
->area
.x
+ icon_width
+ box_width
* i
,
116 box_width
- icon_width
,
117 widget
->statusbar
->height
,
119 widget
->font
->height
/ 2, widget
->font
, c
->name
,
120 d
->fg_sel
, d
->bg_sel
);
123 draw_text(ctx
, widget
->area
.x
+ icon_width
+ box_width
* i
,
125 box_width
- icon_width
,
126 widget
->statusbar
->height
,
128 widget
->font
->height
/ 2, widget
->font
, c
->name
,
131 draw_circle(ctx
, widget
->area
.x
+ icon_width
+ box_width
* i
,
133 (widget
->font
->height
+ 2) / 4,
138 widget
->area
.width
= widget
->statusbar
->width
- used
;
139 widget
->area
.height
= widget
->statusbar
->height
;
141 return widget
->area
.width
;
145 tasklist_button_press(Widget
*widget
, XButtonPressedEvent
*ev
)
149 int n
= 0, box_width
= 0, i
= 0, ci
= 0;
151 /* button1 give focus */
152 if(ev
->button
== Button1
&& CLEANMASK(ev
->state
) == NoSymbol
)
154 for(c
= globalconf
.clients
; c
; c
= c
->next
)
155 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
))
161 box_width
= widget
->area
.width
/ n
;
163 if(ev
->button
== Button1
&& CLEANMASK(ev
->state
) == NoSymbol
)
165 switch(widget
->statusbar
->position
)
169 ci
= (ev
->x
- widget
->area
.x
) / box_width
;
172 ci
= (ev
->y
- widget
->area
.x
) / box_width
;
175 ci
= ((widget
->statusbar
->width
- ev
->y
) - widget
->area
.x
) / box_width
;
178 /* found first visible client */
179 for(c
= globalconf
.clients
;
180 c
&& !ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
);
182 /* found ci-th visible client */
183 for(; c
&& i
< ci
; c
= c
->next
)
184 if(ISVISIBLE_ON_TB(c
, widget
->statusbar
->screen
))
187 focus(c
, True
, widget
->statusbar
->screen
);
192 for(b
= widget
->buttons
; b
; b
= b
->next
)
193 if(ev
->button
== b
->button
&& CLEANMASK(ev
->state
) == b
->mod
&& b
->func
)
195 b
->func(widget
->statusbar
->screen
, b
->arg
);
201 tasklist_new(Statusbar
*statusbar
, cfg_t
*config
)
206 int phys_screen
= get_phys_screen(statusbar
->screen
);
208 w
= p_new(Widget
, 1);
209 widget_common_new(w
, statusbar
, config
);
210 w
->draw
= tasklist_draw
;
211 w
->button_press
= tasklist_button_press
;
212 w
->alignment
= AlignFlex
;
213 w
->data
= d
= p_new(Data
, 1);
215 if((buf
= cfg_getstr(config
, "fg")))
216 d
->fg
= initxcolor(phys_screen
, buf
);
218 d
->fg
= globalconf
.screens
[statusbar
->screen
].colors_normal
[ColFG
];
220 if((buf
= cfg_getstr(config
, "bg")))
221 d
->bg
= initxcolor(phys_screen
, buf
);
223 d
->bg
= globalconf
.screens
[statusbar
->screen
].colors_normal
[ColBG
];
225 if((buf
= cfg_getstr(config
, "focus_bg")))
226 d
->bg_sel
= initxcolor(phys_screen
, buf
);
228 d
->bg_sel
= globalconf
.screens
[statusbar
->screen
].colors_selected
[ColBG
];
230 if((buf
= cfg_getstr(config
, "focus_fg")))
231 d
->fg_sel
= initxcolor(phys_screen
, buf
);
233 d
->fg_sel
= globalconf
.screens
[statusbar
->screen
].colors_selected
[ColFG
];
235 d
->align
= draw_get_align(cfg_getstr(config
, "align"));
236 d
->show_icons
= cfg_getbool(config
, "show_icons");
238 if((buf
= cfg_getstr(config
, "font")))
239 w
->font
= XftFontOpenName(globalconf
.display
, get_phys_screen(statusbar
->screen
), buf
);
242 w
->font
= globalconf
.screens
[statusbar
->screen
].font
;
247 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80