[metacity] let the ui layer (via the core) construct the frame mask



commit 0de997727d3f90dae216c07a01d8d56a8a2f3fd2
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Sun Apr 5 18:28:22 2015 +0300

    let the ui layer (via the core) construct the frame mask
    
    Based on mutter commit:
    https://git.gnome.org/browse/mutter/commit/?id=c2a9ccb7e2e0f7dc37866099a5e5a4a5727c679b

 src/core/frame-private.h |    9 +--
 src/core/frame.c         |   21 +++-----
 src/include/ui.h         |   14 +++---
 src/ui/frames.c          |  116 +++++++++++++++++++++++++++++++++++++++------
 src/ui/frames.h          |   11 ++--
 src/ui/ui.c              |   23 ++++-----
 6 files changed, 133 insertions(+), 61 deletions(-)
---
diff --git a/src/core/frame-private.h b/src/core/frame-private.h
index d0a2176..455a6bc 100644
--- a/src/core/frame-private.h
+++ b/src/core/frame-private.h
@@ -57,12 +57,6 @@ void     meta_frame_queue_draw              (MetaFrame  *frame);
 
 MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
 
-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,
@@ -70,6 +64,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/core/frame.c b/src/core/frame.c
index 6305963..22994a5 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -376,19 +376,6 @@ update_shape (MetaFrame *frame)
     return FALSE;
 }
 
-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,
@@ -453,6 +440,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/include/ui.h b/src/include/ui.h
index 74ed2c1..4d031c1 100644
--- a/src/include/ui.h
+++ b/src/include/ui.h
@@ -65,6 +65,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,
@@ -99,13 +106,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);
 
diff --git a/src/ui/frames.c b/src/ui/frames.c
index 5691d24..c6e636d 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -40,6 +40,10 @@
 
 #define DEFAULT_INNER_BUTTON_BORDER 3
 
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327
+#endif
+
 static void meta_frames_destroy       (GtkWidget *widget);
 static void meta_frames_finalize      (GObject   *object);
 static void meta_frames_style_updated (GtkWidget *widget);
@@ -841,22 +845,6 @@ meta_ui_frame_get_corner_radiuses (MetaFrames  *frames,
     *bottom_right = fgeom.bottom_right_corner_rounded_radius + 
sqrt(fgeom.bottom_right_corner_rounded_radius);
 }
 
-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);
-}
-
 static void
 apply_cairo_region_to_window (Display        *display,
                               Window          xwindow,
@@ -2461,6 +2449,102 @@ find_frame_to_draw (MetaFrames *frames,
   return NULL;
 }
 
+#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 dcce7a4..568a964 100644
--- a/src/ui/frames.h
+++ b/src/ui/frames.h
@@ -146,12 +146,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 ccde3f5..239c63f 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -304,6 +304,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)
@@ -311,19 +321,6 @@ meta_ui_get_frame_borders (MetaUI *ui,
   meta_frames_get_borders (ui->frames, frame_xwindow, 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);
-}
-
 static void
 set_background_none (Display *xdisplay,
                      Window   xwindow)


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