diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2016-04-16 10:53:55 +0300 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2016-04-16 16:56:39 +0300 |
commit | b961350e7c2d53647b9bcbf512309acdb7bf2fd9 (patch) | |
tree | 1c4d2efa9ceb255931e6313337347efccdc82a1b | |
parent | c8421c40105b446c5e466175619c5632fe018554 (diff) | |
download | metacity-b961350e7c2d53647b9bcbf512309acdb7bf2fd9.tar.gz |
compositor: keep more info when window is shaded
-rw-r--r-- | src/compositor/compositor-xrender.c | 164 |
1 files changed, 133 insertions, 31 deletions
diff --git a/src/compositor/compositor-xrender.c b/src/compositor/compositor-xrender.c index 1bc0849c..756c4c56 100644 --- a/src/compositor/compositor-xrender.c +++ b/src/compositor/compositor-xrender.c @@ -150,12 +150,7 @@ typedef struct _MetaCompWindow XWindowAttributes attrs; Pixmap back_pixmap; - - /* When the window is shaded back_pixmap will be replaced with the pixmap - for the shaded window. This is a copy of the original unshaded window - so that we can still see what the window looked like when it is needed - for the _get_window_pixmap function */ - Pixmap shaded_back_pixmap; + Pixmap mask_pixmap; int mode; @@ -193,6 +188,22 @@ typedef struct _MetaCompWindow gboolean updates_frozen; gboolean update_pending; + + /* When the window is shaded we will store few data of the original unshaded + * window so we can still see what the window looked like when it is needed + * for _get_window_surface function. + */ + struct { + Pixmap back_pixmap; + Pixmap mask_pixmap; + + int x; + int y; + int width; + int height; + + XserverRegion client_region; + } shaded; } MetaCompWindow; #define OPAQUE 0xffffffff @@ -1307,7 +1318,6 @@ get_window_mask (MetaCompWindow *cw) int width; int height; XRenderPictFormat *format; - Pixmap pixmap; cairo_surface_t *surface; cairo_t *cr; Picture picture; @@ -1325,12 +1335,17 @@ get_window_mask (MetaCompWindow *cw) height = cw->attrs.height + cw->attrs.border_width * 2; format = XRenderFindStandardFormat (xdisplay, PictStandardA8); - meta_error_trap_push (display); - pixmap = XCreatePixmap (xdisplay, cw->id, width, height, format->depth); - if (meta_error_trap_pop_with_return (display, FALSE) != 0) - return None; + if (cw->mask_pixmap == None) + { + meta_error_trap_push (display); + cw->mask_pixmap = XCreatePixmap (xdisplay, cw->id, width, height, + format->depth); + + if (meta_error_trap_pop_with_return (display, FALSE) != 0) + return None; + } - surface = cairo_xlib_surface_create_with_xrender_format (xdisplay, pixmap, + surface = cairo_xlib_surface_create_with_xrender_format (xdisplay, cw->mask_pixmap, DefaultScreenOfDisplay (xdisplay), format, width, height); @@ -1374,11 +1389,9 @@ get_window_mask (MetaCompWindow *cw) cairo_surface_destroy (surface); meta_error_trap_push (display); - picture = XRenderCreatePicture (xdisplay, pixmap, format, 0, NULL); + picture = XRenderCreatePicture (xdisplay, cw->mask_pixmap, format, 0, NULL); meta_error_trap_pop (display, FALSE); - XFreePixmap (xdisplay, pixmap); - return picture; } @@ -1841,10 +1854,10 @@ free_win (MetaCompWindow *cw, cw->back_pixmap = None; } - if (cw->shaded_back_pixmap && destroy) + if (cw->mask_pixmap && destroy) { - XFreePixmap (xdisplay, cw->shaded_back_pixmap); - cw->shaded_back_pixmap = None; + XFreePixmap (xdisplay, cw->mask_pixmap); + cw->mask_pixmap = None; } if (cw->picture) @@ -1907,6 +1920,24 @@ free_win (MetaCompWindow *cw, cw->extents = None; } + if (cw->shaded.back_pixmap && destroy) + { + XFreePixmap (xdisplay, cw->shaded.back_pixmap); + cw->shaded.back_pixmap = None; + } + + if (cw->shaded.mask_pixmap && destroy) + { + XFreePixmap (xdisplay, cw->shaded.mask_pixmap); + cw->shaded.mask_pixmap = None; + } + + if (cw->shaded.client_region && destroy) + { + XFixesDestroyRegion (xdisplay, cw->shaded.client_region); + cw->shaded.client_region = None; + } + if (destroy) { if (cw->damage != None) { @@ -1946,10 +1977,28 @@ map_win (MetaDisplay *display, cw->back_pixmap = None; } - if (cw->shaded_back_pixmap) + if (cw->mask_pixmap) + { + XFreePixmap (xdisplay, cw->mask_pixmap); + cw->mask_pixmap = None; + } + + if (cw->shaded.back_pixmap) + { + XFreePixmap (xdisplay, cw->shaded.back_pixmap); + cw->shaded.back_pixmap = None; + } + + if (cw->shaded.mask_pixmap) + { + XFreePixmap (xdisplay, cw->shaded.mask_pixmap); + cw->shaded.mask_pixmap = None; + } + + if (cw->shaded.client_region) { - XFreePixmap (xdisplay, cw->shaded_back_pixmap); - cw->shaded_back_pixmap = None; + XFixesDestroyRegion (xdisplay, cw->shaded.client_region); + cw->shaded.client_region = None; } cw->attrs.map_state = IsViewable; @@ -2145,7 +2194,7 @@ add_win (MetaScreen *screen, XSelectInput (xdisplay, xwindow, event_mask); cw->back_pixmap = None; - cw->shaded_back_pixmap = None; + cw->mask_pixmap = None; cw->damaged = FALSE; cw->shaped = is_shaped (display, xwindow); @@ -2183,6 +2232,14 @@ add_win (MetaScreen *screen, cw->border_clip = None; + cw->shaded.back_pixmap = None; + cw->shaded.mask_pixmap = None; + cw->shaded.x = 0; + cw->shaded.y = 0; + cw->shaded.width = 0; + cw->shaded.height = 0; + cw->shaded.client_region = None; + determine_mode (display, screen, cw); cw->needs_shadow = window_has_shadow (cw); @@ -2332,24 +2389,34 @@ resize_win (MetaCompWindow *cw, damage = XFixesCreateRegion (xdisplay, &r, 1); } */ - cw->attrs.x = x; - cw->attrs.y = y; - if (cw->attrs.width != width || cw->attrs.height != height) { - if (cw->shaded_back_pixmap) + if (cw->shaded.back_pixmap) + { + XFreePixmap (xdisplay, cw->shaded.back_pixmap); + cw->shaded.back_pixmap = None; + } + + if (cw->shaded.mask_pixmap) { - XFreePixmap (xdisplay, cw->shaded_back_pixmap); - cw->shaded_back_pixmap = None; + XFreePixmap (xdisplay, cw->shaded.mask_pixmap); + cw->shaded.mask_pixmap = None; + } + + if (cw->shaded.client_region) + { + XFixesDestroyRegion (xdisplay, cw->shaded.client_region); + cw->shaded.client_region = None; } if (cw->back_pixmap) { /* If the window is shaded, we store the old backing pixmap - so we can return a proper image of the window */ + * so we can return a proper image of the window + */ if (cw->window && meta_window_is_shaded (cw->window)) { - cw->shaded_back_pixmap = cw->back_pixmap; + cw->shaded.back_pixmap = cw->back_pixmap; cw->back_pixmap = None; } else @@ -2359,6 +2426,39 @@ resize_win (MetaCompWindow *cw, } } + if (cw->mask_pixmap) + { + /* If the window is shaded, we store the old backing pixmap + * so we can return a proper image of the window + */ + if (cw->window && meta_window_is_shaded (cw->window)) + { + cw->shaded.mask_pixmap = cw->mask_pixmap; + cw->mask_pixmap = None; + } + else + { + XFreePixmap (xdisplay, cw->mask_pixmap); + cw->mask_pixmap = None; + } + } + + if (cw->window && meta_window_is_shaded (cw->window)) + { + cw->shaded.x = cw->attrs.x; + cw->shaded.y = cw->attrs.y; + cw->shaded.width = cw->attrs.width; + cw->shaded.height = cw->attrs.height; + + if (cw->client_region != None) + { + cw->shaded.client_region = XFixesCreateRegion (xdisplay, NULL, 0); + + XFixesCopyRegion (xdisplay, cw->shaded.client_region, + cw->client_region); + } + } + if (cw->picture) { XRenderFreePicture (xdisplay, cw->picture); @@ -2378,6 +2478,8 @@ resize_win (MetaCompWindow *cw, } } + cw->attrs.x = x; + cw->attrs.y = y; cw->attrs.width = width; cw->attrs.height = height; cw->attrs.border_width = border_width; @@ -3177,7 +3279,7 @@ xrender_get_window_surface (MetaCompositor *compositor, display = meta_display_get_xdisplay (xrc->display); if (meta_window_is_shaded (window)) - pixmap = cw->shaded_back_pixmap; + pixmap = cw->shaded.back_pixmap; else pixmap = cw->back_pixmap; |