[gnome-terminal/wip/rishi/command-notify: 2/4] Support desktop notifications from OSC 777



commit f1e376b53cbb05615113cd5827d6f00cd0fc115c
Author: Debarshi Ray <debarshir gnome org>
Date:   Tue Jan 27 18:40:13 2015 +0100

    Support desktop notifications from OSC 777
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711059

 src/terminal-app.c       |   32 +++++++++++++++++++++
 src/terminal-notebook.c  |    4 +++
 src/terminal-screen.c    |   68 ++++++++++++++++++++++++++++++++++++++++++++++
 src/terminal-tab-label.c |   28 ++++++++++++++++++-
 src/terminal-tab-label.h |    4 +++
 5 files changed, 135 insertions(+), 1 deletions(-)
---
diff --git a/src/terminal-app.c b/src/terminal-app.c
index 8a9434f..3d09914 100644
--- a/src/terminal-app.c
+++ b/src/terminal-app.c
@@ -299,6 +299,31 @@ app_menu_quit_cb (GSimpleAction *action,
     gtk_widget_destroy (GTK_WIDGET (window));
 }
 
+/* Other action callbacks */
+
+static void
+action_activate_tab_cb (GSimpleAction *action,
+                        GVariant      *parameter,
+                        gpointer       user_data)
+{
+  GtkApplication *application = user_data;
+  GtkWidget *toplevel;
+  TerminalScreen *screen;
+  const char *uuid;
+
+  g_variant_get (parameter, "&s", &uuid);
+  screen = terminal_app_get_screen_by_uuid (TERMINAL_APP (application), uuid);
+  if (screen == NULL)
+    return;
+
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (screen));
+  if (!gtk_widget_is_toplevel (toplevel))
+    return;
+
+  terminal_window_switch_screen (TERMINAL_WINDOW (toplevel), screen);
+  gtk_window_present (GTK_WINDOW (toplevel));
+}
+
 /* Class implementation */
 
 G_DEFINE_TYPE (TerminalApp, terminal_app, GTK_TYPE_APPLICATION)
@@ -321,6 +346,10 @@ terminal_app_startup (GApplication *application)
     { "quit",        app_menu_quit_cb,          NULL, NULL, NULL }
   };
 
+  const GActionEntry other_actions[] = {
+    { "activate-tab",   action_activate_tab_cb, "s",  NULL, NULL }
+  };
+
   gs_unref_object GtkBuilder *builder;
   GError *error = NULL;
 
@@ -332,6 +361,9 @@ terminal_app_startup (GApplication *application)
   g_action_map_add_action_entries (G_ACTION_MAP (application),
                                    app_menu_actions, G_N_ELEMENTS (app_menu_actions),
                                    application);
