diff options
author | Wolfgang Müller | 2021-06-18 20:52:47 +0200 |
---|---|---|
committer | Wolfgang Müller | 2021-06-19 15:53:07 +0200 |
commit | ff27c3da1266df519aa15d95cfc32ad9d0d7b5e5 (patch) | |
tree | bea9378203f8da92f922e668b58b1489c771a354 /terminal.vala | |
parent | 52134524e92824cfb0a33414e93f35421dd62265 (diff) | |
download | weltschmerz-ff27c3da1266df519aa15d95cfc32ad9d0d7b5e5.tar.gz |
Always draw the scrollbar if overlay scrolling is off
weltschmerz uses GtkScrolledWindow to provide a vertical scrollbar to
the user. By default, this widget enables overlay scrolling. This means
that the scrollbar is painted "inside" the terminal, as if overlaid.
There's no configuration switch to turn this behaviour off, since we are
convinced that overlay scrolling is the right thing to do for terminals.
However, GTK allows users to turn off overlay scrolling in a global
setting [1] or by using the 'GTK_OVERLAY_SCROLLING' environment
variable. Some distributions turn overlay scrolling off by default.
When overlay scrolling is disabled, GtkScrolledWindow falls back to
rendering the scrollbar normally. Since our scrollbar policy is set to
AUTOMATIC, it is only drawn on demand. This means that it is initially
not be visible but can suddenly take up effective window space once it
appears.
When this happens, depending on what is going on in the terminal, one
can be left with a terminal that is scrolling down infinitely as the
reported column width flaps between two values: one accounting for the
size of the scrollbar and the other one ignoring it. Each time the
column width flaps, VTE sends SIGWINCH, possibly getting caught in an
infinite loop of internal resizes.
Since upstream declares GtkScrolledWindow incompatible with VTE [2] [3],
we have not attempted further investigation on this issue, but may
report an issue in the future.
We definitely want to keep using GtkScrolledWindow even with this
incompatibility - it is the most elegant and visually pleasing solution.
The alternative would be to use a GtkBox and supply our own scrollbar.
This scrollbar would either always be visible (even if there is nothing
to scroll) or entirely hidden. An implementation of this may be found in
the box-scroll branch. Note, however, that we do not guarantee that
branch to be up to date with the latest developments.
To work around this problem, detect when overlay scrolling is turned off
and fall back to PolicyType.ALWAYS. This ensures that the scrollbar is
always visible, mitigating the infinite resize loop. Crucially, compared
to the alternative solution, this will still enable users to enjoy
overlay scrolling if they (or their distribution) do not turn it off.
[1] https://developer.gnome.org/gtk3/stable/GtkSettings.html#GtkSettings--gtk-overlay-scrolling
[2] https://gitlab.gnome.org/GNOME/vte/-/issues/11#note_264921
[3] https://bugzilla.gnome.org/show_bug.cgi?id=733210#c2
Diffstat (limited to 'terminal.vala')
-rw-r--r-- | terminal.vala | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/terminal.vala b/terminal.vala index b9f96de..42da259 100644 --- a/terminal.vala +++ b/terminal.vala @@ -34,8 +34,10 @@ class Terminal : Gtk.Overlay { [GtkChild] unowned Gtk.SearchEntry search_entry; [GtkChild] unowned Vte.Terminal vte; Gtk.Clipboard clipboard; + Gtk.Settings settings; bool has_search; + bool overlay_scrolling_env_override; string url_match; string hyperlink_match; uint? infobar_timeout_id; @@ -44,6 +46,11 @@ class Terminal : Gtk.Overlay { public Terminal(string[] args, Gtk.Container parent, Gtk.Window window) { Object(parent: parent, window: window); + settings = Gtk.Settings.get_for_screen(window.screen); + + if (Environment.get_variable("GTK_OVERLAY_SCROLLING") == "0") + overlay_scrolling_env_override = true; + load_config(false); search_update_sensitivity(); @@ -74,11 +81,20 @@ class Terminal : Gtk.Overlay { } } + Gtk.PolicyType get_scrollbar_policy(bool want_scrollbar) { + if (!want_scrollbar) + return Gtk.PolicyType.NEVER; + + if (!settings.gtk_overlay_scrolling || overlay_scrolling_env_override) + return Gtk.PolicyType.ALWAYS; + + return Gtk.PolicyType.AUTOMATIC; + } + public void load_config(bool reload) { var conf = new Config(); - Gtk.PolicyType policy = conf.scrollbar ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER; - scrolled_window.set_policy(Gtk.PolicyType.NEVER, policy); + scrolled_window.set_policy(Gtk.PolicyType.NEVER, get_scrollbar_policy(conf.scrollbar)); vte.set_allow_hyperlink(conf.allow_hyperlinks); |