From 604fa96f1026fbffd4dcf21a864076d068e6f56a Mon Sep 17 00:00:00 2001
From: osch <oliver at luced de>
Date: Tue, 14 May 2019 09:40:11 +0200
Subject: Make alt+tab max columns configurable and consider window label width

---
 src/core/prefs.c               | 36 +++++++++++++++++++++++++++
 src/core/screen.c              |  4 ++-
 src/include/common.h           |  6 +++++
 src/include/prefs.h            |  4 +++
 src/include/tabpopup.h         |  1 +
 src/org.mate.marco.gschema.xml | 11 +++++++++
 src/ui/tabpopup.c              | 56 ++++++++++++++++++++++++++++++++----------
 7 files changed, 104 insertions(+), 14 deletions(-)

(limited to 'src')

diff --git a/src/core/prefs.c b/src/core/prefs.c
index 2c93cf19..b9f0362b 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -53,6 +53,8 @@
 #define KEY_GENERAL_COMPOSITOR_FAST_ALT_TAB "compositing-fast-alt-tab"
 #define KEY_GENERAL_CENTER_NEW_WINDOWS "center-new-windows"
 #define KEY_GENERAL_ICON_SIZE "icon-size"
+#define KEY_GENERAL_ALT_TAB_MAX_COLUMNS "alt-tab-max-columns"
+#define KEY_GENERAL_ALT_TAB_EXPAND_TO_FIT_TITLE "alt-tab-expand-to-fit-title"
 
 #define KEY_COMMAND_SCHEMA "org.mate.Marco.keybinding-commands"
 #define KEY_COMMAND_PREFIX "command-"
@@ -116,6 +118,8 @@ static gboolean mate_animations = TRUE;
 static char *cursor_theme = NULL;
 static int   cursor_size = 24;
 static int   icon_size   = META_DEFAULT_ICON_SIZE;
+static int   alt_tab_max_columns = META_DEFAULT_ALT_TAB_MAX_COLUMNS;
+static gboolean alt_tab_expand_to_fit_title = META_DEFAULT_ALT_TAB_EXPAND_TO_FIT_TITLE;
 static gboolean use_force_compositor_manager = FALSE;
 static gboolean force_compositor_manager = FALSE;
 static gboolean compositing_manager = FALSE;
@@ -439,6 +443,12 @@ static MetaBoolPreference preferences_bool[] =
       &allow_top_tiling,
       FALSE,
     },
+    { "alt-tab-expand-to-fit-title",
+      KEY_GENERAL_SCHEMA,
+      META_PREF_ALT_TAB_EXPAND_TO_FIT_TITLE,
+      &alt_tab_expand_to_fit_title,
+      META_DEFAULT_ALT_TAB_EXPAND_TO_FIT_TITLE,
+    },
     { NULL, NULL, 0, NULL, FALSE },
   };
 
@@ -520,6 +530,14 @@ static MetaIntPreference preferences_int[] =
       &icon_size,
       META_MIN_ICON_SIZE, META_MAX_ICON_SIZE, META_DEFAULT_ICON_SIZE,
     },
+    { "alt-tab-max-columns",
+      KEY_GENERAL_SCHEMA,
+      META_PREF_ALT_TAB_MAX_COLUMNS,
+      &alt_tab_max_columns,
+      META_MIN_ALT_TAB_MAX_COLUMNS, 
+      META_MAX_ALT_TAB_MAX_COLUMNS, 
+      META_DEFAULT_ALT_TAB_MAX_COLUMNS,
+    },
     { NULL, NULL, 0, NULL, 0, 0, 0, },
   };
 
@@ -1122,6 +1140,18 @@ meta_prefs_get_icon_size (void)
   return icon_size;
 }
 
