summaryrefslogtreecommitdiff
path: root/src/stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stack.c')
-rw-r--r--src/stack.c129
1 files changed, 122 insertions, 7 deletions
diff --git a/src/stack.c b/src/stack.c
index f55c6159..7fb02b16 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -251,6 +251,17 @@ is_focused_foreach (MetaWindow *window,
return TRUE;
}
+static gboolean
+windows_on_different_xinerama (MetaWindow *a,
+ MetaWindow *b)
+{
+ if (a->screen != b->screen)
+ return TRUE;
+
+ return meta_screen_get_xinerama_for_window (a->screen, a) !=
+ meta_screen_get_xinerama_for_window (b->screen, b);
+}
+
/* Get layer ignoring any transient or group relationships */
static MetaStackLayer
get_standalone_layer (MetaWindow *window)
@@ -272,10 +283,6 @@ get_standalone_layer (MetaWindow *window)
layer = META_LAYER_DOCK;
break;
- case META_WINDOW_SPLASHSCREEN:
- layer = META_LAYER_SPLASH;
- break;
-
default:
meta_window_foreach_transient (window,
is_focused_foreach,
@@ -283,9 +290,13 @@ get_standalone_layer (MetaWindow *window)
if (window->wm_state_below)
layer = META_LAYER_BOTTOM;
- else if ((window->has_focus || focused_transient ||
- (window == window->display->expected_focus_window)) &&
- (window->fullscreen || window_is_fullscreen_size (window)))
+ else if ((window->fullscreen || window_is_fullscreen_size (window)) &&
+ (window->has_focus || focused_transient ||
+ window == window->display->expected_focus_window ||
+ window->display->focus_window == NULL ||
+ (window->display->focus_window != NULL &&
+ windows_on_different_xinerama (window,
+ window->display->focus_window))))
layer = META_LAYER_FULLSCREEN;
else if (window->wm_state_above)
layer = META_LAYER_DOCK;
@@ -1466,6 +1477,110 @@ meta_stack_windows_cmp (MetaStack *stack,
return 0; /* not reached */
}
+static int
+compare_just_window_stack_position (void *a,
+ void *b)
+{
+ MetaWindow *window_a = a;
+ MetaWindow *window_b = b;
+
+ if (window_a->stack_position < window_b->stack_position)
+ return -1; /* move window_a earlier in list */
+ else if (window_a->stack_position > window_b->stack_position)
+ return 1;
+ else
+ return 0; /* not reached */
+}
+
+GList*
+meta_stack_get_positions (MetaStack *stack)
+{
+ GList *tmp;
+
+ /* Make sure to handle any adds or removes */
+ meta_stack_ensure_sorted (stack);
+
+ tmp = g_list_copy (stack->sorted);
+ tmp = g_list_sort (tmp, (GCompareFunc) compare_just_window_stack_position);
+
+ return tmp;
+}
+
+static gint
+compare_pointers (gconstpointer a,
+ gconstpointer b)
+{
+ if (a > b)
+ return 1;
+ else if (a < b)
+ return -1;
+ else
+ return 0;
+}
+
+static gboolean
+lists_contain_same_windows (GList *a,
+ GList *b)
+{
+ GList *copy1, *copy2;
+ GList *tmp1, *tmp2;
+
+ if (g_list_length (a) != g_list_length (b))
+ return FALSE;
+
+ tmp1 = copy1 = g_list_sort (g_list_copy (a), compare_pointers);
+ tmp2 = copy2 = g_list_sort (g_list_copy (b), compare_pointers);
+
+ while (tmp1 && tmp1->data == tmp2->data) /* tmp2 is non-NULL if tmp1 is */
+ {
+ tmp1 = tmp1->next;
+ tmp2 = tmp2->next;
+ }
+
+ g_list_free (copy1);
+ g_list_free (copy2);
+
+ return (tmp1 == NULL); /* tmp2 is non-NULL if tmp1 is */
+}
+
+void
+meta_stack_set_positions (MetaStack *stack,
+ GList *windows)
+{
+ int i;
+ GList *tmp;
+
+ /* Make sure any adds or removes aren't in limbo -- is this needed? */
+ meta_stack_ensure_sorted (stack);
+
+ if (!lists_contain_same_windows (windows, stack->sorted))
+ {
+ meta_warning ("This list of windows has somehow changed; not resetting "
+ "positions of the windows.\n");
+ return;
+ }
+
+ g_list_free (stack->sorted);
+ stack->sorted = g_list_copy (windows);
+
+ stack->need_resort = TRUE;
+ stack->need_constrain = TRUE;
+
+ i = 0;
+ tmp = windows;
+ while (tmp != NULL)
+ {
+ MetaWindow *w = tmp->data;
+ w->stack_position = i++;
+ tmp = tmp->next;
+ }
+
+ meta_topic (META_DEBUG_STACK,
+ "Reset the stack positions of (nearly) all windows\n");
+
+ meta_stack_sync_to_server (stack);
+}
+
void
meta_window_set_stack_position_no_sync (MetaWindow *window,
int position)