]>
Dogcows Code - chaz/tint2/blob - src/taskbar/taskbar.c
1 /**************************************************************************
5 * Copyright (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr) from Omega distribution
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;
57 default_taskbarname();
60 void cleanup_taskbar()
66 cleanup_taskbarname();
67 if (win_to_task_table
) g_hash_table_foreach(win_to_task_table
, taskbar_remove_task
, 0);
68 for (i
=0 ; i
< nb_panel
; i
++) {
70 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
71 tskbar
= &panel
->taskbar
[j
];
72 for (k
=0; k
<TASKBAR_STATE_COUNT
; ++k
) {
73 if (tskbar
->state_pix
[k
]) XFreePixmap(server
.dsp
, tskbar
->state_pix
[k
]);
75 free_area (&tskbar
->area
);
76 // remove taskbar from the panel
77 panel
->area
.list
= g_slist_remove(panel
->area
.list
, tskbar
);
85 if (win_to_task_table
) {
86 g_hash_table_destroy(win_to_task_table
);
87 win_to_task_table
= 0;
94 if (win_to_task_table
== 0)
95 win_to_task_table
= g_hash_table_new_full(win_hash
, win_compare
, free
, free_ptr_array
);
102 void init_taskbar_panel(void *p
)
104 Panel
*panel
=(Panel
*)p
;
107 if (panel
->g_taskbar
.background
[TASKBAR_NORMAL
] == 0) {
108 panel
->g_taskbar
.background
[TASKBAR_NORMAL
] = &g_array_index(backgrounds
, Background
, 0);
109 panel
->g_taskbar
.background
[TASKBAR_ACTIVE
] = &g_array_index(backgrounds
, Background
, 0);
111 if (panel
->g_taskbar
.background_name
[TASKBAR_NORMAL
] == 0) {
112 panel
->g_taskbar
.background_name
[TASKBAR_NORMAL
] = &g_array_index(backgrounds
, Background
, 0);
113 panel
->g_taskbar
.background_name
[TASKBAR_ACTIVE
] = &g_array_index(backgrounds
, Background
, 0);
115 if (panel
->g_task
.area
.bg
== 0)
116 panel
->g_task
.area
.bg
= &g_array_index(backgrounds
, Background
, 0);
119 panel
->g_taskbar
.area_name
.panel
= panel
;
120 panel
->g_taskbar
.area_name
.size_mode
= SIZE_BY_CONTENT
;
121 panel
->g_taskbar
.area_name
._resize
= resize_taskbarname
;
122 panel
->g_taskbar
.area_name
._draw_foreground
= draw_taskbarname
;
123 panel
->g_taskbar
.area_name
._on_change_layout
= 0;
124 panel
->g_taskbar
.area_name
.resize
= 1;
125 panel
->g_taskbar
.area_name
.on_screen
= 1;
128 panel
->g_taskbar
.area
.parent
= panel
;
129 panel
->g_taskbar
.area
.panel
= panel
;
130 panel
->g_taskbar
.area
.size_mode
= SIZE_BY_LAYOUT
;
131 panel
->g_taskbar
.area
._resize
= resize_taskbar
;
132 panel
->g_taskbar
.area
._draw_foreground
= draw_taskbar
;
133 panel
->g_taskbar
.area
._on_change_layout
= on_change_taskbar
;
134 panel
->g_taskbar
.area
.resize
= 1;
135 panel
->g_taskbar
.area
.on_screen
= 1;
136 if (panel_horizontal
) {
137 panel
->g_taskbar
.area
.posy
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
138 panel
->g_taskbar
.area
.height
= panel
->area
.height
- (2 * panel
->g_taskbar
.area
.posy
);
139 panel
->g_taskbar
.area_name
.posy
= panel
->g_taskbar
.area
.posy
;
140 panel
->g_taskbar
.area_name
.height
= panel
->g_taskbar
.area
.height
;
143 panel
->g_taskbar
.area
.posx
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
144 panel
->g_taskbar
.area
.width
= panel
->area
.width
- (2 * panel
->g_taskbar
.area
.posx
);
145 panel
->g_taskbar
.area_name
.posx
= panel
->g_taskbar
.area
.posx
;
146 panel
->g_taskbar
.area_name
.width
= panel
->g_taskbar
.area
.width
;
150 panel
->g_task
.area
.panel
= panel
;
151 panel
->g_task
.area
.size_mode
= SIZE_BY_LAYOUT
;
152 panel
->g_task
.area
._draw_foreground
= draw_task
;
153 panel
->g_task
.area
._on_change_layout
= on_change_task
;
154 panel
->g_task
.area
.resize
= 1;
155 panel
->g_task
.area
.on_screen
= 1;
156 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_NORMAL
)) == 0) {
157 panel
->g_task
.alpha
[TASK_NORMAL
] = 100;
158 panel
->g_task
.saturation
[TASK_NORMAL
] = 0;
159 panel
->g_task
.brightness
[TASK_NORMAL
] = 0;
161 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ACTIVE
)) == 0) {
162 panel
->g_task
.alpha
[TASK_ACTIVE
] = panel
->g_task
.alpha
[TASK_NORMAL
];
163 panel
->g_task
.saturation
[TASK_ACTIVE
] = panel
->g_task
.saturation
[TASK_NORMAL
];
164 panel
->g_task
.brightness
[TASK_ACTIVE
] = panel
->g_task
.brightness
[TASK_NORMAL
];
166 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ICONIFIED
)) == 0) {
167 panel
->g_task
.alpha
[TASK_ICONIFIED
] = panel
->g_task
.alpha
[TASK_NORMAL
];
168 panel
->g_task
.saturation
[TASK_ICONIFIED
] = panel
->g_task
.saturation
[TASK_NORMAL
];
169 panel
->g_task
.brightness
[TASK_ICONIFIED
] = panel
->g_task
.brightness
[TASK_NORMAL
];
171 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_URGENT
)) == 0) {
172 panel
->g_task
.alpha
[TASK_URGENT
] = panel
->g_task
.alpha
[TASK_ACTIVE
];
173 panel
->g_task
.saturation
[TASK_URGENT
] = panel
->g_task
.saturation
[TASK_ACTIVE
];
174 panel
->g_task
.brightness
[TASK_URGENT
] = panel
->g_task
.brightness
[TASK_ACTIVE
];
176 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.font
[TASK_NORMAL
] = (Color
){{0, 0, 0}, 0};
177 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.font
[TASK_ACTIVE
] = panel
->g_task
.font
[TASK_NORMAL
];
178 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.font
[TASK_ICONIFIED
] = panel
->g_task
.font
[TASK_NORMAL
];
179 if ((panel
->g_task
.config_font_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.font
[TASK_URGENT
] = panel
->g_task
.font
[TASK_ACTIVE
];
180 if ((panel
->g_task
.config_font_mask
& (1<<TASK_NORMAL
)) == 0) panel
->g_task
.background
[TASK_NORMAL
] = &g_array_index(backgrounds
, Background
, 0);
181 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.background
[TASK_ACTIVE
] = panel
->g_task
.background
[TASK_NORMAL
];
182 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.background
[TASK_ICONIFIED
] = panel
->g_task
.background
[TASK_NORMAL
];
183 if ((panel
->g_task
.config_background_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.background
[TASK_URGENT
] = panel
->g_task
.background
[TASK_ACTIVE
];
185 if (panel_horizontal
) {
186 panel
->g_task
.area
.posy
= panel
->g_taskbar
.area
.posy
+ panel
->g_taskbar
.background
[TASKBAR_NORMAL
]->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
187 panel
->g_task
.area
.height
= panel
->area
.height
- (2 * panel
->g_task
.area
.posy
);
190 panel
->g_task
.area
.posx
= panel
->g_taskbar
.area
.posx
+ panel
->g_taskbar
.background
[TASKBAR_NORMAL
]->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
191 panel
->g_task
.area
.width
= panel
->area
.width
- (2 * panel
->g_task
.area
.posx
);
192 panel
->g_task
.area
.height
= panel
->g_task
.maximum_height
;
195 for (j
=0; j
<TASK_STATE_COUNT
; ++j
) {
196 if (panel
->g_task
.background
[j
]->border
.rounded
> panel
->g_task
.area
.height
/2) {
197 printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", j
==0 ? "_" : j
==1 ? "_active_" : j
==2 ? "_iconified_" : "_urgent_");
198 g_array_append_val(backgrounds
, *panel
->g_task
.background
[j
]);
199 panel
->g_task
.background
[j
] = &g_array_index(backgrounds
, Background
, backgrounds
->len
-1);
200 panel
->g_task
.background
[j
]->border
.rounded
= panel
->g_task
.area
.height
/2;
204 // compute vertical position : text and icon
205 int height_ink
, height
;
206 get_text_size(panel
->g_task
.font_desc
, &height_ink
, &height
, panel
->area
.height
, "TAjpg", 5);
208 if (!panel
->g_task
.maximum_width
&& panel_horizontal
)
209 panel
->g_task
.maximum_width
= server
.monitor
[panel
->monitor
].width
;
211 panel
->g_task
.text_posx
= panel
->g_task
.background
[0]->border
.width
+ panel
->g_task
.area
.paddingxlr
;
212 panel
->g_task
.text_height
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
213 if (panel
->g_task
.icon
) {
214 panel
->g_task
.icon_size1
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
215 panel
->g_task
.text_posx
+= panel
->g_task
.icon_size1
;
216 panel
->g_task
.icon_posy
= (panel
->g_task
.area
.height
- panel
->g_task
.icon_size1
) / 2;
218 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
221 panel
->nb_desktop
= server
.nb_desktop
;
222 panel
->taskbar
= calloc(server
.nb_desktop
, sizeof(Taskbar
));
223 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
224 tskbar
= &panel
->taskbar
[j
];
225 memcpy(&tskbar
->area
, &panel
->g_taskbar
.area
, sizeof(Area
));
227 if (j
== server
.desktop
)
228 tskbar
->area
.bg
= panel
->g_taskbar
.background
[TASKBAR_ACTIVE
];
230 tskbar
->area
.bg
= panel
->g_taskbar
.background
[TASKBAR_NORMAL
];
232 init_taskbarname_panel(panel
);
236 void taskbar_remove_task(gpointer key
, gpointer value
, gpointer user_data
)
238 remove_task(task_get_task(*(Window
*)key
));
242 Task
*task_get_task (Window win
)
244 GPtrArray
* task_group
= task_get_tasks(win
);
246 return g_ptr_array_index(task_group
, 0);
252 GPtrArray
* task_get_tasks(Window win
)
254 if (win_to_task_table
&& taskbar_enabled
)
255 return g_hash_table_lookup(win_to_task_table
, &win
);
261 void task_refresh_tasklist ()
266 if (!taskbar_enabled
) return;
267 win
= server_get_property (server
.root_win
, server
.atom
._NET_CLIENT_LIST
, XA_WINDOW
, &num_results
);
270 GList
* win_list
= g_hash_table_get_keys(win_to_task_table
);
272 for (it
=win_list
; it
; it
=it
->next
) {
273 for (i
= 0; i
< num_results
; i
++)
274 if (*((Window
*)it
->data
) == win
[i
])
276 if (i
== num_results
)
277 taskbar_remove_task(it
->data
, 0, 0);
279 g_list_free(win_list
);
282 for (i
= 0; i
< num_results
; i
++)
283 if (!task_get_task (win
[i
]))
290 void draw_taskbar (void *obj
, cairo_t
*c
)
292 Taskbar
*taskbar
= obj
;
293 int state
= (taskbar
->desktop
== server
.desktop
) ? TASKBAR_ACTIVE
: TASKBAR_NORMAL
;
295 taskbar
->state_pix
[state
] = taskbar
->area
.pix
;
299 int resize_taskbar(void *obj
)
301 Taskbar
*taskbar
= (Taskbar
*)obj
;
302 Panel
*panel
= (Panel
*)taskbar
->area
.panel
;
305 //printf("resize_taskbar %d %d\n", taskbar->area.posx, taskbar->area.posy);
306 if (panel_horizontal
) {
307 resize_by_layout(obj
, panel
->g_task
.maximum_width
);
309 text_width
= panel
->g_task
.maximum_width
;
310 GSList
*l
= taskbar
->area
.list
;
311 if (taskbarname_enabled
) l
= l
->next
;
313 text_width
= ((Task
*)l
->data
)->area
.width
;
315 taskbar
->text_width
= text_width
- panel
->g_task
.text_posx
- panel
->g_task
.area
.bg
->border
.width
- panel
->g_task
.area
.paddingx
;
318 resize_by_layout(obj
, panel
->g_task
.maximum_height
);
320 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 void on_change_taskbar (void *obj
)
328 Taskbar
*tskbar
= obj
;
331 // reset Pixmap when position/size changed
332 for (k
=0; k
<TASKBAR_STATE_COUNT
; ++k
) {
333 if (tskbar
->state_pix
[k
]) XFreePixmap(server
.dsp
, tskbar
->state_pix
[k
]);
334 tskbar
->state_pix
[k
] = 0;
336 tskbar
->area
.pix
= 0;
337 tskbar
->area
.redraw
= 1;
341 void set_taskbar_state(Taskbar
*tskbar
, int state
)
343 tskbar
->area
.bg
= panel1
[0].g_taskbar
.background
[state
];
344 tskbar
->area
.pix
= tskbar
->state_pix
[state
];
345 if (panel_mode
!= MULTI_DESKTOP
) {
346 if (state
== TASKBAR_NORMAL
)
347 tskbar
->area
.on_screen
= 0;
349 tskbar
->area
.on_screen
= 1;
351 if (tskbar
->area
.on_screen
== 1) {
352 if (tskbar
->state_pix
[state
] == 0)
353 tskbar
->area
.redraw
= 1;
354 if (panel_mode
== MULTI_DESKTOP
&& panel1
[0].g_taskbar
.background
[TASKBAR_NORMAL
] != panel1
[0].g_taskbar
.background
[TASKBAR_ACTIVE
]) {
355 GSList
*l
= tskbar
->area
.list
;
356 if (taskbarname_enabled
) l
= l
->next
;
357 for ( ; l
; l
= l
->next
)
358 set_task_redraw(l
->data
);
365 void visible_taskbar(void *p
)
367 Panel
*panel
=(Panel
*)p
;
371 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
372 taskbar
= &panel
->taskbar
[j
];
373 if (panel_mode
!= MULTI_DESKTOP
&& taskbar
->desktop
!= server
.desktop
) {
374 // SINGLE_DESKTOP and not current desktop
375 taskbar
->area
.on_screen
= 0;
378 taskbar
->area
.on_screen
= 1;
This page took 0.063905 seconds and 5 git commands to generate.