]>
Dogcows Code - chaz/tint2/blob - src/taskbar/taskbar.c
1 /**************************************************************************
5 * Copyright (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
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.
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 **************************************************************************/
21 #include <X11/Xutil.h>
22 #include <X11/Xatom.h>
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)
40 GHashTable
* win_to_task_table
;
45 guint
win_hash(gconstpointer key
) { return (guint
)*((Window
*)key
); }
46 gboolean
win_compare(gconstpointer a
, gconstpointer b
) { return (*((Window
*)a
) == *((Window
*)b
)); }
47 void free_ptr_array(gpointer data
) { g_ptr_array_free(data
, 1); }
54 if (win_to_task_table
== 0)
55 win_to_task_table
= g_hash_table_new_full(win_hash
, win_compare
, free
, free_ptr_array
);
60 for (i
=0 ; i
< nb_panel
; i
++) {
68 if (panel
->g_taskbar
.bg
== 0) {
69 panel
->g_taskbar
.bg
= &g_array_index(backgrounds
, Background
, 0);
70 panel
->g_taskbar
.area
.bg
= panel
->g_taskbar
.bg
;
72 if (panel
->g_taskbar
.bg_active
== 0)
73 panel
->g_taskbar
.bg_active
= panel
->g_taskbar
.bg
;
74 if (panel
->g_task
.area
.bg
== 0)
75 panel
->g_task
.area
.bg
= &g_array_index(backgrounds
, Background
, 0);
78 panel
->g_taskbar
.area
._resize
= resize_taskbar
;
79 panel
->g_taskbar
.area
.redraw
= 1;
80 panel
->g_taskbar
.area
.on_screen
= 1;
81 if (panel_horizontal
) {
82 panel
->g_taskbar
.area
.posy
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
83 panel
->g_taskbar
.area
.height
= panel
->area
.height
- (2 * panel
->g_taskbar
.area
.posy
);
86 panel
->g_taskbar
.area
.posx
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
87 panel
->g_taskbar
.area
.width
= panel
->area
.width
- (2 * panel
->g_taskbar
.area
.posx
);
91 panel
->g_task
.area
._draw_foreground
= draw_task
;
92 panel
->g_task
.area
.redraw
= 1;
93 panel
->g_task
.area
.on_screen
= 1;
94 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_NORMAL
)) == 0) {
95 panel
->g_task
.alpha
[TASK_NORMAL
] = 100;
96 panel
->g_task
.saturation
[TASK_NORMAL
] = 0;
97 panel
->g_task
.brightness
[TASK_NORMAL
] = 0;
99 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ACTIVE
)) == 0) {
100 panel
->g_task
.alpha
[TASK_ACTIVE
] = panel
->g_task
.alpha
[TASK_NORMAL
];
101 panel
->g_task
.saturation
[TASK_ACTIVE
] = panel
->g_task
.saturation
[TASK_NORMAL
];
102 panel
->g_task
.brightness
[TASK_ACTIVE
] = panel
->g_task
.brightness
[TASK_NORMAL
];
104 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ICONIFIED
)) == 0) {
105 panel
->g_task
.alpha
[TASK_ICONIFIED
] = panel
->g_task
.alpha
[TASK_NORMAL
];
106 panel
->g_task
.saturation
[TASK_ICONIFIED
] = panel
->g_task
.saturation
[TASK_NORMAL
];
107 panel
->g_task
.brightness
[TASK_ICONIFIED
] = panel
->g_task
.brightness
[TASK_NORMAL
];
109 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_URGENT
)) == 0) {
110 panel
->g_task
.alpha
[TASK_URGENT
] = panel
->g_task
.alpha
[TASK_ACTIVE
];
111 panel
->g_task
.saturation
[TASK_URGENT
] = panel
->g_task
.saturation
[TASK_ACTIVE
];
112 panel
->g_task
.brightness
[TASK_URGENT
] = panel
->g_task
.brightness
[TASK_ACTIVE
];
114 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.font
[TASK_NORMAL
] = (Color
){{0, 0, 0}, 0};
115 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.font
[TASK_ACTIVE
] = panel
->g_task
.font
[TASK_NORMAL
];
116 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.font
[TASK_ICONIFIED
] = panel
->g_task
.font
[TASK_NORMAL
];
117 if ((panel
->g_task
.config_font_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.font
[TASK_URGENT
] = panel
->g_task
.font
[TASK_ACTIVE
];
118 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.background
[TASK_NORMAL
] = &g_array_index(backgrounds
, Background
, 0);
119 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.background
[TASK_ACTIVE
] = panel
->g_task
.background
[TASK_NORMAL
];
120 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.background
[TASK_ICONIFIED
] = panel
->g_task
.background
[TASK_NORMAL
];
121 if ((panel
->g_task
.config_background_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.background
[TASK_URGENT
] = panel
->g_task
.background
[TASK_ACTIVE
];
123 if (panel_horizontal
) {
124 panel
->g_task
.area
.posy
= panel
->g_taskbar
.area
.posy
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
125 panel
->g_task
.area
.height
= panel
->area
.height
- (2 * panel
->g_task
.area
.posy
);
128 panel
->g_task
.area
.posx
= panel
->g_taskbar
.area
.posx
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
129 panel
->g_task
.area
.width
= panel
->area
.width
- (2 * panel
->g_task
.area
.posx
);
130 panel
->g_task
.area
.height
= panel
->g_task
.maximum_height
;
134 for (k
=0; k
<TASK_STATE_COUNT
; ++k
) {
135 if (panel
->g_task
.background
[k
]->border
.rounded
> panel
->g_task
.area
.height
/2) {
136 printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", k
==0 ? "_" : k
==1 ? "_active_" : k
==2 ? "_iconified_" : "_urgent_");
137 g_array_append_val(backgrounds
, *panel
->g_task
.background
[k
]);
138 panel
->g_task
.background
[k
] = &g_array_index(backgrounds
, Background
, backgrounds
->len
-1);
139 panel
->g_task
.background
[k
]->border
.rounded
= panel
->g_task
.area
.height
/2;
143 // compute vertical position : text and icon
144 int height_ink
, height
;
145 get_text_size(panel
->g_task
.font_desc
, &height_ink
, &height
, panel
->area
.height
, "TAjpg", 5);
147 if (!panel
->g_task
.maximum_width
&& panel_horizontal
)
148 panel
->g_task
.maximum_width
= server
.monitor
[panel
->monitor
].width
;
150 panel
->g_task
.text_posx
= panel
->g_task
.background
[0]->border
.width
+ panel
->g_task
.area
.paddingxlr
;
151 panel
->g_task
.text_height
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
152 if (panel
->g_task
.icon
) {
153 panel
->g_task
.icon_size1
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
154 panel
->g_task
.text_posx
+= panel
->g_task
.icon_size1
;
155 panel
->g_task
.icon_posy
= (panel
->g_task
.area
.height
- panel
->g_task
.icon_size1
) / 2;
157 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
160 panel
->nb_desktop
= server
.nb_desktop
;
161 panel
->taskbar
= calloc(panel
->nb_desktop
, sizeof(Taskbar
));
162 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
163 tskbar
= &panel
->taskbar
[j
];
164 memcpy(&tskbar
->area
, &panel
->g_taskbar
, sizeof(Area
));
166 if (j
== server
.desktop
&& panel
->g_taskbar
.use_active
)
167 tskbar
->area
.bg
= panel
->g_taskbar
.bg_active
;
169 // add taskbar to the panel
170 panel
->area
.list
= g_slist_append(panel
->area
.list
, tskbar
);
175 void taskbar_remove_task(gpointer key
, gpointer value
, gpointer user_data
)
177 remove_task(task_get_task(*(Window
*)key
));
180 void default_taskbar()
182 win_to_task_table
= 0;
187 void cleanup_taskbar()
193 if (win_to_task_table
) g_hash_table_foreach(win_to_task_table
, taskbar_remove_task
, 0);
194 for (i
=0 ; i
< nb_panel
; i
++) {
196 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
197 tskbar
= &panel
->taskbar
[j
];
198 free_area (&tskbar
->area
);
199 // remove taskbar from the panel
200 panel
->area
.list
= g_slist_remove(panel
->area
.list
, tskbar
);
202 if (panel
->taskbar
) {
203 free(panel
->taskbar
);
208 if (win_to_task_table
) {
209 g_hash_table_destroy(win_to_task_table
);
210 win_to_task_table
= 0;
215 Task
*task_get_task (Window win
)
217 GPtrArray
* task_group
= task_get_tasks(win
);
219 return g_ptr_array_index(task_group
, 0);
225 GPtrArray
* task_get_tasks(Window win
)
227 return g_hash_table_lookup(win_to_task_table
, &win
);
231 void task_refresh_tasklist ()
236 win
= server_get_property (server
.root_win
, server
.atom
._NET_CLIENT_LIST
, XA_WINDOW
, &num_results
);
239 // Remove any old and set active win
240 // remark from Andreas: This seems unneccessary...
243 GList
* win_list
= g_hash_table_get_keys(win_to_task_table
);
245 for (it
=win_list
; it
; it
=it
->next
) {
246 for (i
= 0; i
< num_results
; i
++)
247 if (*((Window
*)it
->data
) == win
[i
])
249 if (i
== num_results
)
250 taskbar_remove_task(it
->data
, 0, 0);
252 g_list_free(win_list
);
255 for (i
= 0; i
< num_results
; i
++)
256 if (!task_get_task (win
[i
]))
263 void resize_taskbar(void *obj
)
265 Taskbar
*taskbar
= (Taskbar
*)obj
;
266 Panel
*panel
= (Panel
*)taskbar
->area
.panel
;
269 int task_count
, border_width
;
271 //printf("resize_taskbar : posx et width des taches\n");
272 taskbar
->area
.redraw
= 1;
274 border_width
= taskbar
->area
.bg
->border
.width
;
276 if (panel_horizontal
) {
277 int pixel_width
, modulo_width
=0;
278 int x
, taskbar_width
;
280 // new task width for 'desktop'
281 task_count
= g_slist_length(taskbar
->area
.list
);
282 if (!task_count
) pixel_width
= panel
->g_task
.maximum_width
;
284 taskbar_width
= taskbar
->area
.width
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
285 if (task_count
>1) taskbar_width
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
287 pixel_width
= taskbar_width
/ task_count
;
288 if (pixel_width
> panel
->g_task
.maximum_width
)
289 pixel_width
= panel
->g_task
.maximum_width
;
291 modulo_width
= taskbar_width
% task_count
;
294 taskbar
->task_width
= pixel_width
;
295 taskbar
->task_modulo
= modulo_width
;
296 taskbar
->text_width
= pixel_width
- panel
->g_task
.text_posx
- panel
->g_task
.area
.bg
->border
.width
- panel
->g_task
.area
.paddingx
;
298 // change pos_x and width for all tasks
299 x
= taskbar
->area
.posx
+ border_width
+ taskbar
->area
.paddingxlr
;
300 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
302 if (!tsk
->area
.on_screen
) continue;
304 set_task_redraw(tsk
); // always redraw task, because the background could have changed (taskbar_active_id)
305 tsk
->area
.width
= pixel_width
;
311 x
+= tsk
->area
.width
+ panel
->g_taskbar
.area
.paddingx
;
315 int pixel_height
, modulo_height
=0;
316 int y
, taskbar_height
;
318 // new task width for 'desktop'
319 task_count
= g_slist_length(taskbar
->area
.list
);
320 if (!task_count
) pixel_height
= panel
->g_task
.maximum_height
;
322 taskbar_height
= taskbar
->area
.height
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
323 if (task_count
>1) taskbar_height
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
325 pixel_height
= taskbar_height
/ task_count
;
326 if (pixel_height
> panel
->g_task
.maximum_height
)
327 pixel_height
= panel
->g_task
.maximum_height
;
329 modulo_height
= taskbar_height
% task_count
;
332 taskbar
->task_width
= pixel_height
;
333 taskbar
->task_modulo
= modulo_height
;
334 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
;
336 // change pos_y and height for all tasks
337 y
= taskbar
->area
.posy
+ border_width
+ taskbar
->area
.paddingxlr
;
338 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
340 if (!tsk
->area
.on_screen
) continue;
342 set_task_redraw(tsk
); // always redraw task, because the background could have changed (taskbar_active_id)
343 tsk
->area
.height
= pixel_height
;
349 y
+= tsk
->area
.height
+ panel
->g_taskbar
.area
.paddingx
;
This page took 0.052306 seconds and 4 git commands to generate.