summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2026-02-09 22:24:52 -0500
committerVictor Kareh <[email protected]>2026-05-27 16:44:49 -0400
commita9c3deabfbd9a0e8001dda65e66e6b204ec6f47a (patch)
tree886be36891996c04785526b9b821b4676ca829d1 /src/core
parentc89fba64c65a281a2de4e90caea788ca5f29ce05 (diff)
downloadmarco-a9c3deabfbd9a0e8001dda65e66e6b204ec6f47a.tar.bz2
marco-a9c3deabfbd9a0e8001dda65e66e6b204ec6f47a.tar.xz
display: Add settings for Alt+Tab window placement
Add user settings to control how minimized and urgent windows are ordered during Alt+Tab. 1. alt-tab-minimized-placement: - 'mru': Mix minimized windows in MRU order - 'end': Show minimized windows last (current behavior, default) - 'hidden': Exclude minimized windows from Alt+Tab 2. alt-tab-urgent-placement: - 'start': Show all urgent windows first (current behavior, default) - 'mru': Mix urgent windows in MRU order Fixes #824 Closes #819
Diffstat (limited to 'src/core')
-rw-r--r--src/core/display.c127
-rw-r--r--src/core/prefs.c30
2 files changed, 93 insertions, 64 deletions
diff --git a/src/core/display.c b/src/core/display.c
index 4d1d9b7b..44ffde0d 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -4746,88 +4746,87 @@ meta_display_get_tab_list (MetaDisplay *display,
MetaScreen *screen,
MetaWorkspace *active_workspace)
{
- GList *tab_list, *mru_list, *l;
+ GList *tab_list, *window_list, *l;
+ GList *start_list, *mru_list, *end_list;
+ MetaMinimizedWindowPlacement minimized_placement;
+ MetaUrgentWindowPlacement urgent_placement;
+ gboolean all_workspaces;
g_return_val_if_fail (active_workspace != NULL, NULL);
- /* Build MRU list based on whether we use global or per-workspace */
- if (type == META_TAB_LIST_NORMAL_ALL_WORKSPACES)
- {
- /* Create global MRU list sorted by user_time */
- GSList *windows = meta_display_list_windows (display);
- GSList *w;
+ /* Get user preferences */
+ minimized_placement = meta_prefs_get_alt_tab_minimized_placement ();
+ urgent_placement = meta_prefs_get_alt_tab_urgent_placement ();
- mru_list = NULL;
- for (w = windows; w; w = w->next)
- {
- MetaWindow *window = w->data;
- if (window->screen == screen)
- mru_list = g_list_prepend (mru_list, window);
- }
+ /* Determine workspace scope */
+ all_workspaces = (type == META_TAB_LIST_NORMAL_ALL_WORKSPACES);
+ if (all_workspaces)
+ type = META_TAB_LIST_NORMAL;
- mru_list = g_list_sort (mru_list, mru_cmp);
+ /* Build a complete window list from all windows */
+ GSList *windows = meta_display_list_windows (display);
+ GSList *w;
- g_slist_free (windows);
- type = META_TAB_LIST_NORMAL;
- }
- else
+ window_list = NULL;
+ for (w = windows; w; w = w->next)
{
- mru_list = g_list_copy (active_workspace->mru_list);
+ MetaWindow *window = w->data;
+ if (window->screen == screen)
+ window_list = g_list_prepend (window_list, window);
}
+ window_list = g_list_sort (window_list, mru_cmp);
- tab_list = NULL;
- /* Windows sellout mode - MRU order. Collect unminimized windows
- * then minimized so minimized windows aren't in the way so much.
- */
- for (l = mru_list; l != NULL; l = l->next)
- {
- MetaWindow *window = l->data;
+ g_slist_free (windows);
- if (!window->minimized &&
- window->screen == screen &&
- IN_TAB_CHAIN (window, type))
- tab_list = g_list_prepend (tab_list, window);
- }
+ /* Initialize placement buckets */
+ start_list = NULL;
+ mru_list = NULL;
+ end_list = NULL;
- for (l = mru_list; l != NULL; l = l->next)
+ /* Windows sellout mode - MRU order. Collect windows into placement
+ * buckets to sort based on user preferences.
+ */
+ for (l = window_list; l != NULL; l = l->next)
{
MetaWindow *window = l->data;
+ gboolean include_window;
- if (window->minimized &&
- window->screen == screen &&
- IN_TAB_CHAIN (window, type))
- tab_list = g_list_prepend (tab_list, window);
- }
-
- tab_list = g_list_reverse (tab_list);
-
- {
- GSList *windows, *tmp;
- MetaWindow *l_window;
-
- windows = meta_display_list_windows (display);
- tmp = windows;
+ if (window->screen != screen || !IN_TAB_CHAIN (window, type))
+ continue;
- /* Go through all windows */
- while (tmp != NULL)
- {
- l_window=tmp->data;
+ /* Determine if window should be included based on workspace */
+ include_window = all_workspaces ||
+ meta_window_located_on_workspace (window, active_workspace);
- /* Check to see if it demands attention */
- if (l_window->wm_state_demands_attention &&
- l_window->workspace!=active_workspace &&
- IN_TAB_CHAIN (l_window, type))
- {
- /* if it does, add it to the popup */
- tab_list = g_list_prepend (tab_list, l_window);
- }
+ /* Handle minimized windows */
+ if (window->minimized && include_window)
+ {
+ if (minimized_placement == META_MINIMIZED_WINDOW_PLACEMENT_MRU)
+ mru_list = g_list_append (mru_list, window);
+ else if (minimized_placement == META_MINIMIZED_WINDOW_PLACEMENT_END)
+ end_list = g_list_append (end_list, window);
+ /* HIDDEN: skip */
+ }
+ /* Handle urgent windows */
+ else if (window->wm_state_demands_attention)
+ {
+ if (urgent_placement == META_URGENT_WINDOW_PLACEMENT_START)
+ start_list = g_list_append (start_list, window);
+ else
+ mru_list = g_list_append (mru_list, window);
+ }
+ /* Handle normal unminimized windows */
+ else if (include_window)
+ {
+ mru_list = g_list_append (mru_list, window);
+ }
+ }
- tmp = tmp->next;
- } /* End while tmp!=NULL */
- g_slist_free (windows);
- }
+ /* Concatenate buckets: start + MRU + end */
+ tab_list = g_list_concat (start_list, mru_list);
+ tab_list = g_list_concat (tab_list, end_list);
- g_list_free (mru_list);
+ g_list_free (window_list);
return tab_list;
}
diff --git a/src/core/prefs.c b/src/core/prefs.c
index e1e09153..65bd1228 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -123,6 +123,8 @@ static int icon_size = META_DEFAULT_ICON_SIZE;
static int alt_tab_max_columns = META_DEFAULT_ALT_TAB_MAX_COLUMNS;
static gboolean alt_tab_raise_windows = META_DEFAULT_ALT_TAB_RAISE_WINDOWS;
static gboolean alt_tab_expand_to_fit_title = META_DEFAULT_ALT_TAB_EXPAND_TO_FIT_TITLE;
+static MetaMinimizedWindowPlacement alt_tab_minimized_placement = META_DEFAULT_ALT_TAB_MINIMIZED_PLACEMENT;
+static MetaUrgentWindowPlacement alt_tab_urgent_placement = META_DEFAULT_ALT_TAB_URGENT_PLACEMENT;
static gboolean use_force_compositor_manager = FALSE;
static gboolean force_compositor_manager = FALSE;
static gboolean compositing_manager = FALSE;
@@ -350,6 +352,16 @@ static MetaEnumPreference preferences_enum[] =
META_PREF_PLACEMENT_MODE,
(gint *) &placement_mode,
},
+ { "alt-tab-minimized-placement",
+ KEY_GENERAL_SCHEMA,
+ META_PREF_ALT_TAB_MINIMIZED_PLACEMENT,
+ (gint *) &alt_tab_minimized_placement,
+ },
+ { "alt-tab-urgent-placement",
+ KEY_GENERAL_SCHEMA,
+ META_PREF_ALT_TAB_URGENT_PLACEMENT,
+ (gint *) &alt_tab_urgent_placement,
+ },
{ NULL, NULL, 0, NULL },
};
@@ -1190,6 +1202,18 @@ meta_prefs_get_alt_tab_raise_windows (void)
return alt_tab_raise_windows;
}
+MetaMinimizedWindowPlacement
+meta_prefs_get_alt_tab_minimized_placement (void)
+{
+ return alt_tab_minimized_placement;
+}
+
+MetaUrgentWindowPlacement
+meta_prefs_get_alt_tab_urgent_placement (void)
+{
+ return alt_tab_urgent_placement;
+}
+
gboolean
meta_prefs_is_in_skip_list (char *class)
{
@@ -1729,6 +1753,12 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_ALT_TAB_RAISE_WINDOWS:
return "ALT_TAB_RAISE_WINDOWS";
+ case META_PREF_ALT_TAB_MINIMIZED_PLACEMENT:
+ return "ALT_TAB_MINIMIZED_PLACEMENT";
+
+ case META_PREF_ALT_TAB_URGENT_PLACEMENT:
+ return "ALT_TAB_URGENT_PLACEMENT";
+
case META_PREF_COMPOSITING_MANAGER:
return "COMPOSITING_MANAGER";