From a88e8d1a31ff001b2d84c80b63b32b794f569051 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Sun, 26 Nov 2023 18:30:19 -0800 Subject: [PATCH 6/9] Support precmd notifications from an interactive shell Add sequences OSC 777 ; precmd BEL OSC 777 ; precmd ST that can be used from an interactive shell's precmd hook to notify the terminal emulator that a first level prompt is about to be shown. Examples of such hooks are Bash's PROMPT_COMMAND and Zsh's precmd. The OSC 777 escape sequence is taken from Enlightenment's Terminology: https://phab.enlightenment.org/T1765 https://bugzilla.gnome.org/show_bug.cgi?id=711059 https://bugzilla.gnome.org/show_bug.cgi?id=711060 --- src/vte.cc | 6 ++++++ src/vte.sh.in | 2 +- src/vte/vteterminal.h | 5 +---- src/vtegtk.cc | 18 ++++++++++++++++++ src/vtegtk.hh | 1 + src/vteinternal.hh | 1 + src/vteseq.cc | 4 +++- 7 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/vte.cc b/src/vte.cc index 49a3d8f3..14a259c2 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10780,6 +10780,12 @@ Terminal::emit_pending_signals() "Emitting `shell-preexec'.\n"); g_signal_emit(freezer.get(), signals[SIGNAL_SHELL_PREEXEC], 0); } + + if (m_pending_changes & vte::to_integral(PendingChanges::SHELL_PRECMD)) { + _vte_debug_print (VTE_DEBUG_SIGNALS, + "Emitting `shell-precmd'.\n"); + g_signal_emit(freezer.get(), signals[SIGNAL_SHELL_PRECMD], 0); + } #endif if (m_pending_changes & vte::to_integral(PendingChanges::TITLE)) { diff --git a/src/vte.sh.in b/src/vte.sh.in index fbbb1a03..22f1fd5c 100644 --- a/src/vte.sh.in +++ b/src/vte.sh.in @@ -38,7 +38,7 @@ __vte_prompt_command() { local pwd='~' [ "$PWD" != "$HOME" ] && pwd=${PWD/#$HOME\//\~\/} pwd="${pwd//[[:cntrl:]]}" - printf '\033]777;notify;Command completed;%s\033\\\033]0;%s@%s:%s\033\\' "${command}" "${USER}" "${HOSTNAME%%.*}" "${pwd}" + printf '\033]777;notify;Command completed;%s\033\\\033]777;precmd\033\\\033]0;%s@%s:%s\033\\' "${command}" "${USER}" "${HOSTNAME%%.*}" "${pwd}" __vte_osc7 } diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h index 29529020..aed105e9 100644 --- a/src/vte/vteterminal.h +++ b/src/vte/vteterminal.h @@ -115,11 +115,8 @@ struct _VteTerminalClass { #if _VTE_GTK == 3 void (*notification_received)(VteTerminal* terminal, const gchar *summary, const gchar *body); + void (*shell_precmd)(VteTerminal* terminal); void (*shell_preexec)(VteTerminal* terminal); - - /* Compatibility padding due to fedora patches intruding on our ABI */ - /*< private >*/ - gpointer _extra_padding[1]; #endif /* _VTE_GTK == 3 */ void (*setup_context_menu)(VteTerminal* terminal, diff --git a/src/vtegtk.cc b/src/vtegtk.cc index c4cf5537..79de4a1b 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1347,6 +1347,7 @@ vte_terminal_class_init(VteTerminalClass *klass) klass->char_size_changed = NULL; #if _VTE_GTK == 3 klass->notification_received = NULL; + klass->shell_precmd = NULL; klass->shell_preexec = NULL; #endif klass->window_title_changed = NULL; @@ -1453,6 +1454,23 @@ vte_terminal_class_init(VteTerminalClass *klass) G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); + /** + * VteTerminal::shell-precmd: + * @vteterminal: the object which received the signal + * + * Emitted right before an interactive shell shows a + * first-level prompt. + */ + signals[SIGNAL_SHELL_PRECMD] = + g_signal_new(I_("shell-precmd"), + G_OBJECT_CLASS_TYPE(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(VteTerminalClass, shell_precmd), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + /** * VteTerminal::shell-preexec: * @vteterminal: the object which received the signal diff --git a/src/vtegtk.hh b/src/vtegtk.hh index 4e400cd3..a1c3f3df 100644 --- a/src/vtegtk.hh +++ b/src/vtegtk.hh @@ -54,6 +54,7 @@ enum { SIGNAL_SELECTION_CHANGED, SIGNAL_SETUP_CONTEXT_MENU, #if _VTE_GTK == 3 + SIGNAL_SHELL_PRECMD, SIGNAL_SHELL_PREEXEC, SIGNAL_NOTIFICATION_RECEIVED, #endif diff --git a/src/vteinternal.hh b/src/vteinternal.hh index 0479ae0e..05625f83 100644 --- a/src/vteinternal.hh +++ b/src/vteinternal.hh @@ -758,6 +758,7 @@ public: #if _VTE_GTK == 3 NOTIFICATION = 1u << 3, SHELL_PREEXEC = 1u << 4, + SHELL_PRECMD = 1u << 5, #endif }; unsigned m_pending_changes{0}; diff --git a/src/vteseq.cc b/src/vteseq.cc index 92d1f857..44f13505 100644 --- a/src/vteseq.cc +++ b/src/vteseq.cc @@ -1326,7 +1326,9 @@ Terminal::handle_urxvt_extension(vte::parser::Sequence const& seq, return; } - if (*token == "preexec") { + if (*token == "precmd") { + m_pending_changes |= vte::to_integral(PendingChanges::SHELL_PRECMD); + } else if (*token == "preexec") { m_pending_changes |= vte::to_integral(PendingChanges::SHELL_PREEXEC); } } -- 2.43.0