]> Dogcows Code - chaz/tint2/blob - src/taskbar/taskbar.c
*fix* stupid mistake corrected
[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 // taskbar
63 panel->g_taskbar.area._resize = resize_taskbar;
64 panel->g_taskbar.area.redraw = 1;
65 panel->g_taskbar.area.on_screen = 1;
66 if (panel_horizontal) {
67 panel->g_taskbar.area.posy = panel->area.bg->border.width + panel->area.paddingy;
68 panel->g_taskbar.area.height = panel->area.height - (2 * panel->g_taskbar.area.posy);
69 }
70 else {
71 panel->g_taskbar.area.posx = panel->area.bg->border.width + panel->area.paddingy;
72 panel->g_taskbar.area.width = panel->area.width - (2 * panel->g_taskbar.area.posx);
73 }
74
75 // task
76 panel->g_task.area._draw_foreground = draw_task;
77 panel->g_task.area.redraw = 1;
78 panel->g_task.area.on_screen = 1;
79 if ((panel->g_task.config_asb_mask & (1<<TASK_ACTIVE)) == 0) {
80 panel->g_task.alpha[TASK_ACTIVE] = panel->g_task.alpha[TASK_NORMAL];
81 panel->g_task.saturation[TASK_ACTIVE] = panel->g_task.saturation[TASK_NORMAL];
82 panel->g_task.brightness[TASK_ACTIVE] = panel->g_task.brightness[TASK_NORMAL];
83 }
84 if ((panel->g_task.config_asb_mask & (1<<TASK_ICONIFIED)) == 0) {
85 panel->g_task.alpha[TASK_ICONIFIED] = panel->g_task.alpha[TASK_NORMAL];
86 panel->g_task.saturation[TASK_ICONIFIED] = panel->g_task.saturation[TASK_NORMAL];
87 panel->g_task.brightness[TASK_ICONIFIED] = panel->g_task.brightness[TASK_NORMAL];
88 }
89 if ((panel->g_task.config_asb_mask & (1<<TASK_URGENT)) == 0) {
90 panel->g_task.alpha[TASK_URGENT] = panel->g_task.alpha[TASK_ACTIVE];
91 panel->g_task.saturation[TASK_URGENT] = panel->g_task.saturation[TASK_ACTIVE];
92 panel->g_task.brightness[TASK_URGENT] = panel->g_task.brightness[TASK_ACTIVE];
93 }
94 if ((panel->g_task.config_font_mask & (1<<TASK_ACTIVE)) == 0) panel->g_task.font[TASK_ACTIVE] = panel->g_task.font[TASK_NORMAL];
95 if ((panel->g_task.config_font_mask & (1<<TASK_ICONIFIED)) == 0) panel->g_task.font[TASK_ICONIFIED] = panel->g_task.font[TASK_NORMAL];
96 if ((panel->g_task.config_font_mask & (1<<TASK_URGENT)) == 0) panel->g_task.font[TASK_URGENT] = panel->g_task.font[TASK_ACTIVE];
97 if ((panel->g_task.config_background_mask & (1<<TASK_ACTIVE)) == 0) panel->g_task.background[TASK_ACTIVE] = panel->g_task.background[TASK_NORMAL];
98 if ((panel->g_task.config_background_mask & (1<<TASK_ICONIFIED)) == 0) panel->g_task.background[TASK_ICONIFIED] = panel->g_task.background[TASK_NORMAL];
99 if ((panel->g_task.config_background_mask & (1<<TASK_URGENT)) == 0) panel->g_task.background[TASK_URGENT] = panel->g_task.background[TASK_ACTIVE];
100
101 if (panel_horizontal) {
102 panel->g_task.area.posy = panel->g_taskbar.area.posy + panel->g_taskbar.bg->border.width + panel->g_taskbar.area.paddingy;
103 panel->g_task.area.height = panel->area.height - (2 * panel->g_task.area.posy);
104 }
105 else {
106 panel->g_task.area.posx = panel->g_taskbar.area.posx + panel->g_taskbar.bg->border.width + panel->g_taskbar.area.paddingy;
107 panel->g_task.area.width = panel->area.width - (2 * panel->g_task.area.posx);
108 panel->g_task.area.height = panel->g_task.maximum_height;
109 }
110
111 int k;
112 for (k=0; k<TASK_STATE_COUNT; ++k) {
113 if (panel->g_task.background[k]->border.rounded > panel->g_task.area.height/2) {
114 printf("task%sbackground_id is too big. Please fix your tint2rc\n", k==0 ? "_" : k==1 ? "_active_" : k==2 ? "_iconified_" : "_urgent_");
115 g_array_append_val(backgrounds, *panel->g_task.background[k]);
116 panel->g_task.background[k] = &g_array_index(backgrounds, Background, backgrounds->len-1);
117 panel->g_task.background[k]->border.rounded = panel->g_task.area.height/2;
118 }
119 }
120
121 // compute vertical position : text and icon
122 int height_ink, height;
123 get_text_size(panel->g_task.font_desc, &height_ink, &height, panel->area.height, "TAjpg", 5);
124
125 if (!panel->g_task.maximum_width && panel_horizontal)
126 panel->g_task.maximum_width = server.monitor[panel->monitor].width;
127
128 panel->g_task.text_posx = panel->g_task.background[0]->border.width + panel->g_task.area.paddingxlr;
129 panel->g_task.text_posy = (panel->g_task.area.height - height) / 2.0;
130 if (panel->g_task.icon) {
131 panel->g_task.icon_size1 = panel->g_task.area.height - (2 * panel->g_task.area.paddingy);
132 panel->g_task.text_posx += panel->g_task.icon_size1;
133 panel->g_task.icon_posy = (panel->g_task.area.height - panel->g_task.icon_size1) / 2;
134 }
135 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
136
137 Taskbar *tskbar;
138 panel->nb_desktop = server.nb_desktop;
139 panel->taskbar = calloc(panel->nb_desktop, sizeof(Taskbar));
140 for (j=0 ; j < panel->nb_desktop ; j++) {
141 tskbar = &panel->taskbar[j];
142 memcpy(&tskbar->area, &panel->g_taskbar, sizeof(Area));
143 tskbar->desktop = j;
144 if (j == server.desktop && panel->g_taskbar.use_active)
145 tskbar->area.bg = panel->g_taskbar.bg_active;
146
147 // add taskbar to the panel
148 panel->area.list = g_slist_append(panel->area.list, tskbar);
149 }
150 }
151 }
152
153 void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data) {remove_task(task_get_task(*(Window*)key)); }
154 void cleanup_taskbar()
155 {
156 Panel *panel;
157 Taskbar *tskbar;
158 int i, j;
159
160 if (win_to_task_table) g_hash_table_foreach(win_to_task_table, taskbar_remove_task, 0);
161 for (i=0 ; i < nb_panel ; i++) {
162 panel = &panel1[i];
163 for (j=0 ; j < panel->nb_desktop ; j++) {
164 tskbar = &panel->taskbar[j];
165 free_area (&tskbar->area);
166 // remove taskbar from the panel
167 panel->area.list = g_slist_remove(panel->area.list, tskbar);
168 }
169 if (panel->taskbar) {
170 free(panel->taskbar);
171 panel->taskbar = 0;
172 }
173 }
174
175 if (win_to_task_table) {
176 g_hash_table_destroy(win_to_task_table);
177 win_to_task_table = 0;
178 }
179 }
180
181
182 Task *task_get_task (Window win)
183 {
184 GPtrArray* task_group = task_get_tasks(win);
185 if (task_group)
186 return g_ptr_array_index(task_group, 0);
187 else
188 return 0;
189 }
190
191
192 GPtrArray* task_get_tasks(Window win)
193 {
194 return g_hash_table_lookup(win_to_task_table, &win);
195 }
196
197
198 void task_refresh_tasklist ()
199 {
200 Window *win;
201 int num_results, i;
202
203 win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results);
204 if (!win) return;
205
206 // Remove any old and set active win
207 // remark from Andreas: This seems unneccessary...
208 // active_task();
209
210 GList* win_list = g_hash_table_get_keys(win_to_task_table);
211 GList* it;
212 for (it=win_list; it; it=it->next) {
213 for (i = 0; i < num_results; i++)
214 if (*((Window*)it->data) == win[i])
215 break;
216 if (i == num_results)
217 taskbar_remove_task(it->data, 0, 0);
218 }
219 g_list_free(win_list);
220
221 // Add any new
222 for (i = 0; i < num_results; i++)
223 if (!task_get_task (win[i]))
224 add_task (win[i]);
225
226 XFree (win);
227 }
228
229
230 void resize_taskbar(void *obj)
231 {
232 Taskbar *taskbar = (Taskbar*)obj;
233 Panel *panel = (Panel*)taskbar->area.panel;
234 Task *tsk;
235 GSList *l;
236 int task_count, border_width;
237
238 //printf("resize_taskbar : posx et width des taches\n");
239 taskbar->area.redraw = 1;
240
241 border_width = taskbar->area.bg->border.width;
242
243 if (panel_horizontal) {
244 int pixel_width, modulo_width=0;
245 int x, taskbar_width;
246
247 // new task width for 'desktop'
248 task_count = g_slist_length(taskbar->area.list);
249 if (!task_count) pixel_width = panel->g_task.maximum_width;
250 else {
251 taskbar_width = taskbar->area.width - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr);
252 if (task_count>1) taskbar_width -= ((task_count-1) * panel->g_taskbar.area.paddingx);
253
254 pixel_width = taskbar_width / task_count;
255 if (pixel_width > panel->g_task.maximum_width)
256 pixel_width = panel->g_task.maximum_width;
257 else
258 modulo_width = taskbar_width % task_count;
259 }
260
261 taskbar->task_width = pixel_width;
262 taskbar->task_modulo = modulo_width;
263 taskbar->text_width = pixel_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx;
264
265 // change pos_x and width for all tasks
266 x = taskbar->area.posx + border_width + taskbar->area.paddingxlr;
267 for (l = taskbar->area.list; l ; l = l->next) {
268 tsk = l->data;
269 if (!tsk->area.on_screen) continue;
270 tsk->area.posx = x;
271 if (tsk->area.width != pixel_width) set_task_redraw(tsk);
272 tsk->area.width = pixel_width;
273 if (modulo_width) {
274 tsk->area.width++;
275 modulo_width--;
276 }
277
278 x += tsk->area.width + panel->g_taskbar.area.paddingx;
279 }
280 }
281 else {
282 int pixel_height, modulo_height=0;
283 int y, taskbar_height;
284
285 // new task width for 'desktop'
286 task_count = g_slist_length(taskbar->area.list);
287 if (!task_count) pixel_height = panel->g_task.maximum_height;
288 else {
289 taskbar_height = taskbar->area.height - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr);
290 if (task_count>1) taskbar_height -= ((task_count-1) * panel->g_taskbar.area.paddingx);
291
292 pixel_height = taskbar_height / task_count;
293 if (pixel_height > panel->g_task.maximum_height)
294 pixel_height = panel->g_task.maximum_height;
295 else
296 modulo_height = taskbar_height % task_count;
297 }
298
299 taskbar->task_width = pixel_height;
300 taskbar->task_modulo = modulo_height;
301 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;
302
303 // change pos_y and height for all tasks
304 y = taskbar->area.posy + border_width + taskbar->area.paddingxlr;
305 for (l = taskbar->area.list; l ; l = l->next) {
306 tsk = l->data;
307 if (!tsk->area.on_screen) continue;
308 tsk->area.posy = y;
309 if (tsk->area.height != pixel_height) set_task_redraw(tsk);
310 tsk->area.height = pixel_height;
311 if (modulo_height) {
312 tsk->area.height++;
313 modulo_height--;
314 }
315
316 y += tsk->area.height + panel->g_taskbar.area.paddingx;
317 }
318 }
319 }
This page took 0.056649 seconds and 5 git commands to generate.