diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/place.c | 18 | ||||
-rw-r--r-- | src/stack.c | 152 |
2 files changed, 128 insertions, 42 deletions
diff --git a/src/place.c b/src/place.c index 3331409a..7c9a2a60 100644 --- a/src/place.c +++ b/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) diff --git a/src/stack.c b/src/stack.c index e9b4b466..aa9f0363 100644 --- a/src/stack.c +++ b/src/stack.c @@ -258,67 +258,130 @@ 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) +{ + MetaStackLayer layer; + + switch (window->type) + { + case META_WINDOW_DESKTOP: + layer = META_LAYER_DESKTOP; + break; + + case META_WINDOW_DOCK: + /* still experimenting here */ + layer = META_LAYER_DOCK; + break; + + case META_WINDOW_SPLASHSCREEN: + layer = META_LAYER_SPLASH; + break; + + default: + if (window->has_focus && + meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) + layer = META_LAYER_FOCUSED_WINDOW; + else if (window->fullscreen) + layer = META_LAYER_FULLSCREEN; + else + 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; - gboolean retval; - - if (window->fullscreen) - return TRUE; + MetaStackLayer max; + MetaStackLayer layer; + + max = META_LAYER_DESKTOP; group = meta_window_get_group (window); - if (group == NULL) - return FALSE; - retval = FALSE; - members = meta_group_list_windows (group); + if (group != NULL) + members = meta_group_list_windows (group); + else + members = NULL; + tmp = members; while (tmp != NULL) { MetaWindow *w = tmp->data; - if (w->fullscreen) - { - retval = TRUE; - break; - } - + layer = get_standalone_layer (w); + if (layer > max) + max = layer; + tmp = tmp->next; } - return retval; + g_slist_free (members); + + layer = get_maximum_layer_of_ancestor (window); + if (layer > max) + max = layer; + + return max; } static void compute_layer (MetaWindow *window) { - switch (window->type) - { - case META_WINDOW_DESKTOP: - window->layer = META_LAYER_DESKTOP; - break; + MetaStackLayer group_max; - case META_WINDOW_DOCK: - /* still experimenting here */ - window->layer = META_LAYER_DOCK; - break; + window->layer = get_standalone_layer (window); + group_max = get_maximum_layer_in_group_or_ancestor (window); - case META_WINDOW_SPLASHSCREEN: - window->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; - else - window->layer = META_LAYER_NORMAL; - break; + 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", @@ -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) { |