From c99c8523877fd72cf53035d63c5fe0f75be7657c Mon Sep 17 00:00:00 2001
From: Victor Kareh <vkareh@redhat.com>
Date: Wed, 23 Jun 2021 07:24:20 -0400
Subject: window: Convert all icons to cairo surfaces

---
 src/core/core.c           |  4 +-
 src/core/screen.c         | 19 ++++------
 src/core/window-private.h |  4 +-
 src/core/window.c         | 24 ++++--------
 src/include/tabpopup.h    |  2 +-
 src/ui/draw-workspace.c   |  4 +-
 src/ui/draw-workspace.h   |  4 +-
 src/ui/frames.c           |  4 +-
 src/ui/preview-widget.c   | 67 ++++++++++++++++++++--------------
 src/ui/preview-widget.h   |  4 +-
 src/ui/tabpopup.c         | 93 +++++++++++++++++++++--------------------------
 src/ui/theme-viewer.c     |  7 +++-
 src/ui/theme.c            | 53 +++++++++------------------
 src/ui/theme.h            | 20 +++++-----
 src/ui/ui.c               |  8 ++--
 15 files changed, 145 insertions(+), 172 deletions(-)

(limited to 'src')

diff --git a/src/core/core.c b/src/core/core.c
index 37459d8f..cdf98d4d 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -176,10 +176,10 @@ meta_core_get (Display *xdisplay,
           break;
           }
       case META_CORE_GET_MINI_ICON:
-        *((GdkPixbuf**)answer) = window->mini_icon;
+        *((cairo_surface_t**)answer) = window->mini_icon;
         break;
       case META_CORE_GET_ICON:
-        *((GdkPixbuf**)answer) = window->icon;
+        *((cairo_surface_t**)answer) = window->icon;
         break;
       case META_CORE_GET_X:
         meta_window_get_position (window, (int*)answer, NULL);
diff --git a/src/core/screen.c b/src/core/screen.c
index 99932393..ca43c232 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -1282,7 +1282,6 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
   int len;
   int i;
   gint border;
-  int scale;
 
   if (screen->tab_popup)
     return;
@@ -1293,7 +1292,6 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
                                         screen->active_workspace);
 
   len = g_list_length (tab_list);
-  scale = gdk_window_get_scale_factor (gdk_get_default_root_window ());
 
   entries = g_new (MetaTabEntry, len + 1);
   entries[len].key = NULL;
@@ -1316,7 +1314,7 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
       entries[i].title = window->title;
       entries[i].win_surface = NULL;
 
-      entries[i].icon = g_object_ref (window->icon);
+      entries[i].icon = cairo_surface_reference (window->icon);
 
       /* Only get the window thumbnail surface if the user has a compositor
        * enabled and does NOT have compositing-fast-alt-tab-set to true in
@@ -1330,7 +1328,7 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
 
           if (win_surface != NULL)
             {
-              cairo_surface_t *surface, *icon;
+              cairo_surface_t *surface;
               cairo_t *cr;
               int width, height, icon_width, icon_height;
 
@@ -1348,15 +1346,12 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
               cairo_set_source_surface (cr, win_surface, 0, 0);
               cairo_paint (cr);
 
-              /* Get the window icon as a surface */
-              icon = gdk_cairo_surface_create_from_pixbuf (window->icon, scale, NULL);
-
-              icon_width = cairo_image_surface_get_width (icon) / scale;
-              icon_height = cairo_image_surface_get_height (icon) / scale;
+              icon_width = cairo_image_surface_get_width (window->icon);
+              icon_height = cairo_image_surface_get_height (window->icon);
 
               /* Overlap the window icon surface over the window thumbnail */
               cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
