diff options
| author | Victor Kareh <[email protected]> | 2026-02-09 22:24:52 -0500 |
|---|---|---|
| committer | Victor Kareh <[email protected]> | 2026-05-27 16:44:49 -0400 |
| commit | a9c3deabfbd9a0e8001dda65e66e6b204ec6f47a (patch) | |
| tree | 886be36891996c04785526b9b821b4676ca829d1 /src/core | |
| parent | c89fba64c65a281a2de4e90caea788ca5f29ce05 (diff) | |
| download | marco-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.c | 127 | ||||
| -rw-r--r-- | src/core/prefs.c | 30 |
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"; |
