]> Dogcows Code - chaz/tint2/blob - src/taskbar/taskbar.c
cleanup default value on SIGUSR1
[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 = panel->g_taskbar.bg;
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)
170 {
171 remove_task(task_get_task(*(Window*)key));
172 }
173
174 void cleanup_taskbar()
175 {
176 Panel *panel;
177 Taskbar *tskbar;
178 int i, j;
179
180 if (win_to_task_table) g_hash_table_foreach(win_to_task_table, taskbar_remove_task, 0);
181 for (i=0 ; i < nb_panel ; i++) {
182 panel = &panel1[i];
183 for (j=0 ; j < panel->nb_desktop ; j++) {
184 tskbar = &panel->taskbar[j];
185 free_area (&tskbar->area);
186 // remove taskbar from the panel
187 panel->area.list = g_slist_remove(panel->area.list, tskbar);
188 }
189 if (panel->taskbar) {
190 free(panel->taskbar);
191 panel->taskbar = 0;
192 }
193 }
194
195 if (win_to_task_table) {
196 g_hash_table_destroy(win_to_task_table);
197 win_to_task_table = 0;
198 }
199 }
200
201
202 Task *task_get_task (Window win)
203 {
204 GPtrArray* task_group = task_get_tasks(win);
205 if (task_group)
206 return g_ptr_array_index(task_group, 0);
207 else
208 return 0;
209 }
210
211
212 GPtrArray* task_get_tasks(Window win)
213 {
214 return g_hash_table_lookup(win_to_task_table, &win);
215 }
216
217
218 void task_refresh_tasklist ()
219 {
220 Window *win;
221 int num_results, i;
222
223 win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results);
224 if (!win) return;
225
226 // Remove any old and set active win
227 // remark from Andreas: This seems unneccessary...
228 // active_task();
229
230 GList* win_list = g_hash_table_get_keys(win_to_task_table);
231 GList* it;
232 for (it=win_list; it; it=it->next) {
233 for (i = 0; i < num_results; i++)
234 if (*((Window*)it->data) == win[i])
235 break;
236 if (i == num_results)
237 taskbar_remove_task(it->data, 0, 0);
238 }
239 g_list_free(win_list);
240
241 // Add any new
242 for (i = 0; i < num_results; i++)
243 if (!task_get_task (win[i]))
244 add_task (win[i]);
245
246 XFree (win);
247 }
248
249
250 void resize_taskbar(void *obj)
251 {
252 Taskbar *taskbar = (Taskbar*)obj;
253 Panel *panel = (Panel*)taskbar->area.panel;
254 Task *tsk;
255 GSList *l;
256 int task_count, border_width;
257
258 //printf("resize_taskbar : posx et width des taches\n");
259 taskbar->area.redraw = 1;
260
261 border_width = taskbar->area.bg->border.width;
262
263 if (panel_horizontal) {
264 int pixel_width, modulo_width=0;
265 int x, taskbar_width;
266
267 // new task width for 'desktop'
268 task_count = g_slist_length(taskbar->area.list);
269 if (!task_count) pixel_width = panel->g_task.maximum_width;
270 else {
271 taskbar_width = taskbar->area.width - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr);
272 if (task_count>1) taskbar_width -= ((task_count-1) * panel->g_taskbar.area.paddingx);
273
274 pixel_width = taskbar_width / task_count;
275 if (pixel_width > panel->g_task.maximum_width)
276 pixel_width = panel->g_task.maximum_width;
277 else
278 modulo_width = taskbar_width % task_count;
279 }
280
281 taskbar->task_width = pixel_width;
282 taskbar->task_modulo = modulo_width;
283 taskbar->text_width = pixel_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx;
284
285 // change pos_x and width for all tasks
286 x = taskbar->area.posx + border_width + taskbar->area.paddingxlr;
287 for (l = taskbar->area.list; l ; l = l->next) {
288 tsk = l->data;
289 if (!tsk->area.on_screen) continue;
290 tsk->area.posx = x;
291 set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id)
292 tsk->area.width = pixel_width;
293 if (modulo_width) {
294 tsk->area.width++;
295 modulo_width--;
296 }
297
298 x += tsk->area.width + panel->g_taskbar.area.paddingx;
299 }
300 }
301 else {
302 int pixel_height, modulo_height=0;
303 int y, taskbar_height;
304
305 // new task width for 'desktop'
306 task_count = g_slist_length(taskbar->area.list);
307 if (!task_count) pixel_height = panel->g_task.maximum_height;
308 else {
309 taskbar_height = taskbar->area.height - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr);
310 if (task_count>1) taskbar_height -= ((task_count-1) * panel->g_taskbar.area.paddingx);
311
312 pixel_height = taskbar_height / task_count;
313 if (pixel_height > panel->g_task.maximum_height)
314 pixel_height = panel->g_task.maximum_height;
315 else
316 modulo_height = taskbar_height % task_count;
317 }
318
319 taskbar->task_width = pixel_height;
320 taskbar->task_modulo = modulo_height;
321 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;
322
323 // change pos_y and height for all tasks
324 y = taskbar->area.posy + border_width + taskbar->area.paddingxlr;
325 for (l = taskbar->area.list; l ; l = l->next) {
326 tsk = l->data;
327 if (!tsk->area.on_screen) continue;
328 tsk->area.posy = y;
329 set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id)
330 tsk->area.height = pixel_height;
331 if (modulo_height) {
332 tsk->area.height++;
333 modulo_height--;
334 }
335
336 y += tsk->area.height + panel->g_taskbar.area.paddingx;
337 }
338 }
339 }
This page took 0.049571 seconds and 5 git commands to generate.