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 +++++++++++++++++++++++++++++++------------------------- src/ui/theme.c | 92 +++++++++---------- src/ui/theme.h | 5 +- 3 files changed, 198 insertions(+), 172 deletions(-) (limited to 'src') 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 diff --git a/src/ui/theme.c b/src/ui/theme.c index b08b3903..773ab0a5 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -644,15 +644,12 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, flags, &borders); - fgeom->left_width = borders.visible.left; - fgeom->right_width = borders.visible.right; - fgeom->top_height = borders.visible.top; - fgeom->bottom_height = borders.visible.bottom; + fgeom->borders = borders; - width = client_width + fgeom->left_width + fgeom->right_width; + width = client_width + borders.total.left + borders.total.right; height = ((flags & META_FRAME_SHADED) ? 0: client_height) + - fgeom->top_height + fgeom->bottom_height; + borders.total.top + borders.total.bottom; fgeom->width = width; fgeom->height = height; @@ -665,7 +662,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, switch (layout->button_sizing) { case META_BUTTON_SIZING_ASPECT: - button_height = fgeom->top_height - layout->button_border.top - layout->button_border.bottom; + button_height = borders.visible.top - layout->button_border.top - layout->button_border.bottom; button_width = button_height / layout->button_aspect; break; case META_BUTTON_SIZING_FIXED: @@ -858,11 +855,11 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, fgeom->n_right_buttons = n_right; /* center buttons vertically */ - button_y = (fgeom->top_height - - (button_height + layout->button_border.top + layout->button_border.bottom)) / 2 + layout->button_border.top; + button_y = (borders.visible.top - + (button_height + layout->button_border.top + layout->button_border.bottom)) / 2 + layout->button_border.top + borders.invisible.top; /* right edge of farthest-right button */ - x = width - layout->right_titlebar_edge; + x = width - layout->right_titlebar_edge - borders.invisible.right; i = n_right - 1; while (i >= 0) @@ -883,7 +880,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, if (flags & META_FRAME_MAXIMIZED || flags & META_FRAME_TILED_LEFT || - flags & META_FRAME_TILED_RIGHT) + flags & META_FRAME_TILED_RIGHT) { rect->clickable.x = rect->visible.x; rect->clickable.y = rect->visible.y; @@ -910,7 +907,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, /* Now x changes to be position from the left and we go through * the left-side buttons */ - x = layout->left_titlebar_edge; + x = layout->left_titlebar_edge + borders.invisible.left; for (i = 0; i < n_left; i++) { MetaButtonSpace *rect; @@ -943,9 +940,9 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, * rather than centering it like the buttons */ fgeom->title_rect.x = x + layout->title_border.left; - fgeom->title_rect.y = layout->title_border.top; + fgeom->title_rect.y = layout->title_border.top + borders.invisible.top; fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x; - fgeom->title_rect.height = fgeom->top_height - layout->title_border.top - layout->title_border.bottom; + fgeom->title_rect.height = borders.visible.top - layout->title_border.top - layout->title_border.bottom; /* Nuke title if it won't fit */ if (fgeom->title_rect.width < 0 || @@ -965,14 +962,14 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, fgeom->bottom_left_corner_rounded_radius = 0; fgeom->bottom_right_corner_rounded_radius = 0; - if (fgeom->top_height + fgeom->left_width >= min_size_for_rounding) + if (borders.visible.top + borders.visible.left >= min_size_for_rounding) fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius; - if (fgeom->top_height + fgeom->right_width >= min_size_for_rounding) + if (borders.visible.top + borders.visible.right >= min_size_for_rounding) fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius; - if (fgeom->bottom_height + fgeom->left_width >= min_size_for_rounding) + if (borders.visible.bottom + borders.visible.left >= min_size_for_rounding) fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius; - if (fgeom->bottom_height + fgeom->right_width >= min_size_for_rounding) + if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding) fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius; } @@ -3632,10 +3629,10 @@ fill_env (MetaPositionExprEnv *env, env->object_height = -1; if (info->fgeom) { - env->left_width = info->fgeom->left_width; - env->right_width = info->fgeom->right_width; - env->top_height = info->fgeom->top_height; - env->bottom_height = info->fgeom->bottom_height; + env->left_width = info->fgeom->borders.visible.left; + env->right_width = info->fgeom->borders.visible.right; + env->top_height = info->fgeom->borders.visible.top; + env->bottom_height = info->fgeom->borders.visible.bottom; env->frame_x_center = info->fgeom->width / 2 - logical_region.x; env->frame_y_center = info->fgeom->height / 2 - logical_region.y; } @@ -4700,6 +4697,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, { /* BOOKMARK */ int i, j; + GdkRectangle visible_rect; GdkRectangle titlebar_rect; GdkRectangle left_titlebar_edge; GdkRectangle right_titlebar_edge; @@ -4708,11 +4706,19 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, GdkRectangle left_edge, right_edge, bottom_edge; PangoRectangle extents; MetaDrawInfo draw_info; + const MetaFrameBorders *borders; - titlebar_rect.x = 0; - titlebar_rect.y = 0; - titlebar_rect.width = fgeom->width; - titlebar_rect.height = fgeom->top_height; + borders = &fgeom->borders; + + visible_rect.x = borders->invisible.left; + visible_rect.y = borders->invisible.top; + visible_rect.width = fgeom->width - borders->invisible.left - borders->invisible.right; + visible_rect.height = fgeom->height - borders->invisible.top - borders->invisible.bottom; + + titlebar_rect.x = visible_rect.x; + titlebar_rect.y = visible_rect.y; + titlebar_rect.width = visible_rect.width; + titlebar_rect.height = borders->visible.top; left_titlebar_edge.x = titlebar_rect.x; left_titlebar_edge.y = titlebar_rect.y + fgeom->top_titlebar_edge; @@ -4734,20 +4740,20 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, bottom_titlebar_edge.height = fgeom->bottom_titlebar_edge; bottom_titlebar_edge.y = titlebar_rect.y + titlebar_rect.height - bottom_titlebar_edge.height; - left_edge.x = 0; - left_edge.y = fgeom->top_height; - left_edge.width = fgeom->left_width; - left_edge.height = fgeom->height - fgeom->top_height - fgeom->bottom_height; + left_edge.x = visible_rect.x; + left_edge.y = visible_rect.y + borders->visible.top; + left_edge.width = borders->visible.left; + left_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom; - right_edge.x = fgeom->width - fgeom->right_width; - right_edge.y = fgeom->top_height; - right_edge.width = fgeom->right_width; - right_edge.height = fgeom->height - fgeom->top_height - fgeom->bottom_height; + right_edge.x = visible_rect.x + visible_rect.width - borders->visible.right; + right_edge.y = visible_rect.y + borders->visible.top; + right_edge.width = borders->visible.right; + right_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom; - bottom_edge.x = 0; - bottom_edge.y = fgeom->height - fgeom->bottom_height; - bottom_edge.width = fgeom->width; - bottom_edge.height = fgeom->bottom_height; + bottom_edge.x = visible_rect.x; + bottom_edge.y = visible_rect.y + visible_rect.height - borders->visible.bottom; + bottom_edge.width = visible_rect.width; + bottom_edge.height = borders->visible.bottom; if (title_layout) pango_layout_get_pixel_extents (title_layout, @@ -4769,10 +4775,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, switch ((MetaFramePiece) i) { case META_FRAME_PIECE_ENTIRE_BACKGROUND: - rect.x = 0; - rect.y = 0; - rect.width = fgeom->width; - rect.height = fgeom->height; + rect = visible_rect; break; case META_FRAME_PIECE_TITLEBAR: @@ -4820,10 +4823,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, break; case META_FRAME_PIECE_OVERLAY: - rect.x = 0; - rect.y = 0; - rect.width = fgeom->width; - rect.height = fgeom->height; + rect = visible_rect; break; case META_FRAME_PIECE_LAST: diff --git a/src/ui/theme.h b/src/ui/theme.h index b341418b..34b98935 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -171,10 +171,7 @@ struct _MetaButtonSpace */ struct _MetaFrameGeometry { - int left_width; - int right_width; - int top_height; - int bottom_height; + MetaFrameBorders borders; int width; int height; -- cgit v1.2.1