X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Ftaskbar%2Ftaskbar.c;h=bb351fe1792096f87c5b92d74018e8aed52706f9;hb=ac96fe8050ff0f5c4d0cb4b794eeee875e1d4bfd;hp=5619aa8eee044cd3d5899de8865fb2e133f55d85;hpb=e177e2a5f09e5037eb4b16fd6d6a1dbfa22b9558;p=chaz%2Ftint2 diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index 5619aa8..bb351fe 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -33,51 +33,108 @@ #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_active; +Task *task_drag; + +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 init_taskbar() { - Panel *panel; - int i, j; + Panel *panel; + int i, j; + + 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; for (i=0 ; i < nb_panel ; i++) { panel = &panel1[i]; - if (panel->taskbar) { - free(panel->taskbar); - panel->taskbar = 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._resize = resize_taskbar; - panel->g_taskbar.redraw = 1; - panel->g_taskbar.on_screen = 1; + 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.posy = panel->area.pix.border.width + panel->area.paddingy; - panel->g_taskbar.height = panel->area.height - (2 * panel->g_taskbar.posy); + 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.posx = panel->area.pix.border.width + panel->area.paddingy; - panel->g_taskbar.width = panel->area.width - (2 * panel->g_taskbar.posx); + 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); } // task + panel->g_task.area.size_mode = SIZE_BY_LAYOUT; 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->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.posy + panel->g_taskbar.pix.border.width + panel->g_taskbar.paddingy; + 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.posx + panel->g_taskbar.pix.border.width + panel->g_taskbar.paddingy; + 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 (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; + int k; + for (k=0; kg_task.background[k]->border.rounded > panel->g_task.area.height/2) { + printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", k==0 ? "_" : k==1 ? "_active_" : k==2 ? "_iconified_" : "_urgent_"); + g_array_append_val(backgrounds, *panel->g_task.background[k]); + panel->g_task.background[k] = &g_array_index(backgrounds, Background, backgrounds->len-1); + panel->g_task.background[k]->border.rounded = panel->g_task.area.height/2; + } } // compute vertical position : text and icon @@ -87,8 +144,8 @@ void init_taskbar() 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; + 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; @@ -97,134 +154,115 @@ void init_taskbar() //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(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; - - // add taskbar to the panel - panel->area.list = g_slist_append(panel->area.list, tskbar); + if (j == server.desktop && panel->g_taskbar.use_active) + 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)); +} + +void default_taskbar() +{ + win_to_task_table = 0; + urgent_timeout = 0; + urgent_list = 0; +} void cleanup_taskbar() { - Panel *panel; + Panel *panel; Taskbar *tskbar; - int i, j; - GSList *l0; - Task *tsk; + 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]; - 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); - // remove taskbar from the panel panel->area.list = g_slist_remove(panel->area.list, tskbar); } - } - - for (i=0 ; i < nb_panel ; i++) { - panel = &panel1[i]; if (panel->taskbar) { free(panel->taskbar); panel->taskbar = 0; } } + + if (win_to_task_table) { + g_hash_table_destroy(win_to_task_table); + win_to_task_table = 0; + } } Task *task_get_task (Window win) { - Task *tsk; - GSList *l0; - int i, j; - - 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_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) + 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; - - 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; + Window *win; + int num_results, i; + + 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); - 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); - } - } - } - - // Add any new - for (i = 0; i < num_results; i++) - if (!task_get_task (win[i])) - add_task (win[i]); + // Add any new + for (i = 0; i < num_results; i++) + if (!task_get_task (win[i])) + add_task (win[i]); - XFree (win); + XFree (win); } -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; + Panel *panel = (Panel*)taskbar->area.panel; + Task *tsk; + GSList *l; + int task_count, border_width; -//printf("resize_taskbar : posx et width des taches\n"); + //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; @@ -234,8 +272,8 @@ void resize_taskbar(void *obj) 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) @@ -244,27 +282,27 @@ 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; + x = taskbar->area.posx + 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; - tsk->area.redraw = 1; + 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; + x += tsk->area.width + panel->g_taskbar.area.paddingx; } } else { @@ -275,8 +313,8 @@ void resize_taskbar(void *obj) 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) @@ -285,30 +323,28 @@ 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; + y = taskbar->area.posy + 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; - tsk->area.redraw = 1; + 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; + y += tsk->area.height + panel->g_taskbar.area.paddingx; } } + return 0; } - - -