[gnome-builder] terminal: allow loading a terminal in the view stack



commit 813c99ac8d95e24e3af8979e084541649a919984
Author: Christian Hergert <christian hergert me>
Date:   Tue Jun 9 16:53:10 2015 -0700

    terminal: allow loading a terminal in the view stack
    
    They still can't be moved, but this at least things things in place for
    future improvements.

 plugins/terminal/Makefile.am                     |    7 ++
 plugins/terminal/gb-terminal-addin.c             |   40 ++++++++--
 plugins/terminal/gb-terminal-application-addin.c |   70 +++++++++++++++++
 plugins/terminal/gb-terminal-application-addin.h |   32 ++++++++
 plugins/terminal/gb-terminal-plugin.c            |   30 +++++++
 plugins/terminal/gb-terminal.c                   |   90 +++++++++-------------
 plugins/terminal/gb-terminal.h                   |    4 +-
 plugins/terminal/gb-terminal.ui                  |    2 +-
 src/util/gb-widget.c                             |   19 ++---
 src/util/gb-widget.h                             |    2 +-
 10 files changed, 221 insertions(+), 75 deletions(-)
---
diff --git a/plugins/terminal/Makefile.am b/plugins/terminal/Makefile.am
index 0840660..588c6b2 100644
--- a/plugins/terminal/Makefile.am
+++ b/plugins/terminal/Makefile.am
@@ -10,6 +10,9 @@ libterminal_la_SOURCES = \
        gb-terminal.h \
        gb-terminal-addin.c \
        gb-terminal-addin.h \
+       gb-terminal-application-addin.c \
+       gb-terminal-application-addin.h \
+       gb-terminal-plugin.c \
        $(NULL)
 
 nodist_libterminal_la_SOURCES = \
@@ -21,6 +24,10 @@ libterminal_la_CFLAGS = \
        $(BUILDER_CFLAGS) \
        -I$(top_srcdir)/libide \
        -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/app \
+       -I$(top_srcdir)/src/documents \
+       -I$(top_srcdir)/src/util \
+       -I$(top_srcdir)/src/views \
        -I$(top_srcdir)/src/workbench \
        -I$(top_srcdir)/src/workspace \
        -I$(top_srcdir)/contrib/egg \
diff --git a/plugins/terminal/gb-terminal-addin.c b/plugins/terminal/gb-terminal-addin.c
index 729d449..6f561c5 100644
--- a/plugins/terminal/gb-terminal-addin.c
+++ b/plugins/terminal/gb-terminal-addin.c
@@ -18,10 +18,9 @@
 
 #include <glib/gi18n.h>
 
-#include "gb-plugins.h"
 #include "gb-terminal.h"
 #include "gb-terminal-addin.h"
-#include "gb-terminal-resources.h"
+#include "gb-view-grid.h"
 #include "gb-workspace.h"
 
 struct _GbTerminalAddin
