]>
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
;
46 guint
win_hash(gconstpointer key
) { return (guint
)*((Window
*)key
); }
47 gboolean
win_compare(gconstpointer a
, gconstpointer b
) { return (*((Window
*)a
) == *((Window
*)b
)); }
48 void free_ptr_array(gpointer data
) { g_ptr_array_free(data
, 1); }
51 void default_taskbar()
53 win_to_task_table
= 0;
59 void cleanup_taskbar()
65 if (win_to_task_table
) g_hash_table_foreach(win_to_task_table
, taskbar_remove_task
, 0);
66 for (i
=0 ; i
< nb_panel
; i
++) {
68 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
69 tskbar
= &panel
->taskbar
[j
];
70 free_area (&tskbar
->area
);
71 // remove taskbar from the panel
72 panel
->area
.list
= g_slist_remove(panel
->area
.list
, tskbar
);
80 if (win_to_task_table
) {
81 g_hash_table_destroy(win_to_task_table
);
82 win_to_task_table
= 0;
89 if (win_to_task_table
== 0)
90 win_to_task_table
= g_hash_table_new_full(win_hash
, win_compare
, free
, free_ptr_array
);
97 void init_taskbar_panel(void *p
)
99 Panel
*panel
=(Panel
*)p
;
102 if (panel
->g_taskbar
.bg
== 0) {
103 panel
->g_taskbar
.bg
= &g_array_index(backgrounds
, Background
, 0);
104 panel
->g_taskbar
.area
.bg
= panel
->g_taskbar
.bg
;
106 if (panel
->g_taskbar
.bg_active
== 0)
107 panel
->g_taskbar
.bg_active
= panel
->g_taskbar
.bg
;
108 if (panel
->g_task
.area
.bg
== 0)
109 panel
->g_task
.area
.bg
= &g_array_index(backgrounds
, Background
, 0);
112 panel
->g_taskbar
.area
.size_mode
= SIZE_BY_LAYOUT
;
113 panel
->g_taskbar
.area
._resize
= resize_taskbar
;
114 panel
->g_taskbar
.area
.redraw
= 1;
115 panel
->g_taskbar
.area
.on_screen
= 1;
116 if (panel_horizontal
) {
117 panel
->g_taskbar
.area
.posy
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
118 panel
->g_taskbar
.area
.height
= panel
->area
.height
- (2 * panel
->g_taskbar
.area
.posy
);
121 panel
->g_taskbar
.area
.posx
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
122 panel
->g_taskbar
.area
.width
= panel
->area
.width
- (2 * panel
->g_taskbar
.area
.posx
);
126 panel
->g_task
.area
.size_mode
= SIZE_BY_LAYOUT
;
127 panel
->g_task
.area
._draw_foreground
= draw_task
;
128 panel
->g_task
.area
._on_change_layout
= on_change_task
;
129 panel
->g_task
.area
.redraw
= 1;
130 panel
->g_task
.area
.on_screen
= 1;
131 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_NORMAL
)) == 0) {
132 panel
->g_task
.alpha
[TASK_NORMAL
] = 100;
133 panel
->g_task
.saturation
[TASK_NORMAL
] = 0;
134 panel
->g_task
.brightness
[TASK_NORMAL
] = 0;
136 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ACTIVE
)) == 0) {
137 panel
->g_task
.alpha
[TASK_ACTIVE
] = panel
->g_task
.alpha
[TASK_NORMAL
];
138 panel
->g_task
.saturation
[TASK_ACTIVE
] = panel
->g_task
.saturation
[TASK_NORMAL
];
139 panel
->g_task
.brightness
[TASK_ACTIVE
] = panel
->g_task
.brightness
[TASK_NORMAL
];
141 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ICONIFIED
)) == 0) {
142 panel
->g_task
.alpha
[TASK_ICONIFIED
] = panel
->g_task
.alpha
[TASK_NORMAL
];
143 panel
->g_task
.saturation
[TASK_ICONIFIED
] = panel
->g_task
.saturation
[TASK_NORMAL
];
144 panel
->g_task
.brightness
[TASK_ICONIFIED
] = panel
->g_task
.brightness
[TASK_NORMAL
];
146 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_URGENT
)) == 0) {
147 panel
->g_task
.alpha
[TASK_URGENT
] = panel
->g_task
.alpha
[TASK_ACTIVE
];
148 panel
->g_task
.saturation
[TASK_URGENT
] = panel
->g_task
.saturation
[TASK_ACTIVE
];
149 panel
->g_task
.brightness
[TASK_URGENT
] = panel
->g_task
.brightness
[TASK_ACTIVE
];
151 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.font
[TASK_NORMAL
] = (Color
){{0, 0, 0}, 0};
152 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.font
[TASK_ACTIVE
] = panel
->g_task
.font
[TASK_NORMAL
];
153 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.font
[TASK_ICONIFIED
] = panel
->g_task
.font
[TASK_NORMAL
];
154 if ((panel
->g_task
.config_font_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.font
[TASK_URGENT
] = panel
->g_task
.font
[TASK_ACTIVE
];
155 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.background
[TASK_NORMAL
] = &g_array_index(backgrounds
, Background
, 0);
156 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.background
[TASK_ACTIVE
] = panel
->g_task
.background
[TASK_NORMAL
];
157 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.background
[TASK_ICONIFIED
] = panel
->g_task
.background
[TASK_NORMAL
];
158 if ((panel
->g_task
.config_background_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.background
[TASK_URGENT
] = panel
->g_task
.background
[TASK_ACTIVE
];
160 if (panel_horizontal
) {
161 panel
->g_task
.area
.posy
= panel
->g_taskbar
.area
.posy
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
162 panel
->g_task
.area
.height
= panel
->area
.height
- (2 * panel
->g_task
.area
.posy
);
165 panel
->g_task
.area
.posx
= panel
->g_taskbar
.area
.posx
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
166 panel
->g_task
.area
.width
= panel
->area
.width
- (2 * panel
->g_task
.area
.posx
);
167 panel
->g_task
.area
.height
= panel
->g_task
.maximum_height
;
170 for (j
=0; j
<TASK_STATE_COUNT
; ++j
) {
171 if (panel
->g_task
.background
[j
]->border
.rounded
> panel
->g_task
.area
.height
/2) {
172 printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", j
==0 ? "_" : j
==1 ? "_active_" : j
==2 ? "_iconified_" : "_urgent_");
173 g_array_append_val(backgrounds
, *panel
->g_task
.background
[j
]);
174 panel
->g_task
.background
[j
] = &g_array_index(backgrounds
, Background
, backgrounds
->len
-1);
175 panel
->g_task
.background
[j
]->border
.rounded
= panel
->g_task
.area
.height
/2;
179 // compute vertical position : text and icon
180 int height_ink
, height
;
181 get_text_size(panel
->g_task
.font_desc
, &height_ink
, &height
, panel
->area
.height
, "TAjpg", 5);
183 if (!panel
->g_task
.maximum_width
&& panel_horizontal
)
184 panel
->g_task
.maximum_width
= server
.monitor
[panel
->monitor
].width
;
186 panel
->g_task
.text_posx
= panel
->g_task
.background
[0]->border
.width
+ panel
->g_task
.area
.paddingxlr
;
187 panel
->g_task
.text_height
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
188 if (panel
->g_task
.icon
) {
189 panel
->g_task
.icon_size1
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
190 panel
->g_task
.text_posx
+= panel
->g_task
.icon_size1
;
191 panel
->g_task
.icon_posy
= (panel
->g_task
.area
.height
- panel
->g_task
.icon_size1
) / 2;
193 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
196 panel
->nb_desktop
= server
.nb_desktop
;
197 panel
->taskbar
= calloc(server
.nb_desktop
, sizeof(Taskbar
));
198 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
199 tskbar
= &panel
->taskbar
[j
];
200 memcpy(&tskbar
->area
, &panel
->g_taskbar
, sizeof(Area
));
202 if (j
== server
.desktop
)
203 tskbar
->area
.bg
= panel
->g_taskbar
.bg_active
;
208 void taskbar_remove_task(gpointer key
, gpointer value
, gpointer user_data
)
210 remove_task(task_get_task(*(Window
*)key
));
214 Task
*task_get_task (Window win
)
216 GPtrArray
* task_group
= task_get_tasks(win
);
218 return g_ptr_array_index(task_group
, 0);
224 GPtrArray
* task_get_tasks(Window win
)
226 if (win_to_task_table
&& taskbar_enabled
)
227 return g_hash_table_lookup(win_to_task_table
, &win
);
233 void task_refresh_tasklist ()
238 if (!taskbar_enabled
) return;
239 win
= server_get_property (server
.root_win
, server
.atom
._NET_CLIENT_LIST
, XA_WINDOW
, &num_results
);
242 GList
* win_list
= g_hash_table_get_keys(win_to_task_table
);
244 for (it
=win_list
; it
; it
=it
->next
) {
245 for (i
= 0; i
< num_results
; i
++)
246 if (*((Window
*)it
->data
) == win
[i
])
248 if (i
== num_results
)
249 taskbar_remove_task(it
->data
, 0, 0);
251 g_list_free(win_list
);
254 for (i
= 0; i
< num_results
; i
++)
255 if (!task_get_task (win
[i
]))
262 int resize_taskbar(void *obj
)
264 //int ret = resize_by_layout(obj);
266 // taskbar->text_width = pixel_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx;
267 //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;
270 Taskbar
*taskbar
= (Taskbar
*)obj
;
271 Panel
*panel
= (Panel
*)taskbar
->area
.panel
;
274 int task_count
, border_width
;
276 //printf("resize_taskbar %d %d\n", taskbar->area.posx, taskbar->area.posy);
277 // taskbar->area.redraw = 1;
278 border_width
= taskbar
->area
.bg
->border
.width
;
280 if (panel_horizontal
) {
281 int pixel_width
, modulo_width
=0;
282 int taskbar_width
, old_width
;
284 // new task width for 'desktop'
285 task_count
= g_slist_length(taskbar
->area
.list
);
286 if (!task_count
) pixel_width
= panel
->g_task
.maximum_width
;
288 taskbar_width
= taskbar
->area
.width
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
289 if (task_count
>1) taskbar_width
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
291 pixel_width
= taskbar_width
/ task_count
;
292 if (pixel_width
> panel
->g_task
.maximum_width
)
293 pixel_width
= panel
->g_task
.maximum_width
;
295 modulo_width
= taskbar_width
% task_count
;
298 taskbar
->task_width
= pixel_width
;
299 taskbar
->task_modulo
= modulo_width
;
300 taskbar
->text_width
= pixel_width
- panel
->g_task
.text_posx
- panel
->g_task
.area
.bg
->border
.width
- panel
->g_task
.area
.paddingx
;
302 // change pos_x and width for all tasks
303 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
305 if (!tsk
->area
.on_screen
) continue;
306 old_width
= tsk
->area
.width
;
307 tsk
->area
.width
= pixel_width
;
312 if (tsk
->area
.width
!= old_width
)
313 tsk
->area
.on_changed
= 1;
317 int pixel_height
, modulo_height
=0;
318 int taskbar_height
, old_height
;
320 // new task width for 'desktop'
321 task_count
= g_slist_length(taskbar
->area
.list
);
322 if (!task_count
) pixel_height
= panel
->g_task
.maximum_height
;
324 taskbar_height
= taskbar
->area
.height
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
325 if (task_count
>1) taskbar_height
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
327 pixel_height
= taskbar_height
/ task_count
;
328 if (pixel_height
> panel
->g_task
.maximum_height
)
329 pixel_height
= panel
->g_task
.maximum_height
;
331 modulo_height
= taskbar_height
% task_count
;
334 taskbar
->task_width
= pixel_height
;
335 taskbar
->task_modulo
= modulo_height
;
336 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
;
338 // change pos_y and height for all tasks
339 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
341 if (!tsk
->area
.on_screen
) continue;
342 old_height
= tsk
->area
.height
;
343 tsk
->area
.height
= pixel_height
;
348 if (tsk
->area
.height
!= old_height
)
349 tsk
->area
.on_changed
= 1;
357 void visible_taskbar(void *p
)
359 Panel
*panel
=(Panel
*)p
;
363 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
364 taskbar
= &panel
->taskbar
[j
];
365 if (panel_mode
!= MULTI_DESKTOP
&& taskbar
->desktop
!= server
.desktop
) {
366 // SINGLE_DESKTOP and not current desktop
367 taskbar
->area
.on_screen
= 0;
370 taskbar
->area
.on_screen
= 1;
This page took 0.056016 seconds and 4 git commands to generate.