mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 03:22:04 +00:00
Revamp placement policy for windows that are maximized when they are
2003-06-09 Rob Adams <robadams@ucla.edu> Revamp placement policy for windows that are maximized when they are mapped, including windows that set a hint to be maximized or windows that are auto-maximized using our heuristic. See #111902. * src/window.h: add new flag maximize_after_placement and new function meta_window_maximize_internal. * src/window.c (meta_window_new): initialize maximize_after_placement to FALSE and remove the automaximize heuristic. (meta_window_maximize_internal): new function accepts a saved_rect argument to be used as the new saved_rect for the window, and does not queue a move_resize. (meta_window_maximize): re-implement using meta_window_maximize_internal. (update_net_wm_state): If a window has a maximize hint set on startup set maximize_after_placement to TRUE * src/constraints.c (meta_window_constrain): Update the xinerama information in the ConstraintInfo after placing the window, and maximize the window after placement if window->maximize_after_placement * src/place.c (find_first_fit): take a natural xinerama list as an argument instead of generating it here (constrain_placement): remove function, since it is no longer needed (meta_window_place): generate the natural xinerama list here and pass it into find_first_fit. If find_first_fit fails, use the list to find empty xineramas where we can place windows that may be maximized later. This makes maximized windows follow the correct placement policy. Move the automaximize heuristic here.
This commit is contained in:
parent
3f6bad087d
commit
010e620a34
35
ChangeLog
35
ChangeLog
@ -1,3 +1,38 @@
|
||||
2003-06-09 Rob Adams <robadams@ucla.edu>
|
||||
|
||||
Revamp placement policy for windows that are maximized when they
|
||||
are mapped, including windows that set a hint to be maximized or
|
||||
windows that are auto-maximized using our heuristic. See #111902.
|
||||
|
||||
* src/window.h: add new flag maximize_after_placement and new
|
||||
function meta_window_maximize_internal.
|
||||
|
||||
* src/window.c (meta_window_new): initialize
|
||||
maximize_after_placement to FALSE and remove the automaximize
|
||||
heuristic.
|
||||
(meta_window_maximize_internal): new function accepts a saved_rect
|
||||
argument to be used as the new saved_rect for the window, and does
|
||||
not queue a move_resize.
|
||||
(meta_window_maximize): re-implement using
|
||||
meta_window_maximize_internal.
|
||||
(update_net_wm_state): If a window has a maximize hint set on
|
||||
startup set maximize_after_placement to TRUE
|
||||
|
||||
* src/constraints.c (meta_window_constrain): Update the xinerama
|
||||
information in the ConstraintInfo after placing the window, and
|
||||
maximize the window after placement if
|
||||
window->maximize_after_placement
|
||||
|
||||
* src/place.c (find_first_fit): take a natural xinerama list as an
|
||||
argument instead of generating it here
|
||||
(constrain_placement): remove function, since it is no longer
|
||||
needed
|
||||
(meta_window_place): generate the natural xinerama list here and
|
||||
pass it into find_first_fit. If find_first_fit fails, use the
|
||||
list to find empty xineramas where we can place windows that may
|
||||
be maximized later. This makes maximized windows follow the
|
||||
correct placement policy. Move the automaximize heuristic here.
|
||||
|
||||
2003-06-09 Rob Adams <robadams@ucla.edu>
|
||||
|
||||
* src/metacity-dialog.c (warn_about_no_sm_support): install an
|
||||
|
@ -1119,20 +1119,38 @@ meta_window_constrain (MetaWindow *window,
|
||||
!window->maximized &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
int x, y;
|
||||
MetaRectangle placed_rect = current;
|
||||
|
||||
meta_window_place (window, orig_fgeom, current.x, current.y,
|
||||
&x, &y);
|
||||
&placed_rect.x, &placed_rect.y);
|
||||
|
||||
/* placing the window may have changed the xinerama. Find the
|
||||
* new xinerama and update the ConstraintInfo
|
||||
*/
|
||||
info.xinerama = meta_screen_get_xinerama_for_rect (window->screen,
|
||||
&placed_rect);
|
||||
meta_window_get_work_area_for_xinerama (window,
|
||||
info.xinerama->number,
|
||||
&info.work_area_xinerama);
|
||||
update_position_limits (window, &info);
|
||||
|
||||
constrain_move (window, &info, ¤t,
|
||||
x - current.x,
|
||||
y - current.y,
|
||||
placed_rect.x - current.x,
|
||||
placed_rect.y - current.y,
|
||||
new);
|
||||
current = *new;
|
||||
|
||||
/* Ignore any non-placement movement */
|
||||
x_move_delta = 0;
|
||||
y_move_delta = 0;
|
||||
|
||||
}
|
||||
|
||||
if (window->maximize_after_placement &&
|
||||
window->placed)
|
||||
{
|
||||
window->maximize_after_placement = FALSE;
|
||||
meta_window_maximize_internal (window, new);
|
||||
}
|
||||
|
||||
/* Maximization, fullscreen, etc. are defined as a move followed by
|
||||
|
149
src/place.c
149
src/place.c
@ -404,6 +404,8 @@ find_first_fit (MetaWindow *window,
|
||||
MetaFrameGeometry *fgeom,
|
||||
/* visible windows on relevant workspaces */
|
||||
GList *windows,
|
||||
int* xineramas_list,
|
||||
int n_xineramas,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
@ -423,8 +425,6 @@ find_first_fit (MetaWindow *window,
|
||||
MetaRectangle rect;
|
||||
MetaRectangle work_area;
|
||||
int i;
|
||||
int* xineramas_list;
|
||||
int n_xineramas;
|
||||
|
||||
retval = FALSE;
|
||||
|
||||
@ -447,9 +447,6 @@ find_first_fit (MetaWindow *window,
|
||||
rect.height += fgeom->top_height + fgeom->bottom_height;
|
||||
}
|
||||
|
||||
meta_screen_get_natural_xinerama_list (window->screen,
|
||||
&xineramas_list,
|
||||
&n_xineramas);
|
||||
for (i = 0; i < n_xineramas; i++)
|
||||
{
|
||||
meta_topic (META_DEBUG_XINERAMA,
|
||||
@ -552,68 +549,11 @@ find_first_fit (MetaWindow *window,
|
||||
|
||||
out:
|
||||
|
||||
g_free (xineramas_list);
|
||||
g_list_free (below_sorted);
|
||||
g_list_free (right_sorted);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
constrain_placement (MetaWindow *window,
|
||||
MetaFrameGeometry *fgeom,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
int *new_y)
|
||||
{
|
||||
/* The purpose of this function is to apply constraints that are not
|
||||
* covered by window.c:constrain_position(), but should apply
|
||||
* whenever we are _placing_ a window regardless of placement algorithm.
|
||||
*/
|
||||
MetaRectangle work_area;
|
||||
int nw_x, nw_y;
|
||||
int offscreen_w, offscreen_h;
|
||||
MetaRectangle outer_rect;
|
||||
|
||||
meta_window_get_outer_rect (window, &outer_rect);
|
||||
|
||||
/* FIXME this is bogus because we get the current xinerama
|
||||
* for the window based on its position, but we haven't
|
||||
* placed it yet.
|
||||
*/
|
||||
meta_window_get_work_area_current_xinerama (window, &work_area);
|
||||
|
||||
nw_x = work_area.x;
|
||||
nw_y = work_area.y;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
nw_x += fgeom->left_width;
|
||||
nw_y += fgeom->top_height;
|
||||
}
|
||||
|
||||
/* Keep window from going off the bottom right, though we don't have
|
||||
* this constraint once the window has been placed
|
||||
*/
|
||||
offscreen_w = (outer_rect.x + outer_rect.width) - (work_area.x + work_area.width);
|
||||
if (offscreen_w > 0)
|
||||
nw_x -= offscreen_w;
|
||||
offscreen_h = (outer_rect.y + outer_rect.height) - (work_area.y + work_area.height);
|
||||
if (offscreen_h > 0)
|
||||
nw_y -= offscreen_h;
|
||||
|
||||
/* Keep window from going off left edge, though again we don't have
|
||||
* this constraint once the window has been placed.
|
||||
*/
|
||||
if (x < nw_x)
|
||||
x = nw_x;
|
||||
if (y < nw_y)
|
||||
y = nw_y;
|
||||
|
||||
*new_x = x;
|
||||
*new_y = y;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_place (MetaWindow *window,
|
||||
MetaFrameGeometry *fgeom,
|
||||
@ -624,6 +564,10 @@ meta_window_place (MetaWindow *window,
|
||||
{
|
||||
GList *windows;
|
||||
const MetaXineramaScreenInfo *xi;
|
||||
int* xineramas_list = NULL;
|
||||
int n_xineramas;
|
||||
int i;
|
||||
int placed_on = -1;
|
||||
|
||||
/* frame member variables should NEVER be used in here, only
|
||||
* MetaFrameGeometry. But remember fgeom == NULL
|
||||
@ -811,16 +755,87 @@ meta_window_place (MetaWindow *window,
|
||||
x = xi->x_origin;
|
||||
y = xi->y_origin;
|
||||
|
||||
if (find_first_fit (window, fgeom, windows, x, y, &x, &y))
|
||||
meta_screen_get_natural_xinerama_list (window->screen,
|
||||
&xineramas_list,
|
||||
&n_xineramas);
|
||||
|
||||
if (find_first_fit (window, fgeom, windows,
|
||||
xineramas_list, n_xineramas,
|
||||
x, y, &x, &y))
|
||||
goto done;
|
||||
|
||||
find_next_cascade (window, fgeom, windows, x, y, &x, &y);
|
||||
|
||||
/* This is a special-case origin-cascade so that windows that are
|
||||
* too large to fit onto a workspace (and which will be
|
||||
* automaximized later) will go onto an empty xinerama if one is
|
||||
* available.
|
||||
*/
|
||||
if (window->has_maximize_func && window->decorated &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
x = fgeom->left_width;
|
||||
y = fgeom->top_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_xineramas; i++)
|
||||
{
|
||||
MetaRectangle work_area;
|
||||
|
||||
meta_window_get_work_area_for_xinerama (window, xineramas_list[i], &work_area);
|
||||
|
||||
if (!rectangle_overlaps_some_window (&work_area, windows))
|
||||
{
|
||||
x += work_area.x;
|
||||
y += work_area.y;
|
||||
placed_on = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if the window wasn't placed at the origin of an empty xinerama,
|
||||
* cascade it onto the current xinerama
|
||||
*/
|
||||
if (placed_on == -1)
|
||||
{
|
||||
find_next_cascade (window, fgeom, windows, x, y, &x, &y);
|
||||
placed_on = 0;
|
||||
}
|
||||
|
||||
/* Maximize windows if they are too big for their work area (bit of
|
||||
* a hack here). Assume undecorated windows probably don't intend to
|
||||
* be maximized.
|
||||
*/
|
||||
if (window->has_maximize_func && window->decorated &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
MetaRectangle workarea;
|
||||
MetaRectangle outer;
|
||||
|
||||
meta_window_get_work_area_for_xinerama (window,
|
||||
xineramas_list[placed_on],
|
||||
&workarea);
|
||||
meta_window_get_outer_rect (window, &outer);
|
||||
|
||||
if (outer.width >= workarea.width &&
|
||||
outer.height >= workarea.height)
|
||||
{
|
||||
outer.x = x;
|
||||
outer.y = y;
|
||||
meta_window_maximize_internal (window, &outer);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
g_free (xineramas_list);
|
||||
g_list_free (windows);
|
||||
|
||||
constrain_placement (window, fgeom, x, y, &x, &y);
|
||||
|
||||
done_no_constraints:
|
||||
|
||||
*new_x = x;
|
||||
|
66
src/window.c
66
src/window.c
@ -417,6 +417,7 @@ meta_window_new (MetaDisplay *display,
|
||||
window->user_has_move_resized = FALSE;
|
||||
|
||||
window->maximized = FALSE;
|
||||
window->maximize_after_placement = FALSE;
|
||||
window->fullscreen = FALSE;
|
||||
window->on_all_workspaces = FALSE;
|
||||
window->shaded = FALSE;
|
||||
@ -695,28 +696,6 @@ meta_window_new (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
/* Maximize windows if they are too big for their work
|
||||
* area (bit of a hack here). Assume undecorated windows
|
||||
* probably don't intend to be maximized.
|
||||
*/
|
||||
if (window->has_maximize_func && window->decorated &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
MetaRectangle workarea;
|
||||
MetaRectangle outer;
|
||||
|
||||
if (!window->placed)
|
||||
meta_warning ("Metacity issue: using position-based current xinerama prior to placement\n");
|
||||
|
||||
meta_window_get_work_area_current_xinerama (window, &workarea);
|
||||
|
||||
meta_window_get_outer_rect (window, &outer);
|
||||
|
||||
if (outer.width >= workarea.width &&
|
||||
outer.height >= workarea.height)
|
||||
meta_window_maximize (window);
|
||||
}
|
||||
|
||||
/* Sync stack changes */
|
||||
meta_stack_thaw (window->screen->stack);
|
||||
|
||||
@ -1840,30 +1819,45 @@ meta_window_save_rect (MetaWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_maximize_internal (MetaWindow *window,
|
||||
MetaRectangle *saved_rect)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Maximizing %s\n", window->desc);
|
||||
|
||||
if (saved_rect != NULL)
|
||||
window->saved_rect = *saved_rect;
|
||||
else
|
||||
meta_window_save_rect (window);
|
||||
|
||||
window->maximized = TRUE;
|
||||
|
||||
recalc_window_features (window);
|
||||
set_net_wm_state (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_maximize (MetaWindow *window)
|
||||
{
|
||||
if (!window->maximized)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Maximizing %s\n", window->desc);
|
||||
|
||||
if (window->shaded)
|
||||
meta_window_unshade (window);
|
||||
|
||||
meta_window_save_rect (window);
|
||||
|
||||
window->maximized = TRUE;
|
||||
/* if the window hasn't been placed yet, we'll maximize it then
|
||||
*/
|
||||
if (!window->placed)
|
||||
{
|
||||
window->maximize_after_placement = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
meta_window_maximize_internal (window, NULL);
|
||||
|
||||
/* FIXME why did I put this here? */
|
||||
meta_window_raise (window);
|
||||
|
||||
/* move_resize with new maximization constraints
|
||||
*/
|
||||
meta_window_queue_move_resize (window);
|
||||
|
||||
recalc_window_features (window);
|
||||
set_net_wm_state (window);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4309,9 +4303,9 @@ update_net_wm_state (MetaWindow *window)
|
||||
if (atoms[i] == window->display->atom_net_wm_state_shaded)
|
||||
window->shaded = TRUE;
|
||||
else if (atoms[i] == window->display->atom_net_wm_state_maximized_horz)
|
||||
window->maximized = TRUE;
|
||||
window->maximize_after_placement = TRUE;
|
||||
else if (atoms[i] == window->display->atom_net_wm_state_maximized_vert)
|
||||
window->maximized = TRUE;
|
||||
window->maximize_after_placement = TRUE;
|
||||
else if (atoms[i] == window->display->atom_net_wm_state_modal)
|
||||
window->wm_state_modal = TRUE;
|
||||
else if (atoms[i] == window->display->atom_net_wm_state_skip_taskbar)
|
||||
|
@ -94,6 +94,7 @@ struct _MetaWindow
|
||||
|
||||
/* Whether we're maximized */
|
||||
guint maximized : 1;
|
||||
guint maximize_after_placement : 1;
|
||||
|
||||
/* Whether we're shaded */
|
||||
guint shaded : 1;
|
||||
@ -304,6 +305,8 @@ void meta_window_queue_calc_showing (MetaWindow *window);
|
||||
void meta_window_minimize (MetaWindow *window);
|
||||
void meta_window_unminimize (MetaWindow *window);
|
||||
void meta_window_maximize (MetaWindow *window);
|
||||
void meta_window_maximize_internal (MetaWindow *window,
|
||||
MetaRectangle *saved_rect);
|
||||
void meta_window_unmaximize (MetaWindow *window);
|
||||
void meta_window_shade (MetaWindow *window);
|
||||
void meta_window_unshade (MetaWindow *window);
|
||||
|
Loading…
Reference in New Issue
Block a user