[gnome-terminal/wip/fmuellner/headerbar: 2/9] window: Support profiles from headerbar



commit d810ced5e0ead7ca83407aba5480c9aa1d0c9dd2
Author: Florian Müllner <fmuellner gnome org>
Date:   Sun Nov 4 21:30:47 2018 +0100

    window: Support profiles from headerbar
    
    The new-tab/new-window items cover a common case, but don't allow
    to switch between profiles or start a terminal with a particular
    one. Support both use cases by making appropriate actions available
    in a primary menu section and a drop-down next to the new-tab button
    if more than one profile has been set up.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756798

 src/terminal-app.c         | 74 ++++++++++++++++++++++++++++++++++++++++++++++
 src/terminal-app.h         |  2 ++
 src/terminal-headerbar.c   | 28 ++++++++++++++++++
 src/terminal-headerbar.ui  | 44 +++++++++++++++++++++------
 src/terminal-headermenu.ui |  1 +
 src/terminal-prefs.c       |  3 +-
 src/terminal.common.css    |  7 +++++
 7 files changed, 149 insertions(+), 10 deletions(-)
---
diff --git a/src/terminal-app.c b/src/terminal-app.c
index fc7ff4fd..fc963457 100644
--- a/src/terminal-app.c
+++ b/src/terminal-app.c
@@ -109,7 +109,11 @@ struct _TerminalApp
   GMenu *menubar_set_profile_section;
   GMenu *menubar_set_encoding_submenu;
 
+  GMenuModel *profilemenu;
   GMenuModel *headermenu;
+  GMenu *headermenu_set_profile_section;
+  GMenu *headermenu_set_encoding_submenu;
+
   GMenu *set_profile_menu;
 
   GtkClipboard *clipboard;
@@ -434,6 +438,27 @@ append_new_terminal_item (GMenu *section,
   g_menu_append_item (section, item);
 }
 
+static void
+fill_header_new_terminal_menu (GMenuModel *menu,
+                               ProfileData *data,
+                               guint n_profiles)
+{
+  gs_unref_object GMenu *section = NULL;
+
+  if (n_profiles <= 1)
+    return;
+
+  section = g_menu_new ();
+
+  for (guint i = 0; i < n_profiles; i++) {
+    menu_append_numbered (section, data[i].label, i + 1,
+                          "win.new-terminal",
+                          g_variant_new ("(ss)", "default", data[i].uuid));
+  }
+
+  g_menu_prepend_section (G_MENU (menu), _("New Terminal"), G_MENU_MODEL (section));
+}
+
 static void
 fill_new_terminal_section (TerminalApp *app,
                            GMenu *section,
@@ -497,6 +522,16 @@ terminal_app_update_profile_menus (TerminalApp *app)
                              G_MENU_MODEL (app->set_profile_menu));
     }
   }
+
+  if (app->headermenu != NULL) {
+    g_menu_remove_all (G_MENU (app->profilemenu));
+    fill_header_new_terminal_menu (app->profilemenu, profiles, n_profiles);
+    g_menu_remove_all (G_MENU (app->headermenu_set_profile_section));
+    if (app->set_profile_menu != NULL) {
+      g_menu_append_submenu (app->headermenu_set_profile_section, _("_Profile"),
+                             G_MENU_MODEL (app->set_profile_menu));
+    }
+  }
 }
 
 static GMenuModel *
@@ -534,7 +569,28 @@ terminal_app_create_headermenu (TerminalApp *app)
 {
   terminal_util_load_objects_resource ("/org/gnome/terminal/ui/headerbar-menu.ui",
                                        "headermenu", &app->headermenu,
+                                       "set-profile-section", &app->headermenu_set_profile_section,
+#if 0
+                                       "set-encoding-submenu", &app->headermenu_set_encoding_submenu,
+#endif
                                        NULL);
+
+#if 0
+  /* Install the encodings submenu */
+  terminal_encodings_append_menu (app->headermenu_set_encoding_submenu);
+#endif
+
+  /* Install profile sections */
+  terminal_app_update_profile_menus (app);
+}
+
+static void
+terminal_app_create_profilemenu (TerminalApp *app)
+{
+  app->profilemenu = G_MENU_MODEL (g_menu_new ());
+
+  /* Install profile sections */
+  terminal_app_update_profile_menus (app);
 }
 
 /* Clipboard */
