[metacity] surface: add meta_surface_opaque_region_changed



commit d87c44e5c577d5bbdfc140b2c97e195f10c809af
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue Oct 15 18:49:04 2019 +0300

    surface: add meta_surface_opaque_region_changed

 src/compositor/meta-compositor.c |   1 +
 src/compositor/meta-surface.c    | 112 +++++++++++++++++++++++++++++++++++++++
 src/compositor/meta-surface.h    |  36 +++++++------
 3 files changed, 133 insertions(+), 16 deletions(-)
---
diff --git a/src/compositor/meta-compositor.c b/src/compositor/meta-compositor.c
index f407df3f..fd84c745 100644
--- a/src/compositor/meta-compositor.c
+++ b/src/compositor/meta-compositor.c
@@ -504,6 +504,7 @@ meta_compositor_window_opaque_region_changed (MetaCompositor *compositor,
     return;
 
   compositor_class->window_opaque_region_changed (compositor, surface);
+  meta_surface_opaque_region_changed (surface);
 }
 
 void
diff --git a/src/compositor/meta-surface.c b/src/compositor/meta-surface.c
index 3a6831ba..7e23bc6b 100644
--- a/src/compositor/meta-surface.c
+++ b/src/compositor/meta-surface.c
@@ -22,6 +22,7 @@
 
 #include "display-private.h"
 #include "errors.h"
+#include "frame.h"
 #include "meta-compositor-private.h"
 #include "window-private.h"
 
@@ -40,6 +41,9 @@ typedef struct
   int             y;
   int             width;
   int             height;
+
+  XserverRegion   opaque_region;
+  gboolean        opaque_region_changed;
 } MetaSurfacePrivate;
 
 enum
@@ -56,6 +60,63 @@ static GParamSpec *surface_properties[LAST_PROP] = { NULL };
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaSurface, meta_surface, G_TYPE_OBJECT)
 
+static void
+update_opaque_region (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+  XserverRegion opaque_region;
+
+  priv = meta_surface_get_instance_private (self);
+
+  if (!priv->opaque_region_changed)
+    return;
+
+  g_assert (priv->opaque_region == None);
+
+  if (priv->window->frame != NULL && priv->window->opaque_region != None)
+    {
+      MetaFrameBorders borders;
+
+      meta_frame_calc_borders (priv->window->frame, &borders);
+
+      opaque_region = XFixesCreateRegion (priv->xdisplay, NULL, 0);
+      XFixesCopyRegion (priv->xdisplay,
+                        opaque_region,
+                        priv->window->opaque_region);
+
+      XFixesTranslateRegion (priv->xdisplay,
+                             opaque_region,
+                             borders.total.left,
+                             borders.total.top);
+    }
+  else if (priv->window->opaque_region != None)
+    {
+      opaque_region = XFixesCreateRegion (priv->xdisplay, NULL, 0);
+      XFixesCopyRegion (priv->xdisplay,
+                        opaque_region,
+                        priv->window->opaque_region);
+    }
+  else
+    {
+      opaque_region = None;
+    }
+
+  if (opaque_region != None)
+    {
+      XserverRegion copy;
+
+      copy = XFixesCreateRegion (priv->xdisplay, NULL, 0);
+      XFixesCopyRegion (priv->xdisplay, copy, opaque_region);
+      XFixesTranslateRegion (priv->xdisplay, copy, priv->x, priv->y);
+
+      meta_compositor_add_damage (priv->compositor, "update_opaque_region", copy);
+      XFixesDestroyRegion (priv->xdisplay, copy);
+    }
+
+  priv->opaque_region = opaque_region;
+  priv->opaque_region_changed = FALSE;
+}
+
 static void
 free_pixmap (MetaSurface *self)
 {
@@ -168,12 +229,20 @@ static void
 meta_surface_finalize (GObject *object)
 {
   MetaSurface *self;
+  MetaSurfacePrivate *priv;
 
   self = META_SURFACE (object);
+  priv = meta_surface_get_instance_private (self);
 
   destroy_damage (self);
   free_pixmap (self);
 
+  if (priv->opaque_region != None)
+    {
+      XFixesDestroyRegion (priv->xdisplay, priv->opaque_region);
+      priv->opaque_region = None;
+    }
+
   G_OBJECT_CLASS (meta_surface_parent_class)->finalize (object);
 }
 
@@ -344,6 +413,16 @@ meta_surface_get_height (MetaSurface *self)
   return priv->height;
 }
 
+XserverRegion
+meta_surface_get_opaque_region (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+
+  priv = meta_surface_get_instance_private (self);
+
+  return priv->opaque_region;
+}
+
 cairo_surface_t *
 meta_surface_get_image (MetaSurface *self)
 {
@@ -398,6 +477,35 @@ meta_surface_opacity_changed (MetaSurface *self)
   META_SURFACE_GET_CLASS (self)->opacity_changed (self);
 }
 
+void
+meta_surface_opaque_region_changed (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+
+  priv = meta_surface_get_instance_private (self);
+
+  if (priv->opaque_region != None)
+    {
+      XFixesTranslateRegion (priv->xdisplay,
+                             priv->opaque_region,
+                             priv->x,
+                             priv->y);
+
+      meta_compositor_add_damage (priv->compositor,
+                                  "meta_surface_opaque_region_changed",
+                                  priv->opaque_region);
+
+      XFixesDestroyRegion (priv->xdisplay, priv->opaque_region);
+      priv->opaque_region = None;
+    }
+  else
+    {
+      meta_compositor_queue_redraw (priv->compositor);
+    }
+
+  priv->opaque_region_changed = TRUE;
+}
+
 void
 meta_surface_sync_geometry (MetaSurface *self)
 {
@@ -420,6 +528,8 @@ meta_surface_sync_geometry (MetaSurface *self)
     {
       free_pixmap (self);
 
+      meta_surface_opaque_region_changed (self);
+
       priv->width = rect.width;
       priv->height = rect.height;
     }
@@ -444,6 +554,8 @@ meta_surface_pre_paint (MetaSurface *self)
   meta_compositor_add_damage (priv->compositor, "meta_surface_pre_paint", parts);
   XFixesDestroyRegion (priv->xdisplay, parts);
 
+  update_opaque_region (self);
+
   ensure_pixmap (self);
 
   META_SURFACE_GET_CLASS (self)->pre_paint (self);
diff --git a/src/compositor/meta-surface.h b/src/compositor/meta-surface.h
index 48bb6fec..7a3b3d5a 100644
--- a/src/compositor/meta-surface.h
+++ b/src/compositor/meta-surface.h
@@ -27,36 +27,40 @@ G_BEGIN_DECLS
 #define META_TYPE_SURFACE (meta_surface_get_type ())
 G_DECLARE_DERIVABLE_TYPE (MetaSurface, meta_surface, META, SURFACE, GObject)
 
-MetaCompositor  *meta_surface_get_compositor  (MetaSurface        *self);
+MetaCompositor  *meta_surface_get_compositor        (MetaSurface        *self);
 
-MetaWindow      *meta_surface_get_window      (MetaSurface        *self);
+MetaWindow      *meta_surface_get_window            (MetaSurface        *self);
 
-Pixmap           meta_surface_get_pixmap      (MetaSurface        *self);
+Pixmap           meta_surface_get_pixmap            (MetaSurface        *self);
 
-int              meta_surface_get_x           (MetaSurface        *self);
+int              meta_surface_get_x                 (MetaSurface        *self);
 
-int              meta_surface_get_y           (MetaSurface        *self);
+int              meta_surface_get_y                 (MetaSurface        *self);
 
-int              meta_surface_get_width       (MetaSurface        *self);
+int              meta_surface_get_width             (MetaSurface        *self);
 
-int              meta_surface_get_height      (MetaSurface        *self);
+int              meta_surface_get_height            (MetaSurface        *self);
 
-cairo_surface_t *meta_surface_get_image       (MetaSurface        *self);
+XserverRegion    meta_surface_get_opaque_region     (MetaSurface        *self);
 
-gboolean         meta_surface_is_visible      (MetaSurface        *self);
+cairo_surface_t *meta_surface_get_image             (MetaSurface        *self);
 
-void             meta_surface_show            (MetaSurface        *self);
+gboolean         meta_surface_is_visible            (MetaSurface        *self);
 
-void             meta_surface_hide            (MetaSurface        *self);
+void             meta_surface_show                  (MetaSurface        *self);
 
-void             meta_surface_process_damage  (MetaSurface        *self,
-                                               XDamageNotifyEvent *event);
+void             meta_surface_hide                  (MetaSurface        *self);
 
-void             meta_surface_opacity_changed (MetaSurface        *self);
+void             meta_surface_process_damage        (MetaSurface        *self,
+                                                     XDamageNotifyEvent *event);
 
-void             meta_surface_sync_geometry   (MetaSurface        *self);
+void             meta_surface_opacity_changed       (MetaSurface        *self);
 
-void             meta_surface_pre_paint       (MetaSurface        *self);
+void             meta_surface_opaque_region_changed (MetaSurface        *self);
+
+void             meta_surface_sync_geometry         (MetaSurface        *self);
+
+void             meta_surface_pre_paint             (MetaSurface        *self);
 
 G_END_DECLS
 


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