diff options
-rw-r--r-- | src/compositor.c | 39 | ||||
-rw-r--r-- | src/compositor.h | 2 | ||||
-rw-r--r-- | src/screen.c | 37 | ||||
-rw-r--r-- | src/ui.c | 32 | ||||
-rw-r--r-- | src/ui.h | 4 |
5 files changed, 112 insertions, 2 deletions
diff --git a/src/compositor.c b/src/compositor.c index 7c880eef..8027c060 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1108,7 +1108,8 @@ free_win (MetaCompWindow *cw, MetaDisplay *display = cw->screen->display; #ifdef HAVE_NAME_WINDOW_PIXMAP - if (cw->pixmap) + /* See comment in map_win */ + if (cw->pixmap && destroy) { XFreePixmap (display->xdisplay, cw->pixmap); cw->pixmap = None; @@ -1181,6 +1182,17 @@ map_win (MetaDisplay *display, if (cw == NULL) return; +#ifdef HAVE_NAME_WINDOW_PIXMAP + /* The reason we deallocate this here and not in unmap + is so that we will still have a valid pixmap for + whenever the window is unmapped */ + if (cw->pixmap) + { + XFreePixmap (display->xdisplay, cw->pixmap); + cw->pixmap = None; + } +#endif + cw->attrs.map_state = IsViewable; cw->damaged = FALSE; } @@ -1998,3 +2010,28 @@ meta_compositor_process_event (MetaCompositor *compositor, return; #endif } + +Pixmap +meta_compositor_get_window_pixmap (MetaCompositor *compositor, + MetaWindow *window) +{ +#ifdef HAVE_COMPOSITE_EXTENSIONS + MetaCompWindow *cw; + + if (window->frame) + { + cw = find_window_for_screen (window->screen, window->frame->xwindow); + if (cw == NULL) + cw = find_window_for_screen (window->screen, window->xwindow); + } + + if (cw == NULL) + return None; + +#ifdef HAVE_NAME_WINDOW_PIXMAP + return cw->pixmap; +#else + return None; +#endif +#endif +} diff --git a/src/compositor.h b/src/compositor.h index 99330f24..0f04e581 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -62,5 +62,7 @@ void meta_compositor_end_move (MetaCompositor *compositor, MetaWindow *window); void meta_compositor_free_window (MetaCompositor *compositor, MetaWindow *window); +Pixmap meta_compositor_get_window_pixmap (MetaCompositor *compositor, + MetaWindow *window); #endif /* META_COMPOSITOR_H */ diff --git a/src/screen.c b/src/screen.c index 6144fc1c..89f7d123 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1230,6 +1230,37 @@ meta_screen_update_cursor (MetaScreen *screen) XFreeCursor (screen->display->xdisplay, xcursor); } +static GdkPixbuf * +get_window_pixbuf (MetaWindow *window) +{ + Pixmap pmap; + GdkPixbuf *pixbuf, *scaled; + int width, height; + double ratio; + + pmap = meta_compositor_get_window_pixmap (window->display->compositor, + window); + if (pmap == None) + return NULL; + + pixbuf = meta_ui_get_pixbuf_from_pixmap (window->display->xdisplay, + window->screen->number, pmap); + if (pixbuf == NULL) + return NULL; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + + /* Scale pixbuf to max width 100 */ + ratio = ((double) width) / 100.0; + + scaled = gdk_pixbuf_scale_simple (pixbuf, 100, + (int)(((double)height) / ratio), + GDK_INTERP_BILINEAR); + g_object_unref (pixbuf); + return scaled; +} + void meta_screen_ensure_tab_popup (MetaScreen *screen, MetaTabList list_type, @@ -1267,7 +1298,11 @@ meta_screen_ensure_tab_popup (MetaScreen *screen, entries[i].key = (MetaTabEntryKey) window->xwindow; entries[i].title = window->title; - entries[i].icon = window->icon; + + entries[i].icon = get_window_pixbuf (window); + if (entries[i].icon == NULL) + entries[i].icon = window->icon; + entries[i].blank = FALSE; entries[i].hidden = !meta_window_showing_on_its_workspace (window); entries[i].demands_attention = window->wm_state_demands_attention; @@ -961,3 +961,35 @@ meta_ui_get_direction (void) return META_UI_DIRECTION_LTR; } + +GdkPixbuf * +meta_ui_get_pixbuf_from_pixmap (Display *xdisplay, + int screen_no, + Pixmap pmap) +{ + GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay); + GdkScreen *screen = gdk_display_get_screen (display, screen_no); + GdkPixbuf *pixbuf; + GdkPixmap *gpmap; + GdkColormap *cmap; + int width, height, depth; + + gpmap = gdk_pixmap_foreign_new (pmap); + gdk_drawable_get_size (GDK_DRAWABLE (gpmap), &width, &height); + + depth = gdk_drawable_get_depth (GDK_DRAWABLE (gpmap)); + if (depth <= 24) + cmap = gdk_screen_get_rgb_colormap (screen); + else + cmap = gdk_screen_get_rgba_colormap (screen); + + pixbuf = gdk_pixbuf_get_from_drawable (NULL, gpmap, cmap, 0, 0, 0, 0, + width, height); + + g_object_unref (gpmap); + + return pixbuf; +} + + + @@ -202,6 +202,10 @@ int meta_ui_get_drag_threshold (MetaUI *ui); MetaUIDirection meta_ui_get_direction (void); +GdkPixbuf *meta_ui_get_pixbuf_from_pixmap (Display *xdisplay, + int screen_no, + Pixmap pmap); + #include "tabpopup.h" #endif |