From 229a985c1ce90d5a7b493dad1261dd72a25e910c Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 7 Jan 2015 16:01:00 +0100 Subject: [PATCH 01/11] Add sequences and signals for desktop notification Add sequences OSC 777 ; notify ; SUMMARY ; BODY BEL OSC 777 ; notify ; SUMMARY BEL OSC 777 ; notify ; SUMMARY ; BODY ST OSC 777 ; notify ; SUMMARY ST that let terminal applications send a notification to the desktop environment. Based on Enlightenment's Terminology: https://phab.enlightenment.org/T1765 https://bugzilla.gnome.org/show_bug.cgi?id=711059 --- src/marshal.list | 1 + src/vte.cc | 10 ++++++++++ src/vte/vteterminal.h | 4 +++- src/vtegtk.cc | 25 +++++++++++++++++++++++++ src/vtegtk.hh | 3 +++ src/vteinternal.hh | 14 ++++++++++++++ src/vteseq.cc | 37 +++++++++++++++++++++++++++++++++++++ 7 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/marshal.list b/src/marshal.list index 241128c3..4412cf3d 100644 --- a/src/marshal.list +++ b/src/marshal.list @@ -1,3 +1,4 @@ VOID:STRING,BOXED +VOID:STRING,STRING VOID:STRING,UINT VOID:UINT,UINT diff --git a/src/vte.cc b/src/vte.cc index 92b19fc8..03868606 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10191,6 +10191,16 @@ Terminal::emit_pending_signals() emit_adjustment_changed(); +#if _VTE_GTK == 3 + 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()); + } +#endif + 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/vteterminal.h b/src/vte/vteterminal.h index 69b26ac3..13caec60 100644 --- a/src/vte/vteterminal.h +++ b/src/vte/vteterminal.h @@ -109,9 +109,11 @@ struct _VteTerminalClass { void (*bell)(VteTerminal* terminal); #if _VTE_GTK == 3 + void (*notification_received)(VteTerminal* terminal, const gchar *summary, const gchar *body); + /* Compatibility padding due to fedora patches intruding on our ABI */ /*< private >*/ - gpointer _extra_padding[3]; + gpointer _extra_padding[2]; #endif /* _VTE_GTK == 3 */ /* Add new vfuncs here, and subtract from the padding below. */ diff --git a/src/vtegtk.cc b/src/vtegtk.cc index 59b74367..e9af14d1 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1263,6 +1263,9 @@ vte_terminal_class_init(VteTerminalClass *klass) klass->child_exited = NULL; klass->encoding_changed = NULL; klass->char_size_changed = NULL; +#if _VTE_GTK == 3 + klass->notification_received = NULL; +#endif klass->window_title_changed = NULL; klass->icon_title_changed = NULL; klass->selection_changed = NULL; @@ -1346,6 +1349,28 @@ vte_terminal_class_init(VteTerminalClass *klass) G_OBJECT_CLASS_TYPE(klass), g_cclosure_marshal_VOID__INTv); +#if _VTE_GTK == 3 + /** + * 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, + G_STRUCT_OFFSET(VteTerminalClass, notification_received), + NULL, + NULL, + _vte_marshal_VOID__STRING_STRING, + G_TYPE_NONE, + 2, G_TYPE_STRING, G_TYPE_STRING); +#endif + /** * VteTerminal::window-title-changed: * @vteterminal: the object which received the signal diff --git a/src/vtegtk.hh b/src/vtegtk.hh index 6b7a1ea2..d5379b16 100644 --- a/src/vtegtk.hh +++ b/src/vtegtk.hh @@ -52,6 +52,9 @@ enum { SIGNAL_RESIZE_WINDOW, SIGNAL_RESTORE_WINDOW, SIGNAL_SELECTION_CHANGED, +#if _VTE_GTK == 3 + SIGNAL_NOTIFICATION_RECEIVED, +#endif SIGNAL_WINDOW_TITLE_CHANGED, LAST_SIGNAL }; diff --git a/src/vteinternal.hh b/src/vteinternal.hh index 0d454649..8dba726c 100644 --- a/src/vteinternal.hh +++ b/src/vteinternal.hh @@ -662,6 +662,12 @@ public: gboolean m_cursor_moved_pending; gboolean m_contents_changed_pending; +#if _VTE_GTK == 3 + /* desktop notification */ + std::string m_notification_summary; + std::string m_notification_body; +#endif + std::string m_window_title{}; std::string m_current_directory_uri{}; std::string m_current_file_uri{}; @@ -675,6 +681,9 @@ public: TITLE = 1u << 0, CWD = 1u << 1, CWF = 1u << 2, +#if _VTE_GTK == 3 + NOTIFICATION = 1u << 3, +#endif }; unsigned m_pending_changes{0}; @@ -1506,6 +1515,11 @@ public: int osc) noexcept; /* OSC handlers */ +#if _VTE_GTK == 3 + void handle_urxvt_extension(vte::parser::Sequence const& seq, + vte::parser::StringTokeniser::const_iterator& token, + vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept; +#endif 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 874d2405..dda487c4 100644 --- a/src/vteseq.cc +++ b/src/vteseq.cc @@ -1376,6 +1376,35 @@ Terminal::delete_lines(vte::grid::row_t param) m_text_deleted_flag = TRUE; } +#if _VTE_GTK == 3 +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 == "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; + } +} +#endif + bool Terminal::get_osc_color_index(int osc, int value, @@ -6541,6 +6570,12 @@ Terminal::OSC(vte::parser::Sequence const& seq) reset_color(VTE_HIGHLIGHT_FG, VTE_COLOR_SOURCE_ESCAPE); break; +#if _VTE_GTK == 3 + case VTE_OSC_URXVT_EXTENSION: + handle_urxvt_extension(seq, it, cend); + break; +#endif + case VTE_OSC_XTERM_SET_ICON_TITLE: case VTE_OSC_XTERM_SET_XPROPERTY: case VTE_OSC_XTERM_SET_COLOR_MOUSE_CURSOR_FG: @@ -6582,7 +6617,9 @@ 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: +#if _VTE_GTK != 3 case VTE_OSC_URXVT_EXTENSION: +#endif case VTE_OSC_YF_RQGWR: default: break; -- 2.40.0 From 74a4ad9c4472c9c628945c336ca1bfb535b105d6 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 29 Jan 2015 13:09:17 +0100 Subject: [PATCH 02/11] vte.sh: Emit OSC 777 from PROMPT_COMMAND For some reason, the three consecutive backslashes break the parsing. As Christian Persch suggested, replacing the double quotes with singles fixes it. https://bugzilla.gnome.org/show_bug.cgi?id=711059 --- src/vte.sh.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vte.sh.in b/src/vte.sh.in index 242d6c42..50242223 100644 --- a/src/vte.sh.in +++ b/src/vte.sh.in @@ -33,10 +33,12 @@ __vte_osc7 () { } __vte_prompt_command() { + local command=$(HISTTIMEFORMAT= history 1 | sed 's/^ *[0-9]\+ *//') + command="${command//;/ }" local pwd='~' [ "$PWD" != "$HOME" ] && pwd=${PWD/#$HOME\//\~\/} pwd="${pwd//[[:cntrl:]]}" - printf "\033]0;%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${pwd}" + printf '\033]777;notify;Command completed;%s\033\\\033]0;%s@%s:%s\033\\' "${command}" "${USER}" "${HOSTNAME%%.*}" "${pwd}" __vte_osc7 } -- 2.40.0 From e67e4455cc51f9d272abd17770ae3cd395932695 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 22 Jan 2015 16:37:10 +0100 Subject: [PATCH 03/11] Test the notification-received signal --- src/app/app.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/app/app.cc b/src/app/app.cc index a69d9327..29e0e953 100644 --- a/src/app/app.cc +++ b/src/app/app.cc @@ -2286,6 +2286,14 @@ window_window_title_changed_cb(VteTerminal* terminal, gtk_window_set_title(GTK_WINDOW(window), title && title[0] ? title : "Terminal"); } +static void +notification_received_cb(VteTerminal *terminal, + const gchar *summary, + const gchar *body) +{ + g_print("[%s]: %s\n", summary, body); +} + static void window_lower_window_cb(VteTerminal* terminal, VteappWindow* window) @@ -2582,8 +2590,10 @@ vteapp_window_constructed(GObject *object) if (options.object_notifications) g_signal_connect(window->terminal, "notify", G_CALLBACK(window_notify_cb), window); - /* Settings */ #if VTE_GTK == 3 + g_signal_connect(window->terminal, "notification-received", G_CALLBACK(notification_received_cb), NULL); + + /* Settings */ if (options.no_double_buffer) { G_GNUC_BEGIN_IGNORE_DEPRECATIONS; gtk_widget_set_double_buffered(GTK_WIDGET(window->terminal), false); -- 2.40.0 From 2514b0691278b74cab734cf29a47c7a86b138f5d Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 13 May 2016 17:53:54 +0200 Subject: [PATCH 04/11] Add a property to configure the scroll speed By default, it is set to zero which gives the current behaviour of moving the buffer by a function of the number of visible rows. https://bugzilla.redhat.com/show_bug.cgi?id=1103380 --- src/vte.cc | 25 ++++++++++++++++++ src/vte/vteterminal.h | 6 +++++ src/vtegtk.cc | 59 +++++++++++++++++++++++++++++++++++++++++++ src/vtegtk.hh | 3 +++ src/vteinternal.hh | 6 +++++ 5 files changed, 99 insertions(+) diff --git a/src/vte.cc b/src/vte.cc index 03868606..1c9abbab 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -9391,6 +9391,9 @@ vte_cairo_get_clip_region(cairo_t *cr) bool Terminal::widget_mouse_scroll(vte::platform::ScrollEvent const& event) { +#if _VTE_GTK == 3 + gdouble scroll_speed; +#endif gdouble v; gint cnt, i; int button; @@ -9425,7 +9428,17 @@ Terminal::widget_mouse_scroll(vte::platform::ScrollEvent const& event) return true; } +#if _VTE_GTK == 3 + if (m_scroll_speed == 0) { + scroll_speed = ceil (m_row_count /* page increment */ / 10.); + } else { + scroll_speed = m_scroll_speed; + } + + v = MAX (1., scroll_speed); +#else v = MAX (1., ceil (m_row_count /* page increment */ / 10.)); +#endif _vte_debug_print(VTE_DEBUG_EVENTS, "Scroll speed is %d lines per non-smooth scroll unit\n", (int) v); @@ -9735,6 +9748,18 @@ Terminal::decscusr_cursor_shape() const noexcept } } +#if _VTE_GTK == 3 +bool +Terminal::set_scroll_speed(unsigned int scroll_speed) +{ + if (scroll_speed == m_scroll_speed) + return false; + + m_scroll_speed = scroll_speed; + return true; +} +#endif + bool Terminal::set_scrollback_lines(long lines) { diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h index 13caec60..5985dda2 100644 --- a/src/vte/vteterminal.h +++ b/src/vte/vteterminal.h @@ -330,6 +330,12 @@ void vte_terminal_set_cursor_shape(VteTerminal *terminal, _VTE_PUBLIC VteCursorShape vte_terminal_get_cursor_shape(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1); +#if _VTE_GTK == 3 +_VTE_PUBLIC +void vte_terminal_set_scroll_speed(VteTerminal *terminal, + guint scroll_speed) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1); +#endif + /* Set the number of scrollback lines, above or at an internal minimum. */ _VTE_PUBLIC void vte_terminal_set_scrollback_lines(VteTerminal *terminal, diff --git a/src/vtegtk.cc b/src/vtegtk.cc index e9af14d1..835470f7 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1014,6 +1014,11 @@ try case PROP_REWRAP_ON_RESIZE: g_value_set_boolean (value, vte_terminal_get_rewrap_on_resize (terminal)); break; +#if _VTE_GTK == 3 + case PROP_SCROLL_SPEED: + g_value_set_uint (value, impl->m_scroll_speed); + break; +#endif case PROP_SCROLLBACK_LINES: g_value_set_uint (value, vte_terminal_get_scrollback_lines(terminal)); break; @@ -1135,6 +1140,11 @@ try case PROP_REWRAP_ON_RESIZE: vte_terminal_set_rewrap_on_resize (terminal, g_value_get_boolean (value)); break; +#if _VTE_GTK == 3 + case PROP_SCROLL_SPEED: + vte_terminal_set_scroll_speed (terminal, g_value_get_uint (value)); + break; +#endif case PROP_SCROLLBACK_LINES: vte_terminal_set_scrollback_lines (terminal, g_value_get_uint (value)); break; @@ -2235,6 +2245,23 @@ vte_terminal_class_init(VteTerminalClass *klass) TRUE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); +#if _VTE_GTK == 3 + /** + * VteTerminal:scroll-speed: + * + * The number of lines by which the buffer is moved when + * scrolling with a mouse wheel on top of the terminal + * Setting it to zero will cause the buffer to be moved by an + * amount depending on the number of visible rows the widget + * can display. + */ + pspecs[PROP_SCROLL_SPEED] = + g_param_spec_uint ("scroll-speed", NULL, NULL, + 0, G_MAXUINT, + 0, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); +#endif + /** * VteTerminal:scrollback-lines: * @@ -6060,6 +6087,38 @@ catch (...) return -1; } +#if _VTE_GTK == 3 +/** + * vte_terminal_set_scroll_speed: + * @terminal: a #VteTerminal + * @scroll_speed: move the buffer by this number of lines while scrolling + * + * Sets the number of lines by which the buffer is moved when + * scrolling with a mouse wheel. Setting it to zero will cause the + * buffer to be moved by an amount depending on the number of visible + * rows the widget can display. + */ +void +vte_terminal_set_scroll_speed(VteTerminal *terminal, + guint scroll_speed) noexcept +try +{ + g_return_if_fail(VTE_IS_TERMINAL(terminal)); + + GObject *object = G_OBJECT(terminal); + g_object_freeze_notify(object); + + if (IMPL(terminal)->set_scroll_speed(scroll_speed)) + g_object_notify_by_pspec(object, pspecs[PROP_SCROLL_SPEED]); + + g_object_thaw_notify(object); +} +catch (...) +{ + vte::log_exception(); +} +#endif + /** * vte_terminal_set_scrollback_lines: * @terminal: a #VteTerminal diff --git a/src/vtegtk.hh b/src/vtegtk.hh index d5379b16..3f1ae86d 100644 --- a/src/vtegtk.hh +++ b/src/vtegtk.hh @@ -88,6 +88,9 @@ enum { PROP_MOUSE_POINTER_AUTOHIDE, PROP_PTY, PROP_REWRAP_ON_RESIZE, +#if _VTE_GTK == 3 + PROP_SCROLL_SPEED, +#endif PROP_SCROLLBACK_LINES, PROP_SCROLL_ON_KEYSTROKE, PROP_SCROLL_ON_OUTPUT, diff --git a/src/vteinternal.hh b/src/vteinternal.hh index 8dba726c..4629c95f 100644 --- a/src/vteinternal.hh +++ b/src/vteinternal.hh @@ -428,6 +428,9 @@ public: bool m_fallback_scrolling{true}; bool m_scroll_on_output{false}; bool m_scroll_on_keystroke{true}; +#if _VTE_GTK == 3 + guint m_scroll_speed; +#endif vte::grid::row_t m_scrollback_lines{0}; inline auto scroll_limit_lower() const noexcept @@ -1385,6 +1388,9 @@ public: bool set_input_enabled(bool enabled); bool set_mouse_autohide(bool autohide); bool set_rewrap_on_resize(bool rewrap); +#if _VTE_GTK == 3 + bool set_scroll_speed(unsigned int scroll_speed); +#endif bool set_scrollback_lines(long lines); bool set_fallback_scrolling(bool set); auto fallback_scrolling() const noexcept { return m_fallback_scrolling; } -- 2.40.0 From 431763fb3dc23ffc0144c8739d9b898bf7a436f4 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 13 May 2016 17:54:57 +0200 Subject: [PATCH 05/11] Test the scroll-speed property https://bugzilla.redhat.com/show_bug.cgi?id=1103380 --- src/app/app.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/app/app.cc b/src/app/app.cc index 29e0e953..a3cc9257 100644 --- a/src/app/app.cc +++ b/src/app/app.cc @@ -118,6 +118,9 @@ public: int verbosity{0}; double cell_height_scale{1.0}; double cell_width_scale{1.0}; +#if _VTE_GTK == 3 + unsigned int scroll_speed{0}; +#endif VteCursorBlinkMode cursor_blink_mode{VTE_CURSOR_BLINK_SYSTEM}; VteCursorShape cursor_shape{VTE_CURSOR_SHAPE_BLOCK}; VteTextBlinkMode text_blink_mode{VTE_TEXT_BLINK_ALWAYS}; @@ -700,6 +703,10 @@ public: "Reverse foreground/background colors", nullptr }, { "require-systemd-scope", 0, 0, G_OPTION_ARG_NONE, &require_systemd_scope, "Require use of a systemd user scope", nullptr }, +#if _VTE_GTK == 3 + { "scroll-speed", 0, 0, G_OPTION_ARG_INT, &scroll_speed, + "Specify the scroll speed", nullptr }, +#endif { "scroll-unit-is-pixels", 0, 0, G_OPTION_ARG_NONE, &scroll_unit_is_pixels, "Use pixels as scroll unit", nullptr }, { "scrollback-lines", 'n', 0, G_OPTION_ARG_INT, &scrollback_lines, @@ -2626,6 +2633,9 @@ vteapp_window_constructed(GObject *object) vte_terminal_set_rewrap_on_resize(window->terminal, !options.no_rewrap); vte_terminal_set_scroll_on_output(window->terminal, false); vte_terminal_set_scroll_on_keystroke(window->terminal, true); +#if _VTE_GTK == 3 + vte_terminal_set_scroll_speed(window->terminal, options.scroll_speed); +#endif vte_terminal_set_scroll_unit_is_pixels(window->terminal, options.scroll_unit_is_pixels); vte_terminal_set_scrollback_lines(window->terminal, options.scrollback_lines); vte_terminal_set_text_blink_mode(window->terminal, options.text_blink_mode); -- 2.40.0 From e20d22a23be7383f8114dc59598be6c8a9bb73a0 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 7 Jan 2015 16:01:00 +0100 Subject: [PATCH 06/11] Support preexec notifications from an interactive shell Add sequences OSC 777 ; preexec BEL OSC 777 ; preexec ST that can be used from an interactive shell's preexec hook to notify the terminal emulator that a new command is about to be executed. Examples of such hooks are Bash's PS0 and Zsh's preexec. 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 | 4 ++-- src/vte/vteterminal.h | 3 ++- src/vtegtk.cc | 18 ++++++++++++++++++ src/vtegtk.hh | 1 + src/vteinternal.hh | 1 + src/vteseq.cc | 4 ++++ 7 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/vte.cc b/src/vte.cc index 1c9abbab..32d3315a 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10224,6 +10224,12 @@ Terminal::emit_pending_signals() 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); + } #endif if (m_pending_changes & vte::to_integral(PendingChanges::TITLE)) { diff --git a/src/vte.sh.in b/src/vte.sh.in index 50242223..01b44e23 100644 --- a/src/vte.sh.in +++ b/src/vte.sh.in @@ -51,9 +51,9 @@ 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_osc7) + PROMPT_COMMAND+=(__vte_osc7) && PS0=$(printf "\033]777;preexec\033\\") else - PROMPT_COMMAND="__vte_prompt_command" + PROMPT_COMMAND="__vte_prompt_command" && PS0=$(printf "\033]777;preexec\033\\") fi elif [[ -n "${ZSH_VERSION:-}" ]]; then diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h index 5985dda2..d6721a52 100644 --- a/src/vte/vteterminal.h +++ b/src/vte/vteterminal.h @@ -110,10 +110,11 @@ struct _VteTerminalClass { #if _VTE_GTK == 3 void (*notification_received)(VteTerminal* terminal, const gchar *summary, const gchar *body); + void (*shell_preexec)(VteTerminal* terminal); /* Compatibility padding due to fedora patches intruding on our ABI */ /*< private >*/ - gpointer _extra_padding[2]; + gpointer _extra_padding[1]; #endif /* _VTE_GTK == 3 */ /* Add new vfuncs here, and subtract from the padding below. */ diff --git a/src/vtegtk.cc b/src/vtegtk.cc index 835470f7..8dd7ea50 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1275,6 +1275,7 @@ vte_terminal_class_init(VteTerminalClass *klass) klass->char_size_changed = NULL; #if _VTE_GTK == 3 klass->notification_received = NULL; + klass->shell_preexec = NULL; #endif klass->window_title_changed = NULL; klass->icon_title_changed = NULL; @@ -1379,6 +1380,23 @@ vte_terminal_class_init(VteTerminalClass *klass) _vte_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); + + /** + * 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, + G_STRUCT_OFFSET(VteTerminalClass, shell_preexec), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); #endif /** diff --git a/src/vtegtk.hh b/src/vtegtk.hh index 3f1ae86d..0c86fb6e 100644 --- a/src/vtegtk.hh +++ b/src/vtegtk.hh @@ -53,6 +53,7 @@ enum { SIGNAL_RESTORE_WINDOW, SIGNAL_SELECTION_CHANGED, #if _VTE_GTK == 3 + SIGNAL_SHELL_PREEXEC, SIGNAL_NOTIFICATION_RECEIVED, #endif SIGNAL_WINDOW_TITLE_CHANGED, diff --git a/src/vteinternal.hh b/src/vteinternal.hh index 4629c95f..dfa3c0b9 100644 --- a/src/vteinternal.hh +++ b/src/vteinternal.hh @@ -686,6 +686,7 @@ public: CWF = 1u << 2, #if _VTE_GTK == 3 NOTIFICATION = 1u << 3, + SHELL_PREEXEC = 1u << 4, #endif }; unsigned m_pending_changes{0}; diff --git a/src/vteseq.cc b/src/vteseq.cc index dda487c4..f2c86b2c 100644 --- a/src/vteseq.cc +++ b/src/vteseq.cc @@ -1402,6 +1402,10 @@ Terminal::handle_urxvt_extension(vte::parser::Sequence const& seq, m_notification_body = *token; return; } + + if (*token == "preexec") { + m_pending_changes |= vte::to_integral(PendingChanges::SHELL_PREEXEC); + } } #endif -- 2.40.0 From b3b23900327e439b50b29372ee89ce887e1c4d06 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 20 Apr 2018 18:21:53 +0200 Subject: [PATCH 07/11] Test the shell-preexec signal https://bugzilla.gnome.org/show_bug.cgi?id=711059 https://bugzilla.gnome.org/show_bug.cgi?id=711060 --- src/app/app.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/app/app.cc b/src/app/app.cc index a3cc9257..813b6d1d 100644 --- a/src/app/app.cc +++ b/src/app/app.cc @@ -2301,6 +2301,12 @@ notification_received_cb(VteTerminal *terminal, g_print("[%s]: %s\n", summary, body); } +static void +shell_preexec_cb(VteTerminal *terminal) +{ + g_print("[shell] executing command\n"); +} + static void window_lower_window_cb(VteTerminal* terminal, VteappWindow* window) @@ -2599,6 +2605,7 @@ vteapp_window_constructed(GObject *object) #if VTE_GTK == 3 g_signal_connect(window->terminal, "notification-received", G_CALLBACK(notification_received_cb), NULL); + g_signal_connect(window->terminal, "shell-preexec", G_CALLBACK(shell_preexec_cb), NULL); /* Settings */ if (options.no_double_buffer) { -- 2.40.0 From 2058ed67cd3d427fb06a25c58c69bf9d9ae35a5e Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 2 May 2018 17:20:30 +0200 Subject: [PATCH 08/11] 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 32d3315a..98e60fcc 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10230,6 +10230,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 01b44e23..877fe93d 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 d6721a52..e488dc40 100644 --- a/src/vte/vteterminal.h +++ b/src/vte/vteterminal.h @@ -110,11 +110,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 */ /* Add new vfuncs here, and subtract from the padding below. */ diff --git a/src/vtegtk.cc b/src/vtegtk.cc index 8dd7ea50..00045f3a 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1275,6 +1275,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; @@ -1381,6 +1382,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 0c86fb6e..e871b946 100644 --- a/src/vtegtk.hh +++ b/src/vtegtk.hh @@ -53,6 +53,7 @@ enum { SIGNAL_RESTORE_WINDOW, SIGNAL_SELECTION_CHANGED, #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 dfa3c0b9..b8e30d15 100644 --- a/src/vteinternal.hh +++ b/src/vteinternal.hh @@ -687,6 +687,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 f2c86b2c..bae18595 100644 --- a/src/vteseq.cc +++ b/src/vteseq.cc @@ -1403,7 +1403,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.40.0 From 468a91b1d8fe95f3bd814361777dd171b9de3df6 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 2 May 2018 17:30:48 +0200 Subject: [PATCH 09/11] Test the shell-precmd signal https://bugzilla.gnome.org/show_bug.cgi?id=711059 https://bugzilla.gnome.org/show_bug.cgi?id=711060 --- src/app/app.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/app/app.cc b/src/app/app.cc index 813b6d1d..eb962e86 100644 --- a/src/app/app.cc +++ b/src/app/app.cc @@ -2301,6 +2301,12 @@ notification_received_cb(VteTerminal *terminal, g_print("[%s]: %s\n", summary, body); } +static void +shell_precmd_cb(VteTerminal *terminal) +{ + g_print("[shell] showing command prompt\n"); +} + static void shell_preexec_cb(VteTerminal *terminal) { @@ -2605,6 +2611,7 @@ vteapp_window_constructed(GObject *object) #if VTE_GTK == 3 g_signal_connect(window->terminal, "notification-received", G_CALLBACK(notification_received_cb), NULL); + g_signal_connect(window->terminal, "shell-precmd", G_CALLBACK(shell_precmd_cb), NULL); g_signal_connect(window->terminal, "shell-preexec", G_CALLBACK(shell_preexec_cb), NULL); /* Settings */ -- 2.40.0 From 329db6eea1479a91f7de428d0b97173f67348b7c Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Mon, 10 Jun 2019 20:30:18 +0200 Subject: [PATCH 10/11] Support tracking the active container inside the terminal Add sequences OSC 777 ; container ; push ; NAME ; RUNTIME ; UID BEL OSC 777 ; container ; push ; NAME ; RUNTIME ; UID ST OSC 777 ; container ; pop ; NAME ; RUNTIME ; UID BEL OSC 777 ; container ; pop ; NAME ; RUNTIME ; UID ST OSC 777 ; container ; push ; NAME ; RUNTIME BEL OSC 777 ; container ; push ; NAME ; RUNTIME ST OSC 777 ; container ; pop ; NAME ; RUNTIME BEL OSC 777 ; container ; pop ; NAME ; RUNTIME ST that let container tools notify the terminal emulator when entering and leaving a container environment. The RUNTIME argument namespaces the NAME and identifies the container tooling being used. eg., docker, flatpak, podman, toolbox, etc.. The UID argument is the real UID of the container tools. Only those containers that are used with the same real UID as the VTE process are tracked. The OSC 777 escape sequence is taken from Enlightenment's Terminology: https://phab.enlightenment.org/T1765 It's a VTE-specific extension until a standard escape sequence is agreed upon across multiple different terminal emulators [1]. [1] https://gitlab.freedesktop.org/terminal-wg/specifications/issues/17 --- src/vte.cc | 8 ++++ src/vte/vteterminal.h | 6 +++ src/vtegtk.cc | 83 +++++++++++++++++++++++++++++++++++++++ src/vtegtk.hh | 4 ++ src/vteinternal.hh | 20 ++++++++++ src/vteseq.cc | 90 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 211 insertions(+) diff --git a/src/vte.cc b/src/vte.cc index 98e60fcc..92ab5711 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10236,6 +10236,14 @@ Terminal::emit_pending_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]); + } #endif if (m_pending_changes & vte::to_integral(PendingChanges::TITLE)) { diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h index e488dc40..b1c70824 100644 --- a/src/vte/vteterminal.h +++ b/src/vte/vteterminal.h @@ -566,6 +566,12 @@ _VTE_PUBLIC glong vte_terminal_get_column_count(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1); _VTE_PUBLIC const char *vte_terminal_get_window_title(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1); +#if _VTE_GTK == 3 +_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); +#endif _VTE_PUBLIC const char *vte_terminal_get_current_directory_uri(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1); _VTE_PUBLIC diff --git a/src/vtegtk.cc b/src/vtegtk.cc index 00045f3a..83ea636e 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -963,6 +963,14 @@ try case PROP_CURSOR_BLINK_MODE: g_value_set_enum (value, vte_terminal_get_cursor_blink_mode (terminal)); break; +#if _VTE_GTK == 3 + 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; +#endif case PROP_CURRENT_DIRECTORY_URI: g_value_set_string (value, vte_terminal_get_current_directory_uri (terminal)); break; @@ -2388,6 +2396,29 @@ vte_terminal_class_init(VteTerminalClass *klass) NULL, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); +#if _VTE_GTK == 3 + /** + * 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)); +#endif + /** * VteTerminal:current-directory-uri: * @@ -5204,6 +5235,58 @@ catch (...) return -1; } +#if _VTE_GTK == 3 +/** + * 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; +} +#endif + /** * vte_terminal_get_current_directory_uri: * @terminal: a #VteTerminal diff --git a/src/vtegtk.hh b/src/vtegtk.hh index e871b946..0a31d205 100644 --- a/src/vtegtk.hh +++ b/src/vtegtk.hh @@ -74,6 +74,10 @@ enum { PROP_CJK_AMBIGUOUS_WIDTH, PROP_CURSOR_BLINK_MODE, PROP_CURSOR_SHAPE, +#if _VTE_GTK == 3 + PROP_CURRENT_CONTAINER_NAME, + PROP_CURRENT_CONTAINER_RUNTIME, +#endif PROP_CURRENT_DIRECTORY_URI, PROP_CURRENT_FILE_URI, PROP_DELETE_BINDING, diff --git a/src/vteinternal.hh b/src/vteinternal.hh index b8e30d15..0c52442b 100644 --- a/src/vteinternal.hh +++ b/src/vteinternal.hh @@ -59,6 +59,9 @@ #include #include #include +#if _VTE_GTK == 3 +#include +#endif #include #include #include @@ -110,6 +113,20 @@ typedef enum _VteCharacterReplacement { VTE_CHARACTER_REPLACEMENT_LINE_DRAWING } VteCharacterReplacement; +#if _VTE_GTK == 3 +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; +}; +#endif + typedef struct _VtePaletteColor { struct { vte::color::rgb color; @@ -666,6 +683,8 @@ public: gboolean m_contents_changed_pending; #if _VTE_GTK == 3 + std::stack m_containers; + /* desktop notification */ std::string m_notification_summary; std::string m_notification_body; @@ -688,6 +707,7 @@ public: NOTIFICATION = 1u << 3, SHELL_PREEXEC = 1u << 4, SHELL_PRECMD = 1u << 5, + CONTAINERS = 1u << 6, #endif }; unsigned m_pending_changes{0}; diff --git a/src/vteseq.cc b/src/vteseq.cc index bae18595..8a7f5b34 100644 --- a/src/vteseq.cc +++ b/src/vteseq.cc @@ -19,6 +19,7 @@ #include "config.h" + #include #include #include @@ -39,6 +40,11 @@ #define ST_C0 _VTE_CAP_ST #include +#if _VTE_GTK == 3 +#include +#include +#include +#endif using namespace std::literals; @@ -1385,6 +1391,90 @@ Terminal::handle_urxvt_extension(vte::parser::Sequence const& seq, if (token == endtoken) return; +#if _VTE_GTK == 3 + 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; + } +#endif + if (*token == "notify") { ++token; -- 2.40.0 From d1db595d6e91bd21dfc4ced7d6ae81ad851a20e9 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Tue, 16 Feb 2021 16:30:44 +0100 Subject: [PATCH 11/11] Revert "widget: Limit select-all to the writable region not including the scrollback" ... as decided by Fedora Workstation WG. https://pagure.io/fedora-workstation/issue/216 This reverts commit 73713ec0644e232fb740170e399282be778d97f9. --- src/vte.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/vte.cc b/src/vte.cc index 92ab5711..9527148c 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -6552,10 +6552,7 @@ Terminal::maybe_end_selection() /* * Terminal::select_all: * - * Selects all text within the terminal. Note that we only select the writable - * region, *not* the scrollback buffer, due to this potentially selecting so - * much data that putting it on the clipboard either hangs the process for a long - * time or even crash it directly. (FIXME!) + * Selects all text within the terminal (including the scrollback buffer). */ void Terminal::select_all() @@ -6564,8 +6561,8 @@ Terminal::select_all() m_selecting_had_delta = TRUE; - m_selection_resolved.set({m_screen->insert_delta, 0}, - {_vte_ring_next(m_screen->row_data), 0}); + m_selection_resolved.set ({ _vte_ring_delta (m_screen->row_data), 0 }, + { _vte_ring_next (m_screen->row_data), 0 }); _vte_debug_print(VTE_DEBUG_SELECTION, "Selecting *all* text.\n"); -- 2.40.0