[vte/wip/command-notify: 1/2] emulation: Add sequences and signals for command termination



commit 5f6daeb7e5f2834afc6cc8685f82a48af8e3812c
Author: Debarshi Ray <debarshir gnome org>
Date:   Wed Jan 7 16:01:00 2015 +0100

    emulation: Add sequences and signals for command termination
    
    Add sequences
      OSC 200 ; CMDLINE BEL
      OSC 200 ; CMDLINE ST
    that set the command line of a foreground process that just terminated.
    We can use the corresponding signal in gnome-terminal to notify about
    long-running commands.

 src/caps.c         |    2 ++
 src/vte-private.h  |    3 +++
 src/vte.c          |   35 +++++++++++++++++++++++++++++++++++
 src/vteseq-n.gperf |    1 +
 src/vteseq.c       |   44 ++++++++++++++++++++++++++++++++++++++++++++
 src/vteterminal.h  |    3 ++-
 6 files changed, 87 insertions(+), 1 deletions(-)
---
diff --git a/src/caps.c b/src/caps.c
index b51882f..428d8e5 100644
--- a/src/caps.c
+++ b/src/caps.c
@@ -254,6 +254,7 @@ const char _vte_xterm_capability_strings[] =
         ENTRY(OSC "117" BEL, "reset-highlight-background-color")
         ENTRY(OSC "118" BEL, "reset-tek-cursor-color")
         ENTRY(OSC "119" BEL, "reset-highlight-foreground-color")
+        ENTRY(OSC "200;%s" BEL, "command-terminated")
 
         COMMENT(/* Set text parameters, ST-terminated versions. */)
         ENTRY(OSC ";%s" ST, "set-icon-and-window-title") COMMENT(/* undocumented default */)
@@ -289,6 +290,7 @@ const char _vte_xterm_capability_strings[] =
         ENTRY(OSC "117" ST, "reset-highlight-background-color")
         ENTRY(OSC "118" ST, "reset-tek-cursor-color")
         ENTRY(OSC "119" ST, "reset-highlight-foreground-color")
+        ENTRY(OSC "200;%s" ST, "command-terminated")
 
         COMMENT(/* These may be bogus, I can't find docs for them anywhere (#104154). */)
         ENTRY(OSC "21;%s" BEL, "set-text-property-21")
diff --git a/src/vte-private.h b/src/vte-private.h
index 3a40131..0639fd6 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -420,6 +420,9 @@ struct _VteTerminalPrivate {
        gboolean cursor_moved_pending;
        gboolean contents_changed_pending;
 
+       /* command termination */
+       gchar *cmdline_changed;
+
        /* window name changes */
         gchar *window_title;
        gchar *window_title_changed;
diff --git a/src/vte.c b/src/vte.c
index 59eceec..e65bf23 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -8559,6 +8559,8 @@ vte_terminal_finalize(GObject *object)
 
        remove_update_timeout (terminal);
 
+       g_free(terminal->pvt->cmdline_changed);
+
        /* discard title updates */
         g_free(terminal->pvt->window_title);
         g_free(terminal->pvt->window_title_changed);
@@ -10284,6 +10286,7 @@ vte_terminal_class_init(VteTerminalClass *klass)
        klass->child_exited = NULL;
        klass->encoding_changed = NULL;
        klass->char_size_changed = NULL;
+       klass->command_terminated = NULL;
        klass->window_title_changed = NULL;
        klass->icon_title_changed = NULL;
        klass->selection_changed = NULL;
@@ -10358,6 +10361,23 @@ vte_terminal_class_init(VteTerminalClass *klass)
                      1, G_TYPE_INT);
 
         /**
+         * VteTerminal::command-terminated:
+         * @vteterminal: the object which received the signal
+         * @cmdline: the full command line
+         *
+         * Emitted when a foregroud process running in the terminal terminates.
+         */
+        g_signal_new(I_("command-terminated"),
+                     G_OBJECT_CLASS_TYPE(klass),
+                     G_SIGNAL_RUN_LAST,
+                     G_STRUCT_OFFSET(VteTerminalClass, command_terminated),
+                     NULL,
+                     NULL,
+                     g_cclosure_marshal_VOID__STRING,
+                     G_TYPE_NONE,
+                     1, G_TYPE_STRING);
+
+        /**
          * VteTerminal::window-title-changed:
          * @vteterminal: the object which received the signal
          *
@@ -12360,6 +12380,15 @@ need_processing (VteTerminal *terminal)
        return _vte_incoming_chunks_length (terminal->pvt->incoming) != 0;
 }
 
+static void
+vte_terminal_emit_command_terminated(VteTerminal *terminal)
+{
+       _vte_debug_print(VTE_DEBUG_SIGNALS,
+                       "Emitting `command-terminated'.\n");
+       g_signal_emit_by_name(terminal, "command-terminated",
+                             terminal->pvt->cmdline_changed);
+}
+
 /* Emit an "icon-title-changed" signal. */
 static void
 vte_terminal_emit_icon_title_changed(VteTerminal *terminal)