+  g_action_map_add_action_entries (G_ACTION_MAP (application),
+                                   other_actions, G_N_ELEMENTS (other_actions),
+                                   application);
 
   builder = gtk_builder_new ();
   gtk_builder_add_from_resource (builder,
diff --git a/src/terminal-notebook.c b/src/terminal-notebook.c
index 81005c5..896ffb1 100644
--- a/src/terminal-notebook.c
+++ b/src/terminal-notebook.c
@@ -241,6 +241,7 @@ terminal_notebook_switch_page (GtkNotebook     *gtk_notebook,
 {
   TerminalNotebook *notebook = TERMINAL_NOTEBOOK (gtk_notebook);
   TerminalNotebookPrivate *priv = notebook->priv;
+  GtkWidget *tab_label;
   TerminalScreen *screen, *old_active_screen;
 
   GTK_NOTEBOOK_CLASS (terminal_notebook_parent_class)->switch_page (gtk_notebook, child, page_num);
@@ -251,6 +252,9 @@ terminal_notebook_switch_page (GtkNotebook     *gtk_notebook,
   if (screen == old_active_screen)
     return;
 
+  tab_label = gtk_notebook_get_tab_label (gtk_notebook, child);
+  terminal_tab_label_set_icon (TERMINAL_TAB_LABEL (tab_label), NULL, NULL);
+
   /* Workaround to remove gtknotebook's feature of computing its size based on
    * all pages. When the widget is hidden, its size will not be taken into
    * account.
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 9f63239..f7e0213 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -48,6 +48,7 @@
 #include "terminal-marshal.h"
 #include "terminal-schemas.h"
 #include "terminal-screen-container.h"
+#include "terminal-tab-label.h"
 #include "terminal-util.h"
 #include "terminal-window.h"
 #include "terminal-info-bar.h"
@@ -81,6 +82,7 @@ struct _TerminalScreenPrivate
   char **initial_env;
   char **override_command;
   gboolean shell;
+  gboolean shell_prompt_shown;
   int child_pid;
   GSList *match_tags;
   guint launch_child_source_id;
@@ -136,6 +138,9 @@ static gboolean terminal_screen_do_exec (TerminalScreen *screen,
                                          GError **error);
 static void terminal_screen_child_exited  (VteTerminal *terminal,
                                            int status);
+static void terminal_screen_notification_received (VteTerminal *terminal,
+                                                   const char  *summary,
+                                                   const char  *body);
 
 static void terminal_screen_window_title_changed      (VteTerminal *vte_terminal,
                                                        TerminalScreen *screen);
@@ -440,6 +445,7 @@ terminal_screen_class_init (TerminalScreenClass *klass)
   widget_class->popup_menu = terminal_screen_popup_menu;
 
   terminal_class->child_exited = terminal_screen_child_exited;
+  terminal_class->notification_received = terminal_screen_notification_received;
 
   signals[PROFILE_SET] =
     g_signal_new (I_("profile-set"),
@@ -561,6 +567,10 @@ terminal_screen_dispose (GObject *object)
   TerminalScreen *screen = TERMINAL_SCREEN (object);
   TerminalScreenPrivate *priv = screen->priv;
   GtkSettings *settings;
+  TerminalApp *app;
+
+  app = terminal_app_get ();
+  g_application_withdraw_notification (G_APPLICATION (app), priv->uuid);
 
   settings = gtk_widget_get_settings (GTK_WIDGET (screen));
   g_signal_handlers_disconnect_matched (settings, G_SIGNAL_MATCH_DATA,
@@ -1596,6 +1606,64 @@ terminal_screen_child_exited (VteTerminal *terminal,
 }
 
 static void
+terminal_screen_notification_received (VteTerminal *terminal,
+                                       const char  *summary,
+                                       const char  *body)
+{
+  TerminalScreen *screen = TERMINAL_SCREEN (terminal);
+  TerminalScreenPrivate *priv = screen->priv;
+  TerminalWindow *window;
+
+  if (G_UNLIKELY (!priv->shell_prompt_shown))
+    {
+      priv->shell_prompt_shown = TRUE;
+      return;
+    }
+
+  window = terminal_screen_get_window (screen);
+  if (window == NULL)
+    return;
+
+  if (gtk_window_is_active (GTK_WINDOW (window)))
+    {
+      GtkWidget *mdi_container;
+      TerminalScreenContainer *screen_container;
+
+      if (screen == terminal_window_get_active (window))
+        return;
+
+      screen_container = terminal_screen_container_get_from_screen (screen);
+      if (screen_container == NULL)
+        return;
+
+      mdi_container = terminal_window_get_mdi_container (window);
+      /* FIXME: add interface method to retrieve tab label */
+      if (GTK_IS_NOTEBOOK (mdi_container))
+        {
+          GtkWidget *tab_label;
+
+          tab_label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (mdi_container), GTK_WIDGET 
(screen_container));
+          terminal_tab_label_set_bold (TERMINAL_TAB_LABEL (tab_label), TRUE);
+          terminal_tab_label_set_icon (TERMINAL_TAB_LABEL (tab_label), "dialog-information-symbolic", 
summary);
+        }
+    }
+  else
+    {
+      gs_unref_object GNotification *notification = NULL;
+      TerminalApp *app;
+      gs_free char *detailed_action = NULL;
+
+      notification = g_notification_new (summary);
+      g_notification_set_body (notification, body);
+      detailed_action = g_strdup_printf ("app.activate-tab::%s", priv->uuid);
+      g_notification_set_default_action (notification, detailed_action);
+
+      app = terminal_app_get ();
+      g_application_send_notification (G_APPLICATION (app), priv->uuid, notification);
+    }
+}
+
+static void
 terminal_screen_drag_data_received (GtkWidget        *widget,
                                     GdkDragContext   *context,
                                     gint              x,
diff --git a/src/terminal-tab-label.c b/src/terminal-tab-label.c
index e213a84..5303d6d 100644
--- a/src/terminal-tab-label.c
+++ b/src/terminal-tab-label.c
@@ -34,6 +34,7 @@
 struct _TerminalTabLabelPrivate
 {
   TerminalScreen *screen;
+  GtkWidget *icon;
   GtkWidget *label;
   GtkWidget *close_button;
   gboolean bold;
@@ -179,7 +180,7 @@ terminal_tab_label_constructed (GObject *object)
 {
   TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
   TerminalTabLabelPrivate *priv = tab_label->priv;
-  GtkWidget *hbox, *label, *close_button;
+  GtkWidget *hbox, *icon, *label, *close_button;
 
   G_OBJECT_CLASS (terminal_tab_label_parent_class)->constructed (object);
 
@@ -189,6 +190,10 @@ terminal_tab_label_constructed (GObject *object)
   
   gtk_box_set_spacing (GTK_BOX (hbox), SPACING);
 
+  priv->icon = icon = gtk_image_new ();
+  gtk_widget_set_no_show_all (icon, TRUE);
+  gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+
   priv->label = label = gtk_label_new (NULL);
   gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
   gtk_misc_set_padding (GTK_MISC (label), 0, 0);
@@ -372,6 +377,27 @@ terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
 }
 
 /**
+ * terminal_tab_label_set_icon:
+ * @tab_label: a #TerminalTabLabel
+ * @icon_name: (allow-none): an icon name
+ * @tooltip: (allow-none): text to be used as tooltip
+ *
+ * Shows an icon at the beginning of @tab_label. If @icon_name is
+ * %NULL, then the icon will be hidden.
+ */
+void
+terminal_tab_label_set_icon (TerminalTabLabel *tab_label,
+                             const char *icon_name,
+                             const char *tooltip)
+{
+  TerminalTabLabelPrivate *priv = tab_label->priv;
+
+  gtk_widget_set_visible (priv->icon, icon_name != NULL);
+  gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon), icon_name, GTK_ICON_SIZE_MENU);
+  gtk_widget_set_tooltip_text (GTK_WIDGET (priv->icon), tooltip);
+}
+
+/**
  * terminal_tab_label_get_screen:
  * @tab_label: a #TerminalTabLabel
  *
diff --git a/src/terminal-tab-label.h b/src/terminal-tab-label.h
index 20cfbce..a987025 100644
--- a/src/terminal-tab-label.h
+++ b/src/terminal-tab-label.h
@@ -59,6 +59,10 @@ GtkWidget *     terminal_tab_label_new        (TerminalScreen *screen);
 void            terminal_tab_label_set_bold   (TerminalTabLabel *tab_label,
                                                gboolean bold);
 
+void            terminal_tab_label_set_icon   (TerminalTabLabel *tab_label,
+                                               const char *icon_name,
+                                               const char *tooltip);
+
 TerminalScreen *terminal_tab_label_get_screen (TerminalTabLabel *tab_label);
 
 G_END_DECLS


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