diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2019-10-23 00:49:05 +0300 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2019-10-23 00:49:05 +0300 |
commit | ebd188833d0b7c95099c9d393e5b4bd2a5b552a8 (patch) | |
tree | aec0a4ee25ce62b676814f1758c27d7a1af34c98 | |
parent | c17c74fd1357619bde29f7514291d001bb2a559a (diff) | |
download | metacity-ebd188833d0b7c95099c9d393e5b4bd2a5b552a8.tar.gz |
compositor-xrender: move shadow to MetaSurfaceXRender
-rw-r--r-- | src/compositor/meta-compositor-xrender.c | 225 | ||||
-rw-r--r-- | src/compositor/meta-surface-xrender.c | 175 | ||||
-rw-r--r-- | src/compositor/meta-surface-xrender.h | 14 |
3 files changed, 181 insertions, 233 deletions
diff --git a/src/compositor/meta-compositor-xrender.c b/src/compositor/meta-compositor-xrender.c index 9a0cc474..be00d311 100644 --- a/src/compositor/meta-compositor-xrender.c +++ b/src/compositor/meta-compositor-xrender.c @@ -82,17 +82,6 @@ typedef struct _shadow guchar *shadow_top; } shadow; -typedef struct _MetaCompWindow -{ - MetaWindow *window; - - MetaRectangle rect; - - MetaShadowXRender *shadow; - - gboolean shadow_changed; -} MetaCompWindow; - struct _MetaCompositorXRender { MetaCompositor parent; @@ -726,76 +715,6 @@ paint_root (MetaCompositorXRender *xrender, } static void -shadow_changed (MetaSurface *surface) -{ - MetaCompositor *compositor; - MetaCompositorXRender *xrender; - MetaCompWindow *cw; - XserverRegion shadow_region; - - compositor = meta_surface_get_compositor (surface); - xrender = META_COMPOSITOR_XRENDER (compositor); - - if (xrender->have_shadows == FALSE) - return; - - cw = g_object_get_data (G_OBJECT (surface), "cw"); - - if (cw->shadow == NULL) - { - meta_compositor_queue_redraw (compositor); - return; - } - - shadow_region = meta_shadow_xrender_get_region (cw->shadow); - XFixesTranslateRegion (xrender->xdisplay, shadow_region, cw->rect.x, cw->rect.y); - meta_compositor_add_damage (compositor, "shadow_changed", shadow_region); - XFixesDestroyRegion (xrender->xdisplay, shadow_region); - - meta_shadow_xrender_free (cw->shadow); - cw->shadow = NULL; - - cw->shadow_changed = TRUE; -} - -static void -paint_shadow (MetaCompositorXRender *xrender, - MetaSurfaceXRender *surface_xrender, - XserverRegion paint_region, - Picture paint_buffer) -{ - MetaCompWindow *cw; - XserverRegion border_clip; - XserverRegion shadow_clip; - - cw = g_object_get_data (G_OBJECT (surface_xrender), "cw"); - - if (cw->shadow == NULL) - return; - - border_clip = meta_surface_xrender_get_border_clip (surface_xrender); - - shadow_clip = XFixesCreateRegion (xrender->xdisplay, NULL, 0); - XFixesCopyRegion (xrender->xdisplay, shadow_clip, border_clip); - - if (paint_region != None) - { - XFixesIntersectRegion (xrender->xdisplay, - shadow_clip, - shadow_clip, - paint_region); - } - - meta_shadow_xrender_paint (cw->shadow, - shadow_clip, - paint_buffer, - cw->rect.x, - cw->rect.y); - - XFixesDestroyRegion (xrender->xdisplay, shadow_clip); -} - -static void paint_dock_shadows (MetaCompositorXRender *xrender, GList *surfaces, Picture root_buffer, @@ -816,7 +735,11 @@ paint_dock_shadows (MetaCompositorXRender *xrender, window = meta_surface_get_window (surface); if (window->type == META_WINDOW_DOCK) - paint_shadow (xrender, META_SURFACE_XRENDER (surface), region, root_buffer); + { + meta_surface_xrender_paint_shadow (META_SURFACE_XRENDER (surface), + region, + root_buffer); + } } } @@ -906,7 +829,7 @@ paint_windows (MetaCompositorXRender *xrender, window = meta_surface_get_window (surface); if (window->type != META_WINDOW_DOCK) - paint_shadow (xrender, surface_xrender, None, root_buffer); + meta_surface_xrender_paint_shadow (surface_xrender, None, root_buffer); meta_surface_xrender_paint (surface_xrender, None, root_buffer, FALSE); } @@ -954,46 +877,6 @@ paint_all (MetaCompositorXRender *xrender, screen_width, screen_height); } -static void -cw_destroy_cb (gpointer data) -{ - MetaCompWindow *cw; - - cw = (MetaCompWindow *) data; - - if (cw->shadow != NULL) - { - meta_shadow_xrender_free (cw->shadow); - cw->shadow = NULL; - } - - g_free (cw); -} - -static void -notify_appears_focused_cb (MetaWindow *window, - GParamSpec *pspec, - MetaSurface *surface) -{ - shadow_changed (surface); -} - -static void -notify_decorated_cb (MetaWindow *window, - GParamSpec *pspec, - MetaSurface *surface) -{ - shadow_changed (surface); -} - -static void -notify_window_type_cb (MetaWindow *window, - GParamSpec *pspec, - MetaSurface *surface) -{ - shadow_changed (surface); -} - /* event processors must all be called with an error trap in place */ static void process_property_notify (MetaCompositorXRender *xrender, @@ -1047,7 +930,7 @@ update_shadows (MetaPreference pref, stack = meta_compositor_get_stack (META_COMPOSITOR (data)); for (index = stack; index; index = index->next) - shadow_changed (META_SURFACE (index->data)); + meta_surface_xrender_update_shadow (META_SURFACE_XRENDER (index->data)); } static void @@ -1191,44 +1074,13 @@ static MetaSurface * meta_compositor_xrender_add_window (MetaCompositor *compositor, MetaWindow *window) { - MetaCompositorXRender *xrender; - MetaDisplay *display; MetaSurface *surface; - MetaCompWindow *cw; - - xrender = META_COMPOSITOR_XRENDER (compositor); - display = meta_compositor_get_display (compositor); - - meta_error_trap_push (display); surface = g_object_new (META_TYPE_SURFACE_XRENDER, "compositor", compositor, "window", window, NULL); - cw = g_new0 (MetaCompWindow, 1); - cw->window = window; - - g_object_set_data_full (G_OBJECT (surface), "cw", cw, cw_destroy_cb); - - meta_window_get_input_rect (window, &cw->rect); - - g_signal_connect_object (window, "notify::appears-focused", - G_CALLBACK (notify_appears_focused_cb), - surface, 0); - - g_signal_connect_object (window, "notify::decorated", - G_CALLBACK (notify_decorated_cb), - surface, 0); - - g_signal_connect_object (window, "notify::window-type", - G_CALLBACK (notify_window_type_cb), - surface, 0); - - cw->shadow_changed = xrender->have_shadows; - - meta_error_trap_pop (display); - return surface; } @@ -1236,7 +1088,6 @@ static void meta_compositor_xrender_remove_window (MetaCompositor *compositor, MetaSurface *surface) { - shadow_changed (surface); } static void @@ -1244,14 +1095,12 @@ meta_compositor_xrender_hide_window (MetaCompositor *compositor, MetaSurface *surface, MetaEffectType effect) { - shadow_changed (surface); } static void meta_compositor_xrender_window_opacity_changed (MetaCompositor *compositor, MetaSurface *surface) { - shadow_changed (surface); } static void @@ -1305,39 +1154,12 @@ static void meta_compositor_xrender_sync_window_geometry (MetaCompositor *compositor, MetaSurface *surface) { - MetaCompositorXRender *xrender; - MetaCompWindow *cw; - MetaRectangle old_rect; - - xrender = META_COMPOSITOR_XRENDER (compositor); - - cw = g_object_get_data (G_OBJECT (surface), "cw"); - - old_rect = cw->rect; - meta_window_get_input_rect (cw->window, &cw->rect); - - if (cw->rect.width != old_rect.width || cw->rect.height != old_rect.height) - { - shadow_changed (surface); - } - else if (cw->shadow != NULL) - { - XserverRegion region; - - region = meta_shadow_xrender_get_region (cw->shadow); - XFixesTranslateRegion (xrender->xdisplay, region, old_rect.x, old_rect.y); - - meta_compositor_add_damage (compositor, "sync_window_geometry", region); - XFixesDestroyRegion (xrender->xdisplay, region); - } } static void meta_compositor_xrender_pre_paint (MetaCompositor *compositor) { MetaCompositorXRender *xrender; - GList *stack; - GList *l; xrender = META_COMPOSITOR_XRENDER (compositor); @@ -1348,39 +1170,6 @@ meta_compositor_xrender_pre_paint (MetaCompositor *compositor) xrender->root_tile = root_tile (xrender->screen); META_COMPOSITOR_CLASS (meta_compositor_xrender_parent_class)->pre_paint (compositor); - - stack = meta_compositor_get_stack (compositor); - - for (l = stack; l != NULL; l = l->next) - { - MetaSurface *surface; - MetaCompWindow *cw; - - surface = META_SURFACE (l->data); - cw = g_object_get_data (G_OBJECT (surface), "cw"); - - if (cw->shadow_changed && - meta_surface_has_shadow (surface)) - { - XserverRegion shadow_region; - - g_assert (cw->shadow == NULL); - cw->shadow = meta_compositor_xrender_create_shadow (xrender, surface); - - shadow_region = meta_shadow_xrender_get_region (cw->shadow); - XFixesTranslateRegion (xrender->xdisplay, - shadow_region, - meta_surface_get_x (surface), - meta_surface_get_y (surface)); - - meta_compositor_add_damage (compositor, - "meta_compositor_xrender_pre_paint", - shadow_region); - - XFixesDestroyRegion (xrender->xdisplay, shadow_region); - cw->shadow_changed = FALSE; - } - } } static void diff --git a/src/compositor/meta-surface-xrender.c b/src/compositor/meta-surface-xrender.c index 74043052..5047cc34 100644 --- a/src/compositor/meta-surface-xrender.c +++ b/src/compositor/meta-surface-xrender.c @@ -25,27 +25,68 @@ #include "display.h" #include "errors.h" #include "frame.h" +#include "meta-compositor-xrender.h" +#include "meta-shadow-xrender.h" #include "window-private.h" #define OPAQUE 0xffffffff struct _MetaSurfaceXRender { - MetaSurface parent; + MetaSurface parent; - MetaDisplay *display; - Display *xdisplay; + MetaDisplay *display; + Display *xdisplay; - Picture picture; + Picture picture; - Pixmap mask_pixmap; - Picture mask_picture; + Pixmap mask_pixmap; + Picture mask_picture; - XserverRegion border_clip; + XserverRegion border_clip; + + MetaShadowXRender *shadow; + gboolean shadow_changed; }; G_DEFINE_TYPE (MetaSurfaceXRender, meta_surface_xrender, META_TYPE_SURFACE) +static void +shadow_changed (MetaSurfaceXRender *self) +{ + MetaSurface *surface; + MetaCompositor *compositor; + + surface = META_SURFACE (self); + + compositor = meta_surface_get_compositor (surface); + + if (self->shadow != NULL) + { + int x; + int y; + XserverRegion shadow_region; + + x = meta_surface_get_x (surface); + y = meta_surface_get_y (surface); + + shadow_region = meta_shadow_xrender_get_region (self->shadow); + XFixesTranslateRegion (self->xdisplay, shadow_region, x, y); + + meta_compositor_add_damage (compositor, "shadow_changed", shadow_region); + XFixesDestroyRegion (self->xdisplay, shadow_region); + + meta_shadow_xrender_free (self->shadow); + self->shadow = NULL; + } + else + { + meta_compositor_queue_redraw (compositor); + } + + self->shadow_changed = TRUE; +} + static gboolean is_argb (MetaSurfaceXRender *self) { @@ -444,6 +485,24 @@ notify_appears_focused_cb (MetaWindow *window, { free_mask_pixmap (self); free_mask_picture (self); + + shadow_changed (self); +} + +static void +notify_decorated_cb (MetaWindow *window, + GParamSpec *pspec, + MetaSurfaceXRender *self) +{ + shadow_changed (self); +} + +static void +notify_window_type_cb (MetaWindow *window, + GParamSpec *pspec, + MetaSurfaceXRender *self) +{ + shadow_changed (self); } static void @@ -464,6 +523,14 @@ meta_surface_xrender_constructed (GObject *object) g_signal_connect_object (window, "notify::appears-focused", G_CALLBACK (notify_appears_focused_cb), self, 0); + + g_signal_connect_object (window, "notify::decorated", + G_CALLBACK (notify_decorated_cb), + self, 0); + + g_signal_connect_object (window, "notify::window-type", + G_CALLBACK (notify_window_type_cb), + self, 0); } static void @@ -484,6 +551,8 @@ meta_surface_xrender_finalize (GObject *object) self->border_clip = None; } + shadow_changed (self); + G_OBJECT_CLASS (meta_surface_xrender_parent_class)->finalize (object); } @@ -620,6 +689,8 @@ meta_surface_xrender_hide (MetaSurface *surface) free_picture (self); free_mask_picture (self); + + shadow_changed (self); } static void @@ -631,6 +702,8 @@ meta_surface_xrender_opacity_changed (MetaSurface *surface) free_mask_pixmap (self); free_mask_picture (self); + + shadow_changed (self); } static void @@ -639,6 +712,33 @@ meta_surface_xrender_sync_geometry (MetaSurface *surface, gboolean position_changed, gboolean size_changed) { + MetaSurfaceXRender *self; + MetaCompositor *compositor; + XserverRegion region; + + self = META_SURFACE_XRENDER (surface); + + if (self->shadow == NULL) + return; + + compositor = meta_surface_get_compositor (surface); + + region = meta_shadow_xrender_get_region (self->shadow); + XFixesTranslateRegion (self->xdisplay, region, old_geometry.x, old_geometry.y); + + meta_compositor_add_damage (compositor, + "meta_surface_xrender_sync_geometry", + region); + + XFixesDestroyRegion (self->xdisplay, region); + + if (size_changed) + { + meta_shadow_xrender_free (self->shadow); + self->shadow = NULL; + + self->shadow_changed = TRUE; + } } static void @@ -676,6 +776,29 @@ meta_surface_xrender_pre_paint (MetaSurface *surface, if (self->mask_picture == None) self->mask_picture = get_window_mask_picture (self); + + if (self->shadow_changed) + { + if (self->shadow == NULL && + meta_surface_has_shadow (surface)) + { + MetaCompositor *compositor; + MetaCompositorXRender *compositor_xrender; + XserverRegion shadow_region; + + compositor = meta_surface_get_compositor (surface); + compositor_xrender = META_COMPOSITOR_XRENDER (compositor); + + self->shadow = meta_compositor_xrender_create_shadow (compositor_xrender, + surface); + + shadow_region = meta_shadow_xrender_get_region (self->shadow); + XFixesUnionRegion (self->xdisplay, damage, damage, shadow_region); + XFixesDestroyRegion (self->xdisplay, shadow_region); + } + + self->shadow_changed = FALSE; + } } static void @@ -703,12 +826,44 @@ meta_surface_xrender_class_init (MetaSurfaceXRenderClass *self_class) static void meta_surface_xrender_init (MetaSurfaceXRender *self) { + self->shadow_changed = TRUE; } -XserverRegion -meta_surface_xrender_get_border_clip (MetaSurfaceXRender *self) +void +meta_surface_xrender_update_shadow (MetaSurfaceXRender *self) { - return self->border_clip; + shadow_changed (self); +} + +void +meta_surface_xrender_paint_shadow (MetaSurfaceXRender *self, + XserverRegion paint_region, + Picture paint_buffer) +{ + MetaSurface *surface; + XserverRegion shadow_clip; + + surface = META_SURFACE (self); + + if (!meta_surface_is_visible (surface)) + return; + + if (self->shadow == NULL) + return; + + shadow_clip = XFixesCreateRegion (self->xdisplay, NULL, 0); + XFixesCopyRegion (self->xdisplay, shadow_clip, self->border_clip); + + if (paint_region != None) + XFixesIntersectRegion (self->xdisplay, shadow_clip, shadow_clip, paint_region); + + meta_shadow_xrender_paint (self->shadow, + shadow_clip, + paint_buffer, + meta_surface_get_x (surface), + meta_surface_get_y (surface)); + + XFixesDestroyRegion (self->xdisplay, shadow_clip); } void diff --git a/src/compositor/meta-surface-xrender.h b/src/compositor/meta-surface-xrender.h index 93db5367..b4fb259f 100644 --- a/src/compositor/meta-surface-xrender.h +++ b/src/compositor/meta-surface-xrender.h @@ -27,12 +27,16 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (MetaSurfaceXRender, meta_surface_xrender, META, SURFACE_XRENDER, MetaSurface) -XserverRegion meta_surface_xrender_get_border_clip (MetaSurfaceXRender *self); +void meta_surface_xrender_update_shadow (MetaSurfaceXRender *self); -void meta_surface_xrender_paint (MetaSurfaceXRender *self, - XserverRegion paint_region, - Picture paint_buffer, - gboolean opaque); +void meta_surface_xrender_paint_shadow (MetaSurfaceXRender *self, + XserverRegion paint_region, + Picture paint_buffer); + +void meta_surface_xrender_paint (MetaSurfaceXRender *self, + XserverRegion paint_region, + Picture paint_buffer, + gboolean opaque); G_END_DECLS |