From 4e76c2bb5dfcbca93f4a4b672476d2e0c78bc7d5 Mon Sep 17 00:00:00 2001 From: o9000 Date: Fri, 30 Jan 2015 09:53:16 +0000 Subject: [PATCH] Taskbar: add option to redistribute size in multi-desktop mode (useful especially when the taskbar is getting full on one desktop) git-svn-id: http://tint2.googlecode.com/svn/trunk@673 121b4492-b84c-0410-8b4c-0d4edfb3f3cc --- src/config.c | 3 ++ src/panel.c | 81 +++++++++++++++++++++++++++++++++++++++++++ src/server.h | 2 +- src/taskbar/task.c | 10 ++++++ src/taskbar/taskbar.c | 9 +++-- src/taskbar/taskbar.h | 2 +- src/tint.c | 5 +++ src/util/area.c | 4 +++ 8 files changed, 112 insertions(+), 4 deletions(-) diff --git a/src/config.c b/src/config.c index 2efaf77..1434273 100644 --- a/src/config.c +++ b/src/config.c @@ -413,6 +413,9 @@ void add_entry (char *key, char *value) if (strcmp (value, "multi_desktop") == 0) panel_mode = MULTI_DESKTOP; else panel_mode = SINGLE_DESKTOP; } + else if (strcmp (key, "taskbar_distribute_size") == 0) { + taskbar_distribute_size = atoi(value); + } else if (strcmp (key, "taskbar_padding") == 0) { extract_values(value, &value1, &value2, &value3); panel_config.g_taskbar.area.paddingxlr = panel_config.g_taskbar.area.paddingx = atoi (value1); diff --git a/src/panel.c b/src/panel.c index 2186dbd..5182286 100644 --- a/src/panel.c +++ b/src/panel.c @@ -322,6 +322,87 @@ int resize_panel(void *obj) panel->taskbar[i].area.resize = 1; } } + if (panel_mode == MULTI_DESKTOP && taskbar_enabled && taskbar_distribute_size) { + // Distribute the available space between taskbars + Panel *panel = (Panel*)obj; + + // Compute the total available size, and the total size requested by the taskbars + int total_size = 0; + int total_name_size = 0; + int total_items = 0; + int i; + for (i = 0; i < panel->nb_desktop; i++) { + if (panel_horizontal) { + total_size += panel->taskbar[i].area.width; + } else { + total_size += panel->taskbar[i].area.height; + } + + Taskbar *taskbar = &panel->taskbar[i]; + GSList *l; + for (l = taskbar->area.list; l; l = l->next) { + Area *child = l->data; + if (!child->on_screen) + continue; + total_items++; + } + if (taskbarname_enabled) { + if (taskbar->area.list) { + total_items--; + Area *name = taskbar->area.list->data; + if (panel_horizontal) { + total_name_size += name->width; + } else { + total_name_size += name->height; + } + } + } + } + // Distribute the space proportionally to the requested size (that is, to the + // number of tasks in each taskbar) + if (total_items) { + int actual_name_size; + if (total_name_size <= total_size) { + actual_name_size = total_name_size / panel->nb_desktop; + } else { + actual_name_size = total_size / panel->nb_desktop; + } + total_size -= total_name_size; + + for (i = 0; i < panel->nb_desktop; i++) { + Taskbar *taskbar = &panel->taskbar[i]; + + int requested_size = (2 * taskbar->area.bg->border.width) + (2 * taskbar->area.paddingxlr); + int items = 0; + GSList *l = taskbar->area.list; + if (taskbarname_enabled) + l = l->next; + for (; l; l = l->next) { + Area *child = l->data; + if (!child->on_screen) + continue; + items++; + if (panel_horizontal) { + requested_size += child->width + taskbar->area.paddingy; + } else { + requested_size += child->height + taskbar->area.paddingx; + } + } + if (panel_horizontal) { + requested_size -= taskbar->area.paddingy; + } else { + requested_size -= taskbar->area.paddingx; + } + + if (panel_horizontal) { + taskbar->area.width = actual_name_size + items / (float)total_items * total_size; + } else { + taskbar->area.height = actual_name_size + items / (float)total_items * total_size; + } + taskbar->area.resize = 1; + } + } + } return 0; } diff --git a/src/server.h b/src/server.h index e330846..effb803 100644 --- a/src/server.h +++ b/src/server.h @@ -150,6 +150,6 @@ void get_root_pixmap(); // detect monitors and desktops void get_monitors(); void get_desktops(); - +int server_get_number_of_desktop(); #endif diff --git a/src/taskbar/task.c b/src/taskbar/task.c index 57d36c4..7e696b9 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -118,6 +118,11 @@ Task *add_task (Window win) if (window_is_urgent(win)) add_urgent(new_tsk2); + if (panel_mode == MULTI_DESKTOP) { + Panel *panel = new_tsk2->area.panel; + panel->area.resize = 1; + } + return new_tsk2; } @@ -126,6 +131,11 @@ void remove_task (Task *tsk) { if (!tsk) return; + if (panel_mode == MULTI_DESKTOP) { + Panel *panel = tsk->area.panel; + panel->area.resize = 1; + } + Window win = tsk->win; // free title and icon just for the first task diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index 6b1e22e..c354add 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -42,6 +42,7 @@ GHashTable* win_to_task_table; Task *task_active; Task *task_drag; int taskbar_enabled; +int taskbar_distribute_size; guint win_hash(gconstpointer key) { return (guint)*((Window*)key); } gboolean win_compare(gconstpointer a, gconstpointer b) { return (*((Window*)a) == *((Window*)b)); } @@ -54,6 +55,7 @@ void default_taskbar() urgent_timeout = 0; urgent_list = 0; taskbar_enabled = 0; + taskbar_distribute_size = 0; default_taskbarname(); } @@ -321,8 +323,11 @@ int resize_taskbar(void *obj) text_width = panel->g_task.maximum_width; GSList *l = taskbar->area.list; if (taskbarname_enabled) l = l->next; - if (l != NULL) { - text_width = ((Task *)l->data)->area.width; + for (; l != NULL; l = l->next) { + if (((Task *)l->data)->area.on_screen) { + text_width = ((Task *)l->data)->area.width; + break; + } } taskbar->text_width = text_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx; } diff --git a/src/taskbar/taskbar.h b/src/taskbar/taskbar.h index a120369..2d46a66 100644 --- a/src/taskbar/taskbar.h +++ b/src/taskbar/taskbar.h @@ -16,7 +16,7 @@ extern GHashTable* win_to_task_table; extern Task *task_active; extern Task *task_drag; extern int taskbar_enabled; - +extern int taskbar_distribute_size; typedef struct { // always start with area diff --git a/src/tint.c b/src/tint.c index a238cf6..d723f56 100644 --- a/src/tint.c +++ b/src/tint.c @@ -461,6 +461,7 @@ void event_button_motion_notify (XEvent *e) drag_taskbar->area.resize = 1; task_dragged = 1; panel_refresh = 1; + panel->area.resize = 1; } } @@ -634,6 +635,8 @@ void event_property_notify (XEvent *e) tsk->area.on_screen = 0; tskbar->area.resize = 1; panel_refresh = 1; + if (panel_mode == MULTI_DESKTOP) + panel->area.resize = 1; } } } @@ -645,6 +648,8 @@ void event_property_notify (XEvent *e) if (tsk->desktop == ALLDESKTOP) { tsk->area.on_screen = 1; tskbar->area.resize = 1; + if (panel_mode == MULTI_DESKTOP) + panel->area.resize = 1; } } } diff --git a/src/util/area.c b/src/util/area.c index 22dbe71..c1a57e3 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -82,11 +82,15 @@ void init_rendering(void *obj, int pos) if (panel_horizontal) { child->posy = pos + a->bg->border.width + a->paddingy; child->height = a->height - (2 * (a->bg->border.width + a->paddingy)); + if (child->_on_change_layout) + child->_on_change_layout(child); init_rendering(child, child->posy); } else { child->posx = pos + a->bg->border.width + a->paddingy; child->width = a->width - (2 * (a->bg->border.width + a->paddingy)); + if (child->_on_change_layout) + child->_on_change_layout(child); init_rendering(child, child->posx); } }