From 099bf06e1a432690ca34ebc961e29caf7a8e698a Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu <fuzun54@outlook.com> Date: Fri, 28 Mar 2025 21:56:52 +0200 Subject: [PATCH 1/5] qml: create the scroll bar depending on the orientation in `ListViewExt` By default we expect the viewport to cover the content width or height depending on the orientation, so in normal cases we only need one scroll bar. This behavior can obviously be overridden where the list view is reused. This fixes multiple things: - Not being able to interact with the bottom part of the list view even if the orientation is vertical and the viewport covers the whole content width, because the scroll bar may still be technically visible and consume events even though it does not display anything visually. - Flashing scroll bar upon creation of the view until the content and viewport sizes are determined (regarding the orientation where scroll bar is not wanted). --- modules/gui/qt/widgets/qml/ListViewExt.qml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/gui/qt/widgets/qml/ListViewExt.qml b/modules/gui/qt/widgets/qml/ListViewExt.qml index ab4bbce99d61..26760c1c3735 100644 --- a/modules/gui/qt/widgets/qml/ListViewExt.qml +++ b/modules/gui/qt/widgets/qml/ListViewExt.qml @@ -44,6 +44,10 @@ ListView { property var isDropAcceptableFunc property var acceptDropFunc + property Component defaultScrollBar: Component { + ScrollBarExt { } + } + // Private property bool _keyPressed: false @@ -81,8 +85,18 @@ ListView { keyNavigationEnabled: false keyNavigationWraps: false - ScrollBar.vertical: ScrollBarExt { } - ScrollBar.horizontal: ScrollBarExt { } + ScrollBar.vertical: { + // By default vertical scroll bar is only used when the orientation is vertical. + if (root.defaultScrollBar && (root.orientation === ListView.Vertical)) + return root.defaultScrollBar.createObject() // rely on JS/QML engine's garbage collection + return null + } + ScrollBar.horizontal: { + // By default horizontal scroll bar is only used when the orientation is horizontal. + if (root.defaultScrollBar && (root.orientation === ListView.Horizontal)) + return root.defaultScrollBar.createObject() // rely on JS/QML engine's garbage collection + return null + } flickableDirection: Flickable.AutoFlickIfNeeded -- GitLab From a4fee8f72f4fc03a0c6462c1c14ffcdeb876a4e1 Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu <fuzun54@outlook.com> Date: Sat, 29 Mar 2025 19:25:09 +0200 Subject: [PATCH 2/5] qml: use 1.0 for `size` by default in `ScrollBarExt` Using 0.0 (default) is not a good idea and it causes the scroll bar to be shown with the full size until the size becomes meaningful when it is attached to a flickable. It is not clear why Qt uses 0.0 for the size by default. --- modules/gui/qt/widgets/qml/ScrollBarExt.qml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/gui/qt/widgets/qml/ScrollBarExt.qml b/modules/gui/qt/widgets/qml/ScrollBarExt.qml index 92fd86c1a1ae..d30db00d903d 100644 --- a/modules/gui/qt/widgets/qml/ScrollBarExt.qml +++ b/modules/gui/qt/widgets/qml/ScrollBarExt.qml @@ -53,6 +53,13 @@ T.ScrollBar { hovered: true } + // NOTE: Before the scroll bar size is set when it is attached to a flickable, + // there is an indeterminate period where the size remains 0.0. QQuickScrollBar + // using 0.0 for the size by default does not help with this situation. + // We can set the size to 1.0 by default, so that we don't show the handle + // (content item) before the size is determined: + size: 1.0 + component DefaultBehavior : Behavior { // WARNING: Qt bug: OpacityAnimator is bugged NumberAnimation { -- GitLab From 0cd86d358c993ff8b052bdb0e024453bd85ca424 Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu <fuzun54@outlook.com> Date: Sat, 29 Mar 2025 19:29:05 +0200 Subject: [PATCH 3/5] qml: instantiate the scroll bar when content is ready in `BannerSources` Both the viewport and content sizes depend on the readiness of the content. --- .../gui/qt/maininterface/qml/BannerSources.qml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/gui/qt/maininterface/qml/BannerSources.qml b/modules/gui/qt/maininterface/qml/BannerSources.qml index 03549a70b071..22052b445e17 100644 --- a/modules/gui/qt/maininterface/qml/BannerSources.qml +++ b/modules/gui/qt/maininterface/qml/BannerSources.qml @@ -348,10 +348,20 @@ T.ToolBar { contentWidth: localMenuGroup.width contentHeight: VLCStyle.localToolbar_height // don't allow vertical flickering - ScrollBar.horizontal: Widgets.ScrollBarExt { - y: localMenuView.height - height - width: localMenuView.availableWidth - policy: ScrollBar.AsNeeded + ScrollBar.horizontal: { + // The content and viewport sizes are not available in here as soon as the + // scroll bar is attached. This causes the scroll bar `size` to be briefly + // set to 0.0, making its handle be displayed only to be hidden afterwards. + if (localMenuGroup.status === Loader.Ready) + return scrollBarComponent.createObject() // rely on JS/QML engine's garbage collection + else + return null + } + + Component { + id: scrollBarComponent + + Widgets.ScrollBarExt { orientation: Qt.Horizontal } } Loader { -- GitLab From 73822592b1683c58275b26a93c9b80f1f866b1eb Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu <fuzun54@outlook.com> Date: Sat, 29 Mar 2025 19:48:26 +0200 Subject: [PATCH 4/5] qml: allow overriding the scroll bar in `ExpandGridView` This also makes it respect the default `size` (if set in the scroll bar). --- modules/gui/qt/widgets/qml/ExpandGridView.qml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/modules/gui/qt/widgets/qml/ExpandGridView.qml b/modules/gui/qt/widgets/qml/ExpandGridView.qml index 61fc52f56e65..9b34345f0bd9 100644 --- a/modules/gui/qt/widgets/qml/ExpandGridView.qml +++ b/modules/gui/qt/widgets/qml/ExpandGridView.qml @@ -19,6 +19,7 @@ import QtQuick import QtQuick.Window import QtQuick.Controls +import QtQuick.Templates as T import QtQml.Models @@ -115,6 +116,10 @@ FocusScope { property bool selected: false } + property Component defaultScrollBar: Component { + ScrollBarExt { } + } + // extra margin taken in account for positionViewAtIndex // // this is required since delegates selection rect may occupy area outside of @@ -135,7 +140,7 @@ FocusScope { property alias contentHeight: flickable.contentHeight property alias contentWidth: flickable.contentWidth property alias contentX: flickable.contentX - property alias gridScrollBar: flickableScrollBar + readonly property T.ScrollBar gridScrollBar: flickable.ScrollBar.vertical property alias expandDelegate: expandItemLoader.sourceComponent property alias expandItem: expandItemLoader.item @@ -784,8 +789,10 @@ FocusScope { boundsBehavior: Flickable.StopAtBounds - ScrollBar.vertical: ScrollBarExt { - id: flickableScrollBar + ScrollBar.vertical: { + if (root.defaultScrollBar) + return root.defaultScrollBar.createObject() // rely on JS/QML engine's garbage collector + return null } Component.onCompleted: { -- GitLab From 0791c68e656ddf28cc4af70000785356109d2fbe Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu <fuzun54@outlook.com> Date: Sat, 29 Mar 2025 19:48:39 +0200 Subject: [PATCH 5/5] qml: allow overriding the scroll bar in `BrowseHomeDisplay` This also makes it respect the default `size` (if set in the scroll bar). --- modules/gui/qt/network/qml/BrowseHomeDisplay.qml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/gui/qt/network/qml/BrowseHomeDisplay.qml b/modules/gui/qt/network/qml/BrowseHomeDisplay.qml index 14f0e41a7ed8..37a2f3bfa261 100644 --- a/modules/gui/qt/network/qml/BrowseHomeDisplay.qml +++ b/modules/gui/qt/network/qml/BrowseHomeDisplay.qml @@ -50,6 +50,10 @@ FocusScope { { text: qsTr("Url"), criteria: "mrl" } ] + property Component defaultScrollBar: Component { + Widgets.ScrollBarExt { } + } + readonly property bool hasGridListMode: true readonly property bool isSearchable: true @@ -135,7 +139,11 @@ FocusScope { anchors.leftMargin: root.leftPadding anchors.rightMargin: root.rightPadding - ScrollBar.vertical: Widgets.ScrollBarExt { } + ScrollBar.vertical: { + if (root.defaultScrollBar) + return root.defaultScrollBar.createObject() // rely on JS/QML engine's garbage collector + return null + } flickableDirection: Flickable.AutoFlickIfNeeded boundsBehavior: Flickable.StopAtBounds -- GitLab