From 059d8da6b2691c3c742fb3a6f89344c7f16bbf50 Mon Sep 17 00:00:00 2001 From: Black Hat Date: Wed, 17 Jul 2019 16:02:54 +0800 Subject: [PATCH 1/2] Remove ScrollHelper. Scrolling is fixed in Qt upstream. --- imports/Spectral/Component/AutoListView.qml | 11 -- imports/Spectral/Component/ScrollHelper.qml | 105 -------------------- imports/Spectral/Component/qmldir | 2 - imports/Spectral/Panel/RoomDrawer.qml | 4 +- imports/Spectral/Panel/RoomListPanel.qml | 4 +- imports/Spectral/Panel/RoomPanel.qml | 12 +-- res.qrc | 2 - 7 files changed, 10 insertions(+), 130 deletions(-) delete mode 100644 imports/Spectral/Component/AutoListView.qml delete mode 100644 imports/Spectral/Component/ScrollHelper.qml diff --git a/imports/Spectral/Component/AutoListView.qml b/imports/Spectral/Component/AutoListView.qml deleted file mode 100644 index ddb82d73b..000000000 --- a/imports/Spectral/Component/AutoListView.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.12 - -ListView { - pixelAligned: true - - ScrollHelper { - anchors.fill: parent - - flickable: parent - } -} diff --git a/imports/Spectral/Component/ScrollHelper.qml b/imports/Spectral/Component/ScrollHelper.qml deleted file mode 100644 index e3a6032b5..000000000 --- a/imports/Spectral/Component/ScrollHelper.qml +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2016 Michael Bohlender, - * Copyright (C) 2017 Christian Mollekopf, - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -import QtQuick 2.12 -import QtQuick.Controls 2.12 - -/* -* The MouseArea + interactive: false + maximumFlickVelocity are required -* to fix scrolling for desktop systems where we don't want flicking behaviour. -* -* See also: -* ScrollView.qml in qtquickcontrols -* qquickwheelarea.cpp in qtquickcontrols -*/ -MouseArea { - id: root - propagateComposedEvents: true - - property Flickable flickable - property alias enabled: root.enabled - - //Place the mouse area under the flickable - z: -1 - onFlickableChanged: { - if (enabled) { - flickable.interactive = false - flickable.maximumFlickVelocity = 100000 - flickable.boundsBehavior = Flickable.StopAtBounds - root.parent = flickable - } - } - - function calculateNewPosition(flickableItem, wheel) { - //Nothing to scroll - if (flickableItem.contentHeight < flickableItem.height) { - return flickableItem.contentY; - } - //Ignore 0 events (happens at least with Christians trackpad) - if (wheel.pixelDelta.y == 0 && wheel.angleDelta.y == 0) { - return flickableItem.contentY; - } - //pixelDelta seems to be the same as angleDelta/8 - var pixelDelta = 0 - //The pixelDelta is a smaller number if both are provided, so pixelDelta can be 0 while angleDelta is still something. So we check the angleDelta - if (wheel.angleDelta.y) { - var wheelScrollLines = 3 //Default value of QApplication wheelScrollLines property - var pixelPerLine = 20 //Default value in Qt, originally comes from QTextEdit - var ticks = (wheel.angleDelta.y / 8) / 15.0 //Divide by 8 gives us pixels typically come in 15pixel steps. - pixelDelta = ticks * pixelPerLine * wheelScrollLines - } else { - pixelDelta = wheel.pixelDelta.y - } - - if (!pixelDelta) { - return flickableItem.contentY; - } - - var minYExtent = flickableItem.originY + flickableItem.topMargin; - var maxYExtent = (flickableItem.contentHeight + flickableItem.bottomMargin + flickableItem.originY) - flickableItem.height; - - if (typeof(flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) { - minYExtent += flickableItem.headerItem.height - } - - //Avoid overscrolling - return Math.max(minYExtent, Math.min(maxYExtent, flickableItem.contentY - pixelDelta)); - } - - onWheel: { - var newPos = calculateNewPosition(flickable, wheel); - // console.warn("Delta: ", wheel.pixelDelta.y); - // console.warn("Old position: ", flickable.contentY); - // console.warn("New position: ", newPos); - - // Show the scrollbars - flickable.flick(0, 0); - flickable.contentY = newPos; - cancelFlickStateTimer.start() - } - - - Timer { - id: cancelFlickStateTimer - //How long the scrollbar will remain visible - interval: 500 - // Hide the scrollbars - onTriggered: flickable.cancelFlick(); - } -} diff --git a/imports/Spectral/Component/qmldir b/imports/Spectral/Component/qmldir index dd821c5c3..79dcf6136 100644 --- a/imports/Spectral/Component/qmldir +++ b/imports/Spectral/Component/qmldir @@ -2,8 +2,6 @@ module Spectral.Component AutoMouseArea 2.0 AutoMouseArea.qml MaterialIcon 2.0 MaterialIcon.qml SideNavButton 2.0 SideNavButton.qml -ScrollHelper 2.0 ScrollHelper.qml -AutoListView 2.0 AutoListView.qml AutoTextField 2.0 AutoTextField.qml Avatar 2.0 Avatar.qml FullScreenImage 2.0 FullScreenImage.qml diff --git a/imports/Spectral/Panel/RoomDrawer.qml b/imports/Spectral/Panel/RoomDrawer.qml index 6875f608b..9d476bbb6 100644 --- a/imports/Spectral/Panel/RoomDrawer.qml +++ b/imports/Spectral/Panel/RoomDrawer.qml @@ -172,7 +172,7 @@ Drawer { } } - AutoListView { + ListView { Layout.fillWidth: true Layout.fillHeight: true @@ -180,6 +180,8 @@ Drawer { clip: true + pixelAligned: true + boundsBehavior: Flickable.DragOverBounds model: UserListModel { diff --git a/imports/Spectral/Panel/RoomListPanel.qml b/imports/Spectral/Panel/RoomListPanel.qml index e72805523..40f207c22 100644 --- a/imports/Spectral/Panel/RoomListPanel.qml +++ b/imports/Spectral/Panel/RoomListPanel.qml @@ -185,7 +185,7 @@ Item { } } - AutoListView { + ListView { Layout.fillWidth: true Layout.fillHeight: true @@ -197,6 +197,8 @@ Item { model: sortedRoomListModel + pixelAligned: true + boundsBehavior: Flickable.DragOverBounds ScrollBar.vertical: ScrollBar {} diff --git a/imports/Spectral/Panel/RoomPanel.qml b/imports/Spectral/Panel/RoomPanel.qml index 9ee0af4e5..cb06d132f 100644 --- a/imports/Spectral/Panel/RoomPanel.qml +++ b/imports/Spectral/Panel/RoomPanel.qml @@ -223,7 +223,7 @@ Item { spacing: 16 - AutoListView { + ListView { readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1 readonly property bool noNeedMoreContent: !currentRoom || currentRoom.eventsHistoryJob || currentRoom.allHistoryLoaded @@ -241,6 +241,8 @@ Item { boundsBehavior: Flickable.DragOverBounds + pixelAligned: true + model: SortFilterProxyModel { id: sortedMessageEventModel @@ -254,16 +256,10 @@ Item { onModelReset: { movingTimer.stop() + messageListView.positionViewAtBeginning() if (currentRoom) { movingTimer.restart() - var lastScrollPosition = sortedMessageEventModel.mapFromSource(currentRoom.savedTopVisibleIndex()) - if (lastScrollPosition === 0) { - messageListView.positionViewAtBeginning() - } else { - messageListView.currentIndex = lastScrollPosition - } - if (messageListView.contentY < messageListView.originY + 10 || currentRoom.timelineSize < 20) currentRoom.getPreviousContent(50) } diff --git a/res.qrc b/res.qrc index 8ab4cf4bb..628625de4 100644 --- a/res.qrc +++ b/res.qrc @@ -26,8 +26,6 @@ imports/Spectral/Panel/RoomListPanel.qml imports/Spectral/Panel/RoomPanel.qml imports/Spectral/Panel/RoomHeader.qml - imports/Spectral/Component/ScrollHelper.qml - imports/Spectral/Component/AutoListView.qml imports/Spectral/Component/AutoTextField.qml imports/Spectral/Panel/RoomPanelInput.qml imports/Spectral/Component/Timeline/SectionDelegate.qml From 9c8d77abdb0bf9b9662bcdb8690c13d4765d890d Mon Sep 17 00:00:00 2001 From: Black Hat Date: Wed, 17 Jul 2019 10:02:50 +0000 Subject: [PATCH 2/2] Revert "Remove ScrollHelper. Scrolling is fixed in Qt upstream." This reverts commit 059d8da6b2691c3c742fb3a6f89344c7f16bbf50 --- imports/Spectral/Component/AutoListView.qml | 11 ++ imports/Spectral/Component/ScrollHelper.qml | 105 ++++++++++++++++++++ imports/Spectral/Component/qmldir | 2 + imports/Spectral/Panel/RoomDrawer.qml | 4 +- imports/Spectral/Panel/RoomListPanel.qml | 4 +- imports/Spectral/Panel/RoomPanel.qml | 12 ++- res.qrc | 2 + 7 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 imports/Spectral/Component/AutoListView.qml create mode 100644 imports/Spectral/Component/ScrollHelper.qml diff --git a/imports/Spectral/Component/AutoListView.qml b/imports/Spectral/Component/AutoListView.qml new file mode 100644 index 000000000..ddb82d73b --- /dev/null +++ b/imports/Spectral/Component/AutoListView.qml @@ -0,0 +1,11 @@ +import QtQuick 2.12 + +ListView { + pixelAligned: true + + ScrollHelper { + anchors.fill: parent + + flickable: parent + } +} diff --git a/imports/Spectral/Component/ScrollHelper.qml b/imports/Spectral/Component/ScrollHelper.qml new file mode 100644 index 000000000..e3a6032b5 --- /dev/null +++ b/imports/Spectral/Component/ScrollHelper.qml @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 Michael Bohlender, + * Copyright (C) 2017 Christian Mollekopf, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +/* +* The MouseArea + interactive: false + maximumFlickVelocity are required +* to fix scrolling for desktop systems where we don't want flicking behaviour. +* +* See also: +* ScrollView.qml in qtquickcontrols +* qquickwheelarea.cpp in qtquickcontrols +*/ +MouseArea { + id: root + propagateComposedEvents: true + + property Flickable flickable + property alias enabled: root.enabled + + //Place the mouse area under the flickable + z: -1 + onFlickableChanged: { + if (enabled) { + flickable.interactive = false + flickable.maximumFlickVelocity = 100000 + flickable.boundsBehavior = Flickable.StopAtBounds + root.parent = flickable + } + } + + function calculateNewPosition(flickableItem, wheel) { + //Nothing to scroll + if (flickableItem.contentHeight < flickableItem.height) { + return flickableItem.contentY; + } + //Ignore 0 events (happens at least with Christians trackpad) + if (wheel.pixelDelta.y == 0 && wheel.angleDelta.y == 0) { + return flickableItem.contentY; + } + //pixelDelta seems to be the same as angleDelta/8 + var pixelDelta = 0 + //The pixelDelta is a smaller number if both are provided, so pixelDelta can be 0 while angleDelta is still something. So we check the angleDelta + if (wheel.angleDelta.y) { + var wheelScrollLines = 3 //Default value of QApplication wheelScrollLines property + var pixelPerLine = 20 //Default value in Qt, originally comes from QTextEdit + var ticks = (wheel.angleDelta.y / 8) / 15.0 //Divide by 8 gives us pixels typically come in 15pixel steps. + pixelDelta = ticks * pixelPerLine * wheelScrollLines + } else { + pixelDelta = wheel.pixelDelta.y + } + + if (!pixelDelta) { + return flickableItem.contentY; + } + + var minYExtent = flickableItem.originY + flickableItem.topMargin; + var maxYExtent = (flickableItem.contentHeight + flickableItem.bottomMargin + flickableItem.originY) - flickableItem.height; + + if (typeof(flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) { + minYExtent += flickableItem.headerItem.height + } + + //Avoid overscrolling + return Math.max(minYExtent, Math.min(maxYExtent, flickableItem.contentY - pixelDelta)); + } + + onWheel: { + var newPos = calculateNewPosition(flickable, wheel); + // console.warn("Delta: ", wheel.pixelDelta.y); + // console.warn("Old position: ", flickable.contentY); + // console.warn("New position: ", newPos); + + // Show the scrollbars + flickable.flick(0, 0); + flickable.contentY = newPos; + cancelFlickStateTimer.start() + } + + + Timer { + id: cancelFlickStateTimer + //How long the scrollbar will remain visible + interval: 500 + // Hide the scrollbars + onTriggered: flickable.cancelFlick(); + } +} diff --git a/imports/Spectral/Component/qmldir b/imports/Spectral/Component/qmldir index 79dcf6136..dd821c5c3 100644 --- a/imports/Spectral/Component/qmldir +++ b/imports/Spectral/Component/qmldir @@ -2,6 +2,8 @@ module Spectral.Component AutoMouseArea 2.0 AutoMouseArea.qml MaterialIcon 2.0 MaterialIcon.qml SideNavButton 2.0 SideNavButton.qml +ScrollHelper 2.0 ScrollHelper.qml +AutoListView 2.0 AutoListView.qml AutoTextField 2.0 AutoTextField.qml Avatar 2.0 Avatar.qml FullScreenImage 2.0 FullScreenImage.qml diff --git a/imports/Spectral/Panel/RoomDrawer.qml b/imports/Spectral/Panel/RoomDrawer.qml index 9d476bbb6..6875f608b 100644 --- a/imports/Spectral/Panel/RoomDrawer.qml +++ b/imports/Spectral/Panel/RoomDrawer.qml @@ -172,7 +172,7 @@ Drawer { } } - ListView { + AutoListView { Layout.fillWidth: true Layout.fillHeight: true @@ -180,8 +180,6 @@ Drawer { clip: true - pixelAligned: true - boundsBehavior: Flickable.DragOverBounds model: UserListModel { diff --git a/imports/Spectral/Panel/RoomListPanel.qml b/imports/Spectral/Panel/RoomListPanel.qml index 40f207c22..e72805523 100644 --- a/imports/Spectral/Panel/RoomListPanel.qml +++ b/imports/Spectral/Panel/RoomListPanel.qml @@ -185,7 +185,7 @@ Item { } } - ListView { + AutoListView { Layout.fillWidth: true Layout.fillHeight: true @@ -197,8 +197,6 @@ Item { model: sortedRoomListModel - pixelAligned: true - boundsBehavior: Flickable.DragOverBounds ScrollBar.vertical: ScrollBar {} diff --git a/imports/Spectral/Panel/RoomPanel.qml b/imports/Spectral/Panel/RoomPanel.qml index cb06d132f..9ee0af4e5 100644 --- a/imports/Spectral/Panel/RoomPanel.qml +++ b/imports/Spectral/Panel/RoomPanel.qml @@ -223,7 +223,7 @@ Item { spacing: 16 - ListView { + AutoListView { readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1 readonly property bool noNeedMoreContent: !currentRoom || currentRoom.eventsHistoryJob || currentRoom.allHistoryLoaded @@ -241,8 +241,6 @@ Item { boundsBehavior: Flickable.DragOverBounds - pixelAligned: true - model: SortFilterProxyModel { id: sortedMessageEventModel @@ -256,10 +254,16 @@ Item { onModelReset: { movingTimer.stop() - messageListView.positionViewAtBeginning() if (currentRoom) { movingTimer.restart() + var lastScrollPosition = sortedMessageEventModel.mapFromSource(currentRoom.savedTopVisibleIndex()) + if (lastScrollPosition === 0) { + messageListView.positionViewAtBeginning() + } else { + messageListView.currentIndex = lastScrollPosition + } + if (messageListView.contentY < messageListView.originY + 10 || currentRoom.timelineSize < 20) currentRoom.getPreviousContent(50) } diff --git a/res.qrc b/res.qrc index 628625de4..8ab4cf4bb 100644 --- a/res.qrc +++ b/res.qrc @@ -26,6 +26,8 @@ imports/Spectral/Panel/RoomListPanel.qml imports/Spectral/Panel/RoomPanel.qml imports/Spectral/Panel/RoomHeader.qml + imports/Spectral/Component/ScrollHelper.qml + imports/Spectral/Component/AutoListView.qml imports/Spectral/Component/AutoTextField.qml imports/Spectral/Panel/RoomPanelInput.qml imports/Spectral/Component/Timeline/SectionDelegate.qml