[vte/wip/issue-335: 2/2] widget: Add API to make scrolling pixel-based
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/issue-335: 2/2] widget: Add API to make scrolling pixel-based
- Date: Tue, 2 Mar 2021 19:46:30 +0000 (UTC)
commit ad377998889c06b5d870ff255567bc0d1428aced
Author: Christian Persch <chpe src gnome org>
Date: Tue Mar 2 20:46:18 2021 +0100
widget: Add API to make scrolling pixel-based
https://gitlab.gnome.org/GNOME/vte/-/issues/335
https://gitlab.gnome.org/GNOME/gtk/-/issues/3707
doc/reference/vte-sections.txt.in | 2 ++
src/app/app.cc | 4 +++
src/vte/vteterminal.h | 6 ++++
src/vtegtk.cc | 68 +++++++++++++++++++++++++++++++++++++++
src/vtegtk.hh | 1 +
src/widget.cc | 27 +++++++++++++---
src/widget.hh | 11 +++++++
7 files changed, 115 insertions(+), 4 deletions(-)
---
diff --git a/doc/reference/vte-sections.txt.in b/doc/reference/vte-sections.txt.in
index 53079292..f078b0ae 100644
--- a/doc/reference/vte-sections.txt.in
+++ b/doc/reference/vte-sections.txt.in
@@ -35,6 +35,8 @@ vte_terminal_set_scroll_on_output
vte_terminal_get_scroll_on_output
vte_terminal_set_scroll_on_keystroke
vte_terminal_get_scroll_on_keystroke
+vte_terminal_set_scroll_unit_pixels
+vte_terminal_get_scroll_unit_pixels
vte_terminal_set_cell_height_scale
vte_terminal_get_cell_height_scale
vte_terminal_set_cell_width_scale
diff --git a/src/app/app.cc b/src/app/app.cc
index e7a20c87..bee48a1a 100644
--- a/src/app/app.cc
+++ b/src/app/app.cc
@@ -81,6 +81,7 @@ public:
gboolean object_notifications{false};
gboolean require_systemd_scope{false};
gboolean reverse{false};
+ gboolean scroll_unit_pixels{false};
gboolean test_mode{false};
gboolean track_clipboard_targets{false};
gboolean use_theme_colors{false};
@@ -622,6 +623,8 @@ 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 },
+ { "scroll-unit-pixels", 0, 0, G_OPTION_ARG_NONE, &scroll_unit_pixels,
+ "Use pixels as scroll unit", nullptr },
{ "scrollback-lines", 'n', 0, G_OPTION_ARG_INT, &scrollback_lines,
"Specify the number of scrollback-lines (-1 for infinite)", nullptr },
{ "sixel", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &no_sixel,
@@ -2528,6 +2531,7 @@ 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);
+ vte_terminal_set_scroll_unit_pixels(window->terminal, options.scroll_unit_pixels);
vte_terminal_set_scrollback_lines(window->terminal, options.scrollback_lines);
vte_terminal_set_text_blink_mode(window->terminal, options.text_blink_mode);
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index 346523ad..95472450 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -270,6 +270,12 @@ void vte_terminal_set_enable_fallback_scrolling(VteTerminal *terminal,
_VTE_PUBLIC
gboolean vte_terminal_get_enable_fallback_scrolling(VteTerminal *terminal) _VTE_CXX_NOEXCEPT
_VTE_GNUC_NONNULL(1);
+_VTE_PUBLIC
+void vte_terminal_set_scroll_unit_pixels(VteTerminal *terminal,
+ gboolean enable) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+_VTE_PUBLIC
+gboolean vte_terminal_get_scroll_unit_pixels(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 1f35e749..01aff289 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -1001,6 +1001,9 @@ try
case PROP_SCROLL_ON_OUTPUT:
g_value_set_boolean (value, vte_terminal_get_scroll_on_output(terminal));
break;
+ case PROP_SCROLL_UNIT_PIXELS:
+ g_value_set_boolean (value, vte_terminal_get_scroll_unit_pixels(terminal));
+ break;
case PROP_TEXT_BLINK_MODE:
g_value_set_enum (value, vte_terminal_get_text_blink_mode (terminal));
break;
@@ -1119,6 +1122,9 @@ try
case PROP_SCROLL_ON_OUTPUT:
vte_terminal_set_scroll_on_output (terminal, g_value_get_boolean (value));
break;
+ case PROP_SCROLL_UNIT_PIXELS:
+ vte_terminal_set_scroll_unit_pixels(terminal, g_value_get_boolean(value));
+ break;
case PROP_TEXT_BLINK_MODE:
vte_terminal_set_text_blink_mode (terminal, (VteTextBlinkMode)g_value_get_enum
(value));
break;
@@ -2239,6 +2245,20 @@ vte_terminal_class_init(VteTerminalClass *klass)
true,
GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY));
+ /**
+ * VteTerminal:scroll-unit-pixels:
+ *
+ * Controls whether the terminal's GtkAdjustment values unit is lines
+ * or pixels. This can be enabled when the terminal is the child of a
+ * GtkScrolledWindow to fix some bugs with its kinetic scrolling.
+ *
+ * Since: 0.66
+ */
+ pspecs[PROP_SCROLL_UNIT_PIXELS] =
+ g_param_spec_boolean ("scroll-unit-pixels", nullptr, nullptr,
+ false,
+ GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY));
+
/**
* VteTerminal:text-blink-mode:
*
@@ -5854,6 +5874,54 @@ catch (...)
return true;
}
+/**
+ * vte_terminal_set_scroll_unit_pixels:
+ * @terminal: a #VteTerminal
+ * @enable: whether to use pixels as scroll unit
+ *
+ * Controls whether the terminal's scroll unit is lines or pixels.
+ *
+ * This function is rarely useful, except when the terminal is added to a
+ * #GtkScrolledWindow.
+ *
+ * Since: 0.66
+ */
+void
+vte_terminal_set_scroll_unit_pixels(VteTerminal *terminal,
+ gboolean enable) noexcept
+try
+{
+ g_return_if_fail(VTE_IS_TERMINAL(terminal));
+
+ if (WIDGET(terminal)->set_scroll_unit_pixels(enable != false))
+ g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_SCROLL_UNIT_PIXELS]);
+}
+catch (...)
+{
+ vte::log_exception();
+}
+
+/**
+ * vte_terminal_get_scroll_unit_pixels:
+ * @terminal: a #VteTerminal
+ *
+ * Returns: %TRUE if the scroll unit is pixels; or %FALSE if the unit is lines
+ *
+ * Since: 0.66
+ */
+gboolean
+vte_terminal_get_scroll_unit_pixels(VteTerminal *terminal) noexcept
+try
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
+ return WIDGET(terminal)->scroll_unit_pixels();
+}
+catch (...)
+{
+ vte::log_exception();
+ return false;
+}
+
/**
* vte_terminal_get_window_title:
* @terminal: a #VteTerminal
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index e56314ad..e46d3ca5 100644
--- a/src/vtegtk.hh
+++ b/src/vtegtk.hh
@@ -88,6 +88,7 @@ enum {
PROP_SCROLLBACK_LINES,
PROP_SCROLL_ON_KEYSTROKE,
PROP_SCROLL_ON_OUTPUT,
+ PROP_SCROLL_UNIT_PIXELS,
PROP_TEXT_BLINK_MODE,
PROP_WINDOW_TITLE,
PROP_WORD_CHAR_EXCEPTIONS,
diff --git a/src/widget.cc b/src/widget.cc
index b9265750..db1a616e 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -151,6 +151,7 @@ catch (...)
Widget::Widget(VteTerminal* t)
: m_widget{&t->widget},
+ m_scroll_unit_pixels{false},
m_hscroll_policy{GTK_SCROLL_NATURAL},
m_vscroll_policy{GTK_SCROLL_NATURAL}
{
@@ -745,8 +746,16 @@ Widget::notify_scroll_bounds_changed(long lower,
auto const freezer = vte::glib::FreezeObjectNotify{m_vadjustment.get()};
auto changed = false;
- auto const dlower = double(lower);
- auto const dupper = double(upper);
+ auto dlower = double(lower);
+ auto dupper = double(upper);
+ auto dline = 1.;
+ if (scroll_unit_pixels()) {
+ auto const factor = m_terminal->get_cell_height();
+ dlower *= factor;
+ dupper *= factor;
+ dline *= factor;
+ row_count *= factor;
+ }
auto current = gtk_adjustment_get_lower(m_vadjustment.get());
if (!_vte_double_equal(current, dlower)) {
@@ -768,7 +777,7 @@ Widget::notify_scroll_bounds_changed(long lower,
/* The step increment should always be one. */
auto v = gtk_adjustment_get_step_increment(m_vadjustment.get());
- if (!_vte_double_equal(v, 1.)) {
+ if (!_vte_double_equal(v, dline)) {
_vte_debug_print(VTE_DEBUG_ADJ,
"Changing step increment from %.0lf to 1.0\n", v);
gtk_adjustment_set_step_increment(m_vadjustment.get(), 1.);
@@ -805,6 +814,11 @@ Widget::notify_scroll_bounds_changed(long lower,
void
Widget::notify_scroll_value_changed(double value)
{
+ if (scroll_unit_pixels()) {
+ auto const factor = m_terminal->get_cell_height();
+ value *= factor;
+ }
+
auto const v = gtk_adjustment_get_value(m_vadjustment.get());
if (!_vte_double_equal(v, value)) {
/* Note that this will generate a 'value-changed' signal */
@@ -1384,7 +1398,12 @@ Widget::vadjustment_value_changed()
if (!m_terminal)
return;
- auto const adj = gtk_adjustment_get_value(m_vadjustment.get());
+ auto adj = gtk_adjustment_get_value(m_vadjustment.get());
+ if (scroll_unit_pixels()) {
+ auto const factor = m_terminal->get_cell_height();
+ adj /= factor;
+ }
+
m_terminal->set_scroll_value(adj);
}
diff --git a/src/widget.hh b/src/widget.hh
index 5e9b5a59..3f475ac5 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -350,6 +350,16 @@ public:
void set_vscroll_policy(GtkScrollablePolicy policy);
auto hscroll_policy() const noexcept { return m_hscroll_policy; }
auto vscroll_policy() const noexcept { return m_vscroll_policy; }
+
+ constexpr bool set_scroll_unit_pixels(bool enable) noexcept
+ {
+ auto const rv = m_scroll_unit_pixels != enable;
+ m_scroll_unit_pixels = enable;
+ return rv;
+ }
+
+ constexpr auto scroll_unit_pixels() const noexcept { return m_scroll_unit_pixels; }
+
auto padding() const noexcept { return terminal()->padding(); }
bool set_cursor_blink_mode(VteCursorBlinkMode mode) { return
terminal()->set_cursor_blink_mode(vte::terminal::Terminal::CursorBlinkMode(mode)); }
@@ -522,6 +532,7 @@ private:
vte::glib::RefPtr<GtkAdjustment> m_vadjustment{};
vte::glib::RefPtr<GtkAdjustment> m_hadjustment{};
+ uint32_t m_scroll_unit_pixels : 1;
uint32_t m_hscroll_policy : 1;
uint32_t m_vscroll_policy : 1;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]