@@ -47,15 +46,45 @@ enum {
 static GParamSpec *gParamSpecs [LAST_PROP];
 
 static void
+new_terminal_activate_cb (GSimpleAction   *action,
+                          GVariant        *param,
+                          GbTerminalAddin *self)
+{
+  GtkWidget *terminal;
+  GtkWidget *grid;
+  GtkWidget *stack;
+
+  g_assert (G_IS_SIMPLE_ACTION (action));
+  g_assert (GB_IS_TERMINAL_ADDIN (self));
+
+  grid = gb_workbench_get_view_grid (self->workbench);
+  terminal = g_object_new (GB_TYPE_TERMINAL,
+                           "visible", TRUE,
+                           NULL);
+  stack = gb_view_grid_get_last_focus (GB_VIEW_GRID (grid));
+  gtk_container_add (GTK_CONTAINER (stack), GTK_WIDGET (terminal));
+  gtk_widget_grab_focus (GTK_WIDGET (terminal));
+}
+
+static void
 gb_terminal_addin_load (GbWorkbenchAddin *addin)
 {
   GbTerminalAddin *self = (GbTerminalAddin *)addin;
   GbWorkspace *workspace;
   GtkWidget *bottom_pane;
+  g_autoptr(GSimpleAction) action = NULL;
 
   g_assert (GB_IS_TERMINAL_ADDIN (self));
   g_assert (GB_IS_WORKBENCH (self->workbench));
 
+  action = g_simple_action_new ("new-terminal", NULL);
+  g_signal_connect_object (action,
+                           "activate",
+                           G_CALLBACK (new_terminal_activate_cb),
+                           self,
+                           0);
+  g_action_map_add_action (G_ACTION_MAP (self->workbench), G_ACTION (action));
+
   if (self->panel_terminal == NULL)
     {
       self->panel_terminal = g_object_new (GB_TYPE_TERMINAL,
@@ -80,6 +109,8 @@ gb_terminal_addin_unload (GbWorkbenchAddin *addin)
 
   g_assert (GB_IS_TERMINAL_ADDIN (self));
 
+  g_action_map_remove_action (G_ACTION_MAP (self->workbench), "new-terminal");
+
   if (self->panel_terminal != NULL)
     {
       GtkWidget *parent;
@@ -147,8 +178,3 @@ workbench_addin_iface_init (GbWorkbenchAddinInterface *iface)
   iface->load = gb_terminal_addin_load;
   iface->unload = gb_terminal_addin_unload;
 }
-
-GB_DEFINE_EMBEDDED_PLUGIN (gb_terminal,
-                           gb_terminal_get_resource (),
-                           "resource:///org/gnome/builder/plugins/terminal/gb-terminal.plugin",
-                           GB_DEFINE_PLUGIN_TYPE (GB_TYPE_WORKBENCH_ADDIN, GB_TYPE_TERMINAL_ADDIN))
diff --git a/plugins/terminal/gb-terminal-application-addin.c 
b/plugins/terminal/gb-terminal-application-addin.c
new file mode 100644
index 0000000..33053e0
--- /dev/null
+++ b/plugins/terminal/gb-terminal-application-addin.c
@@ -0,0 +1,70 @@
+/* gb-terminal-application-addin.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-terminal-application-addin.h"
+
+struct _GbTerminalApplicationAddin
+{
+  GObject parent_instance;
+};
+
+static void application_addin_iface_init (GbApplicationAddinInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GbTerminalApplicationAddin, gb_terminal_application_addin, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GB_TYPE_APPLICATION_ADDIN,
+                                                application_addin_iface_init))
+
+static void
+gb_terminal_application_addin_load (GbApplicationAddin *addin,
+                                    GbApplication      *application)
+{
+  const gchar *new_terminal_accels[] = { "<ctrl><shift>t", NULL };
+
+  g_assert (GB_IS_TERMINAL_APPLICATION_ADDIN (addin));
+  g_assert (GB_IS_APPLICATION (application));
+
+  gtk_application_set_accels_for_action (GTK_APPLICATION (application), "win.new-terminal",
+                                         new_terminal_accels);
+}
+
+static void
+gb_terminal_application_addin_unload (GbApplicationAddin *addin,
+                                      GbApplication      *application)
+{
+  g_assert (GB_IS_TERMINAL_APPLICATION_ADDIN (addin));
+  g_assert (GB_IS_APPLICATION (application));
+
+  gtk_application_set_accels_for_action (GTK_APPLICATION (application), "win.new-terminal", NULL);
+}
+
+static void
+gb_terminal_application_addin_class_init (GbTerminalApplicationAddinClass *klass)
+{
+}
+
+static void
+gb_terminal_application_addin_init (GbTerminalApplicationAddin *self)
+{
+}
+
+static void
+application_addin_iface_init (GbApplicationAddinInterface *iface)
+{
+  iface->load = gb_terminal_application_addin_load;
+  iface->unload = gb_terminal_application_addin_unload;
+}
diff --git a/plugins/terminal/gb-terminal-application-addin.h 
b/plugins/terminal/gb-terminal-application-addin.h
new file mode 100644
index 0000000..a2de62f
--- /dev/null
+++ b/plugins/terminal/gb-terminal-application-addin.h
@@ -0,0 +1,32 @@
+/* gb-terminal-application-addin.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_TERMINAL_APPLICATION_ADDIN_H
+#define GB_TERMINAL_APPLICATION_ADDIN_H
+
+#include "gb-application-addin.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_TERMINAL_APPLICATION_ADDIN (gb_terminal_application_addin_get_type())
+
+G_DECLARE_FINAL_TYPE (GbTerminalApplicationAddin, gb_terminal_application_addin, GB, 
TERMINAL_APPLICATION_ADDIN, GObject)
+
+G_END_DECLS
+
+#endif /* GB_TERMINAL_APPLICATION_ADDIN_H */
diff --git a/plugins/terminal/gb-terminal-plugin.c b/plugins/terminal/gb-terminal-plugin.c
new file mode 100644
index 0000000..e8ebce0
--- /dev/null
+++ b/plugins/terminal/gb-terminal-plugin.c
@@ -0,0 +1,30 @@
+/* gb-terminal-plugin.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-application-addin.h"
+#include "gb-plugins.h"
+#include "gb-terminal-addin.h"
+#include "gb-terminal-application-addin.h"
+#include "gb-terminal-resources.h"
+#include "gb-workbench-addin.h"
+
+GB_DEFINE_EMBEDDED_PLUGIN (gb_terminal,
+                           gb_terminal_get_resource (),
+                           "resource:///org/gnome/builder/plugins/terminal/gb-terminal.plugin",
+                           GB_DEFINE_PLUGIN_TYPE (GB_TYPE_APPLICATION_ADDIN, 
GB_TYPE_TERMINAL_APPLICATION_ADDIN)
+                           GB_DEFINE_PLUGIN_TYPE (GB_TYPE_WORKBENCH_ADDIN, GB_TYPE_TERMINAL_ADDIN))
diff --git a/plugins/terminal/gb-terminal.c b/plugins/terminal/gb-terminal.c
index 96c0370..b26fb97 100644
--- a/plugins/terminal/gb-terminal.c
+++ b/plugins/terminal/gb-terminal.c
@@ -21,27 +21,20 @@
 #include <vte/vte.h>
 
 #include "gb-terminal.h"
+#include "gb-view.h"
+#include "gb-widget.h"
 #include "gb-workbench.h"
 
 struct _GbTerminal
 {
-  GtkBin       parent_instance;
+  GbView       parent_instance;
 
   VteTerminal *terminal;
 
   guint        has_spawned : 1;
 };
 
-G_DEFINE_TYPE (GbTerminal, gb_terminal, GTK_TYPE_BIN)
-
-enum {
-  PROP_0,
-  LAST_PROP
-};
-
-#if 0
-static GParamSpec *gParamSpecs [LAST_PROP];
-#endif
+G_DEFINE_TYPE (GbTerminal, gb_terminal, GB_TYPE_VIEW)
 
 static void
 gb_terminal_respawn (GbTerminal *self)
@@ -102,8 +95,11 @@ child_exited_cb (VteTerminal *terminal,
   g_assert (VTE_IS_TERMINAL (terminal));
   g_assert (GB_IS_TERMINAL (self));
 
-  if (!gtk_widget_in_destruction (GTK_WIDGET (terminal)))
-    gb_terminal_respawn (self);
+  if (!gb_widget_activate_action (GTK_WIDGET (self), "view-stack", "close", NULL))
+    {
+      if (!gtk_widget_in_destruction (GTK_WIDGET (terminal)))
+        gb_terminal_respawn (self);
+    }
 }
 
 static void
@@ -194,8 +190,12 @@ gb_terminal_set_needs_attention (GbTerminal *self,
 
   parent = gtk_widget_get_parent (GTK_WIDGET (self));
 
-  if (GTK_IS_STACK (parent))
+  if (GTK_IS_STACK (parent) &&
+      !gtk_widget_in_destruction (GTK_WIDGET (self)) &&
+      !gtk_widget_in_destruction (GTK_WIDGET (self->terminal)) &&
+      !gtk_widget_in_destruction (parent))
     {
+
       gtk_container_child_set (GTK_CONTAINER (parent), GTK_WIDGET (self),
                                "needs-attention", !!needs_attention,
                                NULL);
@@ -211,8 +211,6 @@ notification_received_cb (VteTerminal *terminal,
   g_assert (VTE_IS_TERMINAL (terminal));
   g_assert (GB_IS_TERMINAL (self));
 
-  g_print ("notification_received_cb: %s: %s\n", summary, body);
-
   if (!gtk_widget_has_focus (GTK_WIDGET (terminal)))
     gb_terminal_set_needs_attention (self, TRUE);
 }
@@ -230,64 +228,48 @@ focus_in_event_cb (VteTerminal *terminal,
   return GDK_EVENT_PROPAGATE;
 }
 
-static gboolean
-focus_out_event_cb (VteTerminal *terminal,
-                    GdkEvent    *event,
-                    GbTerminal  *self)
+static const gchar *
+gb_terminal_get_title (GbView *view)
 {
-  g_assert (VTE_IS_TERMINAL (terminal));
-  g_assert (GB_IS_TERMINAL (self));
+  GbTerminal *self = (GbTerminal *)view;
 
-  gb_terminal_set_needs_attention (self, FALSE);
+  g_assert (GB_IS_TERMINAL (self));
 
-  return GDK_EVENT_PROPAGATE;
+  return vte_terminal_get_window_title (self->terminal);
 }
 
 static void
-gb_terminal_finalize (GObject *object)
+window_title_changed_cb (VteTerminal *terminal,
+                         GbTerminal  *self)
 {
-  G_OBJECT_CLASS (gb_terminal_parent_class)->finalize (object);
-}
+  g_assert (VTE_IS_TERMINAL (terminal));
+  g_assert (GB_IS_TERMINAL (self));
 
-static void
-gb_terminal_get_property (GObject    *object,
-                          guint       prop_id,
-                          GValue     *value,
-                          GParamSpec *pspec)
-{
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  g_object_notify (G_OBJECT (self), "title");
 }
 
 static void
-gb_terminal_set_property (GObject      *object,
-                          guint         prop_id,
-                          const GValue *value,
-                          GParamSpec   *pspec)
+gb_terminal_grab_focus (GtkWidget *widget)
 {
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  GbTerminal *self = (GbTerminal *)widget;
+
+  g_assert (GB_IS_TERMINAL (self));
+
+  gtk_widget_grab_focus (GTK_WIDGET (self->terminal));
 }
 
 static void
 gb_terminal_class_init (GbTerminalClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
-  object_class->finalize = gb_terminal_finalize;
-  object_class->get_property = gb_terminal_get_property;
-  object_class->set_property = gb_terminal_set_property;
+  GbViewClass *view_class = GB_VIEW_CLASS (klass);
 
   widget_class->realize = gb_terminal_realize;
   widget_class->get_preferred_width = gb_terminal_get_preferred_width;
   widget_class->get_preferred_height = gb_terminal_get_preferred_height;
+  widget_class->grab_focus = gb_terminal_grab_focus;
+
+  view_class->get_title = gb_terminal_get_title;
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/terminal/gb-terminal.ui");
   gtk_widget_class_bind_template_child (widget_class, GbTerminal, terminal);
@@ -322,8 +304,8 @@ gb_terminal_init (GbTerminal *self)
                            0);
 
   g_signal_connect_object (self->terminal,
-                           "focus-out-event",
-                           G_CALLBACK (focus_out_event_cb),
+                           "window-title-changed",
+                           G_CALLBACK (window_title_changed_cb),
                            self,
                            0);
 
diff --git a/plugins/terminal/gb-terminal.h b/plugins/terminal/gb-terminal.h
index 6519270..78e416d 100644
--- a/plugins/terminal/gb-terminal.h
+++ b/plugins/terminal/gb-terminal.h
@@ -21,11 +21,13 @@
 
 #include <gtk/gtk.h>
 
+#include "gb-view.h"
+
 G_BEGIN_DECLS
 
 #define GB_TYPE_TERMINAL (gb_terminal_get_type())
 
-G_DECLARE_FINAL_TYPE (GbTerminal, gb_terminal, GB, TERMINAL, GtkBin)
+G_DECLARE_FINAL_TYPE (GbTerminal, gb_terminal, GB, TERMINAL, GbView)
 
 G_END_DECLS
 
diff --git a/plugins/terminal/gb-terminal.ui b/plugins/terminal/gb-terminal.ui
index f250500..43e1604 100644
--- a/plugins/terminal/gb-terminal.ui
+++ b/plugins/terminal/gb-terminal.ui
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.16 -->
-  <template class="GbTerminal" parent="GtkBin">
+  <template class="GbTerminal" parent="GbView">
     <property name="visible">true</property>
     <child>
       <object class="GtkBox" id="box">
diff --git a/src/util/gb-widget.c b/src/util/gb-widget.c
index 4f73d84..66c10a8 100644
--- a/src/util/gb-widget.c
+++ b/src/util/gb-widget.c
@@ -210,7 +210,7 @@ gb_widget_fade_show (GtkWidget *widget)
     }
 }
 
-void
+gboolean
 gb_widget_activate_action (GtkWidget   *widget,
                            const gchar *prefix,
                            const gchar *action_name,
@@ -220,9 +220,9 @@ gb_widget_activate_action (GtkWidget   *widget,
   GtkWidget *toplevel;
   GActionGroup *group = NULL;
 
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (prefix);
-  g_return_if_fail (action_name);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+  g_return_val_if_fail (prefix, FALSE);
+  g_return_val_if_fail (action_name, FALSE);
 
   app = g_application_get_default ();
   toplevel = gtk_widget_get_toplevel (widget);
@@ -239,13 +239,10 @@ gb_widget_activate_action (GtkWidget   *widget,
   if (!group && g_str_equal (prefix, "app") && G_IS_ACTION_GROUP (app))
     group = G_ACTION_GROUP (app);
 
-  if (group)
+  if (group && g_action_group_has_action (group, action_name))
     {
-      if (g_action_group_has_action (group, action_name))
-        {
-          g_action_group_activate_action (group, action_name, parameter);
-          return;
-        }
+      g_action_group_activate_action (group, action_name, parameter);
+      return TRUE;
     }
 
   if (parameter && g_variant_is_floating (parameter))
@@ -254,7 +251,7 @@ gb_widget_activate_action (GtkWidget   *widget,
       g_variant_unref (parameter);
     }
 
-  g_warning ("Failed to resolve action %s.%s", prefix, action_name);
+  return FALSE;
 }
 
 IdeContext *
diff --git a/src/util/gb-widget.h b/src/util/gb-widget.h
index b3aa907..3146bfe 100644
--- a/src/util/gb-widget.h
+++ b/src/util/gb-widget.h
@@ -48,7 +48,7 @@ cairo_surface_t *gb_widget_snapshot            (GtkWidget    *widget,
 GbWorkbench     *gb_widget_get_workbench       (GtkWidget    *widget);
 void             gb_widget_fade_hide           (GtkWidget    *widget);
 void             gb_widget_fade_show           (GtkWidget    *widget);
-void             gb_widget_activate_action     (GtkWidget    *widget,
+gboolean         gb_widget_activate_action     (GtkWidget    *widget,
                                                 const gchar  *prefix,
                                                 const gchar  *action_name,
                                                 GVariant     *parameter);


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