X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftint2;a=blobdiff_plain;f=src%2Ftaskbar%2Ftaskbar.c;h=6901fccabb134ceeef8f303ec4f45f1f239c32bb;hp=1c029881fc4f6f730bfeb8bf585622c2d6cf4cba;hb=63bbffa4af17926ba2d52728883988eae402b07a;hpb=7ef35059d22141cf422ce639fdd6c0f23ecc868a diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index 1c02988..6901fcc 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -33,179 +33,221 @@ #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; -void init_taskbar() +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() +{ + 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; } + } - // taskbar - panel->g_taskbar._resize = resize_taskbar; - panel->g_taskbar.redraw = 1; - panel->g_taskbar.on_screen = 1; - if (panel_horizontal) { - panel->g_taskbar.posy = panel->area.pix.border.width + panel->area.paddingy; - panel->g_taskbar.height = panel->area.height - (2 * panel->g_taskbar.posy); - } - else { - panel->g_taskbar.posx = panel->area.pix.border.width + panel->area.paddingy; - panel->g_taskbar.width = panel->area.width - (2 * panel->g_taskbar.posx); - } + if (win_to_task_table) { + g_hash_table_destroy(win_to_task_table); + win_to_task_table = 0; + } +} - // task - panel->g_task.area._draw_foreground = draw_task; - panel->g_task.area.use_active = 1; - panel->g_task.area.redraw = 1; - panel->g_task.area.on_screen = 1; - if (panel_horizontal) { - panel->g_task.area.posy = panel->g_taskbar.posy + panel->g_taskbar.pix.border.width + panel->g_taskbar.paddingy; - panel->g_task.area.height = panel->area.height - (2 * panel->g_task.area.posy); - } - else { - panel->g_task.area.posx = panel->g_taskbar.posx + panel->g_taskbar.pix.border.width + panel->g_taskbar.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 (panel->g_task.area.pix.border.rounded > panel->g_task.area.height/2) { - panel->g_task.area.pix.border.rounded = panel->g_task.area.height/2; - panel->g_task.area.pix_active.border.rounded = panel->g_task.area.pix.border.rounded; - } +void init_taskbar() +{ + if (win_to_task_table == 0) + win_to_task_table = g_hash_table_new_full(win_hash, win_compare, free, free_ptr_array); - // 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); + task_active = 0; + task_drag = 0; +} - if (!panel->g_task.maximum_width && panel_horizontal) - panel->g_task.maximum_width = server.monitor[panel->monitor].width; - panel->g_task.text_posx = panel->g_task.area.pix.border.width + panel->g_task.area.paddingxlr; - panel->g_task.text_posy = (panel->g_task.area.height - height) / 2.0; - 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); +void init_taskbar_panel(void *p) +{ + Panel *panel =(Panel*)p; + int j; - Taskbar *tskbar; - panel->nb_desktop = server.nb_desktop; - panel->taskbar = calloc(panel->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.use_active) - tskbar->area.is_active = 1; + 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); + } - // add taskbar to the panel - panel->area.list = g_slist_append(panel->area.list, tskbar); - } + // 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; + } -void cleanup_taskbar() -{ - Panel *panel; - Taskbar *tskbar; - int i, j; - GSList *l0; - Task *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 (i=0 ; i < nb_panel ; i++) { - panel = &panel1[i]; + // 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); - for (j=0 ; j < panel->nb_desktop ; j++) { - tskbar = &panel->taskbar[j]; - l0 = tskbar->area.list; - while (l0) { - tsk = l0->data; - l0 = l0->next; - // careful : remove_task change l0->next - remove_task (tsk); - } - free_area (&tskbar->area); + if (!panel->g_task.maximum_width && panel_horizontal) + panel->g_task.maximum_width = server.monitor[panel->monitor].width; - // remove taskbar from the panel - panel->area.list = g_slist_remove(panel->area.list, tskbar); - } + 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); - for (i=0 ; i < nb_panel ; i++) { - panel = &panel1[i]; - if (panel->taskbar) { - free(panel->taskbar); - panel->taskbar = 0; - } + 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; } } +void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data) +{ + remove_task(task_get_task(*(Window*)key)); +} + + Task *task_get_task (Window win) { - Task *tsk; - GSList *l0; - int i, j; + GPtrArray* task_group = task_get_tasks(win); + if (task_group) + return g_ptr_array_index(task_group, 0); + else + return 0; +} - for (i=0 ; i < nb_panel ; i++) { - for (j=0 ; j < panel1[i].nb_desktop ; j++) { - for (l0 = panel1[i].taskbar[j].area.list; l0 ; l0 = l0->next) { - tsk = l0->data; - if (win == tsk->win) - return tsk; - } - } - } - 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, active_win; - int num_results, i, j, k; - GSList *l0; - Task *tsk; + 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; - // Remove any old and set active win - active_win = window_get_active (); - if (task_active) { - task_active->area.is_active = 0; - task_active = 0; - } - - for (i=0 ; i < nb_panel ; i++) { - for (j=0 ; j < panel1[i].nb_desktop ; j++) { - l0 = panel1[i].taskbar[j].area.list; - while (l0) { - tsk = l0->data; - l0 = l0->next; - - if (tsk->win == active_win) { - tsk->area.is_active = 1; - task_active = tsk; - } - - for (k = 0; k < num_results; k++) { - if (tsk->win == win[k]) break; - } - // careful : remove_task change l0->next - if (k == num_results) remove_task (tsk); - } - } + 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++) @@ -216,28 +258,27 @@ void task_refresh_tasklist () } -void resize_taskbar(void *obj) +int resize_taskbar(void *obj) { Taskbar *taskbar = (Taskbar*)obj; Panel *panel = (Panel*)taskbar->area.panel; Task *tsk; GSList *l; - int task_count; + int task_count, border_width; - //printf("resize_taskbar : posx et width des taches\n"); - - taskbar->area.redraw = 1; +// taskbar->area.redraw = 1; + border_width = taskbar->area.bg->border.width; if (panel_horizontal) { int pixel_width, modulo_width=0; - int x, taskbar_width; + 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 * panel->g_taskbar.pix.border.width) - (2 * panel->g_taskbar.paddingxlr); - if (task_count>1) taskbar_width -= ((task_count-1) * panel->g_taskbar.paddingx); + 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) @@ -246,39 +287,36 @@ void resize_taskbar(void *obj) modulo_width = taskbar_width % task_count; } - if ((taskbar->task_width == pixel_width) && (taskbar->task_modulo == modulo_width)) { - } - else { - taskbar->task_width = pixel_width; - taskbar->task_modulo = modulo_width; - taskbar->text_width = pixel_width - panel->g_task.text_posx - panel->g_task.area.pix.border.width - panel->g_task.area.paddingx; - } + 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 - x = taskbar->area.posx + taskbar->area.pix.border.width + taskbar->area.paddingxlr; for (l = taskbar->area.list; l ; l = l->next) { tsk = l->data; if (!tsk->area.on_screen) continue; - tsk->area.posx = x; + //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--; } - - x += tsk->area.width + panel->g_taskbar.paddingx; } } else { int pixel_height, modulo_height=0; - int y, taskbar_height; + 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 * panel->g_taskbar.pix.border.width) - (2 * panel->g_taskbar.paddingxlr); - if (task_count>1) taskbar_height -= ((task_count-1) * panel->g_taskbar.paddingx); + 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) @@ -287,30 +325,47 @@ void resize_taskbar(void *obj) modulo_height = taskbar_height % task_count; } - if ((taskbar->task_width == pixel_height) && (taskbar->task_modulo == modulo_height)) { - } - else { - taskbar->task_width = pixel_height; - taskbar->task_modulo = modulo_height; - taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.paddingy) - panel->g_task.text_posx - panel->g_task.area.pix.border.width - panel->g_task.area.paddingx; - } + 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 - y = taskbar->area.posy + taskbar->area.pix.border.width + taskbar->area.paddingxlr; for (l = taskbar->area.list; l ; l = l->next) { tsk = l->data; if (!tsk->area.on_screen) continue; - tsk->area.posy = y; + //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--; } - - y += tsk->area.height + panel->g_taskbar.paddingx; } } + + 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; +}