window: Move placement code from the constraints path

This way, it's implemented as a special case in move_resize_internal,
which makes it a lot easier to manage.
This commit is contained in:
Jasper St. Pierre 2014-06-17 11:36:27 -04:00
parent 25d7e48077
commit dc6decefb5
2 changed files with 92 additions and 125 deletions

View File

@ -195,8 +195,6 @@ static void setup_constraint_info (ConstraintInfo *info,
int resize_gravity, int resize_gravity,
const MetaRectangle *orig, const MetaRectangle *orig,
MetaRectangle *new); MetaRectangle *new);
static void place_window_if_needed (MetaWindow *window,
ConstraintInfo *info);
static void update_onscreen_requirements (MetaWindow *window, static void update_onscreen_requirements (MetaWindow *window,
ConstraintInfo *info); ConstraintInfo *info);
@ -287,7 +285,6 @@ meta_window_constrain (MetaWindow *window,
resize_gravity, resize_gravity,
orig, orig,
new); new);
place_window_if_needed (window, &info);
while (!satisfied && priority <= PRIORITY_MAXIMUM) { while (!satisfied && priority <= PRIORITY_MAXIMUM) {
gboolean check_only = TRUE; gboolean check_only = TRUE;
@ -435,116 +432,6 @@ setup_constraint_info (ConstraintInfo *info,
info->entire_monitor.width, info->entire_monitor.height); info->entire_monitor.width, info->entire_monitor.height);
} }
static void
place_window_if_needed(MetaWindow *window,
ConstraintInfo *info)
{
gboolean did_placement;
/* Do placement if any, so we go ahead and apply position
* constraints in a move-only context. Don't place
* maximized/minimized/fullscreen windows until they are
* unmaximized, unminimized and unfullscreened.
*/
did_placement = FALSE;
if (!window->placed &&
window->calc_placement &&
!(window->maximized_horizontally ||
window->maximized_vertically) &&
!window->minimized &&
!window->fullscreen)
{
MetaRectangle orig_rect;
MetaRectangle placed_rect;
MetaWorkspace *cur_workspace;
const MetaMonitorInfo *monitor_info;
meta_window_get_frame_rect (window, &placed_rect);
orig_rect = info->orig;
meta_window_place (window, orig_rect.x, orig_rect.y,
&placed_rect.x, &placed_rect.y);
did_placement = TRUE;
/* placing the window may have changed the monitor. Find the
* new monitor and update the ConstraintInfo
*/
monitor_info =
meta_screen_get_monitor_for_rect (window->screen, &placed_rect);
info->entire_monitor = monitor_info->rect;
meta_window_get_work_area_for_monitor (window,
monitor_info->number,
&info->work_area_monitor);
cur_workspace = window->screen->active_workspace;
info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace,
monitor_info->number);
info->current.x = placed_rect.x;
info->current.y = placed_rect.y;
/* Since we just barely placed the window, there's no reason to
* consider any of the directions fixed.
*/
info->fixed_directions = FIXED_DIRECTION_NONE;
}
if (window->placed || did_placement)
{
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement ||
window->fullscreen_after_placement)
{
/* define a sane saved_rect so that the user can unmaximize or
* make unfullscreen to something reasonable.
*/
if (info->current.width >= info->work_area_monitor.width)
{
info->current.width = .75 * info->work_area_monitor.width;
info->current.x = info->work_area_monitor.x +
.125 * info->work_area_monitor.width;
}
if (info->current.height >= info->work_area_monitor.height)
{
info->current.height = .75 * info->work_area_monitor.height;
info->current.y = info->work_area_monitor.y +
.083 * info->work_area_monitor.height;
}
/* idle_move_resize() uses the unconstrained_rect, so make sure it
* uses the placed coordinates (bug #556696).
*/
window->unconstrained_rect = info->current;
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement)
meta_window_maximize_internal (window,
(window->maximize_horizontally_after_placement ?
META_MAXIMIZE_HORIZONTAL : 0 ) |
(window->maximize_vertically_after_placement ?
META_MAXIMIZE_VERTICAL : 0), &info->current);
if (window->fullscreen_after_placement)
{
window->saved_rect = info->current;
window->fullscreen = TRUE;
window->fullscreen_after_placement = FALSE;
g_object_notify (G_OBJECT (window), "fullscreen");
}
window->maximize_horizontally_after_placement = FALSE;
window->maximize_vertically_after_placement = FALSE;
}
if (window->minimize_after_placement)
{
meta_window_minimize (window);
window->minimize_after_placement = FALSE;
}
}
}
static void static void
update_onscreen_requirements (MetaWindow *window, update_onscreen_requirements (MetaWindow *window,
ConstraintInfo *info) ConstraintInfo *info)

View File

@ -3632,6 +3632,93 @@ meta_window_update_monitor (MetaWindow *window)
} }
} }
static gboolean
place_window_if_needed (MetaWindow *window,
MetaRectangle *unconstrained_rect)
{
/* Do placement if any, so we go ahead and apply position
* constraints in a move-only context. Don't place
* maximized/minimized/fullscreen windows until they are
* unmaximized, unminimized and unfullscreened.
*/
if (!window->placed &&
window->calc_placement &&
!(window->maximized_horizontally ||
window->maximized_vertically) &&
!window->minimized &&
!window->fullscreen)
{
meta_window_place (window,
unconstrained_rect->x,
unconstrained_rect->y,
&unconstrained_rect->x,
&unconstrained_rect->y);
return TRUE;
}
else
{
return FALSE;
}
}
static void
apply_after_placement_rules (MetaWindow *window)
{
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement ||
window->fullscreen_after_placement)
{
const MetaMonitorInfo *monitor_info;
MetaRectangle work_area_monitor;
monitor_info = meta_screen_get_monitor_for_rect (window->screen, &window->unconstrained_rect);
meta_window_get_work_area_for_monitor (window,
monitor_info->number,
&work_area_monitor);
/* define a sane saved_rect so that the user can unmaximize or
* make unfullscreen to something reasonable.
*/
if (window->unconstrained_rect.width >= work_area_monitor.width)
{
window->saved_rect.width = .75 * work_area_monitor.width;
window->saved_rect.x = work_area_monitor.x + .125 * work_area_monitor.width;
}
if (window->unconstrained_rect.height >= work_area_monitor.height)
{
window->saved_rect.height = .75 * work_area_monitor.height;
window->saved_rect.y = work_area_monitor.y + .083 * work_area_monitor.height;
}
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement)
{
meta_window_maximize_internal (window,
(window->maximize_horizontally_after_placement ? META_MAXIMIZE_HORIZONTAL : 0 ) |
(window->maximize_vertically_after_placement ? META_MAXIMIZE_VERTICAL : 0),
&window->saved_rect);
window->maximize_horizontally_after_placement = FALSE;
window->maximize_vertically_after_placement = FALSE;
}
if (window->fullscreen_after_placement)
{
window->fullscreen = TRUE;
window->fullscreen_after_placement = FALSE;
g_object_notify (G_OBJECT (window), "fullscreen");
}
}
if (window->minimize_after_placement)
{
meta_window_minimize (window);
window->minimize_after_placement = FALSE;
}
}
void void
meta_window_move_resize_internal (MetaWindow *window, meta_window_move_resize_internal (MetaWindow *window,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
@ -3669,8 +3756,6 @@ meta_window_move_resize_internal (MetaWindow *window,
*/ */
g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_WAYLAND_RESIZE)); g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_WAYLAND_RESIZE));
did_placement = !window->placed && window->calc_placement;
/* We don't need it in the idle queue anymore. */ /* We don't need it in the idle queue anymore. */
meta_window_unqueue (window, META_QUEUE_MOVE_RESIZE); meta_window_unqueue (window, META_QUEUE_MOVE_RESIZE);
@ -3698,10 +3783,15 @@ meta_window_move_resize_internal (MetaWindow *window,
unconstrained_rect.height = window->rect.height; unconstrained_rect.height = window->rect.height;
} }
did_placement = place_window_if_needed (window, &unconstrained_rect);
/* Save the unconstrained rectangle to the position we should be at /* Save the unconstrained rectangle to the position we should be at
* before constraints kick in. */ * before constraints kick in. */
window->unconstrained_rect = unconstrained_rect; window->unconstrained_rect = unconstrained_rect;
if (did_placement)
apply_after_placement_rules (window);
constrained_rect = unconstrained_rect; constrained_rect = unconstrained_rect;
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
{ {
@ -3715,16 +3805,6 @@ meta_window_move_resize_internal (MetaWindow *window,
&constrained_rect); &constrained_rect);
} }
/* If we did placement, then we need to save the position that the window
* was placed at to make sure that meta_window_move_resize_now places the
* window correctly.
*/
if (did_placement)
{
window->unconstrained_rect.x = constrained_rect.x;
window->unconstrained_rect.y = constrained_rect.y;
}
/* Do the protocol-specific move/resize logic */ /* Do the protocol-specific move/resize logic */
META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, unconstrained_rect, constrained_rect, flags, &result); META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, unconstrained_rect, constrained_rect, flags, &result);