@@ -784,7 +840,10 @@ terminal_app_finalize (GObject *object)
   g_clear_object (&app->menubar_new_terminal_section);
   g_clear_object (&app->menubar_set_profile_section);
   g_clear_object (&app->menubar_set_encoding_submenu);
+  g_clear_object (&app->profilemenu);
   g_clear_object (&app->headermenu);
+  g_clear_object (&app->headermenu_set_profile_section);
+  g_clear_object (&app->headermenu_set_encoding_submenu);
   g_clear_object (&app->set_profile_menu);
 
   terminal_accels_shutdown ();
@@ -1113,6 +1172,21 @@ terminal_app_get_headermenu (TerminalApp *app)
   return app->headermenu;
 }
 
+/**
+ * terminal_app_get_profilemenu:
+ * @app: a #TerminalApp
+ *
+ * Returns: (tranfer none): the main window headerbar profile menu as a #GMenuModel
+ */
+GMenuModel *
+terminal_app_get_profilemenu (TerminalApp *app)
+{
+  if (app->profilemenu == NULL)
+    terminal_app_create_profilemenu (app);
+
+  return app->profilemenu;
+}
+
 /**
  * terminal_app_get_profile_section:
  * @app: a #TerminalApp
diff --git a/src/terminal-app.h b/src/terminal-app.h
index 4e354e85..4030262f 100644
--- a/src/terminal-app.h
+++ b/src/terminal-app.h
@@ -103,6 +103,8 @@ GMenuModel *terminal_app_get_menubar (TerminalApp *app);
 
 GMenuModel *terminal_app_get_headermenu (TerminalApp *app);
 
+GMenuModel *terminal_app_get_profilemenu (TerminalApp *app);
+
 GMenuModel *terminal_app_get_profile_section (TerminalApp *app);
 
 gboolean terminal_app_get_menu_unified (TerminalApp *app);
diff --git a/src/terminal-headerbar.c b/src/terminal-headerbar.c
index 66173c20..dfe3dec4 100644
--- a/src/terminal-headerbar.c
+++ b/src/terminal-headerbar.c
@@ -37,6 +37,7 @@ struct _TerminalHeaderbarClass
 
 struct _TerminalHeaderbarPrivate
 {
+  GtkWidget *profilebutton;
   GtkWidget *menubutton;
 };
 
@@ -56,19 +57,45 @@ G_DEFINE_TYPE_WITH_PRIVATE (TerminalHeaderbar, terminal_headerbar, GTK_TYPE_HEAD
 
 #define PRIV(obj) ((TerminalHeaderbarPrivate *) terminal_headerbar_get_instance_private ((TerminalHeaderbar 
*)(obj)))
 
+static void
+profilemenu_items_changed_cb (GMenuModel *menu,
+                              guint       position G_GNUC_UNUSED,
+                              guint       removed G_GNUC_UNUSED,
+                              guint       added G_GNUC_UNUSED,
+                              gpointer    user_data)
+{
+  TerminalHeaderbar *headerbar = user_data;
+  TerminalHeaderbarPrivate *priv = PRIV (headerbar);
+
+  if (g_menu_model_get_n_items (menu) > 0)
+    gtk_widget_show (priv->profilebutton);
+  else
+    gtk_widget_hide (priv->profilebutton);
+}
+
 /* Class implementation */
 
 static void
 terminal_headerbar_init (TerminalHeaderbar *headerbar)
 {
+
   TerminalHeaderbarPrivate *priv = PRIV (headerbar);
   GtkWidget *widget = GTK_WIDGET (headerbar);
   TerminalApp *app = terminal_app_get ();
+  GMenuModel *profilemenu;
 
   gtk_widget_init_template (widget);
 
   gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (priv->menubutton),
                                   terminal_app_get_headermenu (app));