@@ -12407,6 +12436,12 @@ vte_terminal_emit_pending_signals(VteTerminal *terminal)
 
        vte_terminal_emit_adjustment_changed (terminal);
 
+       if (terminal->pvt->cmdline_changed) {
+               vte_terminal_emit_command_terminated(terminal);
+               g_free (terminal->pvt->cmdline_changed);
+               terminal->pvt->cmdline_changed = NULL;
+       }
+
        if (terminal->pvt->window_title_changed) {
                g_free (terminal->pvt->window_title);
                terminal->pvt->window_title = terminal->pvt->window_title_changed;
diff --git a/src/vteseq-n.gperf b/src/vteseq-n.gperf
index f28625b..bf987fe 100644
--- a/src/vteseq-n.gperf
+++ b/src/vteseq-n.gperf
@@ -167,3 +167,4 @@ struct vteseq_n_struct {
 #"reset-mouse-cursor-foreground-color", VTE_SEQUENCE_HANDLER_NULL
 "set-current-directory-uri", VTE_SEQUENCE_HANDLER(vte_sequence_handler_set_current_directory_uri)
 "set-current-file-uri", VTE_SEQUENCE_HANDLER(vte_sequence_handler_set_current_file_uri)
+"command-terminated", VTE_SEQUENCE_HANDLER(vte_sequence_handler_command_terminated)
diff --git a/src/vteseq.c b/src/vteseq.c
index b2f4b7d..ba69376 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -2330,6 +2330,50 @@ vte_sequence_handler_set_current_file_uri (VteTerminal *terminal, GValueArray *p
         terminal->pvt->current_file_uri_changed = uri;
 }
 
+static void
+vte_sequence_handler_command_terminated (VteTerminal *terminal, GValueArray *params)
+{
+       GValue *value;
+       char *cmdline = NULL;
+
+       /* Get the string parameter's value. */
+       value = g_value_array_get_nth(params, 0);
+       if (value) {
+               if (G_VALUE_HOLDS_LONG(value)) {
+                       /* Convert the long to a string. */
+                       cmdline = g_strdup_printf("%ld", g_value_get_long(value));
+               } else
+               if (G_VALUE_HOLDS_STRING(value)) {
+                       /* Copy the string into the buffer. */
+                       cmdline = g_value_dup_string(value);
+               } else
+               if (G_VALUE_HOLDS_POINTER(value)) {
+                       cmdline = vte_ucs4_to_utf8 (terminal, g_value_get_pointer (value));
+               }
+               if (cmdline != NULL) {
+                       char *p, *validated;
+                       const char *end;
+
+                       /* Validate the text. */
+                       g_utf8_validate(cmdline, strlen(cmdline), &end);
+                       validated = g_strndup(cmdline, end - cmdline);
+
+                       /* No control characters allowed. */
+                       for (p = validated; *p != '\0'; p++) {
+                               if ((*p & 0x1f) == *p) {
+                                       *p = ' ';
+                               }
+                       }
+
+                       g_free (terminal->pvt->cmdline_changed);
+                       terminal->pvt->cmdline_changed = g_strdup (validated);
+
+                       g_free (validated);
+                       g_free(cmdline);
+               }
+       }
+}
+
 /* Restrict the scrolling region. */
 static void
 vte_sequence_handler_set_scrolling_region_from_start (VteTerminal *terminal, GValueArray *params)
diff --git a/src/vteterminal.h b/src/vteterminal.h
index 59f8ce7..0e2a81d 100644
--- a/src/vteterminal.h
+++ b/src/vteterminal.h
@@ -72,6 +72,7 @@ struct _VteTerminalClass {
        void (*child_exited)(VteTerminal* terminal, int status);
        void (*encoding_changed)(VteTerminal* terminal);
        void (*char_size_changed)(VteTerminal* terminal, guint char_width, guint char_height);
+       void (*command_terminated)(VteTerminal* terminal, const gchar *cmdline);
        void (*window_title_changed)(VteTerminal* terminal);
        void (*icon_title_changed)(VteTerminal* terminal);
        void (*selection_changed)(VteTerminal* terminal);
@@ -105,7 +106,7 @@ struct _VteTerminalClass {
        void (*bell)(VteTerminal* terminal);
 
         /* Padding for future expansion. */
-        gpointer padding[16];
+        gpointer padding[15];
 
         VteTerminalClassPrivate *priv;
 };


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