diff options
-rw-r--r-- | libwnck/tasklist.c | 216 |
1 files changed, 61 insertions, 155 deletions
diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c index 5095898..1a21b7e 100644 --- a/libwnck/tasklist.c +++ b/libwnck/tasklist.c @@ -154,11 +154,9 @@ struct _WnckTask guint32 dnd_timestamp; - cairo_surface_t *screenshot; - cairo_surface_t *screenshot_faded; - time_t start_needs_attention; gdouble glow_start_time; + gdouble glow_factor; guint button_glow; @@ -364,21 +362,6 @@ static GType wnck_task_get_type (void) G_GNUC_CONST; static void -cleanup_screenshots (WnckTask *task) -{ - if (task->screenshot != NULL) - { - cairo_surface_destroy (task->screenshot); - task->screenshot = NULL; - } - if (task->screenshot_faded != NULL) - { - cairo_surface_destroy (task->screenshot_faded); - task->screenshot_faded = NULL; - } -} - -static void wnck_task_init (WnckTask *task) { task->tasklist = NULL; @@ -416,11 +399,9 @@ wnck_task_init (WnckTask *task) task->dnd_timestamp = 0; - task->screenshot = NULL; - task->screenshot_faded = NULL; - task->start_needs_attention = 0; task->glow_start_time = 0.0; + task->glow_factor = 0.0; task->button_glow = 0; @@ -450,16 +431,10 @@ static gboolean wnck_task_button_glow (WnckTask *task) { GTimeVal tv; - gdouble glow_factor, now; + gdouble now; gfloat fade_opacity, loop_time; gint fade_max_loops; gboolean stopped; - GdkWindow *window; - GtkAllocation allocation; - cairo_t *cr; - - if (task->screenshot == NULL) - return TRUE; g_get_current_time (&tv); now = (tv.tv_sec * (1.0 * G_USEC_PER_SEC) + @@ -476,45 +451,22 @@ wnck_task_button_glow (WnckTask *task) if (task->button_glow == 0) { /* we're in "has stopped glowing" mode */ - glow_factor = fade_opacity * 0.5; + task->glow_factor = fade_opacity * 0.5; stopped = TRUE; } else { - glow_factor = fade_opacity * (0.5 - - 0.5 * cos ((now - task->glow_start_time) * - M_PI * 2.0 / loop_time)); + task->glow_factor = fade_opacity * (0.5 - + 0.5 * cos ((now - task->glow_start_time) * + M_PI * 2.0 / loop_time)); if (now - task->start_needs_attention > loop_time * 1.0 * fade_max_loops) - stopped = ABS (glow_factor - fade_opacity * 0.5) < 0.05; + stopped = ABS (task->glow_factor - fade_opacity * 0.5) < 0.05; else stopped = FALSE; } - window = gtk_widget_get_window (task->button); - gtk_widget_get_allocation (task->button, &allocation); - - gdk_window_begin_paint_rect (window, &allocation); - - cr = gdk_cairo_create (window); - gdk_cairo_rectangle (cr, &allocation); - cairo_translate (cr, allocation.x, allocation.y); - cairo_clip (cr); - - cairo_save (cr); - - cairo_set_source_surface (cr, task->screenshot, 0., 0.); - cairo_paint (cr); - - cairo_restore (cr); - - cairo_set_source_surface (cr, task->screenshot_faded, 0., 0.); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_paint_with_alpha (cr, glow_factor); - - cairo_destroy (cr); - - gdk_window_end_paint (window); + gtk_widget_queue_draw (task->button); if (stopped) wnck_task_stop_glow (task); @@ -654,8 +606,6 @@ wnck_task_finalize (GObject *object) wnck_task_stop_glow (task); - cleanup_screenshots (task); - G_OBJECT_CLASS (wnck_task_parent_class)->finalize (object); } @@ -1559,8 +1509,6 @@ wnck_tasklist_size_allocate (GtkWidget *widget, gtk_widget_set_child_visible (GTK_WIDGET (win_task->button), FALSE); - cleanup_screenshots (win_task); - l = l->next; } } @@ -1568,8 +1516,6 @@ wnck_tasklist_size_allocate (GtkWidget *widget, { visible_tasks = g_list_prepend (visible_tasks, class_group_task->windows->data); gtk_widget_set_child_visible (GTK_WIDGET (class_group_task->button), FALSE); - - cleanup_screenshots (class_group_task); } button_width = wnck_tasklist_layout (allocation, @@ -1588,8 +1534,6 @@ wnck_tasklist_size_allocate (GtkWidget *widget, visible_tasks = g_list_concat (visible_tasks, g_list_copy (class_group_task->windows)); gtk_widget_set_child_visible (GTK_WIDGET (class_group_task->button), FALSE); - cleanup_screenshots (class_group_task); - l = l->next; } @@ -3356,6 +3300,7 @@ wnck_task_update_visible_state (WnckTask *task) { _make_gtk_label_normal ((GTK_LABEL (task->label))); wnck_task_stop_glow (task); + task->glow_factor = 0.0; } g_free (text); } @@ -3906,25 +3851,52 @@ wnck_task_create_widgets (WnckTask *task, GtkReliefStyle relief) G_CONNECT_AFTER); } -static cairo_surface_t * -take_screenshot (WnckTask *task) +static gboolean +wnck_task_draw (GtkWidget *widget, + cairo_t *cr, + gpointer data) { + int x, y; + WnckTask *task; + GtkStyle *style; + GtkAllocation allocation, child_allocation; WnckTasklist *tasklist; - GtkWidget *tasklist_widget; - cairo_surface_t *surface; - GtkAllocation allocation; - cairo_t *cr; + GtkWidget *tasklist_widget, *child; gint width, height; gboolean overlay_rect; + task = WNCK_TASK (data); + + switch (task->type) + { + case WNCK_TASK_CLASS_GROUP: + style = gtk_widget_get_style (widget); + + x = gtk_widget_get_allocated_width (widget) - + (gtk_container_get_border_width (GTK_CONTAINER (widget)) + style->ythickness + 12); + y = gtk_widget_get_allocated_height (widget) / 2 - 5; + + gtk_paint_tab (style, + cr, + task->tasklist->priv->active_class_group == task ? + GTK_STATE_ACTIVE : GTK_STATE_NORMAL, + GTK_SHADOW_NONE, widget, NULL, x, y, 10, 10); + break; + + case WNCK_TASK_WINDOW: + case WNCK_TASK_STARTUP_SEQUENCE: + break; + } + + if (task->glow_factor == 0.0) + return FALSE; + + /* push a translucent overlay to paint to, so we can blend later */ + cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA); + width = gtk_widget_get_allocated_width (task->button); height = gtk_widget_get_allocated_height (task->button); - surface = gdk_window_create_similar_surface (gtk_widget_get_window (task->button), - CAIRO_CONTENT_COLOR_ALPHA, - width, height); - cr = cairo_create (surface); - tasklist = WNCK_TASKLIST (task->tasklist); tasklist_widget = GTK_WIDGET (task->tasklist); @@ -3965,92 +3937,26 @@ take_screenshot (WnckTask *task) g_object_unref (attached_style); } - /* then the image and label */ - cairo_save (cr); - gtk_widget_get_allocation (task->image, &allocation); - cairo_translate (cr, allocation.x, allocation.y); - gtk_widget_draw (task->image, cr); - cairo_restore (cr); - + /* then the contents */ + cairo_save (cr); - gtk_widget_get_allocation (task->label, &allocation); - cairo_translate (cr, allocation.x, allocation.y); - gtk_widget_draw (task->label, cr); + gtk_widget_get_allocation (task->button, &allocation); + child = gtk_bin_get_child (GTK_BIN (task->button)); + gtk_widget_get_allocation (child, &child_allocation); + cairo_translate (cr, + child_allocation.x - allocation.x, + child_allocation.y - allocation.y); + gtk_widget_draw (gtk_bin_get_child (GTK_BIN (task->button)), cr); cairo_restore (cr); - - return surface; -} - -static cairo_surface_t * -copy_surface (GtkWidget *widget) -{ - cairo_surface_t *surface; - cairo_t *cr; - - surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget), - CAIRO_CONTENT_COLOR_ALPHA, - gtk_widget_get_allocated_width (widget), - gtk_widget_get_allocated_height (widget)); - - cr = cairo_create (surface); - gtk_widget_draw (widget, cr); - cairo_destroy (cr); - - return surface; -} - -static gboolean -wnck_task_draw (GtkWidget *widget, - cairo_t *cr, - gpointer data) -{ - int x, y; - WnckTask *task; - GtkStyle *style; - - task = WNCK_TASK (data); - - cleanup_screenshots (task); - - switch (task->type) - { - case WNCK_TASK_CLASS_GROUP: - style = gtk_widget_get_style (widget); - x = gtk_widget_get_allocated_width (widget) - - (gtk_container_get_border_width (GTK_CONTAINER (widget)) + style->ythickness + 12); - y = gtk_widget_get_allocated_height (widget) / 2 - 5; - - gtk_paint_tab (style, - cr, - task->tasklist->priv->active_class_group == task ? - GTK_STATE_ACTIVE : GTK_STATE_NORMAL, - GTK_SHADOW_NONE, widget, NULL, x, y, 10, 10); - - /* Fall through to get screenshot - */ - case WNCK_TASK_WINDOW: - if (task->start_needs_attention) - { - time_t attention = task->start_needs_attention; - - task->start_needs_attention = 0; - - task->screenshot = copy_surface (widget); - task->screenshot_faded = take_screenshot (task); - - task->start_needs_attention = attention; - - wnck_task_button_glow (task); - } - - case WNCK_TASK_STARTUP_SEQUENCE: - break; - } + /* finally blend it */ + cairo_pop_group_to_source (cr); + cairo_paint_with_alpha (cr, task->glow_factor); return FALSE; } + static gint wnck_task_compare_alphabetically (gconstpointer a, gconstpointer b) |