Qt5 scrolling problem

Linus Torvalds torvalds at linux-foundation.org
Sun Apr 26 14:39:31 PDT 2015


So I mentioned to Dirk last week that I had found a regression in
subsurface, but I hadn't pinpointed the cause. I spent some time
trying to figure out why current subsurface does the wrong thing, and
quite frankly, I *still* don't get it, but by now I'm blaming Qt5 for
being horrible and wrong.

The regression is that when I start up subsurface, it scrolls the
divelist view so that the latest dive is at the top. "But that's what
should happen!" I hear you say. No it's not, actually.

The dive list should start with the latest *trip* visible, and that's
how it used to be. But current subsurface starts up with the dive
itself at the top, and the trip description has scrolled off the list
view.

Explicitly to avoid that, our common scrolling pattern is that we
first scroll to the trip that the dive is in, and then scroll to the
dive itself. The reason we do that is exactly so that the trip would
be visible, unless the trip is so big that scrolling to the specific
dive ends up scrolling the trip header off the screen.

Now, the reason seems to be "currentChanged()", which does just

        if (!current.isValid())
                return;
        scrollTo(current);

but the reason I'm blaming Qt5 for this mess is that when I change it to do

        if (!current.isValid())
                return;
        if (current.parent().isValid())
                scrollTo(current.parent());
        scrollTo(current);

it still doesn't work. The last "scrollTo(current)" seems to scroll
the parent (the trip) off the top of the window again, and you end up
with the dive visible on the first line, but the trip not visible.

Removing that final "scrollTo(current):" fixes things for me, but that
will afaik do the wrong thing if a trip has a lot of dives, and we
select one that isn't visible after you've scrolled the trip line to
be visible.

So I'm not sure what's going on. We've used some variation of that
"scroll to parent, then scroll to dive" in several places, sometimes
together with "expand(parent);" and "setAnimated(false/true);" around
the parent scrolling so that we wouldn't be visibly jerking
back-and-forth.

The default for "scrollTo()" is ScrollHint::EnsureVisible, but the
dive *is* visible when you've scrolled the trip to the top, so it
shouldn't scroll the trip away. My *guess* is that this all happens
before the window has been painted and setup completely, so it doesn't
have its final size, leading to Qt5 thinking the dive isn't visible
and scrolling to it, and scrolling away the trip line. But somebody
who actually knows Qt is needed.

Anybody who understands Qt? Tomaz? Thiago?

And this doesn't show up for everything. If I do

     ./build/subsurface dives/*.xml

to try to show this with the test-dives we have, I don't get the same
behavior as I do with . Then I *do* get the trip header visible. So if
some Qt person doesn't go "I know what's up", and cannot reproduce
this, I can send you all my dives in an xml file in private to help
you see the behavior..

                          Linus


More information about the subsurface mailing list