From ca53c82e4cb44eb5ca69130acfe2867fe6405365 Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Wed, 22 May 2019 12:23:16 -0400 Subject: ui: Replace inline borders in MetaFrameGeometry with MetaFrameBorder ... and start compensating for invisible borders in all of the math. https://bugzilla.gnome.org/show_bug.cgi?id=644930 NOTE: Updated for marco... upstream commit: https://gitlab.gnome.org/GNOME/metacity/commit/daf6bc08 --- src/ui/frames.c | 273 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 151 insertions(+), 122 deletions(-) (limited to 'src/ui/frames.c') diff --git a/src/ui/frames.c b/src/ui/frames.c index 5908d991..502ff523 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -906,21 +906,60 @@ apply_cairo_region_to_window (Display *display, } #endif +/* The client rectangle surrounds client window; it subtracts both + * the visible and invisible borders from the frame window's size. + */ +static void +get_client_rect (MetaFrameGeometry *fgeom, + int window_width, + int window_height, + cairo_rectangle_int_t *rect) +{ + rect->x = fgeom->borders.total.left; + rect->y = fgeom->borders.total.top; + rect->width = window_width - fgeom->borders.total.right - rect->x; + rect->height = window_height - fgeom->borders.total.bottom - rect->y; +} + +/* The visible frame rectangle surrounds the visible portion of the + * frame window; it subtracts only the invisible borders from the frame + * window's size. + */ +static void +get_visible_frame_rect (MetaFrameGeometry *fgeom, + int window_width, + int window_height, + cairo_rectangle_int_t *rect) +{ + rect->x = fgeom->borders.invisible.left; + rect->y = fgeom->borders.invisible.top; + rect->width = window_width - fgeom->borders.invisible.right - rect->x; + rect->height = window_height - fgeom->borders.invisible.bottom - rect->y; +} + static cairo_region_t * -get_bounds_region (MetaFrames *frames, - MetaUIFrame *frame, - MetaFrameGeometry *fgeom, - int window_width, - int window_height) +get_visible_region (MetaFrames *frames, + MetaUIFrame *frame, + MetaFrameGeometry *fgeom, + int window_width, + int window_height) { cairo_region_t *corners_region; - cairo_region_t *bounds_region; + cairo_region_t *visible_region; cairo_rectangle_int_t rect; + cairo_rectangle_int_t frame_rect; gint scale; corners_region = cairo_region_create (); scale = gdk_window_get_scale_factor (frame->window); + fgeom->borders.invisible.top *= scale; + fgeom->borders.invisible.bottom *= scale; + fgeom->borders.invisible.left *= scale; + fgeom->borders.invisible.right *= scale; + + get_visible_frame_rect (fgeom, window_width, window_height, &frame_rect); + if (fgeom->top_left_corner_rounded_radius != 0) { const int corner = fgeom->top_left_corner_rounded_radius * scale; @@ -930,8 +969,8 @@ get_bounds_region (MetaFrames *frames, for (i=0; ileft_width; - rect.y = fgeom->top_height; - rect.width = window_width - fgeom->right_width - rect.x; - rect.height = window_height - fgeom->bottom_height - rect.y; + rect.x = fgeom->borders.total.left; + rect.y = fgeom->borders.total.top; + rect.width = window_width - fgeom->borders.total.right - rect.x; + rect.height = window_height - fgeom->borders.total.bottom - rect.y; return cairo_region_create_rectangle (&rect); } @@ -1071,11 +1101,12 @@ meta_frames_apply_shapes (MetaFrames *frames, return; /* nothing to do */ } - window_region = get_bounds_region (frames, - frame, - &fgeom, - new_window_width, - new_window_height); + window_region = get_visible_region (frames, + frame, + &fgeom, + new_window_width, + new_window_height); + if (window_has_shape) { /* The client window is oclock or something and has a shape @@ -1118,8 +1149,8 @@ meta_frames_apply_shapes (MetaFrames *frames, META_CORE_GET_END); XShapeCombineShape (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window, ShapeBounding, - fgeom.left_width, - fgeom.top_height, + fgeom.borders.total.left, + fgeom.borders.total.top, client_window, ShapeBounding, ShapeSet); @@ -1179,11 +1210,11 @@ meta_frames_get_frame_bounds (MetaFrames *frames, meta_frames_calc_geometry (frames, frame, &fgeom); - return get_bounds_region (frames, - frame, - &fgeom, - window_width, - window_height); + return get_visible_region (frames, + frame, + &fgeom, + window_width, + window_height); } void @@ -2285,7 +2316,6 @@ static void populate_cache (MetaFrames *frames, MetaUIFrame *frame) { - int top, bottom, left, right; MetaFrameBorders borders; int width, height; int frame_width, frame_height, screen_width, screen_height; @@ -2319,35 +2349,43 @@ populate_cache (MetaFrames *frames, frame_flags, &borders); - top = borders.visible.top; - left = borders.visible.left; - right = borders.visible.right; - bottom = borders.visible.bottom; - pixels = get_cache (frames, frame); scale = gdk_window_get_scale_factor (frame->window); - /* Setup the rectangles for the four frame borders. First top, then - left, right and bottom. */ - pixels->piece[0].rect.x = 0; - pixels->piece[0].rect.y = 0; - pixels->piece[0].rect.width = (left + width + right) * scale; - pixels->piece[0].rect.height = top * scale; + /* Setup the rectangles for the four visible frame borders. First top, then + * left, right and bottom. Top and bottom extend to the invisible borders + * while left and right snugly fit in between: + * ----- + * | | + * ----- + */ + + /* width and height refer to the client window's + * size without any border added. */ + + /* top */ + pixels->piece[0].rect.x = borders.invisible.left / scale; + pixels->piece[0].rect.y = borders.invisible.top / scale; + pixels->piece[0].rect.width = (width + borders.visible.left + borders.visible.right) * scale; + pixels->piece[0].rect.height = borders.visible.top * scale; - pixels->piece[1].rect.x = 0; - pixels->piece[1].rect.y = top / scale; - pixels->piece[1].rect.width = left * scale; + /* left */ + pixels->piece[1].rect.x = borders.invisible.left / scale; + pixels->piece[1].rect.y = borders.total.top / scale; + pixels->piece[1].rect.width = borders.visible.left * scale; pixels->piece[1].rect.height = height * scale; - pixels->piece[2].rect.x = (left + width) / scale; - pixels->piece[2].rect.y = top / scale; - pixels->piece[2].rect.width = right * scale; + /* right */ + pixels->piece[2].rect.x = (borders.total.left + width) / scale; + pixels->piece[2].rect.y = borders.total.top / scale; + pixels->piece[2].rect.width = borders.visible.right * scale; pixels->piece[2].rect.height = height * scale; - pixels->piece[3].rect.x = 0; - pixels->piece[3].rect.y = (top + height) / scale; - pixels->piece[3].rect.width = (left + width + right) * scale; - pixels->piece[3].rect.height = bottom * scale; + /* bottom */ + pixels->piece[3].rect.x = borders.invisible.left / scale; + pixels->piece[3].rect.y = (borders.total.top + height) / scale; + pixels->piece[3].rect.width = (width + borders.visible.left + borders.visible.right) * scale; + pixels->piece[3].rect.height = borders.visible.bottom * scale; for (i = 0; i < 4; i++) { @@ -2396,35 +2434,10 @@ clip_to_screen (cairo_region_t *region, MetaUIFrame *frame) } static void -cached_pixels_draw (CachedPixels *pixels, - cairo_t *cr, - cairo_region_t *region) +subtract_client_area (cairo_region_t *region, + MetaUIFrame *frame) { - cairo_region_t *region_piece; - int i; - - for (i = 0; i < 4; i++) - { - CachedFramePiece *piece; - piece = &pixels->piece[i]; - - if (piece->pixmap) - { - cairo_set_source_surface (cr, piece->pixmap, - piece->rect.x, piece->rect.y); - cairo_paint (cr); - - region_piece = cairo_region_create_rectangle (&piece->rect); - cairo_region_subtract (region, region_piece); - cairo_region_destroy (region_piece); - } - } -} - -static void -subtract_client_area (cairo_region_t *region, MetaUIFrame *frame) -{ - GdkRectangle area; + cairo_rectangle_int_t area; MetaFrameFlags flags; MetaFrameType type; MetaFrameBorders borders; @@ -2441,21 +2454,46 @@ subtract_client_area (cairo_region_t *region, MetaUIFrame *frame) META_CORE_GET_CLIENT_WIDTH, &area.width, META_CORE_GET_CLIENT_HEIGHT, &area.height, META_CORE_GET_END); - meta_theme_get_frame_borders (meta_theme_get_current (), type, frame->text_height, flags, &borders); area.width /= scale; area.height /= scale; - area.x = borders.visible.left / scale; - area.y = borders.visible.top / scale; + area.x = borders.total.left / scale; + area.y = borders.total.top / scale; tmp_region = cairo_region_create_rectangle (&area); cairo_region_subtract (region, tmp_region); cairo_region_destroy (tmp_region); } +static void +cached_pixels_draw (CachedPixels *pixels, + cairo_t *cr, + cairo_region_t *region) +{ + cairo_region_t *region_piece; + int i; + + for (i = 0; i < 4; i++) + { + CachedFramePiece *piece; + piece = &pixels->piece[i]; + + if (piece->pixmap) + { + cairo_set_source_surface (cr, piece->pixmap, + piece->rect.x, piece->rect.y); + cairo_paint (cr); + + region_piece = cairo_region_create_rectangle (&piece->rect); + cairo_region_subtract (region, region_piece); + cairo_region_destroy (region_piece); + } + } +} + static MetaUIFrame * find_frame_to_draw (MetaFrames *frames, cairo_t *cr) @@ -2787,7 +2825,7 @@ control_rect (MetaFrameControl control, } #define RESIZE_EXTENDS 15 -#define TOP_RESIZE_HEIGHT 2 +#define TOP_RESIZE_HEIGHT 4 static MetaFrameControl get_control (MetaFrames *frames, MetaUIFrame *frame, @@ -2799,16 +2837,12 @@ get_control (MetaFrames *frames, GdkRectangle client; gint scale; - meta_frames_calc_geometry (frames, frame, &fgeom); - scale = gdk_window_get_scale_factor (frame->window); x /= scale; y /= scale; - client.x = fgeom.left_width; - client.y = fgeom.top_height; - client.width = fgeom.width - fgeom.left_width - fgeom.right_width; - client.height = fgeom.height - fgeom.top_height - fgeom.bottom_height; + meta_frames_calc_geometry (frames, frame, &fgeom); + get_client_rect (&fgeom, fgeom.width, fgeom.height, &client); if (POINT_IN_RECT (x, y, client)) return META_FRAME_CONTROL_CLIENT_AREA; @@ -2882,8 +2916,8 @@ get_control (MetaFrames *frames, * in case of overlap. */ - if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) && - x >= (fgeom.width - fgeom.right_width - RESIZE_EXTENDS)) + if (y >= (fgeom.height - fgeom.borders.total.bottom - RESIZE_EXTENDS) && + x >= (fgeom.width - fgeom.borders.total.right - RESIZE_EXTENDS)) { if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_SE; @@ -2892,8 +2926,8 @@ get_control (MetaFrames *frames, else if (has_horiz) return META_FRAME_CONTROL_RESIZE_E; } - else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) && - x <= (fgeom.left_width + RESIZE_EXTENDS)) + else if (y >= (fgeom.height - fgeom.borders.total.bottom - RESIZE_EXTENDS) && + x <= (fgeom.borders.total.left + RESIZE_EXTENDS)) { if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_SW; @@ -2902,8 +2936,8 @@ get_control (MetaFrames *frames, else if (has_horiz) return META_FRAME_CONTROL_RESIZE_W; } - else if (y < (fgeom.top_height + RESIZE_EXTENDS) && - x < RESIZE_EXTENDS) + else if (y < (fgeom.borders.invisible.top + RESIZE_EXTENDS) && + x <= (fgeom.borders.total.left + RESIZE_EXTENDS)) { if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_NW; @@ -2912,8 +2946,8 @@ get_control (MetaFrames *frames, else if (has_horiz) return META_FRAME_CONTROL_RESIZE_W; } - else if (y < (fgeom.top_height + RESIZE_EXTENDS) && - x >= (fgeom.width - RESIZE_EXTENDS)) + else if (y < (fgeom.borders.invisible.top + RESIZE_EXTENDS) && + x >= (fgeom.width - fgeom.borders.total.right - RESIZE_EXTENDS)) { if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_NE; @@ -2922,33 +2956,28 @@ get_control (MetaFrames *frames, else if (has_horiz) return META_FRAME_CONTROL_RESIZE_E; } - else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS)) + else if (y < (fgeom.borders.invisible.top + TOP_RESIZE_HEIGHT * scale)) { if (has_vert) - return META_FRAME_CONTROL_RESIZE_S; + return META_FRAME_CONTROL_RESIZE_N; } - else if (y <= TOP_RESIZE_HEIGHT * scale) + else if (y >= (fgeom.height - fgeom.borders.total.bottom - RESIZE_EXTENDS)) { if (has_vert) - return META_FRAME_CONTROL_RESIZE_N; - else if (has_horiz) - return META_FRAME_CONTROL_TITLE; + return META_FRAME_CONTROL_RESIZE_S; } - else if (x <= fgeom.left_width) + else if (x <= fgeom.borders.total.left + RESIZE_EXTENDS) { if (has_horiz) return META_FRAME_CONTROL_RESIZE_W; } - else if (x >= (fgeom.width - fgeom.right_width)) + else if (x >= (fgeom.width - fgeom.borders.total.right - RESIZE_EXTENDS)) { if (has_horiz) return META_FRAME_CONTROL_RESIZE_E; } - if (y >= fgeom.top_height) - return META_FRAME_CONTROL_NONE; - else - return META_FRAME_CONTROL_TITLE; + return META_FRAME_CONTROL_NONE; } void -- cgit v1.2.1