Skip to content

ScrollablePage: add ensureVisible method

Christoph Wolk requested to merge cwo/kirigami:scrollablepage_visi into master

If the ScrollablePage's contents do not automatically handle positioning the viewable area on focus changes (the way that Views generally do), passing focus with e.g. keyboard navigation may leave the currently focused item out of view. Applications filling the page directly with e.g. a FormLayout or CardsLayout will need to scroll explicitly when necessary. This is possible with ScrollablePage's API, but the scrolling logic needs to be implemented by each application separately.

This change adds a convenience function that scrolls the viewable area in a reasonable manner, which controls can call if they receive focus.


This problem can be seen in Discover's home page prior to 334a3e05, or e.g. in Elisa in either the edit mode of the track metadata view, or (with a sufficiently small window size) the settings dialog. Tabbing through the controls will leave items further down focused but not in the visible area.

The following minimal example also shows the problem:

import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts
import org.kde.kirigami as Kirigami

Kirigami.ScrollablePage {
    id: page
    ColumnLayout {
        Repeater {
            model: 100
            delegate: QQC2.Button {
                text: modelData
                onFocusChanged: if (focus) page.ensureVisible(this)
            }}
    }
}

With the onFocusChanges signal handler set, tab-navigation works; without it users have to scroll the page manually while tabbing to see which button they are on.

This can be handled completely by applications, but Aleix would reasonably prefer a solution in Kirigami (see plasma/discover!1001 (merged) and !1690 (merged)), so we don't need to paste the logic around applications.

Shortcomings of this approach:

  • Applications still need to set the signal handler (as in the code example above). This is not very cumbersome if used with a repeater, but still easy to forget. I could see it being rather cumbersome to add to each element of a FormLayout.
  • The item needs to be in the coordinate system of the ScrollablePage's flickable. I've added optional offset parameters in case of more complicated layouts where an item is in the coordinate system of a child of the flickable, but this is still inconvenient.
Edited by Christoph Wolk

Merge request reports

Loading