]>
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
= 0;
42 guint
win_hash(gconstpointer key
) { return (guint
)*((Window
*)key
); }
43 gboolean
win_compare(gconstpointer a
, gconstpointer b
) { return (*((Window
*)a
) == *((Window
*)b
)); }
44 void free_ptr_array(gpointer data
) { g_ptr_array_free(data
, 1); }
51 if (win_to_task_table
== 0)
52 win_to_task_table
= g_hash_table_new_full(win_hash
, win_compare
, free
, free_ptr_array
);
54 for (i
=0 ; i
< nb_panel
; i
++) {
63 panel
->g_taskbar
.area
._resize
= resize_taskbar
;
64 panel
->g_taskbar
.area
.redraw
= 1;
65 panel
->g_taskbar
.area
.on_screen
= 1;
66 if (panel_horizontal
) {
67 panel
->g_taskbar
.area
.posy
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
68 panel
->g_taskbar
.area
.height
= panel
->area
.height
- (2 * panel
->g_taskbar
.area
.posy
);
71 panel
->g_taskbar
.area
.posx
= panel
->area
.bg
->border
.width
+ panel
->area
.paddingy
;
72 panel
->g_taskbar
.area
.width
= panel
->area
.width
- (2 * panel
->g_taskbar
.area
.posx
);
76 panel
->g_task
.area
._draw_foreground
= draw_task
;
77 panel
->g_task
.area
.redraw
= 1;
78 panel
->g_task
.area
.on_screen
= 1;
79 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ACTIVE
)) == 0) {
80 panel
->g_task
.alpha
[TASK_ACTIVE
] = panel
->g_task
.alpha
[TASK_NORMAL
];
81 panel
->g_task
.saturation
[TASK_ACTIVE
] = panel
->g_task
.saturation
[TASK_NORMAL
];
82 panel
->g_task
.brightness
[TASK_ACTIVE
] = panel
->g_task
.brightness
[TASK_NORMAL
];
84 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_ICONIFIED
)) == 0) {
85 panel
->g_task
.alpha
[TASK_ICONIFIED
] = panel
->g_task
.alpha
[TASK_NORMAL
];
86 panel
->g_task
.saturation
[TASK_ICONIFIED
] = panel
->g_task
.saturation
[TASK_NORMAL
];
87 panel
->g_task
.brightness
[TASK_ICONIFIED
] = panel
->g_task
.brightness
[TASK_NORMAL
];
89 if ((panel
->g_task
.config_asb_mask
& (1<<TASK_URGENT
)) == 0) {
90 panel
->g_task
.alpha
[TASK_URGENT
] = panel
->g_task
.alpha
[TASK_ACTIVE
];
91 panel
->g_task
.saturation
[TASK_URGENT
] = panel
->g_task
.saturation
[TASK_ACTIVE
];
92 panel
->g_task
.brightness
[TASK_URGENT
] = panel
->g_task
.brightness
[TASK_ACTIVE
];
94 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.font
[TASK_ACTIVE
] = panel
->g_task
.font
[TASK_NORMAL
];
95 if ((panel
->g_task
.config_font_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.font
[TASK_ICONIFIED
] = panel
->g_task
.font
[TASK_NORMAL
];
96 if ((panel
->g_task
.config_font_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.font
[TASK_URGENT
] = panel
->g_task
.font
[TASK_ACTIVE
];
97 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ACTIVE
)) == 0) panel
->g_task
.background
[TASK_ACTIVE
] = panel
->g_task
.background
[TASK_NORMAL
];
98 if ((panel
->g_task
.config_background_mask
& (1<<TASK_ICONIFIED
)) == 0) panel
->g_task
.background
[TASK_ICONIFIED
] = panel
->g_task
.background
[TASK_NORMAL
];
99 if ((panel
->g_task
.config_background_mask
& (1<<TASK_URGENT
)) == 0) panel
->g_task
.background
[TASK_URGENT
] = panel
->g_task
.background
[TASK_ACTIVE
];
101 if (panel_horizontal
) {
102 panel
->g_task
.area
.posy
= panel
->g_taskbar
.area
.posy
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
103 panel
->g_task
.area
.height
= panel
->area
.height
- (2 * panel
->g_task
.area
.posy
);
106 panel
->g_task
.area
.posx
= panel
->g_taskbar
.area
.posx
+ panel
->g_taskbar
.bg
->border
.width
+ panel
->g_taskbar
.area
.paddingy
;
107 panel
->g_task
.area
.width
= panel
->area
.width
- (2 * panel
->g_task
.area
.posx
);
108 panel
->g_task
.area
.height
= panel
->g_task
.maximum_height
;
112 for (k
=0; k
<TASK_STATE_COUNT
; ++k
) {
113 if (panel
->g_task
.background
[k
]->border
.rounded
> panel
->g_task
.area
.height
/2) {
114 printf("task%sbackground_id is too big. Please fix your tint2rc\n", k
==0 ? "_" : k
==1 ? "_active_" : k
==2 ? "_iconified_" : "_urgent_");
115 g_array_append_val(backgrounds
, *panel
->g_task
.background
[k
]);
116 panel
->g_task
.background
[k
] = &g_array_index(backgrounds
, Background
, backgrounds
->len
-1);
117 panel
->g_task
.background
[k
]->border
.rounded
= panel
->g_task
.area
.height
/2;
121 // compute vertical position : text and icon
122 int height_ink
, height
;
123 get_text_size(panel
->g_task
.font_desc
, &height_ink
, &height
, panel
->area
.height
, "TAjpg", 5);
125 if (!panel
->g_task
.maximum_width
&& panel_horizontal
)
126 panel
->g_task
.maximum_width
= server
.monitor
[panel
->monitor
].width
;
128 panel
->g_task
.text_posx
= panel
->g_task
.background
[0]->border
.width
+ panel
->g_task
.area
.paddingxlr
;
129 panel
->g_task
.text_posy
= (panel
->g_task
.area
.height
- height
) / 2.0;
130 if (panel
->g_task
.icon
) {
131 panel
->g_task
.icon_size1
= panel
->g_task
.area
.height
- (2 * panel
->g_task
.area
.paddingy
);
132 panel
->g_task
.text_posx
+= panel
->g_task
.icon_size1
;
133 panel
->g_task
.icon_posy
= (panel
->g_task
.area
.height
- panel
->g_task
.icon_size1
) / 2;
135 //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width);
138 panel
->nb_desktop
= server
.nb_desktop
;
139 panel
->taskbar
= calloc(panel
->nb_desktop
, sizeof(Taskbar
));
140 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
141 tskbar
= &panel
->taskbar
[j
];
142 memcpy(&tskbar
->area
, &panel
->g_taskbar
, sizeof(Area
));
144 if (j
== server
.desktop
&& panel
->g_taskbar
.use_active
)
145 tskbar
->area
.bg
= panel
->g_taskbar
.bg_active
;
147 // add taskbar to the panel
148 panel
->area
.list
= g_slist_append(panel
->area
.list
, tskbar
);
153 void taskbar_remove_task(gpointer key
, gpointer value
, gpointer user_data
) {remove_task(task_get_task(*(Window
*)key
)); }
154 void cleanup_taskbar()
160 if (win_to_task_table
) g_hash_table_foreach(win_to_task_table
, taskbar_remove_task
, 0);
161 for (i
=0 ; i
< nb_panel
; i
++) {
163 for (j
=0 ; j
< panel
->nb_desktop
; j
++) {
164 tskbar
= &panel
->taskbar
[j
];
165 free_area (&tskbar
->area
);
166 // remove taskbar from the panel
167 panel
->area
.list
= g_slist_remove(panel
->area
.list
, tskbar
);
169 if (panel
->taskbar
) {
170 free(panel
->taskbar
);
175 if (win_to_task_table
) {
176 g_hash_table_destroy(win_to_task_table
);
177 win_to_task_table
= 0;
182 Task
*task_get_task (Window win
)
184 GPtrArray
* task_group
= task_get_tasks(win
);
186 return g_ptr_array_index(task_group
, 0);
192 GPtrArray
* task_get_tasks(Window win
)
194 return g_hash_table_lookup(win_to_task_table
, &win
);
198 void task_refresh_tasklist ()
203 win
= server_get_property (server
.root_win
, server
.atom
._NET_CLIENT_LIST
, XA_WINDOW
, &num_results
);
206 // Remove any old and set active win
207 // remark from Andreas: This seems unneccessary...
210 GList
* win_list
= g_hash_table_get_keys(win_to_task_table
);
212 for (it
=win_list
; it
; it
=it
->next
) {
213 for (i
= 0; i
< num_results
; i
++)
214 if (*((Window
*)it
->data
) == win
[i
])
216 if (i
== num_results
)
217 taskbar_remove_task(it
->data
, 0, 0);
219 g_list_free(win_list
);
222 for (i
= 0; i
< num_results
; i
++)
223 if (!task_get_task (win
[i
]))
230 void resize_taskbar(void *obj
)
232 Taskbar
*taskbar
= (Taskbar
*)obj
;
233 Panel
*panel
= (Panel
*)taskbar
->area
.panel
;
236 int task_count
, border_width
;
238 //printf("resize_taskbar : posx et width des taches\n");
239 taskbar
->area
.redraw
= 1;
241 border_width
= taskbar
->area
.bg
->border
.width
;
243 if (panel_horizontal
) {
244 int pixel_width
, modulo_width
=0;
245 int x
, taskbar_width
;
247 // new task width for 'desktop'
248 task_count
= g_slist_length(taskbar
->area
.list
);
249 if (!task_count
) pixel_width
= panel
->g_task
.maximum_width
;
251 taskbar_width
= taskbar
->area
.width
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
252 if (task_count
>1) taskbar_width
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
254 pixel_width
= taskbar_width
/ task_count
;
255 if (pixel_width
> panel
->g_task
.maximum_width
)
256 pixel_width
= panel
->g_task
.maximum_width
;
258 modulo_width
= taskbar_width
% task_count
;
261 taskbar
->task_width
= pixel_width
;
262 taskbar
->task_modulo
= modulo_width
;
263 taskbar
->text_width
= pixel_width
- panel
->g_task
.text_posx
- panel
->g_task
.area
.bg
->border
.width
- panel
->g_task
.area
.paddingx
;
265 // change pos_x and width for all tasks
266 x
= taskbar
->area
.posx
+ border_width
+ taskbar
->area
.paddingxlr
;
267 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
269 if (!tsk
->area
.on_screen
) continue;
271 if (tsk
->area
.width
!= pixel_width
) set_task_redraw(tsk
);
272 tsk
->area
.width
= pixel_width
;
278 x
+= tsk
->area
.width
+ panel
->g_taskbar
.area
.paddingx
;
282 int pixel_height
, modulo_height
=0;
283 int y
, taskbar_height
;
285 // new task width for 'desktop'
286 task_count
= g_slist_length(taskbar
->area
.list
);
287 if (!task_count
) pixel_height
= panel
->g_task
.maximum_height
;
289 taskbar_height
= taskbar
->area
.height
- (2 * border_width
) - (2 * panel
->g_taskbar
.area
.paddingxlr
);
290 if (task_count
>1) taskbar_height
-= ((task_count
-1) * panel
->g_taskbar
.area
.paddingx
);
292 pixel_height
= taskbar_height
/ task_count
;
293 if (pixel_height
> panel
->g_task
.maximum_height
)
294 pixel_height
= panel
->g_task
.maximum_height
;
296 modulo_height
= taskbar_height
% task_count
;
299 taskbar
->task_width
= pixel_height
;
300 taskbar
->task_modulo
= modulo_height
;
301 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
;
303 // change pos_y and height for all tasks
304 y
= taskbar
->area
.posy
+ border_width
+ taskbar
->area
.paddingxlr
;
305 for (l
= taskbar
->area
.list
; l
; l
= l
->next
) {
307 if (!tsk
->area
.on_screen
) continue;
309 if (tsk
->area
.height
!= pixel_height
) set_task_redraw(tsk
);
310 tsk
->area
.height
= pixel_height
;
316 y
+= tsk
->area
.height
+ panel
->g_taskbar
.area
.paddingx
;
This page took 0.048218 seconds and 4 git commands to generate.