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, @@ -400,6 +387,14 @@ meta_frame_get_frame_bounds (MetaFrame *frame) frame->rect.height); } +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) { 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 @@ -739,22 +739,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); -} - 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 @@ -324,6 +324,16 @@ meta_ui_free (MetaUI *ui) g_free (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, @@ -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);