diff --git a/src/taskbar/task.c b/src/taskbar/task.c index c0d11cd..8895aa9 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -40,6 +40,7 @@ GSList *urgent_list; void task_dump_geometry(void *obj, int indent); int task_compute_desired_size(void *obj); +void task_refresh_thumbnail(Task *task); char *task_get_tooltip(void *obj) { @@ -50,6 +51,8 @@ char *task_get_tooltip(void *obj) cairo_surface_t *task_get_thumbnail(void *obj) { Task *t = (Task *)obj; + if (!t->thumbnail) + task_refresh_thumbnail(t); return t->thumbnail; } @@ -617,12 +620,22 @@ void reset_active_task() void task_refresh_thumbnail(Task *task) { + if (task->current_state == TASK_ICONIFIED) + return; + double now = get_time(); + if (now - task->thumbnail_last_update < 0.1) + return; cairo_surface_t *thumbnail = get_window_thumbnail(task->win); if (!thumbnail) return; if (task->thumbnail) cairo_surface_destroy(task->thumbnail); task->thumbnail = thumbnail; + task->thumbnail_last_update = get_time(); + if (g_tooltip.mapped && (g_tooltip.area == &task->area)) { + tooltip_update_contents_for(&task->area); + tooltip_update(); + } } void set_task_state(Task *task, TaskState state) @@ -630,9 +643,8 @@ void set_task_state(Task *task, TaskState state) if (!task || state == TASK_UNDEFINED || state >= TASK_STATE_COUNT) return; - if (state != TASK_ICONIFIED) { - task_refresh_thumbnail(task); - } + task_refresh_thumbnail(task); + taskbar_start_thumbnail_timer(); if (state == TASK_ACTIVE && task->current_state != state) { clock_gettime(CLOCK_MONOTONIC, &task->last_activation_time); diff --git a/src/taskbar/task.h b/src/taskbar/task.h index b52f975..4c10801 100644 --- a/src/taskbar/task.h +++ b/src/taskbar/task.h @@ -75,6 +75,7 @@ typedef struct Task { int _icon_x; int _icon_y; cairo_surface_t *thumbnail; + double thumbnail_last_update; } Task; extern timeout *urgent_timeout; @@ -92,6 +93,7 @@ gboolean task_update_title(Task *task); void reset_active_task(); void set_task_state(Task *task, TaskState state); void task_handle_mouse_event(Task *task, MouseAction action); +void task_refresh_thumbnail(Task *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. diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index 3f91c45..8e37689 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -46,6 +46,7 @@ gboolean hide_taskbar_if_empty; gboolean always_show_all_desktop_tasks; TaskbarSortMethod taskbar_sort_method; Alignment taskbar_alignment; +static timeout *thumbnail_update_timer = NULL; static GList *taskbar_task_orderings = NULL; @@ -55,6 +56,8 @@ int taskbar_compute_desired_size(void *obj); // Removes the task with &win = key. The other args are ignored. void taskbar_remove_task(Window *win); +void taskbar_update_thumbnails(void *arg); + guint win_hash(gconstpointer key) { return *((const Window *)key); @@ -120,6 +123,7 @@ void taskbar_save_orderings() void cleanup_taskbar() { + stop_timeout(thumbnail_update_timer); taskbar_save_orderings(); if (win_to_task) { while (g_hash_table_size(win_to_task)) { @@ -353,6 +357,12 @@ void init_taskbar_panel(void *p) } } init_taskbarname_panel(panel); + taskbar_start_thumbnail_timer(); +} + +void taskbar_start_thumbnail_timer() +{ + change_timeout(&thumbnail_update_timer, 100, 10 * 1000, taskbar_update_thumbnails, NULL); } void taskbar_init_fonts() @@ -779,3 +789,17 @@ void update_minimized_icon_positions(void *p) } } } + +void taskbar_update_thumbnails(void *arg) +{ + for (int i = 0; i < num_panels; i++) { + Panel *panel = &panels[i]; + for (int j = 0; j < panel->num_desktops; j++) { + Taskbar *taskbar = &panel->taskbar[j]; + for (GList *c = (taskbar->area.children && taskbarname_enabled) ? taskbar->area.children->next : taskbar->area.children; c; c = c->next) { + Task *t = (Task *)c->data; + task_refresh_thumbnail(t); + } + } + } +} diff --git a/src/taskbar/taskbar.h b/src/taskbar/taskbar.h index 2355c72..deddec2 100644 --- a/src/taskbar/taskbar.h +++ b/src/taskbar/taskbar.h @@ -72,6 +72,7 @@ void init_taskbar_panel(void *p); gboolean resize_taskbar(void *obj); void taskbar_default_font_changed(); +void taskbar_start_thumbnail_timer(); // Reloads the entire list of tasks from the window manager and recreates the task buttons. void taskbar_refresh_tasklist(); diff --git a/src/tooltip/tooltip.c b/src/tooltip/tooltip.c index 098da6e..7a2a727 100644 --- a/src/tooltip/tooltip.c +++ b/src/tooltip/tooltip.c @@ -54,6 +54,7 @@ void default_tooltip() void cleanup_tooltip() { stop_tooltip_timeout(); + stop_timeout(g_tooltip.update_timeout); tooltip_hide(NULL); tooltip_update_contents_for(NULL); if (g_tooltip.window) @@ -333,6 +334,11 @@ void stop_tooltip_timeout() stop_timeout(g_tooltip.timeout); } +void tooltip_update_contents_timeout(void *arg) +{ + tooltip_update_contents_for(g_tooltip.area); +} + void tooltip_update_contents_for(Area *area) { free_and_null(g_tooltip.tooltip_text); @@ -345,6 +351,8 @@ void tooltip_update_contents_for(Area *area) g_tooltip.image = area->_get_tooltip_image(area); if (g_tooltip.image) cairo_surface_reference(g_tooltip.image); + else + change_timeout(&g_tooltip.update_timeout, 300, 0, tooltip_update_contents_timeout, NULL); } g_tooltip.area = area; } diff --git a/src/tooltip/tooltip.h b/src/tooltip/tooltip.h index 56d4a38..f6ccf22 100644 --- a/src/tooltip/tooltip.h +++ b/src/tooltip/tooltip.h @@ -37,6 +37,7 @@ typedef struct { Color font_color; Background *bg; timeout *timeout; + timeout *update_timeout; cairo_surface_t *image; } Tooltip;