diff options
-rw-r--r-- | src/core/screen.c | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/src/core/screen.c b/src/core/screen.c index 2256bdd3..8384dd0d 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1211,6 +1211,49 @@ meta_screen_update_cursor (MetaScreen *screen) XFreeCursor (screen->display->xdisplay, xcursor); } +#define MAX_PREVIEW_SIZE 150.0 + +static GdkPixbuf * +get_window_pixbuf (MetaWindow *window, + int *width, + int *height) +{ + Pixmap pmap; + GdkPixbuf *pixbuf, *scaled; + double ratio; + + pmap = meta_compositor_get_window_pixmap (window->display->compositor, + window); + if (pmap == None) + return NULL; + + pixbuf = meta_ui_get_pixbuf_from_pixmap (pmap); + if (pixbuf == NULL) + return NULL; + + *width = gdk_pixbuf_get_width (pixbuf); + *height = gdk_pixbuf_get_height (pixbuf); + + /* Scale pixbuf to max dimension MAX_PREVIEW_SIZE */ + if (*width > *height) + { + ratio = ((double) *width) / MAX_PREVIEW_SIZE; + *width = (int) MAX_PREVIEW_SIZE; + *height = (int) (((double) *height) / ratio); + } + else + { + ratio = ((double) *height) / MAX_PREVIEW_SIZE; + *height = (int) MAX_PREVIEW_SIZE; + *width = (int) (((double) *width) / ratio); + } + + scaled = gdk_pixbuf_scale_simple (pixbuf, *width, *height, + GDK_INTERP_BILINEAR); + g_object_unref (pixbuf); + return scaled; +} + void meta_screen_ensure_tab_popup (MetaScreen *screen, MetaTabList list_type, @@ -1243,23 +1286,41 @@ meta_screen_ensure_tab_popup (MetaScreen *screen, { MetaWindow *window; MetaRectangle r; + GdkPixbuf *win_pixbuf; + int width, height; window = tmp->data; - - /* Metacity used to generated a thumbnail of the window contents - * using gdk_pixbuf_simple_scale which is so slow with bilinear - * interpolation that it has been removed. - * - * The cairo downscale could have been an alternative, but the - * result is terrible ATM, so it is simply better to have the - * same user story as the non-composited case (no thumbnail). - * - * https://bugzilla.gnome.org/show_bug.cgi?id=504729 - */ - + entries[i].key = (MetaTabEntryKey) window->xwindow; entries[i].title = window->title; - entries[i].icon = g_object_ref (window->icon); + + win_pixbuf = get_window_pixbuf (window, &width, &height); + if (win_pixbuf == NULL) + entries[i].icon = g_object_ref (window->icon); + else + { + int icon_width, icon_height, t_width, t_height; +#define ICON_OFFSET 6 + + icon_width = gdk_pixbuf_get_width (window->icon); + icon_height = gdk_pixbuf_get_height (window->icon); + + t_width = width + ICON_OFFSET; + t_height = height + ICON_OFFSET; + + entries[i].icon = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, + t_width, t_height); + gdk_pixbuf_fill (entries[i].icon, 0x00000000); + gdk_pixbuf_copy_area (win_pixbuf, 0, 0, width, height, + entries[i].icon, 0, 0); + g_object_unref (win_pixbuf); + gdk_pixbuf_composite (window->icon, entries[i].icon, + t_width - icon_width, t_height - icon_height, + icon_width, icon_height, + t_width - icon_width, t_height - icon_height, + 1.0, 1.0, GDK_INTERP_BILINEAR, 255); + } + entries[i].blank = FALSE; entries[i].hidden = !meta_window_showing_on_its_workspace (window); entries[i].demands_attention = window->wm_state_demands_attention; |