]>
Dogcows Code - chaz/tint2/blob - src/taskbar/taskbar.c
2b505dfeab06a32837eebf3fb4145b4020b01b1e
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); }
50 void default_taskbar()
52 win_to_task_table
= 0;
57 void cleanup_taskbar()
63 if (win_to_task_table
) g_hash_table_foreach(win_to_task_table
, taskbar_remove_task
, 0);
64 for (i
=0 ; i
< nb_panel
; i
++) {
66 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
67 tskbar
= &panel
->taskbar
[j
];
68 free_area (&tskbar
->area
);
69 // remove taskbar from the panel
70 panel
->area
.list
= g_slist_remove(panel
->area
.list
, tskbar
);
78 if (win_to_task_table
) {
79 g_hash_table_destroy(win_to_task_table
);
80 win_to_task_table
= 0;
87 if (win_to_task_table
== 0)
88 win_to_task_table
= g_hash_table_new_full(win_hash
, win_compare
, free
, free_ptr_array
);
95 void init_taskbar_panel(void *p
)
97 Panel
*panel
=(Panel
*)p
;
100 if (panel
->g_taskbar
.bg
== 0) {
101 panel
->g_taskbar
.bg
= &g_array_index(backgrounds
, Background
, 0);
102 panel
->g_taskbar
.area
.bg
= panel
->g_taskbar
.bg
;
104 if (panel
->g_taskbar
.bg_active
== 0)
105 panel
->g_taskbar
.bg_active
= panel
->g_taskbar
.bg
;
106 if (panel
->g_task
.area
.bg
== 0)
107 panel
->g_task
.area
.bg
= &g_array_index(backgrounds
, Background
, 0);
110 panel
->g_taskbar
.area
.size_mode
= SIZE_BY_LAYOUT
;
111 panel
->g_taskbar
.area
._resize
= resize_taskbar
;
112 panel
->g_taskbar
.area
.redraw
= 1;
113 panel
->g_taskbar
.area
.on_screen
= 1;
114 if (panel_horizontal
) {
115 panel
->g_taskbar
.area
.posy
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
116 panel
->g_taskbar
.area
.height
= panel
->area
.height
- (2 * panel
->g_taskbar
.area
.posy
);
119 panel
->g_taskbar
.area
.posx
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
120 panel
->g_taskbar
.area
.width
= panel
->area
.width
- (2 * panel
->g_taskbar
.area
.posx
);
124 panel
->g_task
.area
.size_mode
= SIZE_BY_LAYOUT
;
125 panel
->g_task
.area
._draw_foreground
= draw_task
;
126 panel
->g_task
.area
.redraw
= 1;
127 panel
->g_task
.area
.on_screen
= 1;
128 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_NORMAL
)) == 0) {
129 panel
->g_task
.alpha
[TASK_NORMAL
] = 100;
130 panel
->g_task
.saturation
[TASK_NORMAL
] = 0;
131 panel
->g_task
.brightness
[TASK_NORMAL
] = 0;
133 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ACTIVE
)) == 0) {
134 panel
->g_task
.alpha
[TASK_ACTIVE
] = panel
->g_task
.alpha
[TASK_NORMAL
];
135 panel
->g_task
.saturation
[TASK_ACTIVE
] = panel
->g_task
.saturation
[TASK_NORMAL
];
136 panel
->g_task
.brightness
[TASK_ACTIVE
] = panel
->g_task
.brightness
[TASK_NORMAL
];
138 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ICONIFIED
)) == 0) {
139 panel
->g_task
.alpha
[TASK_ICONIFIED
] = panel
->g_task
.alpha
[TASK_NORMAL
];
140 panel
->g_task
.saturation
[TASK_ICONIFIED
] = panel
->g_task
.saturation
[TASK_NORMAL
];
141 panel
->g_task
.brightness
[TASK_ICONIFIED
] = panel
->g_task
.brightness
[TASK_NORMAL
];
143 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_URGENT
)) == 0) {
144 panel
->g_task
.alpha
[TASK_URGENT
] = panel
->g_task
.alpha
[TASK_ACTIVE
];
145 panel
->g_task
.saturation
[TASK_URGENT
] = panel
->g_task
.saturation
[TASK_ACTIVE
];
146 panel
->g_task
.brightness
[TASK_URGENT
] = panel
->g_task
.brightness
[TASK_ACTIVE
];
148 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.font
[TASK_NORMAL
] = (Color
){{0, 0, 0}, 0};
149 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.font
[TASK_ACTIVE
] = panel
->g_task
.font
[TASK_NORMAL
];
150 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.font
[TASK_ICONIFIED
] = panel
->g_task
.font
[TASK_NORMAL
];
151 if ((panel
->g_task
.config_font_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.font
[TASK_URGENT
] = panel
->g_task
.font
[TASK_ACTIVE
];
152 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.background
[TASK_NORMAL
] = &g_array_index(backgrounds
, Background
, 0);
153 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.background
[TASK_ACTIVE
] = panel
->g_task
.background
[TASK_NORMAL
];
154 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.background
[TASK_ICONIFIED
] = panel
->g_task
.background
[TASK_NORMAL
];
155 if ((panel
->g_task
.config_background_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.background
[TASK_URGENT
] = panel
->g_task
.background
[TASK_ACTIVE
];
157 if (panel_horizontal
) {
158 panel
->g_task
.area
.posy
= panel
->g_taskbar
.area
.posy
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
159 panel
->g_task
.area
.height
= panel
->area
.height
- (2 * panel
->g_task
.area
.posy
);
162 panel
->g_task
.area
.posx
= panel
->g_taskbar
.area
.posx
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
163 panel
->g_task
.area
.width
= panel
->area
.width
- (2 * panel
->g_task
.area
.posx
);
164 panel
->g_task
.area
.height
= panel
->g_task
.maximum_height
;
167 for (j
=0; j
<TASK_STATE_COUNT
; ++j
) {
168 if (panel
->g_task
.background
[j
]->border
.rounded
> panel
->g_task
.area
.height
/2) {
169 printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", j
==0 ? "_" : j
==1 ? "_active_" : j
==2 ? "_iconified_" : "_urgent_");
170 g_array_append_val(backgrounds
, *panel
->g_task
.background
[j
]);
171 panel
->g_task
.background
[j
] = &g_array_index(backgrounds
, Background
, backgrounds
->len
-1);
172 panel
->g_task
.background
[j
]->border
.rounded
= panel
->g_task
.area
.height
/2;
176 // compute vertical position : text and icon
177 int height_ink
, height
;
178 get_text_size(panel
->g_task
.font_desc
, &height_ink
, &height
, panel
->area
.height
, "TAjpg", 5);
180 if (!panel
->g_task
.maximum_width
&& panel_horizontal
)
181 panel
->g_task
.maximum_width
= server
.monitor
[panel
->monitor
].width
;
183 panel
->g_task
.text_posx
= panel
->g_task
.background
[0]->border
.width
+ panel
->g_task
.area
.paddingxlr
;
184 panel
->g_task
.text_height
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
185 if (panel
->g_task
.icon
) {
186 panel
->g_task
.icon_size1
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
187 panel
->g_task
.text_posx
+= panel
->g_task
.icon_size1
;
188 panel
->g_task
.icon_posy
= (panel
->g_task
.area
.height
- panel
->g_task
.icon_size1
) / 2;
190 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
193 panel
->nb_desktop
= server
.nb_desktop
;
194 panel
->taskbar
= calloc(server
.nb_desktop
, sizeof(Taskbar
));
195 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
196 tskbar
= &panel
->taskbar
[j
];
197 memcpy(&tskbar
->area
, &panel
->g_taskbar
, sizeof(Area
));
199 if (j
== server
.desktop
&& panel
->g_taskbar
.use_active
)
200 tskbar
->area
.bg
= panel
->g_taskbar
.bg_active
;
205 void taskbar_remove_task(gpointer key
, gpointer value
, gpointer user_data
)
207 remove_task(task_get_task(*(Window
*)key
));
211 Task
*task_get_task (Window win
)
213 GPtrArray
* task_group
= task_get_tasks(win
);
215 return g_ptr_array_index(task_group
, 0);
221 GPtrArray
* task_get_tasks(Window win
)
223 if (win_to_task_table
)
224 return g_hash_table_lookup(win_to_task_table
, &win
);
230 void task_refresh_tasklist ()
235 win
= server_get_property (server
.root_win
, server
.atom
._NET_CLIENT_LIST
, XA_WINDOW
, &num_results
);
238 GList
* win_list
= g_hash_table_get_keys(win_to_task_table
);
240 for (it
=win_list
; it
; it
=it
->next
) {
241 for (i
= 0; i
< num_results
; i
++)
242 if (*((Window
*)it
->data
) == win
[i
])
244 if (i
== num_results
)
245 taskbar_remove_task(it
->data
, 0, 0);
247 g_list_free(win_list
);
250 for (i
= 0; i
< num_results
; i
++)
251 if (!task_get_task (win
[i
]))
258 int resize_taskbar(void *obj
)
260 Taskbar
*taskbar
= (Taskbar
*)obj
;
261 Panel
*panel
= (Panel
*)taskbar
->area
.panel
;
264 int task_count
, border_width
;
266 //printf("resize_taskbar : posx et width des taches\n");
267 taskbar
->area
.redraw
= 1;
269 border_width
= taskbar
->area
.bg
->border
.width
;
271 if (panel_horizontal
) {
272 int pixel_width
, modulo_width
=0;
275 // new task width for 'desktop'
276 task_count
= g_slist_length(taskbar
->area
.list
);
277 if (!task_count
) pixel_width
= panel
->g_task
.maximum_width
;
279 taskbar_width
= taskbar
->area
.width
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
280 if (task_count
>1) taskbar_width
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
282 pixel_width
= taskbar_width
/ task_count
;
283 if (pixel_width
> panel
->g_task
.maximum_width
)
284 pixel_width
= panel
->g_task
.maximum_width
;
286 modulo_width
= taskbar_width
% task_count
;
289 taskbar
->task_width
= pixel_width
;
290 taskbar
->task_modulo
= modulo_width
;
291 taskbar
->text_width
= pixel_width
- panel
->g_task
.text_posx
- panel
->g_task
.area
.bg
->border
.width
- panel
->g_task
.area
.paddingx
;
293 // change pos_x and width for all tasks
294 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
296 if (!tsk
->area
.on_screen
) continue;
297 set_task_redraw(tsk
); // always redraw task, because the background could have changed (taskbar_active_id)
298 tsk
->area
.width
= pixel_width
;
299 // TODO : move later (when posx is known)
300 // long value[] = { panel->posx+x, panel->posy, pixel_width, panel->area.height };
301 // XChangeProperty (server.dsp, tsk->win, server.atom._NET_WM_ICON_GEOMETRY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)value, 4);
310 int pixel_height
, modulo_height
=0;
313 // new task width for 'desktop'
314 task_count
= g_slist_length(taskbar
->area
.list
);
315 if (!task_count
) pixel_height
= panel
->g_task
.maximum_height
;
317 taskbar_height
= taskbar
->area
.height
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
318 if (task_count
>1) taskbar_height
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
320 pixel_height
= taskbar_height
/ task_count
;
321 if (pixel_height
> panel
->g_task
.maximum_height
)
322 pixel_height
= panel
->g_task
.maximum_height
;
324 modulo_height
= taskbar_height
% task_count
;
327 taskbar
->task_width
= pixel_height
;
328 taskbar
->task_modulo
= modulo_height
;
329 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
;
331 // change pos_y and height for all tasks
332 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
334 if (!tsk
->area
.on_screen
) continue;
335 set_task_redraw(tsk
); // always redraw task, because the background could have changed (taskbar_active_id)
336 tsk
->area
.height
= pixel_height
;
337 // TODO : move later (when posy is known)
338 // long value[] = { panel->posx, panel->posy+y, panel->area.width, pixel_height };
339 // XChangeProperty (server.dsp, tsk->win, server.atom._NET_WM_ICON_GEOMETRY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)value, 4);
This page took 0.048074 seconds and 3 git commands to generate.