[mutter] Let the UI layer (via the core) construct the frame mask



commit c2a9ccb7e2e0f7dc37866099a5e5a4a5727c679b
Author: Simon McVittie <simon mcvittie collabora co uk>
Date:   Fri Apr 12 18:00:15 2013 +0100

    Let the UI layer (via the core) construct the frame mask
    
    This essentially just moves install_corners() from the compositor, through
    the core, into the UI layer where it arguably should have been anyway,
    leaving behind stub functions which call through the various layers. This
    removes the compositor's special knowledge of how rounded corners work,
    replacing it with "ask the UI for an alpha mask".
    
    The computation of border widths and heights changes a bit, because the
    width and height used in install_corners() are the
    meta_window_get_outer_rect() (which includes the visible borders but not
    the invisible ones), whereas the more readily-available rectangle is the
    MetaFrame.rect (which includes both). Computing the same width and height
    as meta_window_get_outer_rect() involves compensating for the invisible
    borders, but the UI layer is the authority on those anyway, so it seems
    clearer to have it do the calculations from scratch.
    
    Bug: https://bugzilla.gnome.org/show_bug.cgi?id=697758
    Signed-off-by: Simon McVittie <simon mcvittie collabora co uk>
    Reviewed-by: Jasper St. Pierre <jstpierre mecheye net>

 src/compositor/meta-window-actor.c |  72 +-----------------------
 src/core/frame.c                   |  21 +++----
 src/core/frame.h                   |   9 +--
 src/ui/frames.c                    | 112 +++++++++++++++++++++++++++++++------
 src/ui/frames.h                    |  11 ++--
 src/ui/ui.c                        |  23 ++++----
 src/ui/ui.h                        |  14 ++---
 7 files changed, 131 insertions(+), 131 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 5c667b0..04d754b 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1993,73 +1993,6 @@ meta_window_actor_sync_visibility (MetaWindowActor *self)
     }
 }
 
