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