+int
+meta_prefs_get_alt_tab_max_columns (void)
+{
+  return alt_tab_max_columns;
+}
+
+gboolean
+meta_prefs_get_alt_tab_expand_to_fit_title (void)
+{
+  return alt_tab_expand_to_fit_title;
+}
+
 gboolean
 meta_prefs_is_in_skip_list (char *class)
 {
@@ -1637,6 +1667,12 @@ meta_preference_to_string (MetaPreference pref)
     case META_PREF_ICON_SIZE:
       return "ICON_SIZE";
 
+    case META_PREF_ALT_TAB_MAX_COLUMNS:
+      return "ALT_TAB_MAX_COLUMNS";
+
+    case META_PREF_ALT_TAB_EXPAND_TO_FIT_TITLE:
+      return "ALT_TAB_EXPAND_TO_FIT_TITLE";
+
     case META_PREF_COMPOSITING_MANAGER:
       return "COMPOSITING_MANAGER";
 
diff --git a/src/core/screen.c b/src/core/screen.c
index 8238d291..49e50506 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -1398,7 +1398,8 @@ meta_screen_ensure_tab_popup (MetaScreen      *screen,
 
   screen->tab_popup = meta_ui_tab_popup_new (entries,
                                              len,
-                                             5, /* FIXME */
+                                             meta_prefs_get_alt_tab_max_columns(),
+                                             meta_prefs_get_alt_tab_expand_to_fit_title(),
                                              border);
 
   for (i = 0; i < len; i++)
@@ -1470,6 +1471,7 @@ meta_screen_ensure_workspace_popup (MetaScreen *screen)
   screen->tab_popup = meta_ui_tab_popup_new (entries,
                                              len,
                                              layout.cols,
+                                             FALSE, /* expand_for_titles */
                                              BORDER_OUTLINE_WORKSPACE);
 
   g_free (entries);
diff --git a/src/include/common.h b/src/include/common.h
index 85e4f630..0dc2165e 100644
--- a/src/include/common.h
+++ b/src/include/common.h
@@ -347,4 +347,10 @@ typedef enum
   META_PLACEMENT_MODE_MANUAL
 } MetaPlacementMode;
 
+#define META_DEFAULT_ALT_TAB_MAX_COLUMNS 5
+#define META_MIN_ALT_TAB_MAX_COLUMNS 1
+#define META_MAX_ALT_TAB_MAX_COLUMNS 1024
+
+#define META_DEFAULT_ALT_TAB_EXPAND_TO_FIT_TITLE FALSE
+
 #endif
diff --git a/src/include/prefs.h b/src/include/prefs.h
index 7623dd19..515e9173 100644
--- a/src/include/prefs.h
+++ b/src/include/prefs.h
@@ -61,6 +61,8 @@ typedef enum
   META_PREF_CURSOR_THEME,
   META_PREF_CURSOR_SIZE,
   META_PREF_ICON_SIZE,
+  META_PREF_ALT_TAB_MAX_COLUMNS,
+  META_PREF_ALT_TAB_EXPAND_TO_FIT_TITLE,
   META_PREF_COMPOSITING_MANAGER,
   META_PREF_COMPOSITING_FAST_ALT_TAB,
   META_PREF_RESIZE_WITH_RIGHT_BUTTON,
@@ -131,6 +133,8 @@ void        meta_prefs_change_workspace_name (int         i,
 const char* meta_prefs_get_cursor_theme      (void);
 int         meta_prefs_get_cursor_size       (void);
 int         meta_prefs_get_icon_size         (void);
+int         meta_prefs_get_alt_tab_max_columns (void);
+gboolean    meta_prefs_get_alt_tab_expand_to_fit_title (void);
 gboolean    meta_prefs_get_compositing_manager (void);
 gboolean    meta_prefs_get_compositing_fast_alt_tab (void);
 gboolean    meta_prefs_get_center_new_windows  (void);
diff --git a/src/include/tabpopup.h b/src/include/tabpopup.h
index a93d1b2d..447264e1 100644
--- a/src/include/tabpopup.h
+++ b/src/include/tabpopup.h
@@ -59,6 +59,7 @@ struct _MetaTabEntry
 MetaTabPopup*   meta_ui_tab_popup_new          (const MetaTabEntry *entries,
                                                 int                 entry_count,
                                                 int                 width,
+                                                gboolean            expand_for_titles,
                                                 gboolean            outline);
 void            meta_ui_tab_popup_free         (MetaTabPopup       *popup);
 void            meta_ui_tab_popup_set_showing  (MetaTabPopup       *popup,
diff --git a/src/org.mate.marco.gschema.xml b/src/org.mate.marco.gschema.xml
index 98a91485..012109fe 100644
--- a/src/org.mate.marco.gschema.xml
+++ b/src/org.mate.marco.gschema.xml
@@ -202,6 +202,17 @@
         <summary>Icon size</summary>
         <description>Size of the application icons displayed in alt-tab popup window. The screen's scale factor is applied to this value.</description>
     </key>
+    <key name="alt-tab-max-columns" type="i">
+        <range min="1" max="1024"/>
+        <default>5</default>
+        <summary>Maximum number of columns in alt-tab popup window</summary>
+        <description>The popup window will be expanded to fit up to these many entries per row.</description>
+    </key>
+    <key name="alt-tab-expand-to-fit-title" type="b">
+        <default>false</default>
+        <summary>Expand the alt-tab popup window to fit longer window titles</summary>
+        <description>The popup window may be expanded up to the width determined by the config parameter 'alt-tab-max-columns'.</description>
+    </key>
   </schema>
 
   <schema id="org.mate.Marco.workspace-names" path="/org/mate/marco/workspace-names/">
diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c
index d7887ca8..18ee83d5 100644
--- a/src/ui/tabpopup.c
+++ b/src/ui/tabpopup.c
@@ -221,10 +221,11 @@ MetaTabPopup*
 meta_ui_tab_popup_new (const MetaTabEntry *entries,
                        int                 entry_count,
                        int                 width,
+                       gboolean            expand_for_titles,
                        gint                border)
 {
   MetaTabPopup *popup;
-  int i, left, right, top, bottom;
+  int i, left, top;
   int height;
   GtkWidget *grid;
   GtkWidget *vbox;
@@ -233,7 +234,7 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
   int max_label_width; /* the actual max width of the labels we create */
   AtkObject *obj;
   GdkScreen *screen;
-  int screen_width, scale;
+  int scale;
 
   popup = g_new (MetaTabPopup, 1);
 
@@ -278,7 +279,6 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
   popup->border = border;
 
   scale = gtk_widget_get_scale_factor (GTK_WIDGET (popup->window));
-  screen_width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen));
   for (i = 0; i < entry_count; ++i)
     {
       TabEntry* new_entry = tab_entry_new (&entries[i], border & BORDER_OUTLINE_WINDOW, scale);
@@ -325,13 +325,14 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
 
   max_label_width = 0;
   top = 0;
-  bottom = 1;
+  left = 0;
   tmp = popup->entries;
 
+  gtk_widget_show(popup->label); /* for gtk_widget_get_preferred_size() */
+  
   while (tmp && top < height)
     {
       left = 0;
-      right = 1;
 
       while (tmp && left < width)
         {
@@ -383,11 +384,9 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
           tmp = tmp->next;
 
           ++left;
-          ++right;
         }
 
       ++top;
-      ++bottom;
     }
 
   /* remove all the temporary text */
@@ -395,16 +394,47 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
   /* Make it so that we ellipsize if the text is too long */
   gtk_label_set_ellipsize (GTK_LABEL (popup->label), PANGO_ELLIPSIZE_END);
 
-  /* Limit the window size to no bigger than screen_width/4 */
-  if (max_label_width>(screen_width/4))
+  int default_window_width = 0; /* 0 == small as possible, truncate label */
+
+  if (expand_for_titles && top <= 1 && left < width)
     {
-      max_label_width = screen_width/4;
+      /* only one row partially filled with columns and additional_columns given
+         => calculate default_window_width to fit max_label_width if possible */
+      
+      GtkWidget **dummies = g_try_malloc(sizeof(GtkWidget*) * (width - left));
+      if (dummies)
+        {
+          int j;
+          for (j = 0; j < width - left; ++j) 
+            {
+              GtkWidget *dummy = gtk_label_new ("");
+              dummies[j] = dummy;
+              gtk_grid_attach (GTK_GRID (grid), dummy, left + j, top, 1, 1);
+            }
+            
+          gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
+          gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
+          gtk_widget_show_all(grid); /* for gtk_widget_get_preferred_size */
+    
+          GtkRequisition req;
+          gtk_widget_get_preferred_size (grid, &req, NULL);
+          default_window_width = req.width;
+    
+          for (j = 0; j < width - left; ++j) 
+            {
+              gtk_container_remove(GTK_CONTAINER(grid), dummies[j]);
+            }
+          g_free(dummies);
+          /* Limit the window size to no bigger than max_label_width */
+          if (max_label_width < default_window_width)
+            {
+              default_window_width = max_label_width;
+            }
+        }
     }
 
-  max_label_width += 20; /* add random padding */
-
   gtk_window_set_default_size (GTK_WINDOW (popup->window),
-                               max_label_width,
+                               default_window_width,
                                -1);
 
   return popup;
-- 
cgit v1.2.1