diff options
Diffstat (limited to 'src/stack.c')
-rw-r--r-- | src/stack.c | 129 |
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) |