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
This commit is contained in:
Owen W. Taylor 2013-11-15 18:03:50 -05:00
parent a4a8f1f863
commit 097ee776c7
5 changed files with 52 additions and 91 deletions

View File

@ -118,8 +118,6 @@ typedef struct
{ {
MetaRectangle orig; MetaRectangle orig;
MetaRectangle current; MetaRectangle current;
MetaFrameBorders *borders;
gboolean must_free_borders;
ActionType action_type; ActionType action_type;
gboolean is_user_action; gboolean is_user_action;
@ -195,7 +193,6 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
static void setup_constraint_info (ConstraintInfo *info, static void setup_constraint_info (ConstraintInfo *info,
MetaWindow *window, MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,
@ -208,9 +205,8 @@ static void extend_by_frame (MetaWindow *window,
MetaRectangle *rect); MetaRectangle *rect);
static void unextend_by_frame (MetaWindow *window, static void unextend_by_frame (MetaWindow *window,
MetaRectangle *rect); MetaRectangle *rect);
static inline void get_size_limits (const MetaWindow *window, static inline void get_size_limits (MetaWindow *window,
const MetaFrameBorders *borders, gboolean include_frame,
gboolean include_frame,
MetaRectangle *min_size, MetaRectangle *min_size,
MetaRectangle *max_size); MetaRectangle *max_size);
@ -280,7 +276,6 @@ do_all_constraints (MetaWindow *window,
void void
meta_window_constrain (MetaWindow *window, meta_window_constrain (MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,
@ -303,7 +298,6 @@ meta_window_constrain (MetaWindow *window,
setup_constraint_info (&info, setup_constraint_info (&info,
window, window,
orig_borders,
flags, flags,
resize_gravity, resize_gravity,
orig, orig,
@ -333,19 +327,11 @@ meta_window_constrain (MetaWindow *window,
* if this was a user move or user move-and-resize operation. * if this was a user move or user move-and-resize operation.
*/ */
update_onscreen_requirements (window, &info); 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 static void
setup_constraint_info (ConstraintInfo *info, setup_constraint_info (ConstraintInfo *info,
MetaWindow *window, MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,
@ -357,18 +343,6 @@ setup_constraint_info (ConstraintInfo *info,
info->orig = *orig; info->orig = *orig;
info->current = *new; 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) if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
info->action_type = ACTION_MOVE_AND_RESIZE; info->action_type = ACTION_MOVE_AND_RESIZE;
else if (flags & META_IS_RESIZE_ACTION) else if (flags & META_IS_RESIZE_ACTION)
@ -524,7 +498,7 @@ place_window_if_needed(MetaWindow *window,
const MetaMonitorInfo *monitor_info; const MetaMonitorInfo *monitor_info;
meta_window_get_outer_rect (window, &placed_rect); 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); &placed_rect.x, &placed_rect.y);
did_placement = TRUE; did_placement = TRUE;
@ -588,10 +562,6 @@ place_window_if_needed(MetaWindow *window,
(window->maximize_vertically_after_placement ? (window->maximize_vertically_after_placement ?
META_MAXIMIZE_VERTICAL : 0), &info->current); 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) if (window->fullscreen_after_placement)
{ {
window->saved_rect = info->current; window->saved_rect = info->current;
@ -684,10 +654,13 @@ update_onscreen_requirements (MetaWindow *window,
*/ */
if (window->frame && window->decorated) if (window->frame && window->decorated)
{ {
MetaFrameBorders borders;
MetaRectangle titlebar_rect; MetaRectangle titlebar_rect;
meta_frame_calc_borders (window->frame, &borders);
titlebar_rect = info->current; titlebar_rect = info->current;
titlebar_rect.height = info->borders->visible.top; titlebar_rect.height = borders.visible.top;
old = window->require_titlebar_visible; old = window->require_titlebar_visible;
window->require_titlebar_visible = window->require_titlebar_visible =
meta_rectangle_overlaps_with_region (info->usable_screen_region, meta_rectangle_overlaps_with_region (info->usable_screen_region,
@ -718,15 +691,15 @@ unextend_by_frame (MetaWindow *window,
} }
static inline void static inline void
get_size_limits (const MetaWindow *window, get_size_limits (MetaWindow *window,
const MetaFrameBorders *borders, gboolean include_frame,
gboolean include_frame,
MetaRectangle *min_size, MetaRectangle *min_size,
MetaRectangle *max_size) MetaRectangle *max_size)
{ {
/* We pack the results into MetaRectangle structs just for convienience; we /* We pack the results into MetaRectangle structs just for convienience; we
* don't actually use the position of those rects. * 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->width = window->size_hints.min_width;
min_size->height = window->size_hints.min_height; min_size->height = window->size_hints.min_height;
max_size->width = window->size_hints.max_width; max_size->width = window->size_hints.max_width;
@ -734,22 +707,8 @@ get_size_limits (const MetaWindow *window,
if (include_frame) if (include_frame)
{ {
int fw = borders->visible.left + borders->visible.right; meta_window_client_rect_to_outer_rect (window, min_size, min_size);
int fh = borders->visible.top + borders->visible.bottom; meta_window_client_rect_to_outer_rect (window, max_size, max_size);
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;
} }
} }
@ -859,7 +818,7 @@ constrain_maximization (MetaWindow *window,
/* Check min size constraints; max size constraints are ignored for maximized /* Check min size constraints; max size constraints are ignored for maximized
* windows, as per bug 327543. * 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; hminbad = target_size.width < min_size.width && window->maximized_horizontally;
vminbad = target_size.height < min_size.height && window->maximized_vertically; vminbad = target_size.height < min_size.height && window->maximized_vertically;
if (hminbad || vminbad) if (hminbad || vminbad)
@ -918,7 +877,7 @@ constrain_tiling (MetaWindow *window,
/* Check min size constraints; max size constraints are ignored as for /* Check min size constraints; max size constraints are ignored as for
* maximized windows. * 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; hminbad = target_size.width < min_size.width;
vminbad = target_size.height < min_size.height; vminbad = target_size.height < min_size.height;
if (hminbad || vminbad) if (hminbad || vminbad)
@ -961,7 +920,7 @@ constrain_fullscreen (MetaWindow *window,
monitor = info->entire_monitor; 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_big = !meta_rectangle_could_fit_rect (&monitor, &min_size);
too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor); too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
if (too_big || too_small) if (too_big || too_small)
@ -1070,7 +1029,7 @@ constrain_size_limits (MetaWindow *window,
return TRUE; return TRUE;
/* Determine whether constraint is already satisfied; exit if it is */ /* 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 */ /* We ignore max-size limits for maximized windows; see #327543 */
if (window->maximized_horizontally) if (window->maximized_horizontally)
max_size.width = MAX (max_size.width, info->current.width); 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 */ /* Determine whether constraint applies; exit if it doesn't */
how_far_it_can_be_smushed = info->current; 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); extend_by_frame (window, &info->current);
if (info->action_type != ACTION_MOVE) if (info->action_type != ACTION_MOVE)
@ -1420,8 +1379,11 @@ constrain_titlebar_visible (MetaWindow *window,
*/ */
if (window->frame) if (window->frame)
{ {
bottom_amount = info->current.height + info->borders->visible.bottom; MetaFrameBorders borders;
vert_amount_onscreen = info->borders->visible.top; meta_frame_calc_borders (window->frame, &borders);
bottom_amount = info->current.height + borders.visible.bottom;
vert_amount_onscreen = borders.visible.top;
} }
else else
bottom_amount = vert_amount_offscreen; bottom_amount = vert_amount_offscreen;
@ -1495,8 +1457,11 @@ constrain_partially_onscreen (MetaWindow *window,
*/ */
if (window->frame) if (window->frame)
{ {
bottom_amount = info->current.height + info->borders->visible.bottom; MetaFrameBorders borders;
vert_amount_onscreen = info->borders->visible.top; meta_frame_calc_borders (window->frame, &borders);
bottom_amount = info->current.height + borders.visible.bottom;
vert_amount_onscreen = borders.visible.top;
} }
else else
bottom_amount = vert_amount_offscreen; bottom_amount = vert_amount_offscreen;

View File

@ -40,7 +40,6 @@ typedef enum
} MetaMoveResizeFlags; } MetaMoveResizeFlags;
void meta_window_constrain (MetaWindow *window, void meta_window_constrain (MetaWindow *window,
MetaFrameBorders *orig_borders,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,

View File

@ -74,7 +74,6 @@ northwestcmp (gconstpointer a, gconstpointer b)
static void static void
find_next_cascade (MetaWindow *window, find_next_cascade (MetaWindow *window,
MetaFrameBorders *borders,
/* visible windows on relevant workspaces */ /* visible windows on relevant workspaces */
GList *windows, GList *windows,
int x, int x,
@ -105,10 +104,13 @@ find_next_cascade (MetaWindow *window,
* manually cascade. * manually cascade.
*/ */
#define CASCADE_FUZZ 15 #define CASCADE_FUZZ 15
if (borders) if (window->frame)
{ {
x_threshold = MAX (borders->visible.left, CASCADE_FUZZ); MetaFrameBorders borders;
y_threshold = MAX (borders->visible.top, CASCADE_FUZZ);
meta_frame_calc_borders (window->frame, &borders);
x_threshold = MAX (borders.visible.left, CASCADE_FUZZ);
y_threshold = MAX (borders.visible.top, CASCADE_FUZZ);
} }
else else
{ {
@ -209,7 +211,6 @@ find_next_cascade (MetaWindow *window,
static void static void
find_most_freespace (MetaWindow *window, find_most_freespace (MetaWindow *window,
MetaFrameBorders *borders,
/* visible windows on relevant workspaces */ /* visible windows on relevant workspaces */
MetaWindow *focus_window, MetaWindow *focus_window,
int x, int x,
@ -321,7 +322,6 @@ window_overlaps_focus_window (MetaWindow *window)
static void static void
avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
MetaFrameBorders *borders,
int *x, int *x,
int *y) int *y)
{ {
@ -350,7 +350,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
meta_window_same_application (window, focus_window) && meta_window_same_application (window, focus_window) &&
window_overlaps_focus_window (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, meta_topic (META_DEBUG_PLACEMENT,
"Dialog window %s was denied focus but may be modal " "Dialog window %s was denied focus but may be modal "
"to the focus window; had to move it to avoid the " "to the focus window; had to move it to avoid the "
@ -478,7 +478,6 @@ center_tile_rect_in_area (MetaRectangle *rect,
*/ */
static gboolean static gboolean
find_first_fit (MetaWindow *window, find_first_fit (MetaWindow *window,
MetaFrameBorders *borders,
/* visible windows on relevant workspaces */ /* visible windows on relevant workspaces */
GList *windows, GList *windows,
int monitor, int monitor,
@ -602,7 +601,6 @@ find_first_fit (MetaWindow *window,
void void
meta_window_place (MetaWindow *window, meta_window_place (MetaWindow *window,
MetaFrameBorders *borders,
int x, int x,
int y, int y,
int *new_x, int *new_x,
@ -611,13 +609,6 @@ meta_window_place (MetaWindow *window,
GList *windows; GList *windows;
const MetaMonitorInfo *xi; 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); meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
windows = NULL; windows = NULL;
@ -706,7 +697,7 @@ meta_window_place (MetaWindow *window,
{ {
meta_topic (META_DEBUG_PLACEMENT, meta_topic (META_DEBUG_PLACEMENT,
"Not placing window with PPosition or USPosition set\n"); "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; 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", meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
window->desc); 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; goto done;
} }
@ -816,7 +807,7 @@ meta_window_place (MetaWindow *window,
x = xi->rect.x; x = xi->rect.x;
y = xi->rect.y; y = xi->rect.y;
if (find_first_fit (window, borders, windows, if (find_first_fit (window, windows,
xi->number, xi->number,
x, y, &x, &y)) x, y, &x, &y))
goto done_check_denied_focus; goto done_check_denied_focus;
@ -850,7 +841,7 @@ meta_window_place (MetaWindow *window,
* fully overlapping window (e.g. starting multiple terminals) * fully overlapping window (e.g. starting multiple terminals)
* */ * */
if (x == xi->rect.x && y == xi->rect.y) 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: done_check_denied_focus:
/* If the window is being denied focus and isn't a transient of the /* 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; x = xi->rect.x;
y = xi->rect.y; 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, xi->number,
x, y, &x, &y); x, y, &x, &y);
g_list_free (focus_window_list); g_list_free (focus_window_list);
@ -891,7 +882,7 @@ meta_window_place (MetaWindow *window,
* as possible. * as possible.
*/ */
if (!found_fit) 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: done:

View File

@ -28,7 +28,6 @@
#include "frame.h" #include "frame.h"
void meta_window_place (MetaWindow *window, void meta_window_place (MetaWindow *window,
MetaFrameBorders *borders,
int x, int x,
int y, int y,
int *new_x, int *new_x,

View File

@ -5118,7 +5118,6 @@ meta_window_move_resize_internal (MetaWindow *window,
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
{ {
meta_window_constrain (window, meta_window_constrain (window,
window->frame ? &borders : NULL,
flags, flags,
gravity, gravity,
&old_rect, &old_rect,
@ -6056,6 +6055,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window,
*client_rect = *frame_rect; *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) if (window->frame)
{ {
MetaFrameBorders borders; MetaFrameBorders borders;
@ -6063,8 +6066,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window,
client_rect->x -= borders.visible.left; client_rect->x -= borders.visible.left;
client_rect->y -= borders.visible.top; client_rect->y -= borders.visible.top;
client_rect->width += borders.visible.left + borders.visible.right; if (client_rect->width != G_MAXINT)
client_rect->height += borders.visible.top + borders.visible.bottom; 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 else
{ {
@ -6073,8 +6078,10 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window,
const GtkBorder *extents = &window->custom_frame_extents; const GtkBorder *extents = &window->custom_frame_extents;
client_rect->x += extents->left; client_rect->x += extents->left;
client_rect->y += extents->top; client_rect->y += extents->top;
client_rect->width -= extents->left + extents->right; if (client_rect->width != G_MAXINT)
client_rect->height -= extents->top + extents->bottom; client_rect->width -= extents->left + extents->right;
if (client_rect->height != G_MAXINT)
client_rect->height -= extents->top + extents->bottom;
} }
} }
} }