summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2015-04-05 18:28:22 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2015-04-05 18:28:22 +0300
commit0de997727d3f90dae216c07a01d8d56a8a2f3fd2 (patch)
tree34ab325ec5bf9440c1518b01d3bffd997401251b
parent4f36eb12f9fef06dc44122d310cba0ce5c886ffa (diff)
downloadmetacity-0de997727d3f90dae216c07a01d8d56a8a2f3fd2.tar.gz
let the ui layer (via the core) construct the frame mask
Based on mutter commit: https://git.gnome.org/browse/mutter/commit/?id=c2a9ccb7e2e0f7dc37866099a5e5a4a5727c679b
-rw-r--r--src/core/frame-private.h9
-rw-r--r--src/core/frame.c21
-rw-r--r--src/include/ui.h14
-rw-r--r--src/ui/frames.c116
-rw-r--r--src/ui/frames.h11
-rw-r--r--src/ui/ui.c23
6 files changed, 133 insertions, 61 deletions
diff --git a/src/core/frame-private.h b/src/core/frame-private.h
index d0a2176f..455a6bc8 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 63059635..22994a53 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 74ed2c1e..4d031c1e 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 5691d242..c6e636dd 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 dcce7a44..568a9643 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 ccde3f5f..239c63f0 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)