mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -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>
|
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
|
||||||
|
18
src/place.c
18
src/place.c
@ -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)
|
||||||
|
158
src/stack.c
158
src/stack.c
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user