[metacity] surface: add meta_surface_shape_region_changed



commit 50df3022e5d69997ac32b9618d4f9d32c441857c
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue Oct 15 19:00:30 2019 +0300

    surface: add meta_surface_shape_region_changed

 src/compositor/meta-compositor.c |   1 +
 src/compositor/meta-surface.c    | 115 +++++++++++++++++++++++++++++++++++++++
 src/compositor/meta-surface.h    |   4 ++
 3 files changed, 120 insertions(+)
---
diff --git a/src/compositor/meta-compositor.c b/src/compositor/meta-compositor.c
index fd84c745..5562bdd2 100644
--- a/src/compositor/meta-compositor.c
+++ b/src/compositor/meta-compositor.c
@@ -523,6 +523,7 @@ meta_compositor_window_shape_region_changed (MetaCompositor *compositor,
     return;
 
   compositor_class->window_shape_region_changed (compositor, surface);
+  meta_surface_shape_region_changed (surface);
 }
 
 void
diff --git a/src/compositor/meta-surface.c b/src/compositor/meta-surface.c
index 7e23bc6b..a3021998 100644
--- a/src/compositor/meta-surface.c
+++ b/src/compositor/meta-surface.c
@@ -42,6 +42,9 @@ typedef struct
   int             width;
   int             height;
 
+  XserverRegion   shape_region;
+  gboolean        shape_region_changed;
+
   XserverRegion   opaque_region;
   gboolean        opaque_region_changed;
 } MetaSurfacePrivate;
@@ -60,6 +63,64 @@ static GParamSpec *surface_properties[LAST_PROP] = { NULL };
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaSurface, meta_surface, G_TYPE_OBJECT)
 
+static void
+update_shape_region (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+  MetaFrameBorders borders;
+  XRectangle client_rect;
+  XserverRegion shape_region;
+
+  priv = meta_surface_get_instance_private (self);
+
+  if (!priv->shape_region_changed)
+    return;
+
+  g_assert (priv->shape_region == None);
+
+  meta_frame_calc_borders (priv->window->frame, &borders);
+
+  client_rect.x = borders.total.left;
+  client_rect.y = borders.total.top;
+  client_rect.width = priv->width - borders.total.left - borders.total.right;
+  client_rect.height = priv->height - borders.total.top - borders.total.bottom;
+
+  if (priv->window->frame != NULL && priv->window->shape_region != None)
+    {
+      shape_region = XFixesCreateRegion (priv->xdisplay, NULL, 0);
+      XFixesCopyRegion (priv->xdisplay, shape_region, priv->window->shape_region);
+
+      XFixesTranslateRegion (priv->xdisplay,
+                             shape_region,
+                             client_rect.x,
+                             client_rect.y);
+    }
+  else if (priv->window->shape_region != None)
+    {
+      shape_region = XFixesCreateRegion (priv->xdisplay, NULL, 0);
+      XFixesCopyRegion (priv->xdisplay, shape_region, priv->window->shape_region);
+    }
+  else
+    {
+      shape_region = XFixesCreateRegion (priv->xdisplay, &client_rect, 1);
+    }
+
+  if (shape_region != None)
+    {
+      XserverRegion copy;
+
+      copy = XFixesCreateRegion (priv->xdisplay, NULL, 0);
+      XFixesCopyRegion (priv->xdisplay, copy, shape_region);
+      XFixesTranslateRegion (priv->xdisplay, copy, priv->x, priv->y);
+
+      meta_compositor_add_damage (priv->compositor, "update_shape_region", copy);
+      XFixesDestroyRegion (priv->xdisplay, copy);
+    }
+
+  priv->shape_region = shape_region;
+  priv->shape_region_changed = FALSE;
+}
+
 static void
 update_opaque_region (MetaSurface *self)
 {
@@ -237,6 +298,21 @@ meta_surface_finalize (GObject *object)
   destroy_damage (self);
   free_pixmap (self);
 
+  if (priv->shape_region != None)
+    {
+      XFixesTranslateRegion (priv->xdisplay,
+                             priv->shape_region,
+                             priv->x,
+                             priv->y);
+
+      meta_compositor_add_damage (priv->compositor,
+                                  "meta_surface_finalize",
+                                  priv->shape_region);
+
+      XFixesDestroyRegion (priv->xdisplay, priv->shape_region);
+      priv->shape_region = None;
+    }
+
   if (priv->opaque_region != None)
     {
       XFixesDestroyRegion (priv->xdisplay, priv->opaque_region);
@@ -423,6 +499,16 @@ meta_surface_get_opaque_region (MetaSurface *self)
   return priv->opaque_region;
 }
 
+XserverRegion
+meta_surface_get_shape_region (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+
+  priv = meta_surface_get_instance_private (self);
+
+  return priv->shape_region;
+}
+
 cairo_surface_t *
 meta_surface_get_image (MetaSurface *self)
 {
@@ -506,6 +592,33 @@ meta_surface_opaque_region_changed (MetaSurface *self)
   priv->opaque_region_changed = TRUE;
 }
 
+void
+meta_surface_shape_region_changed (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+
+  priv = meta_surface_get_instance_private (self);
+
+  meta_compositor_queue_redraw (priv->compositor);
+
+  if (priv->shape_region != None)
+    {
+      XFixesTranslateRegion (priv->xdisplay,
+                             priv->shape_region,
+                             priv->x,
+                             priv->y);
+
+      meta_compositor_add_damage (priv->compositor,
+                                  "meta_surface_shape_region_changed",
+                                  priv->shape_region);
+
+      XFixesDestroyRegion (priv->xdisplay, priv->shape_region);
+      priv->shape_region = None;
+    }
+
+  priv->shape_region_changed = TRUE;
+}
+
 void
 meta_surface_sync_geometry (MetaSurface *self)
 {
@@ -529,6 +642,7 @@ meta_surface_sync_geometry (MetaSurface *self)
       free_pixmap (self);
 
       meta_surface_opaque_region_changed (self);
+      meta_surface_shape_region_changed (self);
 
       priv->width = rect.width;
       priv->height = rect.height;
@@ -554,6 +668,7 @@ meta_surface_pre_paint (MetaSurface *self)
   meta_compositor_add_damage (priv->compositor, "meta_surface_pre_paint", parts);
   XFixesDestroyRegion (priv->xdisplay, parts);
 
+  update_shape_region (self);
   update_opaque_region (self);
 
   ensure_pixmap (self);
diff --git a/src/compositor/meta-surface.h b/src/compositor/meta-surface.h
index 7a3b3d5a..b763c885 100644
--- a/src/compositor/meta-surface.h
+++ b/src/compositor/meta-surface.h
@@ -43,6 +43,8 @@ int              meta_surface_get_height            (MetaSurface        *self);
 
 XserverRegion    meta_surface_get_opaque_region     (MetaSurface        *self);
 
+XserverRegion    meta_surface_get_shape_region      (MetaSurface        *self);
+
 cairo_surface_t *meta_surface_get_image             (MetaSurface        *self);
 
 gboolean         meta_surface_is_visible            (MetaSurface        *self);
@@ -58,6 +60,8 @@ void             meta_surface_opacity_changed       (MetaSurface        *self);
 
 void             meta_surface_opaque_region_changed (MetaSurface        *self);
 
+void             meta_surface_shape_region_changed  (MetaSurface        *self);
+
 void             meta_surface_sync_geometry         (MetaSurface        *self);
 
 void             meta_surface_pre_paint             (MetaSurface        *self);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]