static MetaWindow* get_default_focus_window (MetaStack *stack, MetaWorkspace *workspace, MetaWindow *not_this_one, gboolean must_be_at_point, int root_x, int root_y) { /* Find the topmost, focusable, mapped, window. * not_this_one is being unfocused or going away, so exclude it. * Also, prefer to focus transient parent of not_this_one, * or top window in same group as not_this_one. */ MetaWindow *transient_parent; MetaWindow *topmost_in_group; MetaWindow *topmost_overall; MetaGroup *not_this_one_group; GList *l; transient_parent = NULL; topmost_in_group = NULL; topmost_overall = NULL; if (not_this_one) not_this_one_group = meta_window_get_group (not_this_one); else not_this_one_group = 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) { MetaWindow *window = l->data; if (!window) continue; if (window == not_this_one) continue; if (window->unmaps_pending > 0) continue; if (window->minimized) continue; if (window->unmanaging) continue; if (!(window->input || window->take_focus)) continue; if (workspace != NULL && !meta_window_located_on_workspace (window, workspace)) continue; if (must_be_at_point && !window_contains_point (window, root_x, root_y)) continue; if (not_this_one != NULL) { if (transient_parent == NULL && meta_window_get_transient_for (not_this_one) == window) transient_parent = window; if (topmost_in_group == NULL && not_this_one_group != NULL && not_this_one_group == meta_window_get_group (window)) topmost_in_group = window; } if (topmost_overall == NULL && window->type != META_WINDOW_DOCK) topmost_overall = window; /* We could try to bail out early here for efficiency in * some cases, but it's just not worth the code. */ } if (transient_parent) return transient_parent; else if (topmost_in_group) return topmost_in_group; else if (topmost_overall) return topmost_overall; else return NULL; }
static MetaWindow* get_default_focus_window (MetaStack *stack, MetaWorkspace *workspace, MetaWindow *not_this_one, gboolean must_be_at_point, int root_x, int root_y) { /* Find the topmost, focusable, mapped, window. * not_this_one is being unfocused or going away, so exclude it. * Also, prefer to focus transient parent of not_this_one, * or top window in same group as not_this_one. */ MetaWindow *topmost_dock; MetaWindow *transient_parent; MetaWindow *topmost_in_group; MetaWindow *topmost_overall; MetaGroup *not_this_one_group; GList *link; topmost_dock = NULL; transient_parent = NULL; topmost_in_group = NULL; topmost_overall = NULL; if (not_this_one) not_this_one_group = meta_window_get_group (not_this_one); else not_this_one_group = NULL; stack_ensure_sorted (stack); /* top of this layer is at the front of the list */ link = stack->sorted; while (link) { MetaWindow *window = link->data; if (window && window != not_this_one && (window->unmaps_pending == 0) && !window->minimized && (window->input || window->take_focus) && (workspace == NULL || meta_window_located_on_workspace (window, workspace))) { if (topmost_dock == NULL && window->type == META_WINDOW_DOCK) topmost_dock = window; if (not_this_one != NULL) { if (transient_parent == NULL && not_this_one->xtransient_for != None && not_this_one->xtransient_for == window->xwindow && (!must_be_at_point || window_contains_point (window, root_x, root_y))) transient_parent = window; if (topmost_in_group == NULL && not_this_one_group != NULL && not_this_one_group == meta_window_get_group (window) && (!must_be_at_point || window_contains_point (window, root_x, root_y))) topmost_in_group = window; } /* Note that DESKTOP windows can be topmost_overall so * we prefer focusing desktop or other windows over * focusing dock, even though docks are stacked higher. */ if (topmost_overall == NULL && window->type != META_WINDOW_DOCK && (!must_be_at_point || window_contains_point (window, root_x, root_y))) topmost_overall = window; /* We could try to bail out early here for efficiency in * some cases, but it's just not worth the code. */ } link = link->next; } if (transient_parent) return transient_parent; else if (topmost_in_group) return topmost_in_group; else if (topmost_overall) return topmost_overall; else return topmost_dock; }