Taskbar: code cleanup

This commit is contained in:
o9000
2016-01-08 23:43:53 +01:00
parent d08606dc93
commit 92bd9e9184
9 changed files with 117 additions and 143 deletions

View File

@@ -782,9 +782,9 @@ void add_entry(char *key, char *value)
/* Task */ /* Task */
else if (strcmp(key, "task_text") == 0) else if (strcmp(key, "task_text") == 0)
panel_config.g_task.text = atoi(value); panel_config.g_task.has_text = atoi(value);
else if (strcmp(key, "task_icon") == 0) else if (strcmp(key, "task_icon") == 0)
panel_config.g_task.icon = atoi(value); panel_config.g_task.has_icon = atoi(value);
else if (strcmp(key, "task_centered") == 0) else if (strcmp(key, "task_centered") == 0)
panel_config.g_task.centered = atoi(value); panel_config.g_task.centered = atoi(value);
else if (strcmp(key, "task_width") == 0) { else if (strcmp(key, "task_width") == 0) {

View File

@@ -261,10 +261,10 @@ void init_panel()
if (panel_autohide) if (panel_autohide)
autohide_trigger_hide(p); autohide_trigger_hide(p);
visible_taskbar(p); update_taskbar_visibility(p);
} }
task_refresh_tasklist(); taskbar_refresh_tasklist();
reset_active_task(); reset_active_task();
} }
@@ -755,7 +755,7 @@ void set_panel_background(Panel *p)
if (taskbarname_enabled) if (taskbarname_enabled)
l = l->next; l = l->next;
for (; l; l = l->next) { for (; l; l = l->next) {
set_task_redraw((Task *)l->data); schedule_redraw((Area *)l->data);
} }
} }
} }

View File

