summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2013-04-12 18:00:15 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2013-04-17 13:35:06 +0100
commitc2a9ccb7e2e0f7dc37866099a5e5a4a5727c679b (patch)
tree355764b6fdb8efa9741d6d78eee7362131cf7f45
parent4608cb6027f4bfe6c7a705d085810e1dc5e25851 (diff)
downloadmutter-c2a9ccb7e2e0f7dc37866099a5e5a4a5727c679b.tar.gz
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>
-rw-r--r--src/compositor/meta-window-actor.c72
-rw-r--r--src/core/frame.c21
-rw-r--r--src/core/frame.h9
-rw-r--r--src/ui/frames.c112
-rw-r--r--src/ui/frames.h11
-rw-r--r--src/ui/ui.c23
-rw-r--r--src/ui/ui.h14
7 files changed, 131 insertions, 131 deletions
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 5c667b060..04d754ba9 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 15eb0cdcb..2c48bb166 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 d612f7779..cff9cb25c 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 bd862000d..63f18379d 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 be238a84b..3298fc2cf 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 af28263be..c0c819e68 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 4a510b5c7..2ea3ca12c 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);