]>
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
.size_mode
= SIZE_BY_LAYOUT
;
79 panel
->g_taskbar
.area
._resize
= resize_taskbar
;
80 panel
->g_taskbar
.area
.redraw
= 1;
81 panel
->g_taskbar
.area
.on_screen
= 1;
82 if (panel_horizontal
) {
83 panel
->g_taskbar
.area
.posy
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
84 panel
->g_taskbar
.area
.height
= panel
->area
.height
- (2 * panel
->g_taskbar
.area
.posy
);
87 panel
->g_taskbar
.area
.posx
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
88 panel
->g_taskbar
.area
.width
= panel
->area
.width
- (2 * panel
->g_taskbar
.area
.posx
);
92 panel
->g_task
.area
.size_mode
= SIZE_BY_LAYOUT
;
93 panel
->g_task
.area
._draw_foreground
= draw_task
;
94 panel
->g_task
.area
.redraw
= 1;
95 panel
->g_task
.area
.on_screen
= 1;
96 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_NORMAL
)) == 0) {
97 panel
->g_task
.alpha
[TASK_NORMAL
] = 100;
98 panel
->g_task
.saturation
[TASK_NORMAL
] = 0;
99 panel
->g_task
.brightness
[TASK_NORMAL
] = 0;
101 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ACTIVE
)) == 0) {
102 panel
->g_task
.alpha
[TASK_ACTIVE
] = panel
->g_task
.alpha
[TASK_NORMAL
];
103 panel
->g_task
.saturation
[TASK_ACTIVE
] = panel
->g_task
.saturation
[TASK_NORMAL
];
104 panel
->g_task
.brightness
[TASK_ACTIVE
] = panel
->g_task
.brightness
[TASK_NORMAL
];
106 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ICONIFIED
)) == 0) {
107 panel
->g_task
.alpha
[TASK_ICONIFIED
] = panel
->g_task
.alpha
[TASK_NORMAL
];
108 panel
->g_task
.saturation
[TASK_ICONIFIED
] = panel
->g_task
.saturation
[TASK_NORMAL
];
109 panel
->g_task
.brightness
[TASK_ICONIFIED
] = panel
->g_task
.brightness
[TASK_NORMAL
];
111 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_URGENT
)) == 0) {
112 panel
->g_task
.alpha
[TASK_URGENT
] = panel
->g_task
.alpha
[TASK_ACTIVE
];
113 panel
->g_task
.saturation
[TASK_URGENT
] = panel
->g_task
.saturation
[TASK_ACTIVE
];
114 panel
->g_task
.brightness
[TASK_URGENT
] = panel
->g_task
.brightness
[TASK_ACTIVE
];
116 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.font
[TASK_NORMAL
] = (Color
){{0, 0, 0}, 0};
117 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.font
[TASK_ACTIVE
] = panel
->g_task
.font
[TASK_NORMAL
];
118 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.font
[TASK_ICONIFIED
] = panel
->g_task
.font
[TASK_NORMAL
];
119 if ((panel
->g_task
.config_font_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.font
[TASK_URGENT
] = panel
->g_task
.font
[TASK_ACTIVE
];
120 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.background
[TASK_NORMAL
] = &g_array_index(backgrounds
, Background
, 0);
121 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.background
[TASK_ACTIVE
] = panel
->g_task
.background
[TASK_NORMAL
];
122 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.background
[TASK_ICONIFIED
] = panel
->g_task
.background
[TASK_NORMAL
];
123 if ((panel
->g_task
.config_background_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.background
[TASK_URGENT
] = panel
->g_task
.background
[TASK_ACTIVE
];
125 if (panel_horizontal
) {
126 panel
->g_task
.area
.posy
= panel
->g_taskbar
.area
.posy
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
127 panel
->g_task
.area
.height
= panel
->area
.height
- (2 * panel
->g_task
.area
.posy
);
130 panel
->g_task
.area
.posx
= panel
->g_taskbar
.area
.posx
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
131 panel
->g_task
.area
.width
= panel
->area
.width
- (2 * panel
->g_task
.area
.posx
);
132 panel
->g_task
.area
.height
= panel
->g_task
.maximum_height
;
136 for (k
=0; k
<TASK_STATE_COUNT
; ++k
) {
137 if (panel
->g_task
.background
[k
]->border
.rounded
> panel
->g_task
.area
.height
/2) {
138 printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", k
==0 ? "_" : k
==1 ? "_active_" : k
==2 ? "_iconified_" : "_urgent_");
139 g_array_append_val(backgrounds
, *panel
->g_task
.background
[k
]);
140 panel
->g_task
.background
[k
] = &g_array_index(backgrounds
, Background
, backgrounds
->len
-1);
141 panel
->g_task
.background
[k
]->border
.rounded
= panel
->g_task
.area
.height
/2;
145 // compute vertical position : text and icon
146 int height_ink
, height
;
147 get_text_size(panel
->g_task
.font_desc
, &height_ink
, &height
, panel
->area
.height
, "TAjpg", 5);
149 if (!panel
->g_task
.maximum_width
&& panel_horizontal
)
150 panel
->g_task
.maximum_width
= server
.monitor
[panel
->monitor
].width
;
152 panel
->g_task
.text_posx
= panel
->g_task
.background
[0]->border
.width
+ panel
->g_task
.area
.paddingxlr
;
153 panel
->g_task
.text_height
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
154 if (panel
->g_task
.icon
) {
155 panel
->g_task
.icon_size1
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
156 panel
->g_task
.text_posx
+= panel
->g_task
.icon_size1
;
157 panel
->g_task
.icon_posy
= (panel
->g_task
.area
.height
- panel
->g_task
.icon_size1
) / 2;
159 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
162 panel
->nb_desktop
= server
.nb_desktop
;
163 panel
->taskbar
= calloc(panel
->nb_desktop
, sizeof(Taskbar
));
164 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
165 tskbar
= &panel
->taskbar
[j
];
166 memcpy(&tskbar
->area
, &panel
->g_taskbar
, sizeof(Area
));
168 if (j
== server
.desktop
&& panel
->g_taskbar
.use_active
)
169 tskbar
->area
.bg
= panel
->g_taskbar
.bg_active
;
171 // add taskbar to the panel
172 panel
->area
.list
= g_slist_append(panel
->area
.list
, tskbar
);
177 void taskbar_remove_task(gpointer key
, gpointer value
, gpointer user_data
)
179 remove_task(task_get_task(*(Window
*)key
));
182 void default_taskbar()
184 win_to_task_table
= 0;
189 void cleanup_taskbar()
195 if (win_to_task_table
) g_hash_table_foreach(win_to_task_table
, taskbar_remove_task
, 0);
196 for (i
=0 ; i
< nb_panel
; i
++) {
198 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
199 tskbar
= &panel
->taskbar
[j
];
200 free_area (&tskbar
->area
);
201 // remove taskbar from the panel
202 panel
->area
.list
= g_slist_remove(panel
->area
.list
, tskbar
);
204 if (panel
->taskbar
) {
205 free(panel
->taskbar
);
210 if (win_to_task_table
) {
211 g_hash_table_destroy(win_to_task_table
);
212 win_to_task_table
= 0;
217 Task
*task_get_task (Window win
)
219 GPtrArray
* task_group
= task_get_tasks(win
);
221 return g_ptr_array_index(task_group
, 0);
227 GPtrArray
* task_get_tasks(Window win
)
229 if (win_to_task_table
)
230 return g_hash_table_lookup(win_to_task_table
, &win
);
236 void task_refresh_tasklist ()
241 win
= server_get_property (server
.root_win
, server
.atom
._NET_CLIENT_LIST
, XA_WINDOW
, &num_results
);
244 GList
* win_list
= g_hash_table_get_keys(win_to_task_table
);
246 for (it
=win_list
; it
; it
=it
->next
) {
247 for (i
= 0; i
< num_results
; i
++)
248 if (*((Window
*)it
->data
) == win
[i
])
250 if (i
== num_results
)
251 taskbar_remove_task(it
->data
, 0, 0);
253 g_list_free(win_list
);
256 for (i
= 0; i
< num_results
; i
++)
257 if (!task_get_task (win
[i
]))
264 void resize_taskbar(void *obj
)
266 Taskbar
*taskbar
= (Taskbar
*)obj
;
267 Panel
*panel
= (Panel
*)taskbar
->area
.panel
;
270 int task_count
, border_width
;
272 //printf("resize_taskbar : posx et width des taches\n");
273 taskbar
->area
.redraw
= 1;
275 border_width
= taskbar
->area
.bg
->border
.width
;
277 if (panel_horizontal
) {
278 int pixel_width
, modulo_width
=0;
279 int x
, taskbar_width
;
281 // new task width for 'desktop'
282 task_count
= g_slist_length(taskbar
->area
.list
);
283 if (!task_count
) pixel_width
= panel
->g_task
.maximum_width
;
285 taskbar_width
= taskbar
->area
.width
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
286 if (task_count
>1) taskbar_width
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
288 pixel_width
= taskbar_width
/ task_count
;
289 if (pixel_width
> panel
->g_task
.maximum_width
)
290 pixel_width
= panel
->g_task
.maximum_width
;
292 modulo_width
= taskbar_width
% task_count
;
295 taskbar
->task_width
= pixel_width
;
296 taskbar
->task_modulo
= modulo_width
;
297 taskbar
->text_width
= pixel_width
- panel
->g_task
.text_posx
- panel
->g_task
.area
.bg
->border
.width
- panel
->g_task
.area
.paddingx
;
299 // change pos_x and width for all tasks
300 x
= taskbar
->area
.posx
+ border_width
+ taskbar
->area
.paddingxlr
;
301 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
303 if (!tsk
->area
.on_screen
) continue;
305 set_task_redraw(tsk
); // always redraw task, because the background could have changed (taskbar_active_id)
306 tsk
->area
.width
= pixel_width
;
307 long value
[] = { panel
->posx
+x
, panel
->posy
, pixel_width
, panel
->area
.height
};
308 XChangeProperty (server
.dsp
, tsk
->win
, server
.atom
._NET_WM_ICON_GEOMETRY
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char*)value
, 4);
315 x
+= tsk
->area
.width
+ panel
->g_taskbar
.area
.paddingx
;
319 int pixel_height
, modulo_height
=0;
320 int y
, taskbar_height
;
322 // new task width for 'desktop'
323 task_count
= g_slist_length(taskbar
->area
.list
);
324 if (!task_count
) pixel_height
= panel
->g_task
.maximum_height
;
326 taskbar_height
= taskbar
->area
.height
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
327 if (task_count
>1) taskbar_height
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
329 pixel_height
= taskbar_height
/ task_count
;
330 if (pixel_height
> panel
->g_task
.maximum_height
)
331 pixel_height
= panel
->g_task
.maximum_height
;
333 modulo_height
= taskbar_height
% task_count
;
336 taskbar
->task_width
= pixel_height
;
337 taskbar
->task_modulo
= modulo_height
;
338 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
;
340 // change pos_y and height for all tasks
341 y
= taskbar
->area
.posy
+ border_width
+ taskbar
->area
.paddingxlr
;
342 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
344 if (!tsk
->area
.on_screen
) continue;
346 set_task_redraw(tsk
); // always redraw task, because the background could have changed (taskbar_active_id)
347 tsk
->area
.height
= pixel_height
;
348 long value
[] = { panel
->posx
, panel
->posy
+y
, panel
->area
.width
, pixel_height
};
349 XChangeProperty (server
.dsp
, tsk
->win
, server
.atom
._NET_WM_ICON_GEOMETRY
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char*)value
, 4);
356 y
+= tsk
->area
.height
+ panel
->g_taskbar
.area
.paddingx
;
This page took 0.059872 seconds and 4 git commands to generate.