]> Dogcows Code - chaz/tint2/blob - src/taskbar/taskbar.c
*fix* correct comparison whether task_icon_asb is set
[chaz/tint2] / src / taskbar / taskbar.c
1 /**************************************************************************
2 *
3 * Tint2 : taskbar
4 *
5 * Copyright (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2
9 * as published by the Free Software Foundation.
10 *
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **************************************************************************/
19
20 #include <X11/Xlib.h>
21 #include <X11/Xutil.h>
22 #include <X11/Xatom.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <glib.h>
27 #include <Imlib2.h>
28
29 #include "task.h"
30 #include "taskbar.h"
31 #include "server.h"
32 #include "window.h"
33 #include "panel.h"
34
35
36 /* win_to_task_table holds for every Window an array of tasks. Usually the array contains only one
37 element. However for omnipresent windows (windows which are visible in every taskbar) the array
38 contains to every Task* on each panel a pointer (i.e. GPtrArray.len == server.nb_desktop)
39 */
40 GHashTable* win_to_task_table = 0;
41
42 guint win_hash(gconstpointer key) { return (guint)*((Window*)key); }
43 gboolean win_compare(gconstpointer a, gconstpointer b) { return (*((Window*)a) == *((Window*)b)); }
44 void free_ptr_array(gpointer data) { g_ptr_array_free(data, 1); }
45
46 void init_taskbar()
47 {
48 Panel *panel;
49 int i, j;
50
51 if (win_to_task_table == 0)
52 win_to_task_table = g_hash_table_new_full(win_hash, win_compare, free, free_ptr_array);
53
54 for (i=0 ; i < nb_panel ; i++) {
55 panel = &panel1[i];
56
57 if (panel->taskbar) {
58 free(panel->taskbar);
59 panel->taskbar = 0;
60 }
61
62 if (panel->g_taskbar.bg == 0) {
63 panel->g_taskbar.bg = &g_array_index(backgrounds, Background, 0);
64 panel->g_taskbar.area.bg = panel->g_taskbar.bg;
65 }
66 if (panel->g_taskbar.bg_active == 0)
67 panel->g_taskbar.bg_active = &g_array_index(backgrounds, Background, 0);
68 if (panel->g_task.area.bg == 0)
69 panel->g_task.area.bg = &g_array_index(backgrounds, Background, 0);
70
71 // taskbar
72 panel->g_taskbar.area._resize = resize_taskbar;
73 panel->g_taskbar.area.redraw = 1;
74 panel->g_taskbar.area.on_screen = 1;
75 if (panel_horizontal) {
76 panel->g_taskbar.area.posy = panel->area.bg->border.width + panel->area.paddingy;
77 panel->g_taskbar.area.height = panel->area.height - (2 * panel->g_taskbar.area.posy);
78 }
79 else {
80 panel->g_taskbar.area.posx = panel->area.bg->border.width + panel->area.paddingy;
81 panel->g_taskbar.area.width = panel->area.width - (2 * panel->g_taskbar.area.posx);
82 }
83
84 // task
85 panel->g_task.area._draw_foreground = draw_task;
86 panel->g_task.area.redraw = 1;
87 panel->g_task.area.on_screen = 1;
88 if ((panel->g_task.config_asb_mask & (1<<TASK_NORMAL)) == 0) {
89 panel->g_task.alpha[TASK_NORMAL] = 100;
90 panel->g_task.saturation[TASK_NORMAL] = 0;
91 panel->g_task.brightness[TASK_NORMAL] = 0;
92 }
93 if ((panel->g_task.config_asb_mask & (1<<TASK_ACTIVE)) == 0) {
94 panel->g_task.alpha[TASK_ACTIVE] = panel->g_task.alpha[TASK_NORMAL];
95 panel->g_task.saturation[TASK_ACTIVE] = panel->g_task.saturation[TASK_NORMAL];
96 panel->g_task.brightness[TASK_ACTIVE] = panel->g_task.brightness[TASK_NORMAL];
97 }
98 if ((panel->g_task.config_asb_mask & (1<<TASK_ICONIFIED)) == 0) {
99 panel->g_task.alpha[TASK_ICONIFIED] = panel->g_task.alpha[TASK_NORMAL];
100 panel->g_task.saturation[TASK_ICONIFIED] = panel->g_task.saturation[TASK_NORMAL];
101 panel->g_task.brightness[TASK_ICONIFIED] = panel->g_task.brightness[TASK_NORMAL];
102 }
103 if ((panel->g_task.config_asb_mask & (1<<TASK_URGENT)) == 0) {
104 panel->g_task.alpha[TASK_URGENT] = panel->g_task.alpha[TASK_ACTIVE];
105 panel->g_task.saturation[TASK_URGENT] = panel->g_task.saturation[TASK_ACTIVE];
106 panel->g_task.brightness[TASK_URGENT] = panel->g_task.brightness[TASK_ACTIVE];
107 }
108 if ((panel->g_task.config_font_mask & (1<<TASK_NORMAL)) == 0) panel->g_task.font[TASK_NORMAL] = (Color){{0, 0, 0}, 0};
109 if ((panel->g_task.config_font_mask & (1<<TASK_ACTIVE)) == 0) panel->g_task.font[TASK_ACTIVE] = panel->g_task.font[TASK_NORMAL];
110 if ((panel->g_task.config_font_mask & (1<<TASK_ICONIFIED)) == 0) panel->g_task.font[TASK_ICONIFIED] = panel->g_task.font[TASK_NORMAL];
111 if ((panel->g_task.config_font_mask & (1<<TASK_URGENT)) == 0) panel->g_task.font[TASK_URGENT] = panel->g_task.font[TASK_ACTIVE];
112 if ((panel->g_task.config_font_mask & (1<<TASK_NORMAL)) == 0) panel->g_task.background[TASK_NORMAL] = &g_array_index(backgrounds, Background, 0);
113 if ((panel->g_task.config_background_mask & (1<<TASK_ACTIVE)) == 0) panel->g_task.background[TASK_ACTIVE] = panel->g_task.background[TASK_NORMAL];
114 if ((panel->g_task.config_background_mask & (1<<TASK_ICONIFIED)) == 0) panel->g_task.background[TASK_ICONIFIED] = panel->g_task.background[TASK_NORMAL];
115 if ((panel->g_task.config_background_mask & (1<<TASK_URGENT)) == 0) panel->g_task.background[TASK_URGENT] = panel->g_task.background[TASK_ACTIVE];
116
117 if (panel_horizontal) {
118 panel->g_task.area.posy = panel->g_taskbar.area.posy + panel->g_taskbar.bg->border.width + panel->g_taskbar.area.paddingy;
119 panel->g_task.area.height = panel->area.height - (2 * panel->g_task.area.posy);
120 }
121 else {
122 panel->g_task.area.posx = panel->g_taskbar.area.posx + panel->g_taskbar.bg->border.width + panel->g_taskbar.area.paddingy;
123 panel->g_task.area.width = panel->area.width - (2 * panel->g_task.area.posx);
124 panel->g_task.area.height = panel->g_task.maximum_height;
125 }
126
127 int k;
128 for (k=0; k<TASK_STATE_COUNT; ++k) {
129 if (panel->g_task.background[k]->border.rounded > panel->g_task.area.height/2) {
130 printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", k==0 ? "_" : k==1 ? "_active_" : k==2 ? "_iconified_" : "_urgent_");
131 g_array_append_val(backgrounds, *panel->g_task.background[k]);
132 panel->g_task.background[k] = &g_array_index(backgrounds, Background, backgrounds->len-1);
133 panel->g_task.background[k]->border.rounded = panel->g_task.area.height/2;
134 }
135 }
136
137 // compute vertical position : text and icon
138 int height_ink, height;
139 get_text_size(panel->g_task.font_desc, &height_ink, &height, panel->area.height, "TAjpg", 5);
140
141 if (!panel->g_task.maximum_width && panel_horizontal)
142 panel->g_task.maximum_width = server.monitor[panel->monitor].width;
143
144 panel->g_task.text_posx = panel->g_task.background[0]->border.width + panel->g_task.area.paddingxlr;
145 panel->g_task.text_posy = (panel->g_task.area.height - height) / 2.0;
146 if (panel->g_task.icon) {
147 panel->g_task.icon_size1 = panel->g_task.area.height - (2 * panel->g_task.area.paddingy);
148 panel->g_task.text_posx += panel->g_task.icon_size1;
149 panel->g_task.icon_posy = (panel->g_task.area.height - panel->g_task.icon_size1) / 2;
150 }
151 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
152
153 Taskbar *tskbar;
154 panel->nb_desktop = server.nb_desktop;
155 panel->taskbar = calloc(panel->nb_desktop, sizeof(Taskbar));
156 for (j=0 ; j < panel->nb_desktop ; j++) {
157 tskbar = &panel->taskbar[j];
158 memcpy(&tskbar->area, &panel->g_taskbar, sizeof(Area));
159 tskbar->desktop = j;
160 if (j == server.desktop && panel->g_taskbar.use_active)
161 tskbar->area.bg = panel->g_taskbar.bg_active;
162
163 // add taskbar to the panel
164 panel->area.list = g_slist_append(panel->area.list, tskbar);
165 }
166 }
167 }
168
169 void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data) {remove_task(task_get_task(*(Window*)key)); }
170 void cleanup_taskbar()
171 {
172 Panel *panel;
173 Taskbar *tskbar;
174 int i, j;
175
176 if (win_to_task_table) g_hash_table_foreach(win_to_task_table, taskbar_remove_task, 0);
177 for (i=0 ; i < nb_panel ; i++) {
178 panel = &panel1[i];
179 for (j=0 ; j < panel->nb_desktop ; j++) {
180 tskbar = &panel->taskbar[j];
181 free_area (&tskbar->area);
182 // remove taskbar from the panel
183 panel->area.list = g_slist_remove(panel->area.list, tskbar);
184 }
185 if (panel->taskbar) {
186 free(panel->taskbar);
187 panel->taskbar = 0;
188 }
189 }
190
191 if (win_to_task_table) {
192 g_hash_table_destroy(win_to_task_table);
193 win_to_task_table = 0;
194 }
195 }
196
197
198 Task *task_get_task (Window win)
199 {
200 GPtrArray* task_group = task_get_tasks(win);
201 if (task_group)
202 return g_ptr_array_index(task_group, 0);
203 else
204 return 0;
205 }
206
207
208 GPtrArray* task_get_tasks(Window win)
209 {
210 return g_hash_table_lookup(win_to_task_table, &win);
211 }
212
213
214 void task_refresh_tasklist ()
215 {
216 Window *win;
217 int num_results, i;
218
219 win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results);
220 if (!win) return;
221
222 // Remove any old and set active win
223 // remark from Andreas: This seems unneccessary...
224 // active_task();
225
226 GList* win_list = g_hash_table_get_keys(win_to_task_table);
227 GList* it;
228 for (it=win_list; it; it=it->next) {
229 for (i = 0; i < num_results; i++)
230 if (*((Window*)it->data) == win[i])
231 break;
232 if (i == num_results)
233 taskbar_remove_task(it->data, 0, 0);
234 }
235 g_list_free(win_list);
236
237 // Add any new
238 for (i = 0; i < num_results; i++)
239 if (!task_get_task (win[i]))
240 add_task (win[i]);
241
242 XFree (win);
243 }
244
245
246 void resize_taskbar(void *obj)
247 {
248 Taskbar *taskbar = (Taskbar*)obj;
249 Panel *panel = (Panel*)taskbar->area.panel;
250 Task *tsk;
251 GSList *l;
252 int task_count, border_width;
253
254 //printf("resize_taskbar : posx et width des taches\n");
255 taskbar->area.redraw = 1;
256
257 border_width = taskbar->area.bg->border.width;
258
259 if (panel_horizontal) {
260 int pixel_width, modulo_width=0;
261 int x, taskbar_width;
262
263 // new task width for 'desktop'
264 task_count = g_slist_length(taskbar->area.list);
265 if (!task_count) pixel_width = panel->g_task.maximum_width;
266 else {
267 taskbar_width = taskbar->area.width - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr);
268 if (task_count>1) taskbar_width -= ((task_count-1) * panel->g_taskbar.area.paddingx);
269
270 pixel_width = taskbar_width / task_count;
271 if (pixel_width > panel->g_task.maximum_width)
272 pixel_width = panel->g_task.maximum_width;
273 else
274 modulo_width = taskbar_width % task_count;
275 }
276
277 taskbar->task_width = pixel_width;
278 taskbar->task_modulo = modulo_width;
279 taskbar->text_width = pixel_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx;
280
281 // change pos_x and width for all tasks
282 x = taskbar->area.posx + border_width + taskbar->area.paddingxlr;
283 for (l = taskbar->area.list; l ; l = l->next) {
284 tsk = l->data;
285 if (!tsk->area.on_screen) continue;
286 tsk->area.posx = x;
287 set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id)
288 tsk->area.width = pixel_width;
289 if (modulo_width) {
290 tsk->area.width++;
291 modulo_width--;
292 }
293
294 x += tsk->area.width + panel->g_taskbar.area.paddingx;
295 }
296 }
297 else {
298 int pixel_height, modulo_height=0;
299 int y, taskbar_height;
300
301 // new task width for 'desktop'
302 task_count = g_slist_length(taskbar->area.list);
303 if (!task_count) pixel_height = panel->g_task.maximum_height;
304 else {
305 taskbar_height = taskbar->area.height - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr);
306 if (task_count>1) taskbar_height -= ((task_count-1) * panel->g_taskbar.area.paddingx);
307
308 pixel_height = taskbar_height / task_count;
309 if (pixel_height > panel->g_task.maximum_height)
310 pixel_height = panel->g_task.maximum_height;
311 else
312 modulo_height = taskbar_height % task_count;
313 }
314
315 taskbar->task_width = pixel_height;
316 taskbar->task_modulo = modulo_height;
317 taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.area.paddingy) - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx;
318
319 // change pos_y and height for all tasks
320 y = taskbar->area.posy + border_width + taskbar->area.paddingxlr;
321 for (l = taskbar->area.list; l ; l = l->next) {
322 tsk = l->data;
323 if (!tsk->area.on_screen) continue;
324 tsk->area.posy = y;
325 set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id)
326 tsk->area.height = pixel_height;
327 if (modulo_height) {
328 tsk->area.height++;
329 modulo_height--;
330 }
331
332 y += tsk->area.height + panel->g_taskbar.area.paddingx;
333 }
334 }
335 }
This page took 0.054247 seconds and 5 git commands to generate.