From 3354db2ca10487dd6ced2c54130b12e3a7bc53f8 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 a8671845..77533d82 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10164,6 +10164,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 78176f97..ac762498 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 3945ba67..570f8e69 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1251,6 +1251,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; @@ -1334,6 +1337,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.37.3 From ca0549eafe1fd03d11a632d07c0fab7fd4b333ac 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.37.3 From b281275ed320f9a2f82d6e436a397ad005dafce0 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 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/app/app.cc b/src/app/app.cc index a69d9327..88fe5f2f 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,6 +2590,8 @@ vteapp_window_constructed(GObject *object) if (options.object_notifications) g_signal_connect(window->terminal, "notify", G_CALLBACK(window_notify_cb), window); + g_signal_connect(window->terminal, "notification-received", G_CALLBACK(notification_received_cb), NULL); + /* Settings */ #if VTE_GTK == 3 if (options.no_double_buffer) { -- 2.37.3 From 2832ac1e0bf8eb3e0147b0803637765a4b5ac832 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 77533d82..e2723342 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -9364,6 +9364,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; @@ -9398,7 +9401,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); @@ -9708,6 +9721,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 ac762498..972c4a0c 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 570f8e69..a9f58696 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1002,6 +1002,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; @@ -1123,6 +1128,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; @@ -2223,6 +2233,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: * @@ -5958,6 +5985,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.37.3 From 10f3d37fdc465152b805e54d3217a61d69e4c255 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 88fe5f2f..49a1689d 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.37.3 From d2f139cc2f440a390bec6438a4292b50213f5818 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 e2723342..766b7624 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10197,6 +10197,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 972c4a0c..8bdd3ccf 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 a9f58696..797865db 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1263,6 +1263,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; @@ -1367,6 +1368,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.37.3 From 05425620f9e65704eec774cd567e15f5e385f89d 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 49a1689d..90b2dfe5 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) @@ -2598,6 +2604,7 @@ vteapp_window_constructed(GObject *object) g_signal_connect(window->terminal, "notify", G_CALLBACK(window_notify_cb), window); 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 VTE_GTK == 3 -- 2.37.3 From 57dd88ebfe1b3df1bafe7fd904dd0df7c1094f59 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 766b7624..6cef7b17 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10203,6 +10203,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 8bdd3ccf..31bb3b75 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 797865db..bd3a8798 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -1263,6 +1263,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; @@ -1369,6 +1370,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.37.3 From 089580a09de21160f871875fe960e895bc5b5bc2 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 90b2dfe5..5c4946c9 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) { @@ -2604,6 +2610,7 @@ vteapp_window_constructed(GObject *object) g_signal_connect(window->terminal, "notify", G_CALLBACK(window_notify_cb), window); 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.37.3 From 2e940b5a720dea9a06fd47862381f27f765f76dd 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 6cef7b17..21823424 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -10209,6 +10209,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 31bb3b75..12ecf181 100644 --- a/src/vte/vteterminal.h +++ b/src/vte/vteterminal.h @@ -551,6 +551,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 bd3a8798..0457b2b9 100644 --- a/src/vtegtk.cc +++ b/src/vtegtk.cc @@ -951,6 +951,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; @@ -2376,6 +2384,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: * @@ -5129,6 +5160,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.37.3 From f15bfe821e0deefcf62d649c27e73b802f5338f0 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 21823424..20767b61 100644 --- a/src/vte.cc +++ b/src/vte.cc @@ -6525,10 +6525,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() @@ -6537,8 +6534,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.37.3