-#define TAU (2*M_PI)
-
-static void
-install_corners (MetaWindow       *window,
-                 MetaFrameBorders *borders,
-                 cairo_t          *cr)
-{
-  float top_left, top_right, bottom_left, bottom_right;
-  int x, y;
-  MetaRectangle outer;
-
-  meta_frame_get_corner_radiuses (window->frame,
-                                  &top_left,
-                                  &top_right,
-                                  &bottom_left,
-                                  &bottom_right);
-
-  meta_window_get_outer_rect (window, &outer);
-
-  /* top left */
-  x = borders->invisible.left;
-  y = borders->invisible.top;
-
-  cairo_arc (cr,
-             x + top_left,
-             y + top_left,
-             top_left,
-             2 * TAU / 4,
-             3 * TAU / 4);
-
-  /* top right */
-  x = borders->invisible.left + outer.width - top_right;
-  y = borders->invisible.top;
-
-  cairo_arc (cr,
-             x,
-             y + top_right,
-             top_right,
-             3 * TAU / 4,
-             4 * TAU / 4);
-
-  /* bottom right */
-  x = borders->invisible.left + outer.width - bottom_right;
-  y = borders->invisible.top + outer.height - bottom_right;
-
-  cairo_arc (cr,
-             x,
-             y,
-             bottom_right,
-             0 * TAU / 4,
-             1 * TAU / 4);
-
-  /* bottom left */
-  x = borders->invisible.left;
-  y = borders->invisible.top + outer.height - bottom_left;
-
-  cairo_arc (cr,
-             x + bottom_left,
-             y,
-             bottom_left,
-             1 * TAU / 4,
-             2 * TAU / 4);
-
-  cairo_set_source_rgba (cr, 1, 1, 1, 1);
-  cairo_fill (cr);
-}
-
 static cairo_region_t *
 scan_visible_region (guchar         *mask_data,
                      int             stride,
@@ -2099,7 +2032,6 @@ scan_visible_region (guchar         *mask_data,
 
 static void
 build_and_scan_frame_mask (MetaWindowActor       *self,
-                           MetaFrameBorders      *borders,
                            cairo_rectangle_int_t *client_area,
                            cairo_region_t        *shape_region)
 {
@@ -2145,7 +2077,7 @@ build_and_scan_frame_mask (MetaWindowActor       *self,
       gdk_cairo_region (cr, frame_paint_region);
       cairo_clip (cr);
 
-      install_corners (priv->window, borders, cr);
+      meta_frame_get_mask (priv->window->frame, cr);
 
       cairo_surface_flush (surface);
       scanned_region = scan_visible_region (mask_data, stride, frame_paint_region);
@@ -2308,7 +2240,7 @@ check_needs_reshape (MetaWindowActor *self)
        * and scans the mask looking for all opaque pixels,
        * adding it to region.
        */
-      build_and_scan_frame_mask (self, &borders, &client_area, region);
+      build_and_scan_frame_mask (self, &client_area, region);
     }
 
   priv->shape_region = region;
diff --git a/src/core/frame.c b/src/core/frame.c
index 15eb0cd..2c48bb1 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -332,19 +332,6 @@ meta_frame_calc_borders (MetaFrame        *frame,
                                borders);
 }
 
-void
-meta_frame_get_corner_radiuses (MetaFrame *frame,
-                                float     *top_left,
-                                float     *top_right,
-                                float     *bottom_left,
-                                float     *bottom_right)
-{
-  meta_ui_get_corner_radiuses (frame->window->screen->ui,
-                               frame->xwindow,
-                               top_left, top_right,
-                               bottom_left, bottom_right);
-}
-
 gboolean
 meta_frame_sync_to_window (MetaFrame *frame,
                            int        resize_gravity,
@@ -401,6 +388,14 @@ meta_frame_get_frame_bounds (MetaFrame *frame)
 }
 
 void
+meta_frame_get_mask (MetaFrame                    *frame,
+                     cairo_t                      *cr)
+{
+  meta_ui_get_frame_mask (frame->window->screen->ui, frame->xwindow,
+                          frame->rect.width, frame->rect.height, cr);
+}
+
+void
 meta_frame_queue_draw (MetaFrame *frame)
 {
   meta_ui_queue_frame_draw (frame->window->screen->ui,
diff --git a/src/core/frame.h b/src/core/frame.h
index d612f77..cff9cb2 100644
--- a/src/core/frame.h
+++ b/src/core/frame.h
@@ -63,12 +63,6 @@ Window         meta_frame_get_xwindow (MetaFrame *frame);
 void meta_frame_calc_borders      (MetaFrame        *frame,
                                    MetaFrameBorders *borders);
 
-void meta_frame_get_corner_radiuses (MetaFrame *frame,
-                                     float     *top_left,
-                                     float     *top_right,
-                                     float     *bottom_left,
-                                     float     *bottom_right);
-
 gboolean meta_frame_sync_to_window (MetaFrame         *frame,
                                     int                gravity,
                                     gboolean           need_move,
@@ -76,6 +70,9 @@ gboolean meta_frame_sync_to_window (MetaFrame         *frame,
 
 cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
 
+void meta_frame_get_mask (MetaFrame *frame,
+                          cairo_t   *cr);
+
 void meta_frame_set_screen_cursor (MetaFrame   *frame,
                                   MetaCursor   cursor);
 
diff --git a/src/ui/frames.c b/src/ui/frames.c
index bd86200..63f1837 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -740,22 +740,6 @@ meta_ui_frame_get_corner_radiuses (MetaFrames  *frames,
 }
 
 void
-meta_frames_get_corner_radiuses (MetaFrames *frames,
-                                 Window      xwindow,
-                                 float      *top_left,
-                                 float      *top_right,
-                                 float      *bottom_left,
-                                 float      *bottom_right)
-{
-  MetaUIFrame *frame;
-
-  frame = meta_frames_lookup_window (frames, xwindow);
-
-  meta_ui_frame_get_corner_radiuses (frames, frame, top_left, top_right,
-                                     bottom_left, bottom_right);
-}
-
-void
 meta_frames_reset_bg (MetaFrames *frames,
                       Window  xwindow)
 {
@@ -1851,6 +1835,102 @@ clip_region_to_visible_frame_border (cairo_region_t *region,
   cairo_region_destroy (frame_border);
 }
 
+#define TAU (2*M_PI)
+
+/*
+ * Draw the opaque and semi-opaque pixels of this frame into a mask.
+ *
+ * (0,0) in Cairo coordinates is assumed to be the top left corner of the
+ * invisible border.
+ *
+ * The parts of @cr's surface in the clip region are assumed to be
+ * initialized to fully-transparent, and the clip region is assumed to
+ * contain the invisible border and the visible parts of the frame, but
+ * not the client area.
+ *
+ * This function uses @cr to draw pixels of arbitrary color (it will
+ * typically be drawing in a %CAIRO_FORMAT_A8 surface, so the color is
+ * discarded anyway) with appropriate alpha values to reproduce this
+ * frame's alpha channel, as a mask to be applied to an opaque pixmap.
+ *
+ * @frame: This frame
+ * @xwindow: The X window for the frame, which has the client window as a child
+ * @width: The width of the framed window including any invisible borders
+ * @height: The height of the framed window including any invisible borders
+ * @cr: Used to draw the resulting mask
+ */
+void
+meta_frames_get_mask (MetaFrames          *frames,
+                      Window               xwindow,
+                      guint                width,
+                      guint                height,
+                      cairo_t             *cr)
+{
+  MetaUIFrame *frame = meta_frames_lookup_window (frames, xwindow);
+  float top_left, top_right, bottom_left, bottom_right;
+  int x, y;
+  MetaFrameBorders borders;
+
+  if (frame == NULL)
+    meta_bug ("No such frame 0x%lx\n", xwindow);
+
+  cairo_save (cr);
+
+  meta_ui_frame_get_borders (frames, frame, &borders);
+  meta_ui_frame_get_corner_radiuses (frames, frame,
+                                     &top_left, &top_right,
+                                     &bottom_left, &bottom_right);
+
+  /* top left */
+  x = borders.invisible.left;
+  y = borders.invisible.top;
+
+  cairo_arc (cr,
+             x + top_left,
+             y + top_left,
+             top_left,
+             2 * TAU / 4,
+             3 * TAU / 4);
+
+  /* top right */
+  x = width - borders.invisible.right - top_right;
+  y = borders.invisible.top;
+
+  cairo_arc (cr,
+             x,
+             y + top_right,
+             top_right,
+             3 * TAU / 4,
+             4 * TAU / 4);
+
+  /* bottom right */
+  x = width - borders.invisible.right - bottom_right;
+  y = height - borders.invisible.bottom - bottom_right;
+
+  cairo_arc (cr,
+             x,
+             y,
+             bottom_right,
+             0 * TAU / 4,
+             1 * TAU / 4);
+
+  /* bottom left */
+  x = borders.invisible.left;
+  y = height - borders.invisible.bottom - bottom_left;
+
+  cairo_arc (cr,
+             x + bottom_left,
+             y,
+             bottom_left,
+             1 * TAU / 4,
+             2 * TAU / 4);
+
+  cairo_set_source_rgba (cr, 1, 1, 1, 1);
+  cairo_fill (cr);
+
+  cairo_restore (cr);
+}
+
 static gboolean
 meta_frames_draw (GtkWidget *widget,
                   cairo_t   *cr)
diff --git a/src/ui/frames.h b/src/ui/frames.h
index be238a8..3298fc2 100644
--- a/src/ui/frames.h
+++ b/src/ui/frames.h
@@ -140,12 +140,11 @@ cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
                                               int         window_width,
                                               int         window_height);
 
-void meta_frames_get_corner_radiuses (MetaFrames *frames,
-                                      Window      xwindow,
-                                      float      *top_left,
-                                      float      *top_right,
-                                      float      *bottom_left,
-                                      float      *bottom_right);
+void meta_frames_get_mask (MetaFrames *frames,
+                           Window      xwindow,
+                           guint       width,
+                           guint       height,
+                           cairo_t    *cr);
 
 void meta_frames_move_resize_frame (MetaFrames *frames,
                                    Window      xwindow,
diff --git a/src/ui/ui.c b/src/ui/ui.c
index af28263..c0c819e 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -325,6 +325,16 @@ meta_ui_free (MetaUI *ui)
 }
 
 void
+meta_ui_get_frame_mask (MetaUI  *ui,
+                        Window   frame_xwindow,
+                        guint    width,
+                        guint    height,
+                        cairo_t *cr)
+{
+  meta_frames_get_mask (ui->frames, frame_xwindow, width, height, cr);
+}
+
+void
 meta_ui_get_frame_borders (MetaUI *ui,
                            Window frame_xwindow,
                            MetaFrameBorders *borders)
@@ -333,19 +343,6 @@ meta_ui_get_frame_borders (MetaUI *ui,
                            borders);
 }
 
-void
-meta_ui_get_corner_radiuses (MetaUI *ui,
-                             Window  xwindow,
-                             float  *top_left,
-                             float  *top_right,
-                             float  *bottom_left,
-                             float  *bottom_right)
-{
-  meta_frames_get_corner_radiuses (ui->frames, xwindow,
-                                   top_left, top_right,
-                                   bottom_left, bottom_right);
-}
-
 Window
 meta_ui_create_frame_window (MetaUI *ui,
                              Display *xdisplay,
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 4a510b5..2ea3ca1 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -66,6 +66,13 @@ void meta_ui_theme_get_frame_borders (MetaUI *ui,
 void meta_ui_get_frame_borders (MetaUI *ui,
                                 Window frame_xwindow,
                                 MetaFrameBorders *borders);
+
+void meta_ui_get_frame_mask (MetaUI *ui,
+                             Window frame_xwindow,
+                             guint width,
+                             guint height,
+                             cairo_t *cr);
+
 Window meta_ui_create_frame_window (MetaUI *ui,
                                     Display *xdisplay,
                                     Visual *xvisual,
@@ -102,13 +109,6 @@ cairo_region_t *meta_ui_get_frame_bounds (MetaUI  *ui,
                                           int      window_width,
                                           int      window_height);
 
-void meta_ui_get_corner_radiuses (MetaUI *ui,
-                                  Window  xwindow,
-                                  float  *top_left,
-                                  float  *top_right,
-                                  float  *bottom_left,
-                                  float  *bottom_right);
-
 void meta_ui_queue_frame_draw (MetaUI *ui,
                                Window xwindow);
 


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