/* 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 (MetaWindow *window) { GSList *members; MetaGroup *group; GSList *tmp; MetaStackLayer max; MetaStackLayer layer; max = META_LAYER_DESKTOP; group = meta_window_get_group (window); if (group != NULL) members = meta_group_list_windows (group); else members = NULL; tmp = members; while (tmp != NULL) { MetaWindow *w = tmp->data; layer = get_standalone_layer (w); if (layer > max) max = layer; tmp = tmp->next; } g_slist_free (members); return max; }
/** * get_app_from_window_group: * @monitor: a #ShellWindowTracker * @window: a #MetaWindow * * Check other windows in the group for @window to see if we have * an application for one of them. * * Return value: (transfer full): A newly-referenced #ShellApp, or %NULL */ static ShellApp* get_app_from_window_group (ShellWindowTracker *monitor, MetaWindow *window) { ShellApp *result; GSList *group_windows; MetaGroup *group; GSList *iter; group = meta_window_get_group (window); if (group == NULL) return NULL; group_windows = meta_group_list_windows (group); result = NULL; /* Try finding a window in the group of type NORMAL; if we * succeed, use that as our source. */ for (iter = group_windows; iter; iter = iter->next) { MetaWindow *group_window = iter->data; if (meta_window_get_window_type (group_window) != META_WINDOW_NORMAL) continue; result = g_hash_table_lookup (monitor->window_to_app, group_window); if (result) break; } g_slist_free (group_windows); if (result) g_object_ref (result); return result; }
static void create_constraints (Constraint **constraints, GList *windows) { GList *tmp; tmp = windows; while (tmp != NULL) { MetaWindow *w = tmp->data; if (!WINDOW_IN_STACK (w)) { meta_topic (META_DEBUG_STACK, "Window %s not in the stack, not constraining it\n", w->desc); tmp = tmp->next; continue; } if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w)) { GSList *group_windows; GSList *tmp2; MetaGroup *group; group = meta_window_get_group (w); if (group != NULL) group_windows = meta_group_list_windows (group); else group_windows = NULL; tmp2 = group_windows; while (tmp2 != NULL) { MetaWindow *group_window = tmp2->data; if (!WINDOW_IN_STACK (group_window) || w->screen != group_window->screen || group_window->override_redirect) { tmp2 = tmp2->next; continue; } #if 0 /* old way of doing it */ if (!(meta_window_is_ancestor_of_transient (w, group_window)) && !WINDOW_TRANSIENT_FOR_WHOLE_GROUP (group_window)) /* note */;/*note*/ #else /* better way I think, so transient-for-group are constrained * only above non-transient-type windows in their group */ if (!WINDOW_HAS_TRANSIENT_TYPE (group_window)) #endif { meta_topic (META_DEBUG_STACK, "Constraining %s above %s as it's transient for its group\n", w->desc, group_window->desc); add_constraint (constraints, w, group_window); } tmp2 = tmp2->next; } g_slist_free (group_windows); } else if (w->transient_for != NULL) { MetaWindow *parent; parent = w->transient_for; if (parent && WINDOW_IN_STACK (parent)) { meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n", w->desc, parent->desc); add_constraint (constraints, w, parent); } } tmp = tmp->next; } }
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; }