constrain placement to try to keep windows from going offscreen to the

2002-09-27  Havoc Pennington  <hp@pobox.com>

	* src/place.c (constrain_placement): constrain placement to try to
	keep windows from going offscreen to the right/bottom

	* src/stack.c (compute_layer): rearrange the logic here to say
	that a window must always be in at least as high a layer as any of
	its transient parents or group members, rather than special-casing
	fullscreen. Also, group_member_is_fullscreen was leaking the list
	of group members every time, a fairly major memory leak.
This commit is contained in:
Havoc Pennington 2002-09-28 03:11:04 +00:00 committed by Havoc Pennington
parent 5ae85e9c07
commit efc82ee1b9
3 changed files with 142 additions and 45 deletions

View File

@ -1,3 +1,14 @@
2002-09-27 Havoc Pennington <hp@pobox.com>
* src/place.c (constrain_placement): constrain placement to try to
keep windows from going offscreen to the right/bottom
* src/stack.c (compute_layer): rearrange the logic here to say
that a window must always be in at least as high a layer as any of
its transient parents or group members, rather than special-casing
fullscreen. Also, group_member_is_fullscreen was leaking the list
of group members every time, a fairly major memory leak.
2002-09-27 Havoc Pennington <hp@redhat.com> 2002-09-27 Havoc Pennington <hp@redhat.com>
* src/themes/Makefile.am (THEMES): use AgingGorilla not Gorilla * src/themes/Makefile.am (THEMES): use AgingGorilla not Gorilla

View File

@ -576,7 +576,11 @@ constrain_placement (MetaWindow *window,
*/ */
MetaRectangle work_area; MetaRectangle work_area;
int nw_x, nw_y; 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 /* FIXME this is bogus because we get the current xinerama
* for the window based on its position, but we haven't * for the window based on its position, but we haven't
* placed it yet. * placed it yet.
@ -591,7 +595,17 @@ constrain_placement (MetaWindow *window,
nw_y += fgeom->top_height; nw_y += fgeom->top_height;
} }
/* Keep window from going off left edge, though we don't have /* 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. * this constraint once the window has been placed.
*/ */
if (x < nw_x) if (x < nw_x)

View File

@ -258,68 +258,131 @@ meta_stack_thaw (MetaStack *stack)
meta_stack_sync_to_server (stack); meta_stack_sync_to_server (stack);
} }
static gboolean /* Get layer ignoring any transient or group relationships */
group_member_is_fullscreen (MetaWindow *window) static MetaStackLayer
get_standalone_layer (MetaWindow *window)
{ {
GSList *members; MetaStackLayer layer;
MetaGroup *group;
GSList *tmp;
gboolean retval;
if (window->fullscreen)
return TRUE;
group = meta_window_get_group (window);
if (group == NULL)
return FALSE;
retval = FALSE;
members = meta_group_list_windows (group);
tmp = members;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->fullscreen)
{
retval = TRUE;
break;
}
tmp = tmp->next;
}
return retval;
}
static void
compute_layer (MetaWindow *window)
{
switch (window->type) switch (window->type)
{ {
case META_WINDOW_DESKTOP: case META_WINDOW_DESKTOP:
window->layer = META_LAYER_DESKTOP; layer = META_LAYER_DESKTOP;
break; break;
case META_WINDOW_DOCK: case META_WINDOW_DOCK:
/* still experimenting here */ /* still experimenting here */
window->layer = META_LAYER_DOCK; layer = META_LAYER_DOCK;
break; break;
case META_WINDOW_SPLASHSCREEN: case META_WINDOW_SPLASHSCREEN:
window->layer = META_LAYER_SPLASH; layer = META_LAYER_SPLASH;
break; break;
default: default:
if (window->has_focus && if (window->has_focus &&
meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
window->layer = META_LAYER_FOCUSED_WINDOW; layer = META_LAYER_FOCUSED_WINDOW;
else if (group_member_is_fullscreen (window)) else if (window->fullscreen)
window->layer = META_LAYER_FULLSCREEN; layer = META_LAYER_FULLSCREEN;
else else
window->layer = META_LAYER_NORMAL; layer = META_LAYER_NORMAL;
break; break;
} }
return layer;
}
static MetaStackLayer
get_maximum_layer_of_ancestor (MetaWindow *window)
{
MetaWindow *w;
MetaStackLayer max;
MetaStackLayer layer;
max = get_standalone_layer (window);
w = window;
while (w != NULL)
{
if (w->xtransient_for == None ||
w->transient_parent_is_root_window)
break;
w = meta_display_lookup_x_window (w->display, w->xtransient_for);
if (w == window)
break; /* Cute, someone thought they'd make a transient_for cycle */
/* w may be null... */
if (w != NULL)
{
layer = get_standalone_layer (w);
if (layer > max)
max = layer;
}
}
return max;
}
/* Note that this function can never use window->layer only
* get_standalone_layer, or we'd have issues.
*/
static MetaStackLayer
get_maximum_layer_in_group_or_ancestor (MetaWindow *window)
{
GSList *members;
MetaGroup *group;
GSList *tmp;
MetaStackLayer max;
MetaStackLayer layer;
max = META_LAYER_DESKTOP;
group = meta_window_get_group (window);
if (group != NULL)
members = meta_group_list_windows (group);
else
members = NULL;
tmp = members;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
layer = get_standalone_layer (w);
if (layer > max)
max = layer;
tmp = tmp->next;
}
g_slist_free (members);
layer = get_maximum_layer_of_ancestor (window);
if (layer > max)
max = layer;
return max;
}
static void
compute_layer (MetaWindow *window)
{
MetaStackLayer group_max;
window->layer = get_standalone_layer (window);
group_max = get_maximum_layer_in_group_or_ancestor (window);
if (group_max > window->layer)
{
meta_topic (META_DEBUG_STACK,
"Promoting window %s from layer %d to %d due to group or transiency\n",
window->desc, window->layer, group_max);
window->layer = group_max;
}
meta_topic (META_DEBUG_STACK, "Window %s on layer %d type = %d has_focus = %d\n", meta_topic (META_DEBUG_STACK, "Window %s on layer %d type = %d has_focus = %d\n",
window->desc, window->layer, window->desc, window->layer,
@ -689,6 +752,15 @@ meta_stack_sync_to_server (MetaStack *stack)
if (op->update_layer) if (op->update_layer)
{ {
/* FIXME when we move > 1 window into a new layer
* within a single stack freeze/thaw bracket,
* perhaps due to moving a whole window group,
* the ordering of the newly-added windows in the
* layer is not defined. So if you raise a whole group
* from the normal layer to the fullscreen layer, the
* windows in that group may get randomly reordered.
*/
compute_layer (op->window); compute_layer (op->window);
if (op->window->layer != old_layer) if (op->window->layer != old_layer)
@ -715,7 +787,7 @@ meta_stack_sync_to_server (MetaStack *stack)
/* We assume that ordering between changing layers /* We assume that ordering between changing layers
* and raise/lower is irrelevant; if you raise, then * and raise/lower is irrelevant; if you raise, then
* the layer turns out to be different, you still * the layer turns out to be different, you still
* raise inside the new layer * raise inside the new layer.
*/ */
if (op->raised) if (op->raised)
{ {