@@ -48,10 +48,8 @@ Task *add_task(Window win)
{ {
if (!win) if (!win)
return NULL; return NULL;
if (window_is_hidden(win)) { if (window_is_hidden(win))
// fprintf(stderr, "%s %d: win = %ld not adding task: window hidden\n", __FUNCTION__, __LINE__, win);
return NULL; return NULL;
}
XSelectInput(server.display, win, PropertyChangeMask | StructureNotifyMask); XSelectInput(server.display, win, PropertyChangeMask | StructureNotifyMask);
XFlush(server.display); XFlush(server.display);
@@ -81,8 +79,8 @@ Task *add_task(Window win)
for (int k = 0; k < TASK_STATE_COUNT; ++k) { for (int k = 0; k < TASK_STATE_COUNT; ++k) {
task_template.icon[k] = NULL; task_template.icon[k] = NULL;
} }
get_title(&task_template); task_update_title(&task_template);
get_icon(&task_template); task_update_icon(&task_template);
// fprintf(stderr, "%s %d: win = %ld, task = %s\n", __FUNCTION__, __LINE__, win, task_template.title ? task_template.title : "??"); // fprintf(stderr, "%s %d: win = %ld, task = %s\n", __FUNCTION__, __LINE__, win, task_template.title ? task_template.title : "??");
// fprintf(stderr, "new task %s win %u: desktop %d, monitor %d\n", new_task.title, win, new_task.desktop, monitor); // fprintf(stderr, "new task %s win %u: desktop %d, monitor %d\n", new_task.title, win, new_task.desktop, monitor);
@@ -194,11 +192,11 @@ void remove_task(Task *task)
g_hash_table_remove(win_to_task, &win); g_hash_table_remove(win_to_task, &win);
} }
gboolean get_title(Task *task) gboolean task_update_title(Task *task)
{ {
Panel *panel = task->area.panel; Panel *panel = task->area.panel;
if (!panel->g_task.text && !panel->g_task.tooltip_enabled && taskbar_sort_method != TASKBAR_SORT_TITLE) if (!panel->g_task.has_text && !panel->g_task.tooltip_enabled && taskbar_sort_method != TASKBAR_SORT_TITLE)
return FALSE; return FALSE;
char *name = server_get_property(task->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0); char *name = server_get_property(task->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0);
@@ -229,27 +227,23 @@ gboolean get_title(Task *task)
} }
task->title = title; task->title = title;
GPtrArray *task_group = task_get_tasks(task->win); GPtrArray *task_group = get_task_group(task->win);
if (task_group) { if (task_group) {
for (int i = 0; i < task_group->len; ++i) { for (int i = 0; i < task_group->len; ++i) {
Task *task2 = g_ptr_array_index(task_group, i); Task *task2 = g_ptr_array_index(task_group, i);
task2->title = task->title; task2->title = task->title;
set_task_redraw(task2); schedule_redraw(&task2->area);
} }
} }
return TRUE; return TRUE;
} }
void get_icon(Task *task) void task_update_icon(Task *task)
{ {
Panel *panel = task->area.panel; Panel *panel = task->area.panel;
if (!panel->g_task.icon) if (!panel->g_task.has_icon)
return; return;
Imlib_Image img = NULL;
XWMHints *hints = 0;
gulong *data = 0;
for (int k = 0; k < TASK_STATE_COUNT; ++k) { for (int k = 0; k < TASK_STATE_COUNT; ++k) {
if (task->icon[k]) { if (task->icon[k]) {
imlib_context_set_image(task->icon[k]); imlib_context_set_image(task->icon[k]);
@@ -258,8 +252,10 @@ void get_icon(Task *task)
} }
} }
Imlib_Image img = NULL;
int i; int i;
data = server_get_property(task->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i); gulong *data = server_get_property(task->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i);
if (data) { if (data) {
// get ARGB icon // get ARGB icon
int w, h; int w, h;
@@ -269,15 +265,16 @@ void get_icon(Task *task)
#ifdef __x86_64__ #ifdef __x86_64__
DATA32 icon_data[w * h]; DATA32 icon_data[w * h];
int length = w * h; int length = w * h;
for (i = 0; i < length; ++i) for (int j = 0; j < length; ++j)
icon_data[i] = tmp_data[i]; icon_data[j] = tmp_data[j];
img = imlib_create_image_using_copied_data(w, h, icon_data); img = imlib_create_image_using_copied_data(w, h, icon_data);
#else #else
img = imlib_create_image_using_data(w, h, (DATA32 *)tmp_data); img = imlib_create_image_using_data(w, h, (DATA32 *)tmp_data);
#endif #endif
XFree(data);
} else { } else {
// get Pixmap icon // get Pixmap icon
hints = XGetWMHints(server.display, task->win); XWMHints *hints = XGetWMHints(server.display, task->win);
if (hints) { if (hints) {
if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) { if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) {
// get width, height and depth for the pixmap // get width, height and depth for the pixmap
@@ -291,6 +288,7 @@ void get_icon(Task *task)
imlib_context_set_drawable(hints->icon_pixmap); imlib_context_set_drawable(hints->icon_pixmap);
img = imlib_create_image_from_drawable(hints->icon_mask, 0, 0, w, h, 0); img = imlib_create_image_from_drawable(hints->icon_mask, 0, 0, w, h, 0);
} }
XFree(hints);
} }
} }
if (img == NULL) { if (img == NULL) {
@@ -304,7 +302,7 @@ void get_icon(Task *task)
int w = imlib_image_get_width(); int w = imlib_image_get_width();
int h = imlib_image_get_height(); int h = imlib_image_get_height();
Imlib_Image orig_image = Imlib_Image orig_image =
imlib_create_cropped_scaled_image(0, 0, w, h, panel->g_task.icon_size1, panel->g_task.icon_size1); imlib_create_cropped_scaled_image(0, 0, w, h, panel->g_task.icon_size1, panel->g_task.icon_size1);
imlib_free_image(); imlib_free_image();
imlib_context_set_image(orig_image); imlib_context_set_image(orig_image);
@@ -339,12 +337,7 @@ void get_icon(Task *task)
imlib_context_set_image(orig_image); imlib_context_set_image(orig_image);
imlib_free_image(); imlib_free_image();
if (hints) GPtrArray *task_group = get_task_group(task->win);
XFree(hints);
if (data)
XFree(data);
GPtrArray *task_group = task_get_tasks(task->win);
if (task_group) { if (task_group) {
for (i = 0; i < task_group->len; ++i) { for (i = 0; i < task_group->len; ++i) {
Task *task2 = g_ptr_array_index(task_group, i); Task *task2 = g_ptr_array_index(task_group, i);
@@ -355,7 +348,7 @@ void get_icon(Task *task)
task2->icon_hover[k] = task->icon_hover[k]; task2->icon_hover[k] = task->icon_hover[k];
task2->icon_press[k] = task->icon_press[k]; task2->icon_press[k] = task->icon_press[k];
} }
set_task_redraw(task2); schedule_redraw(&task2->area);
} }
} }
} }
@@ -370,7 +363,7 @@ void draw_task_icon(Task *task, int text_width)
int pos_x; int pos_x;
Panel *panel = (Panel *)task->area.panel; Panel *panel = (Panel *)task->area.panel;
if (panel->g_task.centered) { if (panel->g_task.centered) {
if (panel->g_task.text) if (panel->g_task.has_text)
pos_x = (task->area.width - text_width - panel->g_task.icon_size1) / 2; pos_x = (task->area.width - text_width - panel->g_task.icon_size1) / 2;
else else
pos_x = (task->area.width - panel->g_task.icon_size1) / 2; pos_x = (task->area.width - panel->g_task.icon_size1) / 2;
@@ -403,7 +396,7 @@ void draw_task(void *obj, cairo_t *c)
Panel *panel = (Panel *)task->area.panel; Panel *panel = (Panel *)task->area.panel;
int text_width = 0; int text_width = 0;
if (panel->g_task.text) { if (panel->g_task.has_text) {
PangoLayout *layout = pango_cairo_create_layout(c); PangoLayout *layout = pango_cairo_create_layout(c);
pango_layout_set_font_description(layout, panel->g_task.font_desc); pango_layout_set_font_description(layout, panel->g_task.font_desc);
pango_layout_set_text(layout, task->title, -1); pango_layout_set_text(layout, task->title, -1);
@@ -428,9 +421,8 @@ void draw_task(void *obj, cairo_t *c)
g_object_unref(layout); g_object_unref(layout);
} }
if (panel->g_task.icon) { if (panel->g_task.has_icon)
draw_task_icon(task, text_width); draw_task_icon(task, text_width);
}
} }
void on_change_task(void *obj) void on_change_task(void *obj)
@@ -447,9 +439,6 @@ void on_change_task(void *obj)
PropModeReplace, PropModeReplace,
(unsigned char *)value, (unsigned char *)value,
4); 4);
// reset Pixmap when position/size changed
set_task_redraw(task);
} }
Task *find_active_task(Task *current_task) Task *find_active_task(Task *current_task)
@@ -531,12 +520,12 @@ void reset_active_task()
// printf("Change active task %ld\n", w1); // printf("Change active task %ld\n", w1);
if (w1) { if (w1) {
if (!task_get_tasks(w1)) { if (!get_task_group(w1)) {
Window w2; Window w2;
while (XGetTransientForHint(server.display, w1, &w2)) while (XGetTransientForHint(server.display, w1, &w2))
w1 = w2; w1 = w2;
} }
set_task_state((active_task = task_get_task(w1)), TASK_ACTIVE); set_task_state((active_task = get_task(w1)), TASK_ACTIVE);
} }
} }
@@ -548,7 +537,7 @@ void set_task_state(Task *task, TaskState state)
if (state == TASK_ACTIVE && task->current_state != state) { if (state == TASK_ACTIVE && task->current_state != state) {
clock_gettime(CLOCK_MONOTONIC, &task->last_activation_time); clock_gettime(CLOCK_MONOTONIC, &task->last_activation_time);
if (taskbar_sort_method == TASKBAR_SORT_LRU || taskbar_sort_method == TASKBAR_SORT_MRU) { if (taskbar_sort_method == TASKBAR_SORT_LRU || taskbar_sort_method == TASKBAR_SORT_MRU) {
GPtrArray *task_group = task_get_tasks(task->win); GPtrArray *task_group = get_task_group(task->win);
if (task_group) { if (task_group) {
for (int i = 0; i < task_group->len; ++i) { for (int i = 0; i < task_group->len; ++i) {
Task *task1 = g_ptr_array_index(task_group, i); Task *task1 = g_ptr_array_index(task_group, i);
@@ -560,7 +549,7 @@ void set_task_state(Task *task, TaskState state)
} }
if (task->current_state != state || hide_task_diff_monitor) { if (task->current_state != state || hide_task_diff_monitor) {
GPtrArray *task_group = task_get_tasks(task->win); GPtrArray *task_group = get_task_group(task->win);
if (task_group) { if (task_group) {
for (int i = 0; i < task_group->len; ++i) { for (int i = 0; i < task_group->len; ++i) {
Task *task1 = g_ptr_array_index(task_group, i); Task *task1 = g_ptr_array_index(task_group, i);
@@ -587,7 +576,7 @@ void set_task_state(Task *task, TaskState state)
} }
if ((!hide) != task1->area.on_screen) { if ((!hide) != task1->area.on_screen) {
task1->area.on_screen = !hide; task1->area.on_screen = !hide;
set_task_redraw(task1); schedule_redraw(&task1->area);
Panel *p = (Panel *)task->area.panel; Panel *p = (Panel *)task->area.panel;
task->area.resize_needed = TRUE; task->area.resize_needed = TRUE;
p->taskbar->area.resize_needed = TRUE; p->taskbar->area.resize_needed = TRUE;
@@ -599,11 +588,6 @@ void set_task_state(Task *task, TaskState state)
} }
} }
void set_task_redraw(Task *task)
{
schedule_redraw(&task->area);
}
void blink_urgent(void *arg) void blink_urgent(void *arg)
{ {
GSList *urgent_task = urgent_list; GSList *urgent_task = urgent_list;
@@ -629,7 +613,7 @@ void add_urgent(Task *task)
if (active_task && active_task->win == task->win) if (active_task && active_task->win == task->win)
return; return;
task = task_get_task(task->win); // always add the first task for a task group (omnipresent windows) task = get_task(task->win); // always add the first task for a task group (omnipresent windows)
task->urgent_tick = 0; task->urgent_tick = 0;
if (g_slist_find(urgent_list, task)) if (g_slist_find(urgent_list, task))
return; return;

View File

@@ -22,16 +22,11 @@ typedef enum TaskState {
TASK_STATE_COUNT, TASK_STATE_COUNT,
} TaskState; } TaskState;
extern timeout *urgent_timeout;
extern GSList *urgent_list;
typedef struct GlobalTask { typedef struct GlobalTask {
Area area; Area area;
gboolean has_text;
gboolean text; gboolean has_icon;
gboolean icon;
gboolean centered; gboolean centered;
int icon_posy; int icon_posy;
int icon_size1; int icon_size1;
int maximum_width; int maximum_width;
@@ -44,7 +39,6 @@ typedef struct GlobalTask {
int config_background_mask; int config_background_mask;
// starting position for text ~ task_padding + task_border + icon_size // starting position for text ~ task_padding + task_border + icon_size
double text_posx, text_height; double text_posx, text_height;
gboolean has_font; gboolean has_font;
PangoFontDescription *font_desc; PangoFontDescription *font_desc;
Color font[TASK_STATE_COUNT]; Color font[TASK_STATE_COUNT];
@@ -54,12 +48,9 @@ typedef struct GlobalTask {
// Stores information about a task. // Stores information about a task.
// Warning: any dynamically allocated members are shared between the Task instances created for the same window // Warning: any dynamically allocated members are shared between the Task instances created for the same window
// (for example, if the task appears on all desktops, there will be a different instance on each desktop's taskbar). // (if the task appears on all desktops, there will be a different instance on each desktop's taskbar).
typedef struct Task { typedef struct Task {
// always start with area
Area area; Area area;
// TODO: group task with list of windows here
Window win; Window win;
int desktop; int desktop;
TaskState current_state; TaskState current_state;
@@ -78,17 +69,19 @@ typedef struct Task {
struct timespec last_activation_time; struct timespec last_activation_time;
} Task; } Task;
extern timeout *urgent_timeout;
extern GSList *urgent_list;
Task *add_task(Window win); Task *add_task(Window win);
void remove_task(Task *task); void remove_task(Task *task);
void draw_task(void *obj, cairo_t *c); void draw_task(void *obj, cairo_t *c);
void on_change_task(void *obj); void on_change_task(void *obj);
void get_icon(Task *task); void task_update_icon(Task *task);
gboolean get_title(Task *task); gboolean task_update_title(Task *task);
void reset_active_task(); void reset_active_task();
void set_task_state(Task *task, TaskState state); void set_task_state(Task *task, TaskState state);
void set_task_redraw(Task *task);
// Given a pointer to the task that is currently under the mouse (current_task), // Given a pointer to the task that is currently under the mouse (current_task),
// returns a pointer to the Task for the active window on the same taskbar. // returns a pointer to the Task for the active window on the same taskbar.

View File

@@ -33,10 +33,6 @@
#include "panel.h" #include "panel.h"
#include "strnatcmp.h" #include "strnatcmp.h"
/* win_to_task 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.num_desktops)
*/
GHashTable *win_to_task; GHashTable *win_to_task;
Task *active_task; Task *active_task;
@@ -50,6 +46,9 @@ Alignment taskbar_alignment;
void taskbar_init_fonts(); void taskbar_init_fonts();
// Removes the task with &win = key.
void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data);
guint win_hash(gconstpointer key) guint win_hash(gconstpointer key)
{ {
return *((const Window *)key); return *((const Window *)key);
@@ -117,8 +116,8 @@ void cleanup_taskbar()
void init_taskbar() void init_taskbar()
{ {
if (!panel_config.g_task.text && !panel_config.g_task.icon) { if (!panel_config.g_task.has_text && !panel_config.g_task.has_icon) {
panel_config.g_task.text = panel_config.g_task.icon = 1; panel_config.g_task.has_text = panel_config.g_task.has_icon = 1;
} }
if (!win_to_task) if (!win_to_task)
@@ -159,7 +158,6 @@ void init_taskbar_panel(void *p)
panel->g_taskbar.area.size_mode = LAYOUT_DYNAMIC; panel->g_taskbar.area.size_mode = LAYOUT_DYNAMIC;
panel->g_taskbar.area.alignment = taskbar_alignment; panel->g_taskbar.area.alignment = taskbar_alignment;
panel->g_taskbar.area._resize = resize_taskbar; panel->g_taskbar.area._resize = resize_taskbar;
panel->g_taskbar.area._on_change_layout = on_change_taskbar;
panel->g_taskbar.area.resize_needed = 1; panel->g_taskbar.area.resize_needed = 1;
panel->g_taskbar.area.on_screen = TRUE; panel->g_taskbar.area.on_screen = TRUE;
if (panel_horizontal) { if (panel_horizontal) {
@@ -262,7 +260,7 @@ void init_taskbar_panel(void *p)
panel->g_task.text_posx = panel->g_task.background[0]->border.width + panel->g_task.area.paddingxlr; 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); panel->g_task.text_height = panel->g_task.area.height - (2 * panel->g_task.area.paddingy);
if (panel->g_task.icon) { if (panel->g_task.has_icon) {
panel->g_task.icon_size1 = panel->g_task.area.height - (2 * panel->g_task.area.paddingy); 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.area.paddingx; panel->g_task.text_posx += panel->g_task.icon_size1 + panel->g_task.area.paddingx;
panel->g_task.icon_posy = (panel->g_task.area.height - panel->g_task.icon_size1) / 2; panel->g_task.icon_posy = (panel->g_task.area.height - panel->g_task.icon_size1) / 2;
@@ -326,25 +324,25 @@ void taskbar_default_font_changed()
void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data) void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data)
{ {
remove_task(task_get_task(*(Window *)key)); remove_task(get_task(*(Window *)key));
} }
Task *task_get_task(Window win) Task *get_task(Window win)
{ {
GPtrArray *task_group = task_get_tasks(win); GPtrArray *task_group = get_task_group(win);
if (task_group) if (task_group)
return g_ptr_array_index(task_group, 0); return g_ptr_array_index(task_group, 0);
return NULL; return NULL;
} }
GPtrArray *task_get_tasks(Window win) GPtrArray *get_task_group(Window win)
{ {
if (win_to_task && taskbar_enabled) if (win_to_task && taskbar_enabled)
return g_hash_table_lookup(win_to_task, &win); return g_hash_table_lookup(win_to_task, &win);
return NULL; return NULL;
} }
void task_refresh_tasklist() void taskbar_refresh_tasklist()
{ {
if (!taskbar_enabled) if (!taskbar_enabled)
return; return;
@@ -368,7 +366,7 @@ void task_refresh_tasklist()
// Add any new // Add any new
for (int i = 0; i < num_results; i++) for (int i = 0; i < num_results; i++)
if (!task_get_task(win[i])) if (!get_task(win[i]))
add_task(win[i]); add_task(win[i]);
XFree(win); XFree(win);
@@ -404,12 +402,6 @@ gboolean resize_taskbar(void *obj)
return FALSE; return FALSE;
} }
void on_change_taskbar(void *obj)
{
Taskbar *taskbar = (Taskbar *)obj;
schedule_redraw(&taskbar->area);
}
void set_taskbar_state(Taskbar *taskbar, TaskbarState state) void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
{ {
taskbar->area.bg = panels[0].g_taskbar.background[state]; taskbar->area.bg = panels[0].g_taskbar.background[state];
@@ -433,19 +425,18 @@ void set_taskbar_state(Taskbar *taskbar, TaskbarState state)
if (taskbarname_enabled) if (taskbarname_enabled)
l = l->next; l = l->next;
for (; l; l = l->next) for (; l; l = l->next)
set_task_redraw((Task *)l->data); schedule_redraw((Area *)l->data);
} }
} }
panel_refresh = TRUE; panel_refresh = TRUE;
} }
void visible_taskbar(void *p) void update_taskbar_visibility(void *p)
{ {
Panel *panel = (Panel *)p; Panel *panel = (Panel *)p;
Taskbar *taskbar;
for (int j = 0; j < panel->num_desktops; j++) { for (int j = 0; j < panel->num_desktops; j++) {
taskbar = &panel->taskbar[j]; Taskbar *taskbar = &panel->taskbar[j];
if (taskbar_mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) { if (taskbar_mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) {
// SINGLE_DESKTOP and not current desktop // SINGLE_DESKTOP and not current desktop
taskbar->area.on_screen = FALSE; taskbar->area.on_screen = FALSE;
@@ -575,7 +566,7 @@ void sort_taskbar_for_win(Window win)
if (taskbar_sort_method == TASKBAR_NOSORT) if (taskbar_sort_method == TASKBAR_NOSORT)
return; return;
GPtrArray *task_group = task_get_tasks(win); GPtrArray *task_group = get_task_group(win);
if (task_group) { if (task_group) {
Task *task0 = g_ptr_array_index(task_group, 0); Task *task0 = g_ptr_array_index(task_group, 0);
if (task0) { if (task0) {

View File

@@ -25,9 +25,26 @@ typedef enum TaskbarSortMethod {
TASKBAR_SORT_MRU, TASKBAR_SORT_MRU,
} TaskbarSortMethod; } TaskbarSortMethod;
extern GHashTable *win_to_task; typedef struct {
extern Task *active_task; Area area;
extern Task *task_drag; gchar *name;
int posy;
} TaskbarName;
typedef struct {
Area area;
int desktop;
TaskbarName bar_name;
int text_width;
} Taskbar;
typedef struct GlobalTaskbar {
Area area;
Area area_name;
Background *background[TASKBAR_STATE_COUNT];
Background *background_name[TASKBAR_STATE_COUNT];
} GlobalTaskbar;
extern gboolean taskbar_enabled; extern gboolean taskbar_enabled;
extern gboolean taskbar_distribute_size; extern gboolean taskbar_distribute_size;
extern gboolean hide_inactive_tasks; extern gboolean hide_inactive_tasks;
@@ -35,51 +52,40 @@ extern gboolean hide_task_diff_monitor;
extern TaskbarSortMethod taskbar_sort_method; extern TaskbarSortMethod taskbar_sort_method;
extern Alignment taskbar_alignment; extern Alignment taskbar_alignment;
typedef struct { // win_to_task holds for every Window an array of tasks. Usually the array contains only one
Area area; // element. However for omnipresent windows (windows which are visible in every taskbar) the array
gchar *name; // contains to every Task* on each panel a pointer (i.e. GPtrArray.len == server.num_desktops)
int posy; extern GHashTable *win_to_task;
} Taskbarname;
typedef struct { extern Task *active_task;
Area area; extern Task *task_drag;
int desktop;
Taskbarname bar_name;
int text_width;
} Taskbar;
typedef struct GlobalTaskbar {
// always start with area
Area area;
Area area_name;
Background *background[TASKBAR_STATE_COUNT];
Background *background_name[TASKBAR_STATE_COUNT];
} GlobalTaskbar;
// default global data
void default_taskbar(); void default_taskbar();
// freed memory
void cleanup_taskbar(); void cleanup_taskbar();
void init_taskbar(); void init_taskbar();
void init_taskbar_panel(void *p); void init_taskbar_panel(void *p);
void taskbar_remove_task(gpointer key, gpointer value, gpointer user_data);
Task *task_get_task(Window win);
GPtrArray *task_get_tasks(Window win);
void task_refresh_tasklist();
gboolean resize_taskbar(void *obj); gboolean resize_taskbar(void *obj);
void on_change_taskbar(void *obj);
void set_taskbar_state(Taskbar *taskbar, TaskbarState state);
// show/hide taskbar according to current desktop
void visible_taskbar(void *p);
void sort_taskbar_for_win(Window win);
void sort_tasks(Taskbar *taskbar);
void taskbar_default_font_changed(); void taskbar_default_font_changed();
// Reloads the entire list of tasks from the window manager and recreates the task buttons.
void taskbar_refresh_tasklist();
// Returns the task button for this window. If there are multiple buttons, returns the first one.
Task *get_task(Window win);
// Returns the task group, i.e. the set of task buttons for this window, usually having only one element.
// However for windows shown on all desktops, there is one button for each taskbar (usually only one visible).
GPtrArray *get_task_group(Window win);
void set_taskbar_state(Taskbar *taskbar, TaskbarState state);
// Updates the visibility of each taskbar when the current desktop changes.
void update_taskbar_visibility(void *p);
// Sorts the taskbar(s) on which the window is present.
void sort_taskbar_for_win(Window win);
void sort_tasks(Taskbar *taskbar);
#endif #endif

View File

@@ -132,7 +132,7 @@ void cleanup_taskbarname()
gboolean resize_taskbarname(void *obj) gboolean resize_taskbarname(void *obj)
{ {
Taskbarname *taskbar_name = obj; TaskbarName *taskbar_name = obj;
Panel *panel = taskbar_name->area.panel; Panel *panel = taskbar_name->area.panel;
int name_height, name_width, name_height_ink; int name_height, name_width, name_height_ink;
int ret = 0; int ret = 0;
@@ -170,7 +170,7 @@ gboolean resize_taskbarname(void *obj)
void draw_taskbarname(void *obj, cairo_t *c) void draw_taskbarname(void *obj, cairo_t *c)
{ {
Taskbarname *taskbar_name = obj; TaskbarName *taskbar_name = obj;
Taskbar *taskbar = taskbar_name->area.parent; Taskbar *taskbar = taskbar_name->area.parent;
PangoLayout *layout; PangoLayout *layout;
Color *config_text = (taskbar->desktop == server.desktop) ? &taskbarname_active_font : &taskbarname_font; Color *config_text = (taskbar->desktop == server.desktop) ? &taskbarname_active_font : &taskbarname_font;

View File

@@ -957,10 +957,10 @@ void event_property_notify(XEvent *e)
for (int i = 0; i < num_panels; i++) { for (int i = 0; i < num_panels; i++) {
init_taskbar_panel(&panels[i]); init_taskbar_panel(&panels[i]);
set_panel_items_order(&panels[i]); set_panel_items_order(&panels[i]);
visible_taskbar(&panels[i]); update_taskbar_visibility(&panels[i]);
panels[i].area.resize_needed = 1; panels[i].area.resize_needed = 1;
} }
task_refresh_tasklist(); taskbar_refresh_tasklist();
reset_active_task(); reset_active_task();
panel_refresh = TRUE; panel_refresh = TRUE;
} else if (old_desktop != server.desktop) { } else if (old_desktop != server.desktop) {
@@ -1009,7 +1009,7 @@ void event_property_notify(XEvent *e)
g_hash_table_iter_init(&iter, win_to_task); g_hash_table_iter_init(&iter, win_to_task);
while (g_hash_table_iter_next(&iter, &key, &value)) { while (g_hash_table_iter_next(&iter, &key, &value)) {
Window task_win = *(Window *)key; Window task_win = *(Window *)key;
Task *task = task_get_task(task_win); Task *task = get_task(task_win);
if (task) { if (task) {
int desktop = get_window_desktop(task_win); int desktop = get_window_desktop(task_win);
if (desktop != task->desktop) { if (desktop != task->desktop) {
@@ -1029,7 +1029,7 @@ void event_property_notify(XEvent *e)
else if (at == server.atom._NET_CLIENT_LIST) { else if (at == server.atom._NET_CLIENT_LIST) {
if (debug) if (debug)
fprintf(stderr, "%s %d: win = root, atom = _NET_CLIENT_LIST\n", __FUNCTION__, __LINE__); fprintf(stderr, "%s %d: win = root, atom = _NET_CLIENT_LIST\n", __FUNCTION__, __LINE__);
task_refresh_tasklist(); taskbar_refresh_tasklist();
panel_refresh = TRUE; panel_refresh = TRUE;
} }
// Change active // Change active
@@ -1054,7 +1054,7 @@ void event_property_notify(XEvent *e)
return; return;
} }
Task *task = task_get_task(win); Task *task = get_task(win);
if (debug) { if (debug) {
char *atom_name = XGetAtomName(server.display, at); char *atom_name = XGetAtomName(server.display, at);
fprintf(stderr, "%s %d: win = %ld, task = %s, atom = %s\n", __FUNCTION__, __LINE__, win, task ? (task->title ? task->title : "??") : "null", atom_name); fprintf(stderr, "%s %d: win = %ld, task = %s, atom = %s\n", __FUNCTION__, __LINE__, win, task ? (task->title ? task->title : "??") : "null", atom_name);
@@ -1079,7 +1079,7 @@ void event_property_notify(XEvent *e)
// Window title changed // Window title changed
if (at == server.atom._NET_WM_VISIBLE_NAME || at == server.atom._NET_WM_NAME || at == server.atom.WM_NAME) { if (at == server.atom._NET_WM_VISIBLE_NAME || at == server.atom._NET_WM_NAME || at == server.atom.WM_NAME) {
if (get_title(task)) { if (task_update_title(task)) {
if (g_tooltip.mapped && (g_tooltip.area == (Area *)task)) { if (g_tooltip.mapped && (g_tooltip.area == (Area *)task)) {
tooltip_copy_text((Area *)task); tooltip_copy_text((Area *)task);
tooltip_update(); tooltip_update();
@@ -1118,7 +1118,7 @@ void event_property_notify(XEvent *e)
} }
// Window icon changed // Window icon changed
else if (at == server.atom._NET_WM_ICON) { else if (at == server.atom._NET_WM_ICON) {
get_icon(task); task_update_icon(task);
panel_refresh = TRUE; panel_refresh = TRUE;
} }
// Window desktop changed // Window desktop changed
@@ -1157,7 +1157,7 @@ void event_configure_notify(XEvent *e)
Window win = e->xconfigure.window; Window win = e->xconfigure.window;
if (0) { if (0) {
Task *task = task_get_task(win); Task *task = get_task(win);
fprintf(stderr, "%s %d: win = %ld, task = %s\n", __FUNCTION__, __LINE__, win, task ? (task->title ? task->title : "??") : "null"); fprintf(stderr, "%s %d: win = %ld, task = %s\n", __FUNCTION__, __LINE__, win, task ? (task->title ? task->title : "??") : "null");
} }
@@ -1175,7 +1175,7 @@ void event_configure_notify(XEvent *e)
// 'win' move in another monitor // 'win' move in another monitor
if (num_panels > 1 || hide_task_diff_monitor) { if (num_panels > 1 || hide_task_diff_monitor) {
Task *task = task_get_task(win); Task *task = get_task(win);
if (task) { if (task) {
Panel *p = task->area.panel; Panel *p = task->area.panel;
int monitor = get_window_monitor(win); int monitor = get_window_monitor(win);
@@ -1194,7 +1194,7 @@ void event_configure_notify(XEvent *e)
} }
if (server.viewports) { if (server.viewports) {
Task *task = task_get_task(win); Task *task = get_task(win);
if (task) { if (task) {
int desktop = get_window_desktop(win); int desktop = get_window_desktop(win);
if (task->desktop != desktop) { if (task->desktop != desktop) {

View File

@@ -75,7 +75,7 @@ gboolean window_is_hidden(Window win)
// do not add transient_for windows if the transient window is already in the taskbar // do not add transient_for windows if the transient window is already in the taskbar
window = win; window = win;
while (XGetTransientForHint(server.display, window, &window)) { while (XGetTransientForHint(server.display, window, &window)) {
if (task_get_tasks(window)) { if (get_task_group(window)) {
XFree(at); XFree(at);
return TRUE; return TRUE;
} }