summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2019-10-22 23:45:02 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2019-10-22 23:45:02 +0300
commit16a3262615e7d1cf5de89a6e9cc8d58ad5c6ad2c (patch)
treec419aa98a17ea28d7931440e2f9163f5065cef5a
parente944c77e505306615e7eb35c3f4c47375a82ec3b (diff)
downloadmetacity-16a3262615e7d1cf5de89a6e9cc8d58ad5c6ad2c.tar.gz
compositor-xrender: move shadow to MetaShadowXRender
-rw-r--r--src/Makefile.am2
-rw-r--r--src/compositor/meta-compositor-xrender.c200
-rw-r--r--src/compositor/meta-shadow-xrender.c78
-rw-r--r--src/compositor/meta-shadow-xrender.h54
4 files changed, 228 insertions, 106 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 98f9a698..bc7915eb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,6 +32,8 @@ metacity_SOURCES= \
compositor/meta-compositor-private.h \
compositor/meta-compositor-xrender.c \
compositor/meta-compositor-xrender.h \
+ compositor/meta-shadow-xrender.c \
+ compositor/meta-shadow-xrender.h \
compositor/meta-surface.c \
compositor/meta-surface.h \
compositor/meta-surface-private.h \
diff --git a/src/compositor/meta-compositor-xrender.c b/src/compositor/meta-compositor-xrender.c
index 51063ca9..1585fae6 100644
--- a/src/compositor/meta-compositor-xrender.c
+++ b/src/compositor/meta-compositor-xrender.c
@@ -39,6 +39,7 @@
#include "prefs.h"
#include "window-private.h"
#include "meta-compositor-xrender.h"
+#include "meta-shadow-xrender.h"
#include "meta-surface-xrender.h"
#include "xprops.h"
#include "util.h"
@@ -87,13 +88,7 @@ typedef struct _MetaCompWindow
MetaRectangle rect;
- XserverRegion shadow_region;
-
- Picture shadow;
- int shadow_dx;
- int shadow_dy;
- int shadow_width;
- int shadow_height;
+ MetaShadowXRender *shadow;
gboolean shadow_changed;
} MetaCompWindow;
@@ -113,7 +108,6 @@ struct _MetaCompositorXRender
Picture root_picture;
Picture root_buffer;
- Picture black_picture;
Picture root_tile;
gboolean prefs_listener_added;
@@ -737,6 +731,7 @@ shadow_changed (MetaSurface *surface)
MetaCompositor *compositor;
MetaCompositorXRender *xrender;
MetaCompWindow *cw;
+ XserverRegion shadow_region;
compositor = meta_surface_get_compositor (surface);
xrender = META_COMPOSITOR_XRENDER (compositor);
@@ -746,78 +741,89 @@ shadow_changed (MetaSurface *surface)
cw = g_object_get_data (G_OBJECT (surface), "cw");
- if (cw->shadow_region != None)
+ if (cw->shadow == NULL)
{
- meta_compositor_add_damage (compositor, "shadow_changed", cw->shadow_region);
- XFixesDestroyRegion (xrender->xdisplay, cw->shadow_region);
- cw->shadow_region = None;
+ meta_compositor_queue_redraw (compositor);
+ return;
}
- if (cw->shadow != None)
- {
- XRenderFreePicture (xrender->xdisplay, cw->shadow);
- cw->shadow = None;
- }
+ 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_compositor_queue_redraw (compositor);
+ meta_shadow_xrender_free (cw->shadow);
+ cw->shadow = NULL;
cw->shadow_changed = TRUE;
}
-static XserverRegion
-get_shadow_region (MetaCompositorXRender *xrender,
- MetaCompWindow *cw,
- MetaShadowType shadow_type)
+static MetaShadowXRender *
+create_shadow (MetaCompositorXRender *xrender,
+ MetaSurface *surface,
+ MetaShadowType shadow_type)
{
- MetaFrame *frame;
+ MetaWindow *window;
MetaFrameBorders borders;
- XRectangle sr;
- Display *xdisplay;
- XserverRegion shadow_region;
+ GtkBorder *invisible;
+ double opacity;
+ int width;
+ int height;
+ MetaShadowXRender *ret;
cairo_region_t *frame_bounds;
- frame = meta_window_get_frame (cw->window);
- meta_frame_calc_borders (frame, &borders);
+ window = meta_surface_get_window (surface);
- cw->shadow_dx = (int) shadow_offsets_x [shadow_type] + borders.invisible.left;
- cw->shadow_dy = (int) shadow_offsets_y [shadow_type] + borders.invisible.top;
+ meta_frame_calc_borders (window->frame, &borders);
+ invisible = &borders.invisible;
- if (!cw->shadow)
- {
- double opacity = SHADOW_OPACITY;
- int invisible_width = borders.invisible.left + borders.invisible.right;
- int invisible_height = borders.invisible.top + borders.invisible.bottom;
+ opacity = SHADOW_OPACITY;
+ if (window->opacity != OPAQUE)
+ opacity = opacity * ((double) window->opacity) / OPAQUE;
- if (cw->window->opacity != (guint) OPAQUE)
- opacity = opacity * ((double) cw->window->opacity) / ((double) OPAQUE);
+ width = meta_surface_get_width (surface);
+ height = meta_surface_get_height (surface);
- cw->shadow = shadow_picture (xrender, shadow_type, opacity,
- cw->rect.width - invisible_width,
- cw->rect.height - invisible_height,
- &cw->shadow_width, &cw->shadow_height);
- }
+ ret = g_new0 (MetaShadowXRender, 1);
+ ret->xdisplay = xrender->xdisplay;
- sr.x = cw->shadow_dx;
- sr.y = cw->shadow_dy;
- sr.width = cw->shadow_width;
- sr.height = cw->shadow_height;
+ ret->dx = shadow_offsets_x[shadow_type] + invisible->left;
+ ret->dy = shadow_offsets_y[shadow_type] + invisible->top;
- xdisplay = xrender->xdisplay;
- shadow_region = XFixesCreateRegion (xdisplay, &sr, 1);
- frame_bounds = meta_window_get_frame_bounds (cw->window);
+ ret->black = solid_picture (xrender->xdisplay, TRUE, 1, 0, 0, 0);
+ ret->shadow = shadow_picture (xrender,
+ shadow_type,
+ opacity,
+ width - invisible->left - invisible->right,
+ height - invisible->top - invisible->bottom,
+ &ret->width,
+ &ret->height);
+
+ ret->region = XFixesCreateRegion (xrender->xdisplay, &(XRectangle) {
+ .x = ret->dx,
+ .y = ret->dy,
+ .width = ret->width,
+ .height = ret->height
+ }, 1);
+
+ frame_bounds = meta_window_get_frame_bounds (window);
if (frame_bounds != NULL)
{
XserverRegion bounds_region;
- bounds_region = cairo_region_to_xserver_region (xdisplay, frame_bounds);
- XFixesSubtractRegion (xdisplay, shadow_region, shadow_region, bounds_region);
- XFixesDestroyRegion (xdisplay, bounds_region);
- }
+ bounds_region = cairo_region_to_xserver_region (xrender->xdisplay,
+ frame_bounds);
- XFixesTranslateRegion (xdisplay, shadow_region, cw->rect.x, cw->rect.y);
+ XFixesSubtractRegion (xrender->xdisplay,
+ ret->region,
+ ret->region,
+ bounds_region);
- return shadow_region;
+ XFixesDestroyRegion (xrender->xdisplay, bounds_region);
+ }
+
+ return ret;
}
static void
@@ -827,21 +833,18 @@ paint_shadow (MetaCompositorXRender *xrender,
Picture paint_buffer)
{
MetaCompWindow *cw;
- XserverRegion shadow_clip;
XserverRegion border_clip;
- int x;
- int y;
+ XserverRegion shadow_clip;
cw = g_object_get_data (G_OBJECT (surface_xrender), "cw");
- if (cw->shadow == None)
+ if (cw->shadow == NULL)
return;
- shadow_clip = XFixesCreateRegion (xrender->xdisplay, NULL, 0);
- XFixesCopyRegion (xrender->xdisplay, shadow_clip, cw->shadow_region);
-
border_clip = meta_surface_xrender_get_border_clip (surface_xrender);
- XFixesIntersectRegion (xrender->xdisplay, shadow_clip, shadow_clip, border_clip);
+
+ shadow_clip = XFixesCreateRegion (xrender->xdisplay, NULL, 0);
+ XFixesCopyRegion (xrender->xdisplay, shadow_clip, border_clip);
if (paint_region != None)
{
@@ -851,17 +854,13 @@ paint_shadow (MetaCompositorXRender *xrender,
paint_region);
}
- XFixesSetPictureClipRegion (xrender->xdisplay, paint_buffer, 0, 0, shadow_clip);
- XFixesDestroyRegion (xrender->xdisplay, shadow_clip);
-
- x = cw->rect.x;
- y = cw->rect.y;
+ meta_shadow_xrender_paint (cw->shadow,
+ shadow_clip,
+ paint_buffer,
+ cw->rect.x,
+ cw->rect.y);
- XRenderComposite (xrender->xdisplay, PictOpOver,
- xrender->black_picture, cw->shadow, paint_buffer,
- 0, 0, 0, 0,
- x + cw->shadow_dx, y + cw->shadow_dy,
- cw->shadow_width, cw->shadow_height);
+ XFixesDestroyRegion (xrender->xdisplay, shadow_clip);
}
static void
@@ -1027,24 +1026,13 @@ static void
cw_destroy_cb (gpointer data)
{
MetaCompWindow *cw;
- MetaDisplay *display;
- Display *xdisplay;
cw = (MetaCompWindow *) data;
- display = meta_window_get_display (cw->window);
- xdisplay = meta_display_get_xdisplay (display);
-
- if (cw->shadow)
- {
- XRenderFreePicture (xdisplay, cw->shadow);
- cw->shadow = None;
- }
-
- if (cw->shadow_region != None)
+ if (cw->shadow != NULL)
{
- XFixesDestroyRegion (xdisplay, cw->shadow_region);
- cw->shadow_region = None;
+ meta_shadow_xrender_free (cw->shadow);
+ cw->shadow = NULL;
}
g_free (cw);
@@ -1166,9 +1154,6 @@ meta_compositor_xrender_finalize (GObject *object)
if (xrender->root_picture)
XRenderFreePicture (xdisplay, xrender->root_picture);
- if (xrender->black_picture)
- XRenderFreePicture (xdisplay, xrender->black_picture);
-
if (xrender->have_shadows)
{
int i;
@@ -1246,7 +1231,6 @@ meta_compositor_xrender_manage (MetaCompositor *compositor,
}
xrender->root_buffer = None;
- xrender->black_picture = solid_picture (xdisplay, TRUE, 1, 0, 0, 0);
xrender->root_tile = None;
@@ -1404,16 +1388,15 @@ meta_compositor_xrender_sync_window_geometry (MetaCompositor *compositor,
{
shadow_changed (surface);
}
- else if (cw->shadow_region != None)
+ else if (cw->shadow != NULL)
{
- meta_compositor_add_damage (compositor, "sync_window_geometry", cw->shadow_region);
+ XserverRegion region;
- XFixesTranslateRegion (xrender->xdisplay,
- cw->shadow_region,
- cw->rect.x - old_rect.x,
- cw->rect.y - old_rect.y);
+ 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", cw->shadow_region);
+ meta_compositor_add_damage (compositor, "sync_window_geometry", region);
+ XFixesDestroyRegion (xrender->xdisplay, region);
}
}
@@ -1448,22 +1431,27 @@ meta_compositor_xrender_pre_paint (MetaCompositor *compositor)
meta_surface_has_shadow (surface))
{
MetaShadowType shadow_type;
+ XserverRegion shadow_region;
if (meta_window_appears_focused (cw->window))
shadow_type = META_SHADOW_LARGE;
else
shadow_type = META_SHADOW_MEDIUM;
- g_assert (cw->shadow_region == None);
- cw->shadow_region = get_shadow_region (xrender, cw, shadow_type);
+ g_assert (cw->shadow == NULL);
+ cw->shadow = create_shadow (xrender, surface, shadow_type);
- if (cw->shadow_region != None)
- {
- meta_compositor_add_damage (compositor,
- "meta_compositor_xrender_pre_paint",
- cw->shadow_region);
- }
+ 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;
}
}
diff --git a/src/compositor/meta-shadow-xrender.c b/src/compositor/meta-shadow-xrender.c
new file mode 100644
index 00000000..058ef057
--- /dev/null
+++ b/src/compositor/meta-shadow-xrender.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "meta-shadow-xrender.h"
+
+void
+meta_shadow_xrender_free (MetaShadowXRender *self)
+{
+ if (self->black != None)
+ {
+ XRenderFreePicture (self->xdisplay, self->black);
+ self->black = None;
+ }
+
+ if (self->shadow != None)
+ {
+ XRenderFreePicture (self->xdisplay, self->shadow);
+ self->shadow = None;
+ }
+
+ if (self->region != None)
+ {
+ XFixesDestroyRegion (self->xdisplay, self->region);
+ self->region = None;
+ }
+
+ g_free (self);
+}
+
+XserverRegion
+meta_shadow_xrender_get_region (MetaShadowXRender *self)
+{
+ XserverRegion region;
+
+ region = XFixesCreateRegion (self->xdisplay, NULL, 0);
+ XFixesCopyRegion (self->xdisplay, region, self->region);
+
+ return region;
+}
+
+void
+meta_shadow_xrender_paint (MetaShadowXRender *self,
+ XserverRegion paint_region,
+ Picture paint_buffer,
+ int x,
+ int y)
+{
+ XserverRegion shadow_clip;
+
+ shadow_clip = XFixesCreateRegion (self->xdisplay, NULL, 0);
+ XFixesCopyRegion (self->xdisplay, shadow_clip, self->region);
+ XFixesTranslateRegion (self->xdisplay, shadow_clip, x, y);
+
+ XFixesIntersectRegion (self->xdisplay, shadow_clip, shadow_clip, paint_region);
+ XFixesSetPictureClipRegion (self->xdisplay, paint_buffer, 0, 0, shadow_clip);
+ XFixesDestroyRegion (self->xdisplay, shadow_clip);
+
+ XRenderComposite (self->xdisplay, PictOpOver,
+ self->black, self->shadow, paint_buffer,
+ 0, 0, 0, 0,
+ x + self->dx, y + self->dy,
+ self->width, self->height);
+}
diff --git a/src/compositor/meta-shadow-xrender.h b/src/compositor/meta-shadow-xrender.h
new file mode 100644
index 00000000..d6f2ebf8
--- /dev/null
+++ b/src/compositor/meta-shadow-xrender.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_SHADOW_XRENDER_H
+#define META_SHADOW_XRENDER_H
+
+#include <glib-object.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xrender.h>
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+ Display *xdisplay;
+
+ int dx;
+ int dy;
+ int width;
+ int height;
+
+ Picture black;
+ Picture shadow;
+
+ XserverRegion region;
+} MetaShadowXRender;
+
+void meta_shadow_xrender_free (MetaShadowXRender *self);
+
+XserverRegion meta_shadow_xrender_get_region (MetaShadowXRender *self);
+
+void meta_shadow_xrender_paint (MetaShadowXRender *self,
+ XserverRegion paint_region,
+ Picture paint_buffer,
+ int x,
+ int y);
+
+G_END_DECLS
+
+#endif