Backport changes from Fedora 40

Resolves: RHEL-42425
Resolves: RHEL-41136
This commit is contained in:
Christian Hergert 2024-06-19 16:41:06 -07:00
parent 7b6f7f134a
commit 84aaa7968c
6 changed files with 1868 additions and 2730 deletions

1
.gitignore vendored
View File

@ -98,3 +98,4 @@
/vte-0.74.1.tar.xz
/vte-0.74.2.tar.xz
/vte-0.76.2.tar.xz
/vte-0.76.3.tar.xz

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,533 @@
From f31af265a19a406cd193a82b96dff1dd2e4595b4 Mon Sep 17 00:00:00 2001
From: Christian Hergert <chergert@redhat.com>
Date: Mon, 4 Mar 2024 14:03:38 -0800
Subject: [PATCH] add notification and shell precmd/preexec
This is a bit simpler to manage as a single patch rather than a series of
patches which incrementally update things.
This alters some of the original patches so that we don't need to have
such careful integration with the vtable of the class as that isn't used.
You can always connect to the signal rather than the vtable default func.
---
src/marshal.list | 1 +
src/vte.cc | 28 +++++++++
src/vte.sh.in | 7 ++-
src/vte/vteterminal.h | 4 ++
src/vtegtk.cc | 131 ++++++++++++++++++++++++++++++++++++++++++
src/vtegtk.hh | 5 ++
src/vteinternal.hh | 26 +++++++++
src/vteseq.cc | 123 ++++++++++++++++++++++++++++++++++++++-
8 files changed, 322 insertions(+), 3 deletions(-)
diff --git a/src/marshal.list b/src/marshal.list
index 241128c3..f9b3818f 100644
--- a/src/marshal.list
+++ b/src/marshal.list
@@ -1,3 +1,4 @@
VOID:STRING,BOXED
VOID:STRING,UINT
+VOID:STRING,STRING
VOID:UINT,UINT
diff --git a/src/vte.cc b/src/vte.cc
index 2cba7369..a8a0e22c 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -10771,6 +10771,34 @@ Terminal::emit_pending_signals()
emit_adjustment_changed();
+ if (m_pending_changes & vte::to_integral(PendingChanges::NOTIFICATION)) {
+ _vte_debug_print (VTE_DEBUG_SIGNALS,
+ "Emitting `notification-received'.\n");
+ g_signal_emit(freezer.get(), signals[SIGNAL_NOTIFICATION_RECEIVED], 0,
+ m_notification_summary.c_str(),
+ m_notification_body.c_str());
+ }
+
+ if (m_pending_changes & vte::to_integral(PendingChanges::SHELL_PREEXEC)) {
+ _vte_debug_print (VTE_DEBUG_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);
+ }
+
+ if (m_pending_changes & vte::to_integral(PendingChanges::CONTAINERS)) {
+ _vte_debug_print(VTE_DEBUG_SIGNALS,
+ "Notifying `current-container-name' and `current-container-runtime'.\n");
+
+ g_object_notify_by_pspec(freezer.get(), pspecs[PROP_CURRENT_CONTAINER_NAME]);
+ g_object_notify_by_pspec(freezer.get(), pspecs[PROP_CURRENT_CONTAINER_RUNTIME]);
+ }
+
if (m_pending_changes & vte::to_integral(PendingChanges::TITLE)) {
if (m_window_title != m_window_title_pending) {
m_window_title.swap(m_window_title_pending);
diff --git a/src/vte.sh.in b/src/vte.sh.in
index 2328a9ec..93f45ea8 100644
--- a/src/vte.sh.in
+++ b/src/vte.sh.in
@@ -28,6 +28,12 @@ case "$TERM" in
*) return 0 ;;
esac
+__vte_shell_precmd() {
+ local command=$(HISTTIMEFORMAT= history 1 | sed 's/^ *[0-9]\+ *//')
+ command="${command//;/ }"
+ printf '\033]777;notify;Command completed;%s\033\\\033]777;precmd\033\\' "${command}"
+}
+
__vte_osc7 () {
printf "\033]7;file://%s%s\033\\" "${HOSTNAME}" "$(@libexecdir@/vte-urlencode-cwd)"
}
@@ -37,6 +43,7 @@ __vte_prompt_command() {
[ "$PWD" != "$HOME" ] && pwd=${PWD/#$HOME\//\~\/}
pwd="${pwd//[[:cntrl:]]}"
printf "\033]0;%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${pwd}"
+ __vte_shell_precmd
__vte_osc7
}
@@ -49,9 +56,12 @@ if [[ -n "${BASH_VERSION:-}" ]]; then
# use the __vte_prompt_command function which also sets the title.
if [[ "$(declare -p PROMPT_COMMAND 2>&1)" =~ "declare -a" ]]; then
+ PROMPT_COMMAND+=(__vte_shell_precmd)
PROMPT_COMMAND+=(__vte_osc7)
+ PS0=$(printf "\033]777;preexec\033\\")
else
PROMPT_COMMAND="__vte_prompt_command"
+ PS0=$(printf "\033]777;preexec\033\\")
fi
# Shell integration
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index a9e1e494..9c2e2dae 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -559,6 +559,10 @@ glong vte_terminal_get_column_count(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VT
_VTE_PUBLIC
const char *vte_terminal_get_window_title(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
_VTE_PUBLIC
+const char *vte_terminal_get_current_container_name(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+_VTE_PUBLIC
+const char *vte_terminal_get_current_container_runtime(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+_VTE_PUBLIC
const char *vte_terminal_get_current_directory_uri(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
_VTE_PUBLIC
const char *vte_terminal_get_current_file_uri(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 92eb6881..c713a95a 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -999,6 +999,12 @@ try
case PROP_CURSOR_BLINK_MODE:
g_value_set_enum (value, vte_terminal_get_cursor_blink_mode (terminal));
break;
+ case PROP_CURRENT_CONTAINER_NAME:
+ g_value_set_string (value, vte_terminal_get_current_container_name (terminal));
+ break;
+ case PROP_CURRENT_CONTAINER_RUNTIME:
+ g_value_set_string (value, vte_terminal_get_current_container_runtime (terminal));
+ break;
case PROP_CURRENT_DIRECTORY_URI:
g_value_set_string (value, vte_terminal_get_current_directory_uri (terminal));
break;
@@ -1434,6 +1440,60 @@ vte_terminal_class_init(VteTerminalClass *klass)
G_OBJECT_CLASS_TYPE(klass),
g_cclosure_marshal_VOID__INTv);
+ /**
+ * VteTerminal::notification-received:
+ * @vteterminal: the object which received the signal
+ * @summary: The summary
+ * @body: (allow-none): Extra optional text
+ *
+ * Emitted when a process running in the terminal wants to
+ * send a notification to the desktop environment.
+ */
+ signals[SIGNAL_NOTIFICATION_RECEIVED] =
+ g_signal_new(I_("notification-received"),
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ _vte_marshal_VOID__STRING_STRING,
+ 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,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * VteTerminal::shell-preexec:
+ * @vteterminal: the object which received the signal
+ *
+ * Emitted when the interactive shell has read in a complete
+ * command and is about to execute it.
+ */
+ signals[SIGNAL_SHELL_PREEXEC] =
+ g_signal_new(I_("shell-preexec"),
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
/**
* VteTerminal::window-title-changed:
* @vteterminal: the object which received the signal
@@ -2487,6 +2547,27 @@ vte_terminal_class_init(VteTerminalClass *klass)
NULL,
(GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
+ /**
+ * VteTerminal:current-container-name:
+ *
+ * The name of the current container, or %NULL if unset.
+ */
+ pspecs[PROP_CURRENT_CONTAINER_NAME] =
+ g_param_spec_string ("current-container-name", NULL, NULL,
+ NULL,
+ (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
+
+ /**
+ * VteTerminal:current-container-runtime:
+ *
+ * The name of the runtime toolset used to set up the current
+ * container, or %NULL if unset.
+ */
+ pspecs[PROP_CURRENT_CONTAINER_RUNTIME] =
+ g_param_spec_string ("current-container-runtime", NULL, NULL,
+ NULL,
+ (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
+
/**
* VteTerminal:current-directory-uri:
*
@@ -5419,6 +5500,56 @@ catch (...)
return -1;
}
+/**
+ * vte_terminal_get_current_container_name:
+ * @terminal: a #VteTerminal
+ *
+ * Returns: (nullable) (transfer none): the name of the current
+ * container, or %NULL
+ */
+const char *
+vte_terminal_get_current_container_name(VteTerminal *terminal) noexcept
+try
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
+ auto impl = IMPL(terminal);
+ if (impl->m_containers.empty())
+ return NULL;
+
+ const VteContainer &container = impl->m_containers.top();
+ return container.m_name.c_str();
+}
+catch (...)
+{
+ vte::log_exception();
+ return NULL;
+}
+
+/**
+ * vte_terminal_get_current_container_runtime:
+ * @terminal: a #VteTerminal
+ *
+ * Returns: (nullable) (transfer none): the name of the runtime
+ * toolset used to set up the current container, or %NULL
+ */
+const char *
+vte_terminal_get_current_container_runtime(VteTerminal *terminal) noexcept
+try
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
+ auto impl = IMPL(terminal);
+ if (impl->m_containers.empty())
+ return NULL;
+
+ const VteContainer &container = impl->m_containers.top();
+ return container.m_runtime.c_str();
+}
+catch (...)
+{
+ vte::log_exception();
+ return NULL;
+}
+
/**
* vte_terminal_get_current_directory_uri:
* @terminal: a #VteTerminal
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index 1d1383af..566c8508 100644
--- a/src/vtegtk.hh
+++ b/src/vtegtk.hh
@@ -53,6 +53,9 @@ enum {
SIGNAL_RESTORE_WINDOW,
SIGNAL_SELECTION_CHANGED,
SIGNAL_SETUP_CONTEXT_MENU,
+ SIGNAL_SHELL_PRECMD,
+ SIGNAL_SHELL_PREEXEC,
+ SIGNAL_NOTIFICATION_RECEIVED,
SIGNAL_WINDOW_TITLE_CHANGED,
LAST_SIGNAL
};
@@ -72,6 +75,8 @@ enum {
PROP_CONTEXT_MENU,
PROP_CURSOR_BLINK_MODE,
PROP_CURSOR_SHAPE,
+ PROP_CURRENT_CONTAINER_NAME,
+ PROP_CURRENT_CONTAINER_RUNTIME,
PROP_CURRENT_DIRECTORY_URI,
PROP_CURRENT_FILE_URI,
PROP_DELETE_BINDING,
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index ed57ad16..07a9e993 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -63,6 +63,7 @@
#include <list>
#include <queue>
#include <optional>
+#include <stack>
#include <string>
#include <variant>
#include <vector>
@@ -121,6 +122,18 @@ typedef enum _VteCharacterReplacement {
VTE_CHARACTER_REPLACEMENT_LINE_DRAWING
} VteCharacterReplacement;
+struct VteContainer {
+public:
+ VteContainer(const std::string &name, const std::string &runtime) :
+ m_name{name},
+ m_runtime{runtime}
+ {
+ }
+
+ std::string m_name;
+ std::string m_runtime;
+};
+
typedef struct _VtePaletteColor {
struct {
vte::color::rgb color;
@@ -710,6 +723,12 @@ public:
gboolean m_cursor_moved_pending;
gboolean m_contents_changed_pending;
+ /* desktop notification */
+ std::stack<VteContainer> m_containers;
+
+ std::string m_notification_summary;
+ std::string m_notification_body;
+
std::string m_window_title{};
std::string m_current_directory_uri{};
std::string m_current_file_uri{};
@@ -723,6 +742,10 @@ public:
TITLE = 1u << 0,
CWD = 1u << 1,
CWF = 1u << 2,
+ NOTIFICATION = 1u << 4,
+ SHELL_PREEXEC = 1u << 5,
+ SHELL_PRECMD = 1u << 6,
+ CONTAINERS = 1u << 7,
};
unsigned m_pending_changes{0};
@@ -1654,6 +1677,9 @@ public:
int osc) noexcept;
/* OSC handlers */
+ void handle_urxvt_extension(vte::parser::Sequence const& seq,
+ vte::parser::StringTokeniser::const_iterator& token,
+ vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept;
void set_color(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
vte::parser::StringTokeniser::const_iterator const& endtoken,
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 904837e1..26f7b0d6 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -39,6 +39,9 @@
#define ST_C0 _VTE_CAP_ST
#include <algorithm>
+#include <string>
+#include <unistd.h>
+#include <sys/types.h>
using namespace std::literals;
@@ -1276,6 +1279,121 @@ Terminal::erase_in_line(vte::parser::Sequence const& seq)
m_text_deleted_flag = TRUE;
}
+void
+Terminal::handle_urxvt_extension(vte::parser::Sequence const& seq,
+ vte::parser::StringTokeniser::const_iterator& token,
+ vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept
+{
+ if (token == endtoken)
+ return;
+
+ if (*token == "container") {
+ ++token;
+
+ if (token == endtoken)
+ return;
+
+ const std::string sub_command = *token;
+ ++token;
+
+ if (sub_command == "pop") {
+ if (token == endtoken)
+ return;
+
+ ++token;
+
+ if (token == endtoken)
+ return;
+
+ ++token;
+
+ if (token == endtoken) {
+ if (!m_containers.empty()) {
+ m_containers.pop();
+ m_pending_changes |= vte::to_integral(PendingChanges::CONTAINERS);
+ }
+
+ return;
+ }
+
+ const std::string uid_token = *token;
+ ++token;
+
+ const uid_t uid = getuid();
+ const std::string uid_str = std::to_string(uid);
+
+ if (uid_token == uid_str) {
+ if (!m_containers.empty()) {
+ m_containers.pop();
+ m_pending_changes |= vte::to_integral(PendingChanges::CONTAINERS);
+ }
+
+ return;
+ }
+
+ return;
+ } else if (sub_command == "push") {
+ if (token == endtoken)
+ return;
+
+ const std::string name = *token;
+ ++token;
+
+ if (token == endtoken)
+ return;
+
+ const std::string runtime = *token;
+ ++token;
+
+ if (token == endtoken) {
+ m_containers.emplace(name, runtime);
+ m_pending_changes |= vte::to_integral(PendingChanges::CONTAINERS);
+ return;
+ }
+
+ const std::string uid_token = *token;
+ ++token;
+
+ const uid_t uid = getuid();
+ const std::string uid_str = std::to_string(uid);
+
+ if (uid_token == uid_str) {
+ m_containers.emplace(name, runtime);
+ m_pending_changes |= vte::to_integral(PendingChanges::CONTAINERS);
+ return;
+ }
+
+ return;
+ }
+
+ return;
+ }
+
+ if (*token == "notify") {
+ ++token;
+
+ if (token == endtoken)
+ return;
+
+ m_notification_summary = *token;
+ m_notification_body.clear();
+ m_pending_changes |= vte::to_integral(PendingChanges::NOTIFICATION);
+ ++token;
+
+ if (token == endtoken)
+ return;
+
+ m_notification_body = *token;
+ return;
+ }
+
+ 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);
+ }
+}
+
bool
Terminal::get_osc_color_index(int osc,
int value,
@@ -6596,6 +6714,10 @@ Terminal::OSC(vte::parser::Sequence const& seq)
reset_color(VTE_HIGHLIGHT_FG, VTE_COLOR_SOURCE_ESCAPE);
break;
+ case VTE_OSC_URXVT_EXTENSION:
+ handle_urxvt_extension(seq, it, cend);
+ break;
+
case VTE_OSC_XTERM_SET_ICON_TITLE:
case VTE_OSC_XTERM_SET_XPROPERTY:
case VTE_OSC_XTERM_SET_COLOR_MOUSE_CURSOR_FG:
@@ -6636,7 +6758,6 @@ Terminal::OSC(vte::parser::Sequence const& seq)
case VTE_OSC_URXVT_SET_FONT_BOLD_ITALIC:
case VTE_OSC_URXVT_VIEW_UP:
case VTE_OSC_URXVT_VIEW_DOWN:
- case VTE_OSC_URXVT_EXTENSION:
case VTE_OSC_YF_RQGWR:
default:
break;
--
2.43.1

View File

@ -1 +1 @@
SHA512 (vte-0.76.2.tar.xz) = 206e2706c926972d4f389cf0418b840345ba6eb0336a3cae8b0d604f773b8b86746ef4986c94cfd6b0716449351ecb51a62f3ba08885b9cc8c8a8580e75f7fbf
SHA512 (vte-0.76.3.tar.xz) = 59cf3241f59b7ce795098814a04816d150330e4464a2438c974ac03cfd6aa05e7e037121a6a21929d6b12eb17fb1a4bf48c936604f0e0b770e3f125adb5a4c50

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
%global pcre2_version 10.21
Name: vte291
Version: 0.76.2
Version: 0.76.3
Release: 1%{?dist}
Summary: GTK+ 3 terminal emulator library
@ -24,7 +24,8 @@ Source0: https://download.gnome.org/sources/vte/0.76/vte-%{version}.tar.x
# https://bugzilla.gnome.org/show_bug.cgi?id=711059
# https://bugzilla.redhat.com/show_bug.cgi?id=1103380
# https://pagure.io/fedora-workstation/issue/216
Patch0: vte291-cntnr-precmd-preexec-scroll.patch
Patch: 0001-a11y-implement-GtkAccessibleText.patch
Patch: 0001-add-notification-and-shell-precmd-preexec.patch
BuildRequires: pkgconfig(fribidi) >= %{fribidi_version}
BuildRequires: pkgconfig(gio-2.0) >= %{glib2_version}
@ -179,6 +180,12 @@ sed -i -e "/^vte_systemduserunitdir =/s|vte_prefix|'/usr'|" meson.build
%{_sysconfdir}/profile.d/vte.sh
%changelog
* Mon Jun 10 2024 David King <amigadave@amigadave.com> - 0.76.3-1
- Update to 0.76.3
* Fri Jun 07 2024 David King <amigadave@amigadave.com> - 0.76.2-2
- Use updated notification patches from ptyxis
* Tue May 28 2024 David King <amigadave@amigadave.com> - 0.76.2-1
- Update to 0.76.2