[vte] widget: Add API to disable fallback scrolling



commit cb8f16c0bd6bbd8c0675a83541c72014e5464659
Author: Christian Persch <chpe src gnome org>
Date:   Mon Nov 16 21:34:23 2020 +0100

    widget: Add API to disable fallback scrolling
    
    Ordinarily, when the VteTerminal hasn't consumed a scroll event otherwise
    (e.g. by sending the event to the application), it falls back to perform
    a history scroll.  When the terminal is added to a GtkScrolledWindow, this
    result in the scrolled window not performing kinetic scrolling.
    
    This commit adds API (and GObject property) to VteTerminal to disable the
    fallback scrolling.
    
    Based on a patch by Tony Houghton <h realh co uk>.
    
    Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/234

 doc/reference/vte-sections.txt |  2 ++
 src/app/app.cc                 |  4 +++
 src/vte.cc                     | 17 +++++++---
 src/vte/vteterminal.h          |  6 ++++
 src/vtegtk.cc                  | 75 ++++++++++++++++++++++++++++++++++++++++--
 src/vtegtk.hh                  |  1 +
 src/vteinternal.hh             |  3 ++
 src/widget.hh                  |  3 ++
 8 files changed, 103 insertions(+), 8 deletions(-)
---
diff --git a/doc/reference/vte-sections.txt b/doc/reference/vte-sections.txt
index 28c1c958..c69181da 100644
--- a/doc/reference/vte-sections.txt
+++ b/doc/reference/vte-sections.txt
@@ -29,6 +29,8 @@ vte_terminal_set_bold_is_bright
 vte_terminal_get_bold_is_bright
 vte_terminal_set_allow_hyperlink
 vte_terminal_get_allow_hyperlink
+vte_terminal_set_enable_fallback_scrolling
+vte_terminal_get_enable_fallback_scrolling
 vte_terminal_set_scroll_on_output
 vte_terminal_get_scroll_on_output
 vte_terminal_set_scroll_on_keystroke
diff --git a/src/app/app.cc b/src/app/app.cc
index 01856462..57f56f8c 100644
--- a/src/app/app.cc
+++ b/src/app/app.cc
@@ -63,6 +63,7 @@ public:
         gboolean no_context_menu{false};
         gboolean no_decorations{false};
         gboolean no_double_buffer{false};
+        gboolean no_fallback_scrolling{false};
         gboolean no_geometry_hints{false};
         gboolean no_hyperlink{false};
         gboolean no_pty{false};
@@ -558,6 +559,8 @@ public:
                           "Disable window decorations", nullptr },
                         { "no-double-buffer", '2', 0, G_OPTION_ARG_NONE, &no_double_buffer,
                           "Disable double-buffering", nullptr },
+                        { "no-fallback-scrolling", 0, 0, G_OPTION_ARG_NONE, &no_fallback_scrolling,
+                          "Disable fallback scrolling", nullptr },
                         { "no-geometry-hints", 'G', 0, G_OPTION_ARG_NONE, &no_geometry_hints,
                           "Allow the terminal to be resized to any dimension, not constrained to fit to an 
integer multiple of characters", nullptr },
                         { "no-hyperlink", 'H', 0, G_OPTION_ARG_NONE, &no_hyperlink,
@@ -2139,6 +2142,7 @@ vteapp_window_constructed(GObject *object)
         vte_terminal_set_enable_bidi(window->terminal, !options.no_bidi);
         vte_terminal_set_enable_shaping(window->terminal, !options.no_shaping);
         vte_terminal_set_enable_sixel(window->terminal, !options.no_sixel);
+        vte_terminal_set_enable_fallback_scrolling(window->terminal, !options.no_fallback_scrolling);
         vte_terminal_set_mouse_autohide(window->terminal, true);
         vte_terminal_set_rewrap_on_resize(window->terminal, !options.no_rewrap);
         vte_terminal_set_scroll_on_output(window->terminal, false);
diff --git a/src/vte.cc b/src/vte.cc
index c364bbf5..f32c8632 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -9389,18 +9389,15 @@ Terminal::widget_mouse_scroll(vte::platform::ScrollEvent const& event)
                        send_child({normal, normal_length});
                }
                g_free (normal);
-
                 return true;
-       } else {
+       } else if (m_fallback_scrolling) {
                /* Perform a history scroll. */
                double dcnt = m_screen->scroll_delta + v * m_mouse_smooth_scroll_delta;
                queue_adjustment_value_changed_clamped(dcnt);
                m_mouse_smooth_scroll_delta = 0;
-
                 return true;
        }
-
-        return true;
+        return false;
 }
 
 bool
@@ -9506,6 +9503,16 @@ Terminal::set_allow_hyperlink(bool setting)
         return true;
 }
 
+bool
+Terminal::set_fallback_scrolling(bool set)
+{
+        if (set == m_fallback_scrolling)
+                return false;
+
+        m_fallback_scrolling = set;
+        return true;
+}
+
 bool
 Terminal::set_scroll_on_output(bool scroll)
 {
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index a255dede..a5471fd0 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -257,6 +257,12 @@ void vte_terminal_set_scroll_on_keystroke(VteTerminal *terminal,
 _VTE_PUBLIC
 gboolean vte_terminal_get_scroll_on_keystroke(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
+_VTE_PUBLIC
+void vte_terminal_set_enable_fallback_scrolling(VteTerminal *terminal,
+                                         gboolean enable) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+_VTE_PUBLIC
+gboolean vte_terminal_get_enable_fallback_scrolling(VteTerminal *terminal)  _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
+
 /* Set the color scheme. */
 _VTE_PUBLIC
 void vte_terminal_set_color_bold(VteTerminal *terminal,
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 8d725255..7cc8fb9a 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -367,9 +367,8 @@ vte_terminal_scroll(GtkWidget *widget,
                     GdkEventScroll *event) noexcept
 try
 {
-       VteTerminal *terminal = VTE_TERMINAL(widget);
-        WIDGET(terminal)->scroll(event);
-        return TRUE;
+        auto terminal = VTE_TERMINAL(widget);
+        return WIDGET(terminal)->scroll(event);
 }
 catch (...)
 {
@@ -725,6 +724,9 @@ try
                 case PROP_ENABLE_BIDI:
                         g_value_set_boolean (value, vte_terminal_get_enable_bidi (terminal));
                         break;
+                case PROP_ENABLE_FALLBACK_SCROLLING:
+                        g_value_set_boolean (value, vte_terminal_get_enable_fallback_scrolling(terminal));
+                        break;
                 case PROP_ENABLE_SHAPING:
                         g_value_set_boolean (value, vte_terminal_get_enable_shaping (terminal));
                         break;
@@ -846,6 +848,9 @@ try
                 case PROP_ENABLE_BIDI:
                         vte_terminal_set_enable_bidi (terminal, g_value_get_boolean (value));
                         break;
+                case PROP_ENABLE_FALLBACK_SCROLLING:
+                        vte_terminal_set_enable_fallback_scrolling (terminal, g_value_get_boolean (value));
+                        break;
                 case PROP_ENABLE_SHAPING:
                         vte_terminal_set_enable_shaping (terminal, g_value_get_boolean (value));
                         break;
@@ -1985,6 +1990,20 @@ vte_terminal_class_init(VteTerminalClass *klass)
                                       TRUE,
                                       (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | 
G_PARAM_EXPLICIT_NOTIFY));
 
+        /**
+         * VteTerminal:handle-scroll:
+         *
+         * Controls whether or not the terminal manages its own scrolling. This can be
+         * disabled when the terminal is the child of a GtkScrolledWindow to take
+         * advantage of kinetic scrolling.
+         *
+         * Since: 0.64
+         */
+        pspecs[PROP_ENABLE_FALLBACK_SCROLLING] =
+                g_param_spec_boolean ("enable-fallback-scrolling", nullptr, nullptr,
+                                      true,
+                                      GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | 
G_PARAM_EXPLICIT_NOTIFY));
+
         /**
          * VteTerminal:text-blink-mode:
          *
@@ -5509,6 +5528,56 @@ catch (...)
         return false;
 }
 
+/**
+ * vte_terminal_set_enable_fallback_scrolling:
+ * @terminal: a #VteTerminal
+ * @enable: whether to enable fallback scrolling
+ *
+ * Controls whether the terminal uses scroll events to scroll the history
+ * if the event was not otherwise consumed by it.
+ *
+ * This function is rarely useful, except when the terminal is added to a
+ * #GtkScrolledWindow, to perform kinetic scrolling (while vte itself does
+ * not, yet, implement kinetic scrolling by itself).
+ *
+ * Since: 0.64
+ */
+void
+vte_terminal_set_enable_fallback_scrolling(VteTerminal *terminal,
+                                           gboolean enable) noexcept
+try
+{
+        g_return_if_fail(VTE_IS_TERMINAL(terminal));
+
+        if (WIDGET(terminal)->set_fallback_scrolling(enable != false))
+                g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_ENABLE_FALLBACK_SCROLLING]);
+}
+catch (...)
+{
+        vte::log_exception();
+}
+
+/**
+ * vte_terminal_get_enable_fallback_scrolling:
+ * @terminal: a #VteTerminal
+ *
+ * Returns: %TRUE if fallback scrolling is enabled
+ *
+ * Since: 0.64
+ */
+gboolean
+vte_terminal_get_enable_fallback_scrolling(VteTerminal *terminal) noexcept
+try
+{
+    g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
+    return WIDGET(terminal)->fallback_scrolling();
+}
+catch (...)
+{
+        vte::log_exception();
+        return true;
+}
+
 /**
  * vte_terminal_get_window_title:
  * @terminal: a #VteTerminal
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index cb207e57..6a87a948 100644
--- a/src/vtegtk.hh
+++ b/src/vtegtk.hh
@@ -77,6 +77,7 @@ enum {
         PROP_CURRENT_FILE_URI,
         PROP_DELETE_BINDING,
         PROP_ENABLE_BIDI,
+        PROP_ENABLE_FALLBACK_SCROLLING,
         PROP_ENABLE_SHAPING,
         PROP_ENABLE_SIXEL,
         PROP_ENCODING,
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 19b8c19f..d3881e10 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -406,6 +406,7 @@ public:
         gboolean m_text_deleted_flag;
 
        /* Scrolling options. */
+        bool m_fallback_scrolling{true};
         bool m_scroll_on_output{false};
         bool m_scroll_on_keystroke{true};
         vte::grid::row_t m_scrollback_lines{0};
@@ -1260,6 +1261,8 @@ public:
         bool set_mouse_autohide(bool autohide);
         bool set_rewrap_on_resize(bool rewrap);
         bool set_scrollback_lines(long lines);
+        bool set_fallback_scrolling(bool set);
+        auto fallback_scrolling() const noexcept { return m_fallback_scrolling; }
         bool set_scroll_on_keystroke(bool scroll);
         bool set_scroll_on_output(bool scroll);
         bool set_images_enabled(bool enabled);
diff --git a/src/widget.hh b/src/widget.hh
index bcce34f9..8f245154 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -324,6 +324,9 @@ public:
         bool set_word_char_exceptions(std::optional<std::string_view> stropt);
         auto word_char_exceptions() const noexcept { return m_word_char_exceptions ? 
m_word_char_exceptions.value().c_str() : nullptr; }
 
+        bool set_fallback_scrolling(bool set) { return terminal()->set_fallback_scrolling(set); }
+        bool fallback_scrolling() const noexcept { return terminal()->fallback_scrolling(); }
+
         char const* encoding() const noexcept { return m_terminal->encoding(); }
 
         void emit_child_exited(int status) noexcept;


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