From 097ee776c7073c7e5dc9e23666f24f894716177f Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 15 Nov 2013 18:03:50 -0500 Subject: [PATCH] Stop passing around MetaFrameBorders Instead of passing around MetaFrameBorders, compute it when we need it. This also allows us to know that we are using MetaFrameBorders only for windows with frames (where it is meaningful) and not for frameless windows, which can have custom borders which we need to interpret differently. https://bugzilla.gnome.org/show_bug.cgi?id=707194 --- src/core/constraints.c | 89 +++++++++++++----------------------------- src/core/constraints.h | 1 - src/core/place.c | 35 ++++++----------- src/core/place.h | 1 - src/core/window.c | 17 +++++--- 5 files changed, 52 insertions(+), 91 deletions(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index a60595fb4..97e1e79de 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -118,8 +118,6 @@ typedef struct { MetaRectangle orig; MetaRectangle current; - MetaFrameBorders *borders; - gboolean must_free_borders; ActionType action_type; gboolean is_user_action; @@ -195,7 +193,6 @@ static gboolean constrain_partially_onscreen (MetaWindow *window, static void setup_constraint_info (ConstraintInfo *info, MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, @@ -208,9 +205,8 @@ static void extend_by_frame (MetaWindow *window, MetaRectangle *rect); static void unextend_by_frame (MetaWindow *window, MetaRectangle *rect); -static inline void get_size_limits (const MetaWindow *window, - const MetaFrameBorders *borders, - gboolean include_frame, +static inline void get_size_limits (MetaWindow *window, + gboolean include_frame, MetaRectangle *min_size, MetaRectangle *max_size); @@ -280,7 +276,6 @@ do_all_constraints (MetaWindow *window, void meta_window_constrain (MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, @@ -303,7 +298,6 @@ meta_window_constrain (MetaWindow *window, setup_constraint_info (&info, window, - orig_borders, flags, resize_gravity, orig, @@ -333,19 +327,11 @@ meta_window_constrain (MetaWindow *window, * if this was a user move or user move-and-resize operation. */ update_onscreen_requirements (window, &info); - - /* Ew, what an ugly way to do things. Destructors (in a real OOP language, - * not gobject-style--gobject would be more pain than it's worth) or - * smart pointers would be so much nicer here. *shrug* - */ - if (info.must_free_borders) - g_free (info.borders); } static void setup_constraint_info (ConstraintInfo *info, MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, @@ -357,18 +343,6 @@ setup_constraint_info (ConstraintInfo *info, info->orig = *orig; info->current = *new; - /* Create a fake frame geometry if none really exists */ - if (orig_borders && !window->fullscreen) - { - info->borders = orig_borders; - info->must_free_borders = FALSE; - } - else - { - info->borders = g_new0 (MetaFrameBorders, 1); - info->must_free_borders = TRUE; - } - if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION) info->action_type = ACTION_MOVE_AND_RESIZE; else if (flags & META_IS_RESIZE_ACTION) @@ -524,7 +498,7 @@ place_window_if_needed(MetaWindow *window, const MetaMonitorInfo *monitor_info; meta_window_get_outer_rect (window, &placed_rect); - meta_window_place (window, info->borders, info->orig.x, info->orig.y, + meta_window_place (window, info->orig.x, info->orig.y, &placed_rect.x, &placed_rect.y); did_placement = TRUE; @@ -588,10 +562,6 @@ place_window_if_needed(MetaWindow *window, (window->maximize_vertically_after_placement ? META_MAXIMIZE_VERTICAL : 0), &info->current); - /* maximization may have changed frame geometry */ - if (!window->fullscreen) - meta_frame_calc_borders (window->frame, info->borders); - if (window->fullscreen_after_placement) { window->saved_rect = info->current; @@ -684,10 +654,13 @@ update_onscreen_requirements (MetaWindow *window, */ if (window->frame && window->decorated) { + MetaFrameBorders borders; MetaRectangle titlebar_rect; + meta_frame_calc_borders (window->frame, &borders); + titlebar_rect = info->current; - titlebar_rect.height = info->borders->visible.top; + titlebar_rect.height = borders.visible.top; old = window->require_titlebar_visible; window->require_titlebar_visible = meta_rectangle_overlaps_with_region (info->usable_screen_region, @@ -718,15 +691,15 @@ unextend_by_frame (MetaWindow *window, } static inline void -get_size_limits (const MetaWindow *window, - const MetaFrameBorders *borders, - gboolean include_frame, +get_size_limits (MetaWindow *window, + gboolean include_frame, MetaRectangle *min_size, MetaRectangle *max_size) { /* We pack the results into MetaRectangle structs just for convienience; we * don't actually use the position of those rects. */ + min_size->x = min_size->y = max_size->x = max_size->y = 0; min_size->width = window->size_hints.min_width; min_size->height = window->size_hints.min_height; max_size->width = window->size_hints.max_width; @@ -734,22 +707,8 @@ get_size_limits (const MetaWindow *window, if (include_frame) { - int fw = borders->visible.left + borders->visible.right; - int fh = borders->visible.top + borders->visible.bottom; - - min_size->width += fw; - min_size->height += fh; - /* Do check to avoid overflow (e.g. max_size->width & max_size->height - * may be set to G_MAXINT by meta_set_normal_hints()). - */ - if (max_size->width < (G_MAXINT - fw)) - max_size->width += fw; - else - max_size->width = G_MAXINT; - if (max_size->height < (G_MAXINT - fh)) - max_size->height += fh; - else - max_size->height = G_MAXINT; + meta_window_client_rect_to_outer_rect (window, min_size, min_size); + meta_window_client_rect_to_outer_rect (window, max_size, max_size); } } @@ -859,7 +818,7 @@ constrain_maximization (MetaWindow *window, /* Check min size constraints; max size constraints are ignored for maximized * windows, as per bug 327543. */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); hminbad = target_size.width < min_size.width && window->maximized_horizontally; vminbad = target_size.height < min_size.height && window->maximized_vertically; if (hminbad || vminbad) @@ -918,7 +877,7 @@ constrain_tiling (MetaWindow *window, /* Check min size constraints; max size constraints are ignored as for * maximized windows. */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); hminbad = target_size.width < min_size.width; vminbad = target_size.height < min_size.height; if (hminbad || vminbad) @@ -961,7 +920,7 @@ constrain_fullscreen (MetaWindow *window, monitor = info->entire_monitor; - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size); too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor); if (too_big || too_small) @@ -1070,7 +1029,7 @@ constrain_size_limits (MetaWindow *window, return TRUE; /* Determine whether constraint is already satisfied; exit if it is */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, FALSE, &min_size, &max_size); /* We ignore max-size limits for maximized windows; see #327543 */ if (window->maximized_horizontally) max_size.width = MAX (max_size.width, info->current.width); @@ -1262,7 +1221,7 @@ do_screen_and_monitor_relative_constraints ( /* Determine whether constraint applies; exit if it doesn't */ how_far_it_can_be_smushed = info->current; - get_size_limits (window, info->borders, TRUE, &min_size, &max_size); + get_size_limits (window, TRUE, &min_size, &max_size); extend_by_frame (window, &info->current); if (info->action_type != ACTION_MOVE) @@ -1420,8 +1379,11 @@ constrain_titlebar_visible (MetaWindow *window, */ if (window->frame) { - bottom_amount = info->current.height + info->borders->visible.bottom; - vert_amount_onscreen = info->borders->visible.top; + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + bottom_amount = info->current.height + borders.visible.bottom; + vert_amount_onscreen = borders.visible.top; } else bottom_amount = vert_amount_offscreen; @@ -1495,8 +1457,11 @@ constrain_partially_onscreen (MetaWindow *window, */ if (window->frame) { - bottom_amount = info->current.height + info->borders->visible.bottom; - vert_amount_onscreen = info->borders->visible.top; + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + bottom_amount = info->current.height + borders.visible.bottom; + vert_amount_onscreen = borders.visible.top; } else bottom_amount = vert_amount_offscreen; diff --git a/src/core/constraints.h b/src/core/constraints.h index 0bea43d11..07c65290c 100644 --- a/src/core/constraints.h +++ b/src/core/constraints.h @@ -40,7 +40,6 @@ typedef enum } MetaMoveResizeFlags; void meta_window_constrain (MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, int resize_gravity, const MetaRectangle *orig, diff --git a/src/core/place.c b/src/core/place.c index 7835deeef..a2c7df3c7 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -74,7 +74,6 @@ northwestcmp (gconstpointer a, gconstpointer b) static void find_next_cascade (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ GList *windows, int x, @@ -105,10 +104,13 @@ find_next_cascade (MetaWindow *window, * manually cascade. */ #define CASCADE_FUZZ 15 - if (borders) + if (window->frame) { - x_threshold = MAX (borders->visible.left, CASCADE_FUZZ); - y_threshold = MAX (borders->visible.top, CASCADE_FUZZ); + MetaFrameBorders borders; + + meta_frame_calc_borders (window->frame, &borders); + x_threshold = MAX (borders.visible.left, CASCADE_FUZZ); + y_threshold = MAX (borders.visible.top, CASCADE_FUZZ); } else { @@ -209,7 +211,6 @@ find_next_cascade (MetaWindow *window, static void find_most_freespace (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ MetaWindow *focus_window, int x, @@ -321,7 +322,6 @@ window_overlaps_focus_window (MetaWindow *window) static void avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, - MetaFrameBorders *borders, int *x, int *y) { @@ -350,7 +350,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, meta_window_same_application (window, focus_window) && window_overlaps_focus_window (window)) { - find_most_freespace (window, borders, focus_window, *x, *y, x, y); + find_most_freespace (window, focus_window, *x, *y, x, y); meta_topic (META_DEBUG_PLACEMENT, "Dialog window %s was denied focus but may be modal " "to the focus window; had to move it to avoid the " @@ -478,7 +478,6 @@ center_tile_rect_in_area (MetaRectangle *rect, */ static gboolean find_first_fit (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ GList *windows, int monitor, @@ -602,7 +601,6 @@ find_first_fit (MetaWindow *window, void meta_window_place (MetaWindow *window, - MetaFrameBorders *borders, int x, int y, int *new_x, @@ -611,13 +609,6 @@ meta_window_place (MetaWindow *window, GList *windows; const MetaMonitorInfo *xi; - /* frame member variables should NEVER be used in here, only - * MetaFrameBorders. But remember borders == NULL - * for undecorated windows. Also, this function should - * NEVER have side effects other than computing the - * placement coordinates. - */ - meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); windows = NULL; @@ -706,7 +697,7 @@ meta_window_place (MetaWindow *window, { meta_topic (META_DEBUG_PLACEMENT, "Not placing window with PPosition or USPosition set\n"); - avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); + avoid_being_obscured_as_second_modal_dialog (window, &x, &y); goto done_no_constraints; } } @@ -745,7 +736,7 @@ meta_window_place (MetaWindow *window, meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n", window->desc); - avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); + avoid_being_obscured_as_second_modal_dialog (window, &x, &y); goto done; } @@ -816,7 +807,7 @@ meta_window_place (MetaWindow *window, x = xi->rect.x; y = xi->rect.y; - if (find_first_fit (window, borders, windows, + if (find_first_fit (window, windows, xi->number, x, y, &x, &y)) goto done_check_denied_focus; @@ -850,7 +841,7 @@ meta_window_place (MetaWindow *window, * fully overlapping window (e.g. starting multiple terminals) * */ if (x == xi->rect.x && y == xi->rect.y) - find_next_cascade (window, borders, windows, x, y, &x, &y); + find_next_cascade (window, windows, x, y, &x, &y); done_check_denied_focus: /* If the window is being denied focus and isn't a transient of the @@ -881,7 +872,7 @@ meta_window_place (MetaWindow *window, x = xi->rect.x; y = xi->rect.y; - found_fit = find_first_fit (window, borders, focus_window_list, + found_fit = find_first_fit (window, focus_window_list, xi->number, x, y, &x, &y); g_list_free (focus_window_list); @@ -891,7 +882,7 @@ meta_window_place (MetaWindow *window, * as possible. */ if (!found_fit) - find_most_freespace (window, borders, focus_window, x, y, &x, &y); + find_most_freespace (window, focus_window, x, y, &x, &y); } done: diff --git a/src/core/place.h b/src/core/place.h index 7a8c12699..d9647e25b 100644 --- a/src/core/place.h +++ b/src/core/place.h @@ -28,7 +28,6 @@ #include "frame.h" void meta_window_place (MetaWindow *window, - MetaFrameBorders *borders, int x, int y, int *new_x, diff --git a/src/core/window.c b/src/core/window.c index f7b62841e..e98aa843e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5118,7 +5118,6 @@ meta_window_move_resize_internal (MetaWindow *window, if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) { meta_window_constrain (window, - window->frame ? &borders : NULL, flags, gravity, &old_rect, @@ -6056,6 +6055,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, *client_rect = *frame_rect; + /* The support for G_MAXINT here to mean infinity is a convenience for + * constraints.c:get_size_limits() and not something that we provide + * in other locations or document. + */ if (window->frame) { MetaFrameBorders borders; @@ -6063,8 +6066,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, client_rect->x -= borders.visible.left; client_rect->y -= borders.visible.top; - client_rect->width += borders.visible.left + borders.visible.right; - client_rect->height += borders.visible.top + borders.visible.bottom; + if (client_rect->width != G_MAXINT) + client_rect->width += borders.visible.left + borders.visible.right; + if (client_rect->height != G_MAXINT) + client_rect->height += borders.visible.top + borders.visible.bottom; } else { @@ -6073,8 +6078,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, const GtkBorder *extents = &window->custom_frame_extents; client_rect->x += extents->left; client_rect->y += extents->top; - client_rect->width -= extents->left + extents->right; - client_rect->height -= extents->top + extents->bottom; + if (client_rect->width != G_MAXINT) + client_rect->width -= extents->left + extents->right; + if (client_rect->height != G_MAXINT) + client_rect->height -= extents->top + extents->bottom; } } }