[metacity/cherry-pick-15161227] surface-xrender: restore opacity handling




commit e1c1b3c3fcb3e34a7e6c8b9248b6d74281322a71
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Jun 17 17:11:50 2021 +0300

    surface-xrender: restore opacity handling
    
    Commit 1021494e347da7045c1db834bf9e4f1b5e076f17 removed too much.
    
    https://gitlab.gnome.org/GNOME/metacity/-/issues/19
    
    
    (cherry picked from commit 15161227389385a1d55c86d4c27eb1254eb88500)

 src/compositor/meta-surface-xrender.c | 67 ++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)
---
diff --git a/src/compositor/meta-surface-xrender.c b/src/compositor/meta-surface-xrender.c
index 1ce839fe..bcf1e7d3 100644
--- a/src/compositor/meta-surface-xrender.c
+++ b/src/compositor/meta-surface-xrender.c
@@ -39,6 +39,7 @@ struct _MetaSurfaceXRender
   Display           *xdisplay;
 
   Picture            picture;
+  Picture            alpha_pict;
 
   XserverRegion      border_clip;
 
@@ -190,7 +191,7 @@ paint_argb_parts (MetaSurfaceXRender *self,
   XFixesSetPictureClipRegion (self->xdisplay, paint_buffer, 0, 0, border_clip);
 
   XRenderComposite (self->xdisplay, PictOpOver,
-                    self->picture, None, paint_buffer,
+                    self->picture, self->alpha_pict, paint_buffer,
                     0, 0, 0, 0,
                     x, y, width, height);
 }
@@ -275,6 +276,55 @@ get_window_picture (MetaSurfaceXRender *self)
   return picture;
 }
 
+static Picture
+create_alpha_picture (MetaSurfaceXRender *self,
+                      guint               opacity)
+{
+  Window xroot;
+  Pixmap pixmap;
+  XRenderPictFormat *format;
+  XRenderPictureAttributes pa;
+  Picture picture;
+  XRenderColor c;
+
+  xroot = DefaultRootWindow (self->xdisplay);
+  pixmap = XCreatePixmap (self->xdisplay, xroot, 1, 1, 32);
+
+  if (pixmap == None)
+    return None;
+
+  format = XRenderFindStandardFormat (self->xdisplay, PictStandardARGB32);
+
+  if (format == NULL)
+    {
+      XFreePixmap (self->xdisplay, pixmap);
+      return None;
+    }
+
+  pa.repeat = True;
+  picture = XRenderCreatePicture (self->xdisplay,
+                                  pixmap,
+                                  format,
+                                  CPRepeat,
+                                  &pa);
+
+  if (picture == None)
+    {
+      XFreePixmap (self->xdisplay, pixmap);
+      return None;
+    }
+
+  c.alpha = ((double) opacity / OPAQUE) * 0xffff;
+  c.red = 0;
+  c.green = 0;
+  c.blue = 0;
+
+  XRenderFillRectangle (self->xdisplay, PictOpSrc, picture, &c, 0, 0, 1, 1);
+  XFreePixmap (self->xdisplay, pixmap);
+
+  return picture;
+}
+
 static void
 notify_appears_focused_cb (MetaWindow         *window,
                            GParamSpec         *pspec,
@@ -336,6 +386,12 @@ meta_surface_xrender_finalize (GObject *object)
 
   free_picture (self);
 
+  if (self->alpha_pict != None)
+    {
+      XRenderFreePicture (self->xdisplay, self->alpha_pict);
+      self->alpha_pict = None;
+    }
+
   if (self->border_clip != None)
     {
       XFixesDestroyRegion (self->xdisplay, self->border_clip);
@@ -430,6 +486,12 @@ meta_surface_xrender_opacity_changed (MetaSurface *surface)
 
   self = META_SURFACE_XRENDER (surface);
 
+  if (self->alpha_pict != None)
+    {
+      XRenderFreePicture (self->xdisplay, self->alpha_pict);
+      self->alpha_pict = None;
+    }
+
   shadow_changed (self);
 }
 
@@ -495,6 +557,9 @@ meta_surface_xrender_pre_paint (MetaSurface   *surface,
   if (self->picture == None)
     self->picture = get_window_picture (self);
 
+  if (window->opacity != OPAQUE && self->alpha_pict == None)
+    self->alpha_pict = create_alpha_picture (self, window->opacity);
+
   if (self->shadow_changed)
     {
       MetaCompositor *compositor;


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