+
+  profilemenu = terminal_app_get_profilemenu (app);
+  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (priv->profilebutton),
+                                  profilemenu);
+
+  g_signal_connect (profilemenu, "items-changed",
+                    G_CALLBACK (profilemenu_items_changed_cb), headerbar);
+  profilemenu_items_changed_cb (profilemenu, 0, 0, 0, headerbar);
 }
 
 static void
@@ -124,6 +151,7 @@ terminal_headerbar_class_init (TerminalHeaderbarClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/terminal/ui/headerbar.ui");
   gtk_widget_class_bind_template_child_private (widget_class, TerminalHeaderbar, menubutton);
+  gtk_widget_class_bind_template_child_private (widget_class, TerminalHeaderbar, profilebutton);
 }
 
 /* public API */
diff --git a/src/terminal-headerbar.ui b/src/terminal-headerbar.ui
index 1e12ac51..b9268549 100644
--- a/src/terminal-headerbar.ui
+++ b/src/terminal-headerbar.ui
@@ -59,20 +59,46 @@
       </packing>
     </child>
     <child>
-      <object class="GtkButton">
+      <object class="GtkBox">
         <property name="visible">True</property>
-        <property name="focus_on_click">False</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">False</property>
-        <property name="action-name">win.new-terminal</property>
-        <property name="action-target">('tab','current')</property>
         <style>
-          <class name="image-button"/>
+          <class name="linked"/>
         </style>
         <child>
-          <object class="GtkImage">
+          <object class="GtkButton">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="action-name">win.new-terminal</property>
+            <property name="action-target">('tab','current')</property>
+            <style>
+              <class name="image-button"/>
+            </style>
+            <child>
+              <object class="GtkImage">
+                <property name="visible">True</property>
+                <property name="icon_name">tab-new-symbolic</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkMenuButton" id="profilebutton">
             <property name="visible">True</property>
-            <property name="icon_name">tab-new-symbolic</property>
+            <property name="focus_on_click">False</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <style>
+              <class name="image-button"/>
+              <class name="disclosure-button"/>
+            </style>
+            <child>
+              <object class="GtkImage">
+                <property name="visible">True</property>
+                <property name="icon_name">pan-down-symbolic</property>
+              </object>
+            </child>
           </object>
         </child>
       </object>
diff --git a/src/terminal-headermenu.ui b/src/terminal-headermenu.ui
index ed967c40..ebed75c6 100644
--- a/src/terminal-headermenu.ui
+++ b/src/terminal-headermenu.ui
@@ -23,6 +23,7 @@
         <attribute name="action">win.new-terminal</attribute>
         <attribute name="target" type="(ss)">('window', 'current')</attribute>
       </item>
+      <section id="set-profile-section" />
     </section>
     <section>
       <item>
diff --git a/src/terminal-prefs.c b/src/terminal-prefs.c
index f5262650..8b66ceec 100644
--- a/src/terminal-prefs.c
+++ b/src/terminal-prefs.c
@@ -848,7 +848,8 @@ terminal_prefs_show_preferences (GSettings *profile, const char *widget_name)
   gtk_widget_set_visible (theme_variant_combo, FALSE);
 #endif /* GTK+ 3.19 */
 
-  if (terminal_app_get_menu_unified (app)) {
+  if (terminal_app_get_menu_unified (app) ||
+      terminal_app_get_use_headerbar (app)) {
     g_settings_bind (settings,
                      TERMINAL_SETTING_NEW_TERMINAL_MODE_KEY,
                      new_terminal_mode_combo,
diff --git a/src/terminal.common.css b/src/terminal.common.css
index 1d4d41f0..8ec36889 100644
--- a/src/terminal.common.css
+++ b/src/terminal.common.css
@@ -7,3 +7,10 @@ terminal-window scrolledwindow overshoot.bottom
 {
   background: none;
 }
+
+.disclosure-button
+{
+  padding-left: 4px;
+  padding-right: 4px;
+  min-width: 0;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]