summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2019-11-29 16:32:23 +0200
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2019-11-29 16:32:23 +0200
commit186b2b7851208afb52b5239a36a86620d2fcd5c4 (patch)
tree259234e0faab8900c194b31a4e740c9363adeed2
parentaca1488c93e93338d29c1a44b31b1d2c6cd84600 (diff)
downloadmetacity-186b2b7851208afb52b5239a36a86620d2fcd5c4.tar.gz
stack: change how we choose default focus window
Commit f628d8f8901f46fa9e00707ae9d7ccfd1e85f427 changed how we choose the default focus window from the MRU to the topmost in the stack. Unfortunately most of the time this gives unexpected result if there are windows in META_LAYER_TOP and/or META_LAYER_FULLSCREEN layers. Re-sort windows using only stack position with one exception, keep windows in META_LAYER_DESKTOP layer last and apply two rules when choosing default window: - fullscreen window should not get focus if it is not on the same monitor as not_this_one window. If fullscreen window is on other monitor then windows under it also should not get focus. - desktop window should be always last choice.
-rw-r--r--src/core/stack.c86
1 files changed, 79 insertions, 7 deletions
diff --git a/src/core/stack.c b/src/core/stack.c
index dc96d818..8ca11cde 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -1155,6 +1155,53 @@ window_contains_point (MetaWindow *window,
return POINT_IN_RECT (root_x, root_y, rect);
}
+static int
+compare_default_focus_window_layer (MetaWindow *a,
+ MetaWindow *b)
+{
+ if (a->layer == META_LAYER_DESKTOP ||
+ b->layer == META_LAYER_DESKTOP)
+ {
+ if (a->layer < b->layer)
+ return 1;
+ else if (a->layer > b->layer)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+compare_default_focus_window_position (MetaWindow *a,
+ MetaWindow *b)
+{
+ if (a->stack_position < b->stack_position)
+ return 1;
+ else if (a->stack_position > b->stack_position)
+ return -1;
+
+ return 0;
+}
+
+static int
+compare_default_focus_window_func (gconstpointer a,
+ gconstpointer b)
+{
+ MetaWindow *window_a;
+ MetaWindow *window_b;
+ int result;
+
+ window_a = (MetaWindow *) a;
+ window_b = (MetaWindow *) b;
+
+ result = compare_default_focus_window_layer (window_a, window_b);
+
+ if (result == 0)
+ result = compare_default_focus_window_position (window_a, window_b);
+
+ return result;
+}
+
static MetaWindow*
get_default_focus_window (MetaStack *stack,
MetaWorkspace *workspace,
@@ -1163,20 +1210,28 @@ get_default_focus_window (MetaStack *stack,
int root_x,
int root_y)
{
+ MetaWindow *default_focus_window;
+ GList *tmp;
+ GList *l;
+
/* Find the topmost, focusable, mapped, window.
* not_this_one is being unfocused or going away, so exclude it.
*/
- GList *l;
+ default_focus_window = NULL;
stack_ensure_sorted (stack);
- /* top of this layer is at the front of the list */
- for (l = stack->sorted; l != NULL; l = l->next)
+ tmp = g_list_copy (stack->sorted);
+ tmp = g_list_sort (tmp, compare_default_focus_window_func);
+
+ for (l = tmp; l != NULL; l = l->next)
{
- MetaWindow *window = l->data;
+ MetaWindow *window;
+
+ window = l->data;
- if (!window)
+ if (window == NULL)
continue;
if (window == not_this_one)
@@ -1200,10 +1255,27 @@ get_default_focus_window (MetaStack *stack,
if (window->type == META_WINDOW_DOCK)
continue;
- return window;
+ if (window->fullscreen &&
+ not_this_one != NULL &&
+ default_focus_window == NULL &&
+ windows_on_different_monitor (window, not_this_one))
+ {
+ default_focus_window = window;
+ continue;
+ }
+
+ if (default_focus_window != NULL &&
+ (!windows_on_different_monitor (window, default_focus_window) ||
+ window->layer == META_LAYER_DESKTOP))
+ continue;
+
+ default_focus_window = window;
+ break;
}
- return NULL;
+ g_list_free (tmp);
+
+ return default_focus_window;
}
MetaWindow*