-              cairo_set_source_surface (cr, icon,
+              cairo_set_source_surface (cr, window->icon,
                                         width  - icon_width - ICON_OFFSET,
                                         height - icon_height - ICON_OFFSET);
               cairo_paint (cr);
@@ -1364,7 +1359,6 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
               entries[i].win_surface = surface;
 
               cairo_destroy (cr);
-              cairo_surface_destroy (icon);
               cairo_surface_destroy (win_surface);
             }
         }
@@ -1414,7 +1408,8 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
 
   for (i = 0; i < len; i++)
     {
-      g_object_unref (entries[i].icon);
+      if (entries[i].icon)
+        cairo_surface_destroy (entries[i].icon);
       if (entries[i].win_surface)
         cairo_surface_destroy (entries[i].win_surface);
     }
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 02b7df42..ca0a6e41 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -114,8 +114,8 @@ struct _MetaWindow
   char *title;
 
   char *icon_name;
-  GdkPixbuf *icon;
-  GdkPixbuf *mini_icon;
+  cairo_surface_t *icon;
+  cairo_surface_t *mini_icon;
   MetaIconCache icon_cache;
   Pixmap wm_hints_pixmap;
   Pixmap wm_hints_mask;
diff --git a/src/core/window.c b/src/core/window.c
index 08cd99c7..7a1ddb3b 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -6126,24 +6126,14 @@ meta_window_update_icon_now (MetaWindow *window)
                        &icon,
                        icon_size,
                        &mini_icon,
-                       META_MINI_ICON_SIZE,
+                       META_MINI_ICON_SIZE * scale,
                        scale))
     {
-      if (window->icon)
-        g_object_unref (G_OBJECT (window->icon));
+      g_clear_pointer (&window->icon, cairo_surface_destroy);
+      g_clear_pointer (&window->mini_icon, cairo_surface_destroy);
 
-      if (window->mini_icon)
-        g_object_unref (G_OBJECT (window->mini_icon));
-
-      window->icon = gdk_pixbuf_get_from_surface (icon,
-                                                  0, 0,
-                                                  icon_size, icon_size);
-      cairo_surface_destroy (icon);
-
-      window->mini_icon = gdk_pixbuf_get_from_surface (mini_icon,
-                                                       0, 0,
-                                                       META_MINI_ICON_SIZE, META_MINI_ICON_SIZE);
-      cairo_surface_destroy (mini_icon);
+      window->icon = icon;
+      window->mini_icon = mini_icon;
 
       redraw_icon (window);
     }
@@ -9003,8 +8993,8 @@ meta_window_finalize (GObject *object)
 
   window = META_WINDOW (object);
 
-  g_clear_object (&window->icon);
-  g_clear_object (&window->mini_icon);
+  g_clear_pointer (&window->icon, cairo_surface_destroy);
+  g_clear_pointer (&window->mini_icon, cairo_surface_destroy);
 
   g_clear_pointer (&window->frame_bounds, cairo_region_destroy);
 
diff --git a/src/include/tabpopup.h b/src/include/tabpopup.h
index 19e8621b..7f11bb17 100644
--- a/src/include/tabpopup.h
+++ b/src/include/tabpopup.h
@@ -48,7 +48,7 @@ struct _MetaTabEntry
 {
   MetaTabEntryKey  key;
   const char      *title;
-  GdkPixbuf       *icon;
+  cairo_surface_t *icon;
   cairo_surface_t *win_surface;
   MetaRectangle    rect;
   MetaRectangle    inner_rect;
diff --git a/src/ui/draw-workspace.c b/src/ui/draw-workspace.c
index c5519cae..d7e3c81a 100644
--- a/src/ui/draw-workspace.c
+++ b/src/ui/draw-workspace.c
@@ -119,7 +119,7 @@ draw_window (GtkWidget                   *widget,
 
   scale = gtk_widget_get_scale_factor (widget);
 
-  icon = gdk_cairo_surface_create_from_pixbuf (win->icon, scale, NULL);
+  icon = cairo_surface_reference (win->icon);
 
   icon_w = icon_h = 0;
 
@@ -132,7 +132,7 @@ draw_window (GtkWidget                   *widget,
       if (icon_w > (winrect->width - 2) || icon_h > (winrect->height - 2))
         {
           cairo_surface_destroy (icon);
-          icon = gdk_cairo_surface_create_from_pixbuf (win->mini_icon, scale, NULL);
+          icon = cairo_surface_reference (win->mini_icon);
           if (icon)
             {
               icon_w = cairo_image_surface_get_width (icon) / scale;
diff --git a/src/ui/draw-workspace.h b/src/ui/draw-workspace.h
index d70568cb..ac20b137 100644
--- a/src/ui/draw-workspace.h
+++ b/src/ui/draw-workspace.h
@@ -34,8 +34,8 @@
 
 typedef struct
 {
-  GdkPixbuf *icon;
-  GdkPixbuf *mini_icon;
+  cairo_surface_t *icon;
+  cairo_surface_t *mini_icon;
   int x;
   int y;
   int width;
diff --git a/src/ui/frames.c b/src/ui/frames.c
index d65dac82..54851a2b 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -2563,8 +2563,8 @@ meta_frames_paint_to_drawable (MetaFrames   *frames,
 {
   MetaFrameFlags flags;
   MetaFrameType type;
-  GdkPixbuf *mini_icon;
-  GdkPixbuf *icon;
+  cairo_surface_t *mini_icon;
+  cairo_surface_t *icon;
   int w, h, scale;
   MetaButtonState button_states[META_BUTTON_TYPE_LAST];
   Window grab_frame;
diff --git a/src/ui/preview-widget.c b/src/ui/preview-widget.c
index 9c7fd3ec..3ea29451 100644
--- a/src/ui/preview-widget.c
+++ b/src/ui/preview-widget.c
@@ -192,6 +192,7 @@ meta_preview_draw (GtkWidget *widget,
   int border_width;
   int client_width;
   int client_height;
+  int scale;
   MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
   {
     META_BUTTON_STATE_NORMAL,
@@ -219,6 +220,8 @@ meta_preview_draw (GtkWidget *widget,
   if (client_height < 0)
     client_height = 1;
 
+  scale = gtk_widget_get_scale_factor (widget);
+
   if (preview->theme)
     {
       meta_theme_draw_frame (preview->theme,
@@ -231,8 +234,8 @@ meta_preview_draw (GtkWidget *widget,
                              preview->text_height,
                              &preview->button_layout,
                              button_states,
-                             meta_preview_get_mini_icon (),
-                             meta_preview_get_icon ());
+                             meta_preview_get_mini_icon (scale),
+                             meta_preview_get_icon (scale));
     }
 
   cairo_restore (cr);
@@ -421,10 +424,10 @@ meta_preview_set_button_layout (MetaPreview            *preview,
   gtk_widget_queue_draw (GTK_WIDGET (preview));
 }
 
-GdkPixbuf*
-meta_preview_get_icon (void)
+cairo_surface_t*
+meta_preview_get_icon (int scale)
 {
-  static GdkPixbuf *default_icon = NULL;
+  static cairo_surface_t *default_icon = NULL;
 
   if (default_icon == NULL)
     {
@@ -436,17 +439,21 @@ meta_preview_get_icon (void)
       icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
 
       if (icon_exists)
-          default_icon = gtk_icon_theme_load_icon (theme,
-                                                   META_DEFAULT_ICON_NAME,
-                                                   META_DEFAULT_ICON_SIZE,
-                                                   0,
-                                                   NULL);
+          default_icon = gtk_icon_theme_load_surface (theme,
+                                                      META_DEFAULT_ICON_NAME,
+                                                      META_DEFAULT_ICON_SIZE,
+                                                      scale,
+                                                      NULL,
+                                                      0,
+                                                      NULL);
       else
-          default_icon = gtk_icon_theme_load_icon (theme,
-                                                   "image-missing",
-                                                   META_DEFAULT_ICON_SIZE,
-                                                   0,
-                                                   NULL);
+          default_icon = gtk_icon_theme_load_surface (theme,
+                                                      "image-missing",
+                                                      META_DEFAULT_ICON_SIZE,
+                                                      scale,
+                                                      NULL,
+                                                      0,
+                                                      NULL);
 
       g_assert (default_icon);
     }
@@ -454,10 +461,10 @@ meta_preview_get_icon (void)
   return default_icon;
 }
 
-GdkPixbuf*
-meta_preview_get_mini_icon (void)
+cairo_surface_t*
+meta_preview_get_mini_icon (int scale)
 {
-  static GdkPixbuf *default_icon = NULL;
+  static cairo_surface_t *default_icon = NULL;
 
   if (default_icon == NULL)
     {
@@ -469,17 +476,21 @@ meta_preview_get_mini_icon (void)
       icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
 
       if (icon_exists)
-          default_icon = gtk_icon_theme_load_icon (theme,
-                                                   META_DEFAULT_ICON_NAME,
-                                                   META_MINI_ICON_SIZE,
-                                                   0,
-                                                   NULL);
+          default_icon = gtk_icon_theme_load_surface (theme,
+                                                      META_DEFAULT_ICON_NAME,
+                                                      META_MINI_ICON_SIZE,
+                                                      scale,
+                                                      NULL,
+                                                      0,
+                                                      NULL);
       else
-          default_icon = gtk_icon_theme_load_icon (theme,
-                                                   "image-missing",
-                                                   META_MINI_ICON_SIZE,
-                                                   0,
-                                                   NULL);
+          default_icon = gtk_icon_theme_load_surface (theme,
+                                                      "image-missing",
+                                                      META_MINI_ICON_SIZE,
+                                                      scale,
+                                                      NULL,
+                                                      0,
+                                                      NULL);
 
       g_assert (default_icon);
     }
diff --git a/src/ui/preview-widget.h b/src/ui/preview-widget.h
index 462c445a..00a893c1 100644
--- a/src/ui/preview-widget.h
+++ b/src/ui/preview-widget.h
@@ -78,7 +78,7 @@ cairo_region_t* meta_preview_get_clip_region (MetaPreview *preview,
                                           gint new_window_width,
                                           gint new_window_height);
 
-GdkPixbuf* meta_preview_get_icon (void);
-GdkPixbuf* meta_preview_get_mini_icon (void);
+cairo_surface_t* meta_preview_get_icon (int scale);
+cairo_surface_t* meta_preview_get_mini_icon (int scale);
 
 #endif
diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c
index d3b9ba62..2da0daba 100644
--- a/src/ui/tabpopup.c
+++ b/src/ui/tabpopup.c
@@ -49,8 +49,7 @@ struct _TabEntry
   char            *title;
   gint             grid_left;
   gint             grid_top;
-  GdkPixbuf       *icon, *dimmed_icon;
-  cairo_surface_t *win_surface;
+  cairo_surface_t *icon, *dimmed_icon, *win_surface;
   GtkWidget       *widget;
   GdkRectangle     rect;
   GdkRectangle     inner_rect;
@@ -69,7 +68,7 @@ struct _MetaTabPopup
   gint border;
 };
 
-static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf, cairo_surface_t *win_surface);
+static GtkWidget* selectable_image_new (cairo_surface_t *surface, cairo_surface_t *win_surface);
 static void       select_image         (GtkWidget *widget);
 static void       unselect_image       (GtkWidget *widget);
 
@@ -133,42 +132,45 @@ popup_window_screen_changed (GtkWidget *widget,
   gtk_widget_set_visual(widget, visual);
 }
 
-static GdkPixbuf*
-dimm_icon (GdkPixbuf *pixbuf)
+static cairo_surface_t*
+dimm_icon (cairo_surface_t *orig, gint scale)
 {
-  int x, y, pixel_stride, row_stride;
-  guchar *row, *pixels;
-  int w, h;
-  GdkPixbuf *dimmed_pixbuf;
+  cairo_surface_t *dimmed, *temp;
+  cairo_t *dimmed_cr, *cr;
 
-  if (gdk_pixbuf_get_has_alpha (pixbuf))
-    {
-      dimmed_pixbuf = gdk_pixbuf_copy (pixbuf);
-    }
-  else
-    {
-      dimmed_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
-    }
+  g_assert (orig != NULL);
+  g_assert (cairo_surface_get_content (orig) != CAIRO_CONTENT_COLOR);
 
-  w = gdk_pixbuf_get_width (dimmed_pixbuf);
-  h = gdk_pixbuf_get_height (dimmed_pixbuf);
+  /* Create a new surface based on the original icon */
+  dimmed = cairo_surface_create_similar (orig,
+                                         cairo_surface_get_content (orig),
+                                         cairo_image_surface_get_width (orig) / scale,
+                                         cairo_image_surface_get_height (orig) / scale);
 
-  pixel_stride = 4;
+  dimmed_cr = cairo_create (dimmed);
 
-  row = gdk_pixbuf_get_pixels (dimmed_pixbuf);
-  row_stride = gdk_pixbuf_get_rowstride (dimmed_pixbuf);
+  cairo_set_source_surface (dimmed_cr, orig, 0, 0);
+  cairo_paint (dimmed_cr);
 
-  for (y = 0; y < h; y++)
-    {
-      pixels = row;
-      for (x = 0; x < w; x++)
-        {
-          pixels[3] /= 2;
-          pixels += pixel_stride;
-        }
-      row += row_stride;
-    }
-  return dimmed_pixbuf;
+  /* Create a new temporary surface to use for creating the dimming effect */
+  temp = cairo_surface_create_similar (dimmed,
+                                       cairo_surface_get_content (dimmed),
+                                       cairo_image_surface_get_width (dimmed),
+                                       cairo_image_surface_get_height (dimmed));
+
+  cr = cairo_create (temp);
+
+  cairo_set_source_surface (cr, dimmed, 0, 0);
+  cairo_paint_with_alpha (cr, 0.5);
+
+  cairo_set_operator (dimmed_cr, CAIRO_OPERATOR_IN);
+  cairo_set_source_surface (dimmed_cr, temp, 0, 0);
+  cairo_paint (dimmed_cr);
+
+  cairo_destroy (dimmed_cr);
+  cairo_surface_destroy (temp);
+
+  return dimmed;
 }
 
 static TabEntry*
@@ -213,9 +215,9 @@ tab_entry_new (const MetaTabEntry *entry,
   te->dimmed_icon = NULL;
   if (te->icon)
     {
-      g_object_ref (G_OBJECT (te->icon));
+      cairo_surface_reference (te->icon);
       if (entry->hidden)
-        te->dimmed_icon = dimm_icon (entry->icon);
+        te->dimmed_icon = dimm_icon (entry->icon, scale);
     }
 
   if (outline)
@@ -466,10 +468,9 @@ free_tab_entry (gpointer data, gpointer user_data)
   te = data;
 
   g_free (te->title);
-  if (te->icon)
-    g_object_unref (G_OBJECT (te->icon));
-  if (te->dimmed_icon)
-    g_object_unref (G_OBJECT (te->dimmed_icon));
+
+  g_clear_pointer (&te->icon, cairo_surface_destroy);
+  g_clear_pointer (&te->dimmed_icon, cairo_surface_destroy);
 
   g_free (te);
 }
@@ -747,24 +748,14 @@ struct _MetaSelectImageClass
 static GType meta_select_image_get_type (void) G_GNUC_CONST;
 
 static GtkWidget*
-selectable_image_new (GdkPixbuf *pixbuf, cairo_surface_t *win_surface)
+selectable_image_new (cairo_surface_t *surface, cairo_surface_t *win_surface)
 {
   GtkWidget *widget;
 
   widget = g_object_new (meta_select_image_get_type (), NULL);
 
   if (win_surface == NULL)
-    {
-      int scale;
-      cairo_surface_t *surface;
-
-      scale = gtk_widget_get_scale_factor (widget);
-      surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
-
-      gtk_image_set_from_surface (GTK_IMAGE (widget), surface);
-
-      cairo_surface_destroy (surface);
-    }
+    gtk_image_set_from_surface (GTK_IMAGE (widget), surface);
   else
     gtk_image_set_from_surface (GTK_IMAGE (widget), win_surface);
 
diff --git a/src/ui/theme-viewer.c b/src/ui/theme-viewer.c
index 21fafbd7..9a6719d8 100644
--- a/src/ui/theme-viewer.c
+++ b/src/ui/theme-viewer.c
@@ -1038,10 +1038,13 @@ run_theme_benchmark (void)
   int client_width;
   int client_height;
   int inc;
+  int scale;
 
   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_widget_realize (widget);
 
+  scale = gtk_widget_get_scale_factor (widget);
+
   meta_theme_get_frame_borders (global_theme,
                                 META_FRAME_TYPE_NORMAL,
                                 get_text_height (widget),
@@ -1095,8 +1098,8 @@ run_theme_benchmark (void)
                              get_text_height (widget),
                              &button_layout,
                              button_states,
-                             meta_preview_get_mini_icon (),
-                             meta_preview_get_icon ());
+                             meta_preview_get_mini_icon (scale),
+                             meta_preview_get_icon (scale));
 
       cairo_destroy (cr);
       cairo_surface_destroy (pixmap);
diff --git a/src/ui/theme.c b/src/ui/theme.c
index 25d35b1f..9ffafa63 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -3732,20 +3732,6 @@ draw_op_as_pixbuf (const MetaDrawOp    *op,
       break;
 
     case META_DRAW_ICON:
-      if (info->mini_icon &&
-          width <= gdk_pixbuf_get_width (info->mini_icon) &&
-          height <= gdk_pixbuf_get_height (info->mini_icon))
-        pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
-                                         op->data.icon.alpha_spec,
-                                         op->data.icon.fill_type,
-                                         width, height,
-                                         FALSE, FALSE);
-      else if (info->icon)
-        pixbuf = scale_and_alpha_pixbuf (info->icon,
-                                         op->data.icon.alpha_spec,
-                                         op->data.icon.fill_type,
-                                         width, height,
-                                         FALSE, FALSE);
       break;
 
     case META_DRAW_TITLE:
@@ -3819,13 +3805,11 @@ draw_op_as_surface (const MetaDrawOp   *op,
 
     case META_DRAW_ICON:
       if (info->mini_icon &&
-          width <= gdk_pixbuf_get_width (info->mini_icon) &&
-          height <= gdk_pixbuf_get_height (info->mini_icon))
-        surface = get_surface_from_pixbuf (info->mini_icon, op->data.icon.fill_type,
-                                           width, height, FALSE, FALSE);
+          width <= cairo_image_surface_get_width (info->mini_icon) &&
+          height <= cairo_image_surface_get_height (info->mini_icon))
+        surface = cairo_surface_reference (info->mini_icon);
       else if (info->icon)
-        surface = get_surface_from_pixbuf (info->icon, op->data.icon.fill_type,
-                                           width, height, FALSE, FALSE);
+        surface = cairo_surface_reference (info->icon);
       break;
 
     case META_DRAW_TINT:
@@ -3878,10 +3862,10 @@ fill_env (MetaPositionExprEnv *env,
       env->frame_y_center = 0;
     }
 
-  env->mini_icon_width = info->mini_icon ? gdk_pixbuf_get_width (info->mini_icon) : 0;
-  env->mini_icon_height = info->mini_icon ? gdk_pixbuf_get_height (info->mini_icon) : 0;
-  env->icon_width = info->icon ? gdk_pixbuf_get_width (info->icon) : 0;
-  env->icon_height = info->icon ? gdk_pixbuf_get_height (info->icon) : 0;
+  env->mini_icon_width = info->mini_icon ? cairo_image_surface_get_width (info->mini_icon) : 0;
+  env->mini_icon_height = info->mini_icon ? cairo_image_surface_get_height (info->mini_icon) : 0;
+  env->icon_width = info->icon ? cairo_image_surface_get_width (info->icon) : 0;
+  env->icon_height = info->icon ? cairo_image_surface_get_height (info->icon) : 0;
 
   env->title_width = info->title_layout_width;
   env->title_height = info->title_layout_height;
@@ -4237,10 +4221,9 @@ meta_draw_op_draw_with_env (const MetaDrawOp    *op,
         cairo_surface_t *surface;
 
         scale = gdk_window_get_scale_factor (gdk_get_default_root_window ());
-        cairo_scale (cr, 1.0 / scale, 1.0 / scale);
 
-        rwidth = parse_size_unchecked (op->data.icon.width, env) * scale;
-        rheight = parse_size_unchecked (op->data.icon.height, env) * scale;
+        rwidth = parse_size_unchecked (op->data.icon.width, env);
+        rheight = parse_size_unchecked (op->data.icon.height, env);
 
         surface = draw_op_as_surface (op, style_gtk, info, rwidth, rheight);
 
@@ -4962,8 +4945,8 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
                                   PangoLayout             *title_layout,
                                   int                      text_height,
                                   MetaButtonState          button_states[META_BUTTON_TYPE_LAST],
-                                  GdkPixbuf               *mini_icon,
-                                  GdkPixbuf               *icon)
+                                  cairo_surface_t         *mini_icon,
+                                  cairo_surface_t         *icon)
 {
     /* BOOKMARK */
   int i, j;
@@ -5202,8 +5185,8 @@ meta_frame_style_draw (MetaFrameStyle          *style,
                        PangoLayout             *title_layout,
                        int                      text_height,
                        MetaButtonState          button_states[META_BUTTON_TYPE_LAST],
-                       GdkPixbuf               *mini_icon,
-                       GdkPixbuf               *icon)
+                       cairo_surface_t         *mini_icon,
+                       cairo_surface_t         *icon)
 {
   meta_frame_style_draw_with_style (style,
                                     gtk_widget_get_style_context (widget),
@@ -5833,8 +5816,8 @@ meta_theme_draw_frame (MetaTheme              *theme,
                        int                     text_height,
                        const MetaButtonLayout *button_layout,
                        MetaButtonState         button_states[META_BUTTON_TYPE_LAST],
-                       GdkPixbuf              *mini_icon,
-                       GdkPixbuf              *icon)
+                       cairo_surface_t        *mini_icon,
+                       cairo_surface_t        *icon)
 {
   MetaFrameGeometry fgeom;
   MetaFrameStyle *style;
@@ -5878,8 +5861,8 @@ meta_theme_draw_frame_by_name (MetaTheme              *theme,
                                int                     text_height,
                                const MetaButtonLayout *button_layout,
                                MetaButtonState         button_states[META_BUTTON_TYPE_LAST],
-                               GdkPixbuf              *mini_icon,
-                               GdkPixbuf              *icon)
+                               cairo_surface_t        *mini_icon,
+                               cairo_surface_t        *icon)
 {
   MetaFrameGeometry fgeom;
   MetaFrameStyle *style;
diff --git a/src/ui/theme.h b/src/ui/theme.h
index b32690f1..4bf098a9 100644
--- a/src/ui/theme.h
+++ b/src/ui/theme.h
@@ -296,8 +296,8 @@ struct _MetaAlphaGradientSpec
 
 struct _MetaDrawInfo
 {
-  GdkPixbuf   *mini_icon;
-  GdkPixbuf   *icon;
+  cairo_surface_t *mini_icon;
+  cairo_surface_t *icon;
   PangoLayout *title_layout;
   int title_layout_width;
   int title_layout_height;
@@ -979,8 +979,8 @@ void meta_frame_style_draw (MetaFrameStyle          *style,
                             PangoLayout             *title_layout,
                             int                      text_height,
                             MetaButtonState          button_states[META_BUTTON_TYPE_LAST],
-                            GdkPixbuf               *mini_icon,
-                            GdkPixbuf               *icon);
+                            cairo_surface_t         *mini_icon,
+                            cairo_surface_t         *icon);
 
 void meta_frame_style_draw_with_style (MetaFrameStyle          *style,
                                        GtkStyleContext         *style_gtk,
@@ -991,8 +991,8 @@ void meta_frame_style_draw_with_style (MetaFrameStyle          *style,
                                        PangoLayout             *title_layout,
                                        int                      text_height,
                                        MetaButtonState          button_states[META_BUTTON_TYPE_LAST],
-                                       GdkPixbuf               *mini_icon,
-                                       GdkPixbuf               *icon);
+                                       cairo_surface_t         *mini_icon,
+                                       cairo_surface_t         *icon);
 
 gboolean       meta_frame_style_validate (MetaFrameStyle    *style,
                                           guint              current_theme_version,
@@ -1037,8 +1037,8 @@ void meta_theme_draw_frame (MetaTheme              *theme,
                             int                     text_height,
                             const MetaButtonLayout *button_layout,
                             MetaButtonState         button_states[META_BUTTON_TYPE_LAST],
-                            GdkPixbuf              *mini_icon,
-                            GdkPixbuf              *icon);
+                            cairo_surface_t        *mini_icon,
+                            cairo_surface_t        *icon);
 
 void meta_theme_draw_frame_by_name (MetaTheme              *theme,
                                     GtkWidget              *widget,
@@ -1051,8 +1051,8 @@ void meta_theme_draw_frame_by_name (MetaTheme              *theme,
                                     int                     text_height,
                                     const MetaButtonLayout *button_layout,
                                     MetaButtonState         button_states[META_BUTTON_TYPE_LAST],
-                                    GdkPixbuf              *mini_icon,
-                                    GdkPixbuf              *icon);
+                                    cairo_surface_t        *mini_icon,
+                                    cairo_surface_t        *icon);
 
 void meta_theme_get_frame_borders (MetaTheme         *theme,
                                    MetaFrameType      type,
diff --git a/src/ui/ui.c b/src/ui/ui.c
index 40a475a4..560dc483 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -626,12 +626,12 @@ meta_ui_get_default_window_icon (MetaUI *ui)
 {
   static cairo_surface_t *default_icon = NULL;
   static int icon_size = 0;
-  int current_icon_size = meta_prefs_get_icon_size();
 
-  int scale;
+  int scale = gtk_widget_get_scale_factor (GTK_WIDGET (ui->frames));
+  int current_icon_size = meta_prefs_get_icon_size() / scale;
+
   if (default_icon == NULL || current_icon_size != icon_size)
     {
-      scale = gtk_widget_get_scale_factor (GTK_WIDGET (ui->frames));
       default_icon = load_default_window_icon (current_icon_size, scale);
       g_assert (default_icon);
       icon_size = current_icon_size;
@@ -734,7 +734,7 @@ meta_ui_get_mini_icon_from_name (MetaUI *ui, char *name)
   int size;
 
   scale = gtk_widget_get_scale_factor (GTK_WIDGET (ui->frames));
-  size = META_MINI_ICON_SIZE / scale;
+  size = META_MINI_ICON_SIZE;
 
   return load_window_icon_from_name (name, size, scale);
 }
-- 
cgit v1.2.1