[metacity] frames: apply shapes in different way



commit cd383e725b9a73a91a671a2ec6208645a89186a1
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue Jan 20 03:56:54 2015 +0200

    frames: apply shapes in different way

 src/core/frame.c |   24 +++++++++++++++++++++++
 src/ui/frames.c  |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/ui/frames.h  |    1 +
 3 files changed, 77 insertions(+), 4 deletions(-)
---
diff --git a/src/core/frame.c b/src/core/frame.c
index 6584d74..7389da1 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -26,6 +26,7 @@
 #include "bell.h"
 #include "errors.h"
 #include "keybindings.h"
+#include "prefs.h"
 
 #ifdef HAVE_RENDER
 #include <X11/extensions/Xrender.h>
@@ -40,6 +41,25 @@
                     FocusChangeMask |                              \
                     ColormapChangeMask)
 
+static gboolean update_shape (MetaFrame *frame);
+
+static void
+prefs_changed_callback (MetaPreference preference,
+                        gpointer       data)
+{
+  MetaFrame *frame = (MetaFrame *) data;
+
+  switch (preference)
+    {
+      case META_PREF_COMPOSITING_MANAGER:
+        frame->need_reapply_frame_shape = TRUE;
+        update_shape (frame);
+        break;
+      default:
+        break;
+    }
+}
+
 void
 meta_window_ensure_frame (MetaWindow *window)
 {
@@ -167,6 +187,8 @@ meta_window_ensure_frame (MetaWindow *window)
   frame->need_reapply_frame_shape = FALSE;
 
   meta_display_ungrab (window->display);
+
+  meta_prefs_add_listener (prefs_changed_callback, frame);
 }
 
 void
@@ -182,6 +204,8 @@ meta_window_destroy_frame (MetaWindow *window)
 
   frame = window->frame;
 
+  meta_prefs_remove_listener (prefs_changed_callback, frame);
+
   meta_frame_calc_borders (frame, &borders);
 
   meta_bell_notify_frame_destroy (frame);
diff --git a/src/ui/frames.c b/src/ui/frames.c
index 518185a..c79b4ac 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -668,6 +668,7 @@ meta_frames_manage_window (MetaFrames *frames,
   frame->title = NULL;
   frame->expose_delayed = FALSE;
   frame->shape_applied = FALSE;
+  frame->dest_kind = ShapeBounding;
   frame->prelit_control = META_FRAME_CONTROL_NONE;
 
   meta_core_grab_buttons (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow);
@@ -996,6 +997,20 @@ get_client_region (MetaFrameGeometry *fgeom,
   return cairo_region_create_rectangle (&rect);
 }
 
+static cairo_region_t *
+get_frame_region (int window_width,
+                  int window_height)
+{
+  cairo_rectangle_int_t rect;
+
+  rect.x = 0;
+  rect.y = 0;
+  rect.width = window_width;
+  rect.height = window_height;
+
+  return cairo_region_create_rectangle (&rect);
+}
+
 void
 meta_frames_apply_shapes (MetaFrames *frames,
                           Window      xwindow,
@@ -1009,6 +1024,8 @@ meta_frames_apply_shapes (MetaFrames *frames,
   MetaFrameGeometry fgeom;
   cairo_region_t *window_region;
   Display *display;
+  gboolean compositing_manager;
+  int dest_kind;
 
   frame = meta_frames_lookup_window (frames, xwindow);
   g_return_if_fail (frame != NULL);
@@ -1031,6 +1048,8 @@ meta_frames_apply_shapes (MetaFrames *frames,
 
           XShapeCombineMask (display, frame->xwindow,
                              ShapeBounding, 0, 0, None, ShapeSet);
+          XShapeCombineMask (display, frame->xwindow,
+                             ShapeClip, 0, 0, None, ShapeSet);
           frame->shape_applied = FALSE;
         }
       else
@@ -1043,6 +1062,18 @@ meta_frames_apply_shapes (MetaFrames *frames,
       return; /* nothing to do */
     }
 
+  compositing_manager = meta_prefs_get_compositing_manager ();
+
+  dest_kind = ShapeClip;
+  if (!compositing_manager)
+    dest_kind = ShapeBounding;
+
+  if (frame->dest_kind != dest_kind)
+    {
+      XShapeCombineMask (display, frame->xwindow,
+                         frame->dest_kind, 0, 0, None, ShapeSet);
+    }
+
   window_region = get_visible_region (frames,
                                       frame,
                                       &fgeom,
@@ -1060,7 +1091,9 @@ meta_frames_apply_shapes (MetaFrames *frames,
       XSetWindowAttributes attrs;
       Window shape_window;
       Window client_window;
+      cairo_region_t *frame_region;
       cairo_region_t *client_region;
+      cairo_region_t *tmp_region;
       GdkScreen *screen;
       int screen_number;
 
@@ -1100,16 +1133,22 @@ meta_frames_apply_shapes (MetaFrames *frames,
       /* Punch the client area out of the normal frame shape,
        * then union it with the shape_window's existing shape
        */
+      frame_region = get_frame_region (new_window_width,
+                                       new_window_height);
       client_region = get_client_region (&fgeom,
                                          new_window_width,
                                          new_window_height);
 
-      cairo_region_subtract (window_region, client_region);
+      tmp_region = compositing_manager ? frame_region : window_region;
+
+      cairo_region_subtract (tmp_region, client_region);
 
       cairo_region_destroy (client_region);
 
       apply_cairo_region_to_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window,
-                                    window_region, ShapeBounding, ShapeUnion);
+                                    tmp_region, ShapeBounding, ShapeUnion);
+
+      cairo_region_destroy (frame_region);
 
       /* Now copy shape_window shape to the real frame */
       XShapeCombineShape (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, ShapeBounding,
@@ -1119,6 +1158,13 @@ meta_frames_apply_shapes (MetaFrames *frames,
                           ShapeSet);
 
       XDestroyWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window);
+
+      if (compositing_manager)
+        {
+          apply_cairo_region_to_window (display,
+                                        frame->xwindow, window_region,
+                                        dest_kind, ShapeSet);
+        }
     }
   else
     {
@@ -1128,10 +1174,12 @@ meta_frames_apply_shapes (MetaFrames *frames,
                   "Frame 0x%lx has shaped corners\n",
                   frame->xwindow);
 
-      apply_cairo_region_to_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
-                                    window_region, ShapeBounding, ShapeSet);
+      apply_cairo_region_to_window (display,
+                                    frame->xwindow, window_region,
+                                    dest_kind, ShapeSet);
     }
 
+  frame->dest_kind = dest_kind;
   frame->shape_applied = TRUE;
 
   cairo_region_destroy (window_region);
diff --git a/src/ui/frames.h b/src/ui/frames.h
index 4f8705e..01d51a5 100644
--- a/src/ui/frames.h
+++ b/src/ui/frames.h
@@ -81,6 +81,7 @@ struct _MetaUIFrame
   char *title; /* NULL once we have a layout */
   guint expose_delayed : 1;
   guint shape_applied : 1;
+  int dest_kind;
 
   /* FIXME get rid of this, it can just be in the MetaFrames struct */
   MetaFrameControl prelit_control;


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