awesome-client send now everything in one message
[awesome.git] / widgets / taglist.c
blob2cb42bac1af9c420fb5f662a773287417ef63126
1 /*
2 * taglist.c - tag list widget
4 * Copyright © 2007 Aldo Cortesi <aldo@nullcube.com>
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.
22 #include "config.h"
23 #include "util.h"
24 #include "widget.h"
25 #include "tag.h"
26 #include "event.h"
28 extern AwesomeConf globalconf;
30 /** Check if at least one client is tagged with tag number t and is on screen
31 * screen
32 * \param screen screen number
33 * \param t tag
34 * \return True or False
36 static Bool
37 isoccupied(Tag *t)
39 Client *c;
41 for(c = globalconf.clients; c; c = c->next)
42 if(is_client_tagged(c, t))
43 return True;
44 return False;
47 static Bool
48 isurgent(Tag *t)
50 Client *c;
52 for(c = globalconf.clients; c; c = c->next)
53 if(is_client_tagged(c, t) && c->isurgent)
54 return True;
56 return False;
59 static int
60 taglist_draw(Widget *widget,
61 DrawCtx *ctx,
62 int offset,
63 int used __attribute__ ((unused)))
65 Tag *tag;
66 Client *sel = globalconf.focus->client;
67 VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
68 int w = 0, flagsize;
69 XColor *colors;
71 flagsize = (vscreen.font->height + 2) / 3;
73 widget->area.width = 0;
75 for(tag = vscreen.tags; tag; tag = tag->next)
76 widget->area.width += draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
78 if(!widget->user_supplied_x)
79 widget->area.x = widget_calculate_offset(widget->statusbar->width,
80 widget->area.width,
81 offset,
82 widget->alignment);
84 if(!widget->user_supplied_y)
85 widget->area.y = 0;
87 widget->area.width = 0;
88 for(tag = vscreen.tags; tag; tag = tag->next)
90 w = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
91 if(tag->selected)
92 colors = vscreen.colors_selected;
93 else if(isurgent(tag))
94 colors = vscreen.colors_urgent;
95 else
96 colors = vscreen.colors_normal;
97 draw_text(ctx,
98 widget->area.x + widget->area.width, widget->area.y,
99 w, widget->statusbar->height,
100 AlignCenter,
101 vscreen.font->height / 2,
102 vscreen.font,
103 tag->name,
104 colors[ColFG],
105 colors[ColBG]);
106 if(isoccupied(tag))
107 draw_rectangle(ctx,
108 widget->area.x + widget->area.width, widget->area.y,
109 flagsize, flagsize,
110 sel && is_client_tagged(sel, tag), colors[ColFG]);
111 widget->area.width += w;
114 widget->area.height = widget->statusbar->height;
115 return widget->area.width;
118 static void
119 taglist_button_press(Widget *widget, XButtonPressedEvent *ev)
121 VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
122 Button *b;
123 Tag *tag;
124 char buf[4];
125 int prev_width = 0, width = 0, i = 1;
127 for(b = widget->buttons; b; b = b->next)
128 if(ev->button == b->button && CLEANMASK(ev->state) == b->mod && b->func)
129 switch(widget->statusbar->position)
131 case Top:
132 case Bottom:
133 for(tag = vscreen.tags; tag; tag = tag->next, i++)
135 width = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
136 if(ev->x >= widget->area.x + prev_width
137 && ev->x < widget->area.x + prev_width + width)
139 snprintf(buf, sizeof(buf), "%d", i);
140 b->func(widget->statusbar->screen, buf);
141 return;
143 prev_width += width;
145 break;
146 case Right:
147 for(tag = vscreen.tags; tag; tag = tag->next, i++)
149 width = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
150 if(ev->y >= widget->area.x + prev_width
151 && ev->y < widget->area.x + prev_width + width)
153 snprintf(buf, sizeof(buf), "%d", i);
154 b->func(widget->statusbar->screen, buf);
155 return;
157 prev_width += width;
159 break;
160 default:
161 for(tag = vscreen.tags; tag; tag = tag->next, i++)
163 width = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
164 if(widget->statusbar->width - ev->y >= widget->area.x + prev_width
165 && widget->statusbar->width - ev->y < widget->area.x + prev_width + width)
167 snprintf(buf, sizeof(buf), "%d", i);
168 b->func(widget->statusbar->screen, buf);
169 return;
171 prev_width += width;
173 break;
177 Widget *
178 taglist_new(Statusbar *statusbar, cfg_t *config)
180 Widget *w;
181 w = p_new(Widget, 1);
182 widget_common_new(w, statusbar, config);
183 w->draw = taglist_draw;
184 w->button_press = taglist_button_press;
186 /* Set cache property */
187 w->cache.flags = WIDGET_CACHE_TAGS;
189 return w;
192 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80