mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
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:
parent
5ae85e9c07
commit
efc82ee1b9
11
ChangeLog
11
ChangeLog
@ -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>
|
||||
|
||||
* src/themes/Makefile.am (THEMES): use AgingGorilla not Gorilla
|
||||
|
18
src/place.c
18
src/place.c
@ -576,7 +576,11 @@ constrain_placement (MetaWindow *window,
|
||||
*/
|
||||
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.
|
||||
@ -591,7 +595,17 @@ constrain_placement (MetaWindow *window,
|
||||
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.
|
||||
*/
|
||||
if (x < nw_x)
|
||||
|
158
src/stack.c
158
src/stack.c
@ -258,68 +258,131 @@ meta_stack_thaw (MetaStack *stack)
|
||||
meta_stack_sync_to_server (stack);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
group_member_is_fullscreen (MetaWindow *window)
|
||||
/* Get layer ignoring any transient or group relationships */
|
||||
static MetaStackLayer
|
||||
get_standalone_layer (MetaWindow *window)
|
||||
{
|
||||
GSList *members;
|
||||
MetaGroup *group;
|
||||
GSList *tmp;
|
||||
gboolean retval;
|
||||
|
||||
if (window->fullscreen)
|
||||
return TRUE;
|
||||
MetaStackLayer layer;
|
||||
|
||||
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)
|
||||
{
|
||||
case META_WINDOW_DESKTOP:
|
||||
window->layer = META_LAYER_DESKTOP;
|
||||
layer = META_LAYER_DESKTOP;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DOCK:
|
||||
/* still experimenting here */
|
||||
window->layer = META_LAYER_DOCK;
|
||||
layer = META_LAYER_DOCK;
|
||||
break;
|
||||
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
window->layer = META_LAYER_SPLASH;
|
||||
layer = META_LAYER_SPLASH;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (window->has_focus &&
|
||||
meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
|
||||
window->layer = META_LAYER_FOCUSED_WINDOW;
|
||||
else if (group_member_is_fullscreen (window))
|
||||
window->layer = META_LAYER_FULLSCREEN;
|
||||
layer = META_LAYER_FOCUSED_WINDOW;
|
||||
else if (window->fullscreen)
|
||||
layer = META_LAYER_FULLSCREEN;
|
||||
else
|
||||
window->layer = META_LAYER_NORMAL;
|
||||
layer = META_LAYER_NORMAL;
|
||||
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",
|
||||
window->desc, window->layer,
|
||||
@ -689,6 +752,15 @@ meta_stack_sync_to_server (MetaStack *stack)
|
||||
|
||||
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);
|
||||
|
||||
if (op->window->layer != old_layer)
|
||||
@ -715,7 +787,7 @@ meta_stack_sync_to_server (MetaStack *stack)
|
||||
/* We assume that ordering between changing layers
|
||||
* and raise/lower is irrelevant; if you raise, then
|
||||
* the layer turns out to be different, you still
|
||||
* raise inside the new layer
|
||||
* raise inside the new layer.
|
||||
*/
|
||||
if (op->raised)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user