Search code examples
csscgtk3

GtkScrolledWindow - How to always show the overlay scrollbar


I am working with a GTK3 application that needs always visible, always active scrollbars with visible steppers. I have been able to achieve this with css:

scrollbar.hover,
scrollbar {
    margin-left: 2px;
    -GtkScrollbar-has-backward-stepper: 1;
    -GtkScrollbar-has-forward-stepper: 1;
}

scrollbar trough {
    min-width: 30px;
}

scrollbar button {
    min-height: 30px;
    min-width: 30px;
}

scrollbar.right slider {
    min-height: 70px;
    min-width: 30px;
}

along with this code:

GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); //never horizontal, always vertical
g_object_set(sw, "overlay-scrolling", FALSE, NULL);

However setting overlay-scrolling to FALSE means that the scrollbars are off to the side of the GtkScrolledWindow, rather than within it. This causes layout problems for the application (a legacy application that was ported from an earlier version of gtk).

But, if I enable overlay-scrolling, the scrollbars are hidden after a couple of seconds without motion events to the GtkScolledWindow.

I've been using GtkInspector to mess with anything I can to try and disable hiding the scrollbars, but without success.

A hack would be to set a timer to keep sending motion events to the window to keep the scrollbar from hiding... but that's terribly ugly.

Any advice on where to find the secret sauce to disable overlay scrollbar hiding?


Solution

  • The short answer is that you can't using GtkScrollableWindow as is.

    I dug into the source code of the GtkScrollableWindow (search for 'opacity') to confirm that this behavior is baked-in.

    This could probably be hacked by sending a periodic "motion" signal to the window to trick it into keeping the scrollbar visible (ugly!), or, of course, modifying the GtkScrollableWindow source code. Less hacky would be to implement my own GtkScrollable, or perhaps by creating a GtkOverlay and putting a GtkScrollbar on top of the GtkScrollableWindow and mapping those scrollbar actions to the window.

    This is lower priority for the project, so I may not get the opportunity to take it further, but if any reader is able to chime in with the "best" method, it would be appreciated for at least my curiosity :)