X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftint2;a=blobdiff_plain;f=src%2Ftaskbar%2Ftaskbar.c;h=6901fccabb134ceeef8f303ec4f45f1f239c32bb;hp=7118182611f562012f7da718764e87a220cd8802;hb=63bbffa4af17926ba2d52728883988eae402b07a;hpb=3f12a587406ddc975bff3fe505924e62cd125ff6 diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index 7118182..6901fcc 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -26,158 +26,346 @@ #include #include +#include "task.h" #include "taskbar.h" #include "server.h" #include "window.h" #include "panel.h" +/* win_to_task_table holds for every Window an array of tasks. Usually the array contains only one + element. However for omnipresent windows (windows which are visible in every taskbar) the array + contains to every Task* on each panel a pointer (i.e. GPtrArray.len == server.nb_desktop) +*/ +GHashTable* win_to_task_table; -Task *task_get_task (Window win) +Task *task_active; +Task *task_drag; +int taskbar_enabled; + +guint win_hash(gconstpointer key) { return (guint)*((Window*)key); } +gboolean win_compare(gconstpointer a, gconstpointer b) { return (*((Window*)a) == *((Window*)b)); } +void free_ptr_array(gpointer data) { g_ptr_array_free(data, 1); } + + +void default_taskbar() { - Task *tsk; - GSList *l0; - int i, nb; - - nb = panel.nb_desktop * panel.nb_monitor; - for (i=0 ; i < nb ; i++) { - for (l0 = panel.taskbar[i].area.list; l0 ; l0 = l0->next) { - tsk = l0->data; - if (win == tsk->win) return tsk; - } - } - return 0; + win_to_task_table = 0; + urgent_timeout = 0; + urgent_list = 0; + taskbar_enabled = 0; } +void cleanup_taskbar() +{ + Panel *panel; + Taskbar *tskbar; + int i, j; + + if (win_to_task_table) g_hash_table_foreach(win_to_task_table, taskbar_remove_task, 0); + for (i=0 ; i < nb_panel ; i++) { + panel = &panel1[i]; + for (j=0 ; j < panel->nb_desktop ; j++) { + tskbar = &panel->taskbar[j]; + free_area (&tskbar->area); + // remove taskbar from the panel + panel->area.list = g_slist_remove(panel->area.list, tskbar); + } + if (panel->taskbar) { + free(panel->taskbar); + panel->taskbar = 0; + } + } -void task_refresh_tasklist () + if (win_to_task_table) { + g_hash_table_destroy(win_to_task_table); + win_to_task_table = 0; + } +} + + +void init_taskbar() { - Window *win, active_win; - int num_results, i, j, nb; - GSList *l0; - Task *tsk; + if (win_to_task_table == 0) + win_to_task_table = g_hash_table_new_full(win_hash, win_compare, free, free_ptr_array); + + task_active = 0; + task_drag = 0; +} - win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results); - if (!win) return; +void init_taskbar_panel(void *p) +{ + Panel *panel =(Panel*)p; + int j; - // Remove any old and set active win - active_win = window_get_active (); - if (panel.task_active) { - panel.task_active->area.is_active = 0; - panel.task_active = 0; + if (panel->g_taskbar.bg == 0) { + panel->g_taskbar.bg = &g_array_index(backgrounds, Background, 0); + panel->g_taskbar.area.bg = panel->g_taskbar.bg; + } + if (panel->g_taskbar.bg_active == 0) + panel->g_taskbar.bg_active = panel->g_taskbar.bg; + if (panel->g_task.area.bg == 0) + panel->g_task.area.bg = &g_array_index(backgrounds, Background, 0); + + // taskbar + panel->g_taskbar.area.size_mode = SIZE_BY_LAYOUT; + panel->g_taskbar.area._resize = resize_taskbar; + panel->g_taskbar.area.redraw = 1; + panel->g_taskbar.area.on_screen = 1; + if (panel_horizontal) { + panel->g_taskbar.area.posy = panel->area.bg->border.width + panel->area.paddingy; + panel->g_taskbar.area.height = panel->area.height - (2 * panel->g_taskbar.area.posy); + } + else { + panel->g_taskbar.area.posx = panel->area.bg->border.width + panel->area.paddingy; + panel->g_taskbar.area.width = panel->area.width - (2 * panel->g_taskbar.area.posx); } - nb = panel.nb_desktop * panel.nb_monitor; - for (i=0 ; i < nb ; i++) { - l0 = panel.taskbar[i].area.list; - while (l0) { - tsk = l0->data; - l0 = l0->next; + // task + panel->g_task.area.size_mode = SIZE_BY_LAYOUT; + panel->g_task.area._draw_foreground = draw_task; + panel->g_task.area.redraw = 1; + panel->g_task.area.on_screen = 1; + if ((panel->g_task.config_asb_mask & (1<g_task.alpha[TASK_NORMAL] = 100; + panel->g_task.saturation[TASK_NORMAL] = 0; + panel->g_task.brightness[TASK_NORMAL] = 0; + } + if ((panel->g_task.config_asb_mask & (1<g_task.alpha[TASK_ACTIVE] = panel->g_task.alpha[TASK_NORMAL]; + panel->g_task.saturation[TASK_ACTIVE] = panel->g_task.saturation[TASK_NORMAL]; + panel->g_task.brightness[TASK_ACTIVE] = panel->g_task.brightness[TASK_NORMAL]; + } + if ((panel->g_task.config_asb_mask & (1<g_task.alpha[TASK_ICONIFIED] = panel->g_task.alpha[TASK_NORMAL]; + panel->g_task.saturation[TASK_ICONIFIED] = panel->g_task.saturation[TASK_NORMAL]; + panel->g_task.brightness[TASK_ICONIFIED] = panel->g_task.brightness[TASK_NORMAL]; + } + if ((panel->g_task.config_asb_mask & (1<g_task.alpha[TASK_URGENT] = panel->g_task.alpha[TASK_ACTIVE]; + panel->g_task.saturation[TASK_URGENT] = panel->g_task.saturation[TASK_ACTIVE]; + panel->g_task.brightness[TASK_URGENT] = panel->g_task.brightness[TASK_ACTIVE]; + } + if ((panel->g_task.config_font_mask & (1<g_task.font[TASK_NORMAL] = (Color){{0, 0, 0}, 0}; + if ((panel->g_task.config_font_mask & (1<g_task.font[TASK_ACTIVE] = panel->g_task.font[TASK_NORMAL]; + if ((panel->g_task.config_font_mask & (1<g_task.font[TASK_ICONIFIED] = panel->g_task.font[TASK_NORMAL]; + if ((panel->g_task.config_font_mask & (1<g_task.font[TASK_URGENT] = panel->g_task.font[TASK_ACTIVE]; + if ((panel->g_task.config_font_mask & (1<g_task.background[TASK_NORMAL] = &g_array_index(backgrounds, Background, 0); + if ((panel->g_task.config_background_mask & (1<g_task.background[TASK_ACTIVE] = panel->g_task.background[TASK_NORMAL]; + if ((panel->g_task.config_background_mask & (1<g_task.background[TASK_ICONIFIED] = panel->g_task.background[TASK_NORMAL]; + if ((panel->g_task.config_background_mask & (1<g_task.background[TASK_URGENT] = panel->g_task.background[TASK_ACTIVE]; + + if (panel_horizontal) { + panel->g_task.area.posy = panel->g_taskbar.area.posy + panel->g_taskbar.bg->border.width + panel->g_taskbar.area.paddingy; + panel->g_task.area.height = panel->area.height - (2 * panel->g_task.area.posy); + } + else { + panel->g_task.area.posx = panel->g_taskbar.area.posx + panel->g_taskbar.bg->border.width + panel->g_taskbar.area.paddingy; + panel->g_task.area.width = panel->area.width - (2 * panel->g_task.area.posx); + panel->g_task.area.height = panel->g_task.maximum_height; + } - if (tsk->win == active_win) { - tsk->area.is_active = 1; - panel.task_active = tsk; - } + for (j=0; jg_task.background[j]->border.rounded > panel->g_task.area.height/2) { + printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", j==0 ? "_" : j==1 ? "_active_" : j==2 ? "_iconified_" : "_urgent_"); + g_array_append_val(backgrounds, *panel->g_task.background[j]); + panel->g_task.background[j] = &g_array_index(backgrounds, Background, backgrounds->len-1); + panel->g_task.background[j]->border.rounded = panel->g_task.area.height/2; + } + } - for (j = 0; j < num_results; j++) { - if (tsk->win == win[j]) break; - } - // careful : remove_task change l0->next - if (tsk->win != win[j]) remove_task (tsk); - } - } + // compute vertical position : text and icon + int height_ink, height; + get_text_size(panel->g_task.font_desc, &height_ink, &height, panel->area.height, "TAjpg", 5); - // Add any new - for (i = 0; i < num_results; i++) - if (!task_get_task (win[i])) - add_task (win[i]); + if (!panel->g_task.maximum_width && panel_horizontal) + panel->g_task.maximum_width = server.monitor[panel->monitor].width; - XFree (win); + panel->g_task.text_posx = panel->g_task.background[0]->border.width + panel->g_task.area.paddingxlr; + panel->g_task.text_height = panel->g_task.area.height - (2 * panel->g_task.area.paddingy); + if (panel->g_task.icon) { + panel->g_task.icon_size1 = panel->g_task.area.height - (2 * panel->g_task.area.paddingy); + panel->g_task.text_posx += panel->g_task.icon_size1; + panel->g_task.icon_posy = (panel->g_task.area.height - panel->g_task.icon_size1) / 2; + } + //printf("monitor %d, task_maximum_width %d\n", panel->monitor, panel->g_task.maximum_width); + + Taskbar *tskbar; + panel->nb_desktop = server.nb_desktop; + panel->taskbar = calloc(server.nb_desktop, sizeof(Taskbar)); + for (j=0 ; j < panel->nb_desktop ; j++) { + tskbar = &panel->taskbar[j]; + memcpy(&tskbar->area, &panel->g_taskbar, sizeof(Area)); + tskbar->desktop = j; + if (j == server.desktop) + tskbar->area.bg = panel->g_taskbar.bg_active; + } } -int resize_tasks (Taskbar *taskbar) +void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data) { - int ret, task_count, pixel_width, modulo_width=0; - int x, taskbar_width; - Task *tsk; - GSList *l; - - // new task width for 'desktop' - task_count = g_slist_length(taskbar->area.list); - if (!task_count) pixel_width = g_task.maximum_width; - else { - taskbar_width = taskbar->area.width - (2 * g_taskbar.pix.border.width) - ((task_count+1) * g_taskbar.paddingx); - - pixel_width = taskbar_width / task_count; - if (pixel_width > g_task.maximum_width) pixel_width = g_task.maximum_width; - else modulo_width = taskbar_width % task_count; - } - - if ((taskbar->task_width == pixel_width) && (taskbar->task_modulo == modulo_width)) { - ret = 0; - } - else { - ret = 1; - taskbar->task_width = pixel_width; - taskbar->task_modulo = modulo_width; - taskbar->text_width = pixel_width - g_task.text_posx - g_task.area.pix.border.width - g_task.area.paddingx; - } - - // change pos_x and width for all tasks - x = taskbar->area.posx + taskbar->area.pix.border.width + taskbar->area.paddingx; - for (l = taskbar->area.list; l ; l = l->next) { - tsk = l->data; - tsk->area.posx = x; - tsk->area.width = pixel_width; - if (modulo_width) { - tsk->area.width++; - modulo_width--; - } - - x += tsk->area.width + g_taskbar.paddingx; - } - return ret; + remove_task(task_get_task(*(Window*)key)); } -// initialise taskbar posx and width -void resize_taskbar() +Task *task_get_task (Window win) { - int taskbar_width, modulo_width, taskbar_on_screen; - - if (panel.mode == MULTI_DESKTOP) taskbar_on_screen = panel.nb_desktop; - else taskbar_on_screen = panel.nb_monitor; - - taskbar_width = panel.area.width - (2 * panel.area.paddingx) - (2 * panel.area.pix.border.width); - if (panel.clock.time1_format) - taskbar_width -= (panel.clock.area.width + panel.area.paddingx); - taskbar_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) / taskbar_on_screen; - - if (taskbar_on_screen > 1) - modulo_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) % taskbar_on_screen; - else - modulo_width = 0; - - int i, nb, modulo=0, posx=0; - nb = panel.nb_desktop * panel.nb_monitor; - for (i=0 ; i < nb ; i++) { - if ((i % taskbar_on_screen) == 0) { - posx = panel.area.pix.border.width + panel.area.paddingx; - modulo = modulo_width; - } - else posx += taskbar_width + panel.area.paddingx; - - panel.taskbar[i].area.posx = posx; - panel.taskbar[i].area.width = taskbar_width; - if (modulo) { - panel.taskbar[i].area.width++; - modulo--; - } - - resize_tasks(&panel.taskbar[i]); - } + GPtrArray* task_group = task_get_tasks(win); + if (task_group) + return g_ptr_array_index(task_group, 0); + else + return 0; +} + + +GPtrArray* task_get_tasks(Window win) +{ + if (win_to_task_table && taskbar_enabled) + return g_hash_table_lookup(win_to_task_table, &win); + else + return 0; +} + + +void task_refresh_tasklist () +{ + Window *win; + int num_results, i; + + if (!taskbar_enabled) return; + win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results); + if (!win) return; + + GList* win_list = g_hash_table_get_keys(win_to_task_table); + GList* it; + for (it=win_list; it; it=it->next) { + for (i = 0; i < num_results; i++) + if (*((Window*)it->data) == win[i]) + break; + if (i == num_results) + taskbar_remove_task(it->data, 0, 0); + } + g_list_free(win_list); + + // Add any new + for (i = 0; i < num_results; i++) + if (!task_get_task (win[i])) + add_task (win[i]); + + XFree (win); } +int resize_taskbar(void *obj) +{ + Taskbar *taskbar = (Taskbar*)obj; + Panel *panel = (Panel*)taskbar->area.panel; + Task *tsk; + GSList *l; + int task_count, border_width; + +// taskbar->area.redraw = 1; + border_width = taskbar->area.bg->border.width; + + if (panel_horizontal) { + int pixel_width, modulo_width=0; + int taskbar_width; + + // new task width for 'desktop' + task_count = g_slist_length(taskbar->area.list); + if (!task_count) pixel_width = panel->g_task.maximum_width; + else { + taskbar_width = taskbar->area.width - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr); + if (task_count>1) taskbar_width -= ((task_count-1) * panel->g_taskbar.area.paddingx); + + pixel_width = taskbar_width / task_count; + if (pixel_width > panel->g_task.maximum_width) + pixel_width = panel->g_task.maximum_width; + else + modulo_width = taskbar_width % task_count; + } + + taskbar->task_width = pixel_width; + taskbar->task_modulo = modulo_width; + taskbar->text_width = pixel_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx; + + // change pos_x and width for all tasks + for (l = taskbar->area.list; l ; l = l->next) { + tsk = l->data; + if (!tsk->area.on_screen) continue; + //set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id) + tsk->area.width = pixel_width; +// TODO : move later (when posx is known) +// long value[] = { panel->posx+x, panel->posy, pixel_width, panel->area.height }; +// XChangeProperty (server.dsp, tsk->win, server.atom._NET_WM_ICON_GEOMETRY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)value, 4); + + if (modulo_width) { + tsk->area.width++; + modulo_width--; + } + } + } + else { + int pixel_height, modulo_height=0; + int taskbar_height; + + // new task width for 'desktop' + task_count = g_slist_length(taskbar->area.list); + if (!task_count) pixel_height = panel->g_task.maximum_height; + else { + taskbar_height = taskbar->area.height - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr); + if (task_count>1) taskbar_height -= ((task_count-1) * panel->g_taskbar.area.paddingx); + + pixel_height = taskbar_height / task_count; + if (pixel_height > panel->g_task.maximum_height) + pixel_height = panel->g_task.maximum_height; + else + modulo_height = taskbar_height % task_count; + } + + taskbar->task_width = pixel_height; + taskbar->task_modulo = modulo_height; + 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; + + // change pos_y and height for all tasks + for (l = taskbar->area.list; l ; l = l->next) { + tsk = l->data; + if (!tsk->area.on_screen) continue; + //set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id) + tsk->area.height = pixel_height; +// TODO : move later (when posy is known) +// long value[] = { panel->posx, panel->posy+y, panel->area.width, pixel_height }; +// XChangeProperty (server.dsp, tsk->win, server.atom._NET_WM_ICON_GEOMETRY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)value, 4); + + if (modulo_height) { + tsk->area.height++; + modulo_height--; + } + } + } + + return 0; +} + + +void visible_taskbar(void *p) +{ + Panel *panel =(Panel*)p; + int j; + + Taskbar *taskbar; + for (j=0 ; j < panel->nb_desktop ; j++) { + taskbar = &panel->taskbar[j]; + if (panel_mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) { + // SINGLE_DESKTOP and not current desktop + taskbar->area.on_screen = 0; + } + else { + taskbar->area.on_screen = 1; + } + } + panel_refresh = 1; +} +