From c9f1a449d825d5879735f95ebfb0c7acec101226 Mon Sep 17 00:00:00 2001 From: Reilly Brogan Date: Wed, 12 Jun 2024 15:24:53 -0500 Subject: [PATCH] linux: Use kirigami mouse handling if available Qt6 changed the mouse scroll wheel handling for QtQuick to a type that mimics how touch pads/screens work, which most people find feels very poor. KDE fixes this by creating a custom type which re-implements the QtWidgets handling (see https://invent.kde.org/frameworks/kirigami/-/merge_requests/415). On Matrix Nico has expressed a desire not to have to deal with compiling Kirigami for Windows and Mac, which is understandable. Linux users on the other hand almost always have kirigami available in their package repos which sidesteps that particular issue. We can search for Kirigami at build time and if present define a QML context property to allow it to be used, which should fix this issue for Linux users at least. Helps with nheko-reborn/nheko#1819 (which won't be completely resolved until this is working for Windows and Mac as well). Signed-off-by: Reilly Brogan --- CMakeLists.txt | 24 ++++++++++++++++++- resources/qml/CommunitiesList.qml | 4 ++++ resources/qml/Completer.qml | 4 ++++ resources/qml/MessageView.qml | 4 ++++ resources/qml/RoomList.qml | 4 ++++ resources/qml/UploadBox.qml | 4 ++++ resources/qml/components/AdaptiveLayout.qml | 4 ++++ .../qml/components/KirigamiWheelHandler.qml | 12 ++++++++++ .../qml/components/ReorderableListview.qml | 4 ++++ resources/qml/dialogs/AliasEditor.qml | 3 +++ .../dialogs/AllowedRoomsSettingsDialog.qml | 3 +++ resources/qml/dialogs/IgnoredUsers.qml | 4 ++++ .../qml/dialogs/ImagePackEditorDialog.qml | 3 +++ .../qml/dialogs/ImagePackSettingsDialog.qml | 4 +++- resources/qml/dialogs/InviteDialog.qml | 7 ++++++ .../dialogs/PowerLevelSpacesApplyDialog.qml | 4 ++++ resources/qml/dialogs/ReadReceipts.qml | 4 ++++ resources/qml/dialogs/RoomDirectory.qml | 4 ++++ resources/qml/dialogs/RoomMembers.qml | 3 +++ resources/qml/dialogs/UserProfile.qml | 4 ++++ resources/qml/emoji/StickerPicker.qml | 4 ++++ src/MainWindow.cpp | 7 ++++++ 22 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 resources/qml/components/KirigamiWheelHandler.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index 1832968ea..2016a4ff2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,6 +277,20 @@ else() find_package(KDSingleApplication-qt6 REQUIRED) endif() +if(UNIX) + set(KF_MIN_VERSION "6.0.0") + find_package(ECM ${KF_MIN_VERSION}) + if(ECM_FOUND) + list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + find_package(KF6 COMPONENTS + Kirigami + ) + if(KF6_FOUND) + add_compile_definitions(NHEKO_USE_KIRIGAMI) + endif() + endif() +endif() + if(Qt6Widgets_FOUND) if(Qt6Widgets_VERSION VERSION_LESS 6.5.0) message(STATUS "Qt version ${Qt6Widgets_VERSION}") @@ -821,12 +835,20 @@ set(QML_SOURCES resources/qml/delegates/EncryptionEnabled.qml resources/qml/ui/TimelineEffects.qml ) +set(QML_DEPENDENCIES + QtQuick + QtQml.Models +) +if(KF6_FOUND) + list(APPEND QML_SOURCES "resources/qml/components/KirigamiWheelHandler.qml") + list(APPEND QML_DEPENDENCIES "org.kde.kirigami") +endif() qt_add_qml_module(nheko URI im.nheko NO_RESOURCE_TARGET_PATH RESOURCE_PREFIX "/" VERSION 1.1 - DEPENDENCIES QtQuick QtQml.Models + DEPENDENCIES ${QML_DEPENDENCIES} QML_FILES ${QML_SOURCES} SOURCES diff --git a/resources/qml/CommunitiesList.qml b/resources/qml/CommunitiesList.qml index 2b0be72c0..c4a5a9837 100644 --- a/resources/qml/CommunitiesList.qml +++ b/resources/qml/CommunitiesList.qml @@ -38,6 +38,10 @@ Page { model: Communities.filtered() boundsBehavior: Flickable.StopAtBounds + Loader { + source: NHEKO_USE_KIRIGAMI ? "components/KirigamiWheelHandler.qml" : "" + } + ScrollBar.vertical: ScrollBar { id: scrollbar diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index c6fea98ea..890ba2036 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -93,6 +93,10 @@ Control { contentItem: ListView { id: listView + Loader { + source: NHEKO_USE_KIRIGAMI ? "components/KirigamiWheelHandler.qml" : "" + } + clip: true displayMarginBeginning: height / 2 displayMarginEnd: height / 2 diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index a49761b23..9e83f2b7d 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -65,6 +65,10 @@ Item { spacing: 2 verticalLayoutDirection: ListView.BottomToTop + Loader { + source: NHEKO_USE_KIRIGAMI ? "components/KirigamiWheelHandler.qml" : "" + } + property int lastScrollPos: 0 // Fixup the scroll position when the height changes. Without this, the view is kept around the center of the currently visible content, while we usually want to stick to the bottom. diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index 44a3e333d..f3c4ecca4 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -446,6 +446,10 @@ Page { model: Rooms boundsBehavior: Flickable.StopAtBounds + Loader { + source: NHEKO_USE_KIRIGAMI ? "components/KirigamiWheelHandler.qml" : "" + } + //reuseItems: true ScrollBar.vertical: ScrollBar { id: scrollbar diff --git a/resources/qml/UploadBox.qml b/resources/qml/UploadBox.qml index 1d9415e5c..dd3d2188e 100644 --- a/resources/qml/UploadBox.qml +++ b/resources/qml/UploadBox.qml @@ -22,6 +22,10 @@ Page { contentItem: ListView { id: uploadsList + Loader { + source: NHEKO_USE_KIRIGAMI ? "components/KirigamiWheelHandler.qml" : "" + } + anchors.horizontalCenter: parent.horizontalCenter boundsBehavior: Flickable.StopAtBounds model: room ? room.input.uploads : undefined diff --git a/resources/qml/components/AdaptiveLayout.qml b/resources/qml/components/AdaptiveLayout.qml index eb8ec341d..3fda3fb81 100644 --- a/resources/qml/components/AdaptiveLayout.qml +++ b/resources/qml/components/AdaptiveLayout.qml @@ -122,6 +122,10 @@ Container { contentItem: ListView { id: view + Loader { + source: NHEKO_USE_KIRIGAMI ? "KirigamiWheelHandler.qml" : "" + } + model: container.contentModel snapMode: ListView.SnapOneItem orientation: ListView.Horizontal diff --git a/resources/qml/components/KirigamiWheelHandler.qml b/resources/qml/components/KirigamiWheelHandler.qml new file mode 100644 index 000000000..d1d444360 --- /dev/null +++ b/resources/qml/components/KirigamiWheelHandler.qml @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import org.kde.kirigami as Kirigami + +Kirigami.WheelHandler { + id: wheelHandler + target: parent + filterMouseEvents: true + keyNavigationEnabled: true +} diff --git a/resources/qml/components/ReorderableListview.qml b/resources/qml/components/ReorderableListview.qml index b5d5f5e58..4ed604b2c 100644 --- a/resources/qml/components/ReorderableListview.qml +++ b/resources/qml/components/ReorderableListview.qml @@ -100,6 +100,10 @@ Item { ListView { id: view + Loader { + source: NHEKO_USE_KIRIGAMI ? "KirigamiWheelHandler.qml" : "" + } + clip: true anchors { fill: parent; margins: 2 } diff --git a/resources/qml/dialogs/AliasEditor.qml b/resources/qml/dialogs/AliasEditor.qml index 82f127505..619fce4f4 100644 --- a/resources/qml/dialogs/AliasEditor.qml +++ b/resources/qml/dialogs/AliasEditor.qml @@ -52,6 +52,9 @@ ApplicationWindow { clip: true + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } model: editingModel spacing: 4 diff --git a/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml b/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml index 82b5506e4..a689a1c20 100644 --- a/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml +++ b/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml @@ -51,6 +51,9 @@ ApplicationWindow { clip: true + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } model: roomSettings.allowedRoomsModel spacing: 4 diff --git a/resources/qml/dialogs/IgnoredUsers.qml b/resources/qml/dialogs/IgnoredUsers.qml index 6d6585f0b..ac45de352 100644 --- a/resources/qml/dialogs/IgnoredUsers.qml +++ b/resources/qml/dialogs/IgnoredUsers.qml @@ -26,6 +26,10 @@ Window { spacing: Nheko.paddingMedium footerPositioning: ListView.OverlayFooter + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } + model: TimelineManager.ignoredUsers header: ColumnLayout { Text { diff --git a/resources/qml/dialogs/ImagePackEditorDialog.qml b/resources/qml/dialogs/ImagePackEditorDialog.qml index 9416ec971..be8a58425 100644 --- a/resources/qml/dialogs/ImagePackEditorDialog.qml +++ b/resources/qml/dialogs/ImagePackEditorDialog.qml @@ -49,6 +49,9 @@ ApplicationWindow { model: imagePack + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } header: AvatarListTile { title: imagePack.packname diff --git a/resources/qml/dialogs/ImagePackSettingsDialog.qml b/resources/qml/dialogs/ImagePackSettingsDialog.qml index 690684054..c4496f49c 100644 --- a/resources/qml/dialogs/ImagePackSettingsDialog.qml +++ b/resources/qml/dialogs/ImagePackSettingsDialog.qml @@ -59,7 +59,9 @@ ApplicationWindow { model: packlist clip: true - + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } footer: ColumnLayout { Button { diff --git a/resources/qml/dialogs/InviteDialog.qml b/resources/qml/dialogs/InviteDialog.qml index 9fc165c7b..a45099390 100644 --- a/resources/qml/dialogs/InviteDialog.qml +++ b/resources/qml/dialogs/InviteDialog.qml @@ -166,6 +166,9 @@ ApplicationWindow { Layout.fillWidth: true Layout.fillHeight: true clip: true + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } delegate: UserListRow { id: del2 width: ListView.view.width @@ -192,6 +195,10 @@ ApplicationWindow { clip: true visible: inviteDialogRoot.width >= 500 + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } + delegate: UserListRow { id: del hoverEnabled: true diff --git a/resources/qml/dialogs/PowerLevelSpacesApplyDialog.qml b/resources/qml/dialogs/PowerLevelSpacesApplyDialog.qml index 6a2e74b2b..946332f5b 100644 --- a/resources/qml/dialogs/PowerLevelSpacesApplyDialog.qml +++ b/resources/qml/dialogs/PowerLevelSpacesApplyDialog.qml @@ -86,6 +86,10 @@ ApplicationWindow { spacing: 4 cacheBuffer: 50 + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } + delegate: RowLayout { anchors.left: parent.left anchors.right: parent.right diff --git a/resources/qml/dialogs/ReadReceipts.qml b/resources/qml/dialogs/ReadReceipts.qml index 74a4d1d8e..e93a2a947 100644 --- a/resources/qml/dialogs/ReadReceipts.qml +++ b/resources/qml/dialogs/ReadReceipts.qml @@ -54,6 +54,10 @@ ApplicationWindow { boundsBehavior: Flickable.StopAtBounds model: readReceipts + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } + delegate: ItemDelegate { id: del diff --git a/resources/qml/dialogs/RoomDirectory.qml b/resources/qml/dialogs/RoomDirectory.qml index dbf3b4591..9de3dfa3e 100644 --- a/resources/qml/dialogs/RoomDirectory.qml +++ b/resources/qml/dialogs/RoomDirectory.qml @@ -34,6 +34,10 @@ ApplicationWindow { anchors.fill: parent model: publicRooms + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } + delegate: Rectangle { id: roomDirDelegate diff --git a/resources/qml/dialogs/RoomMembers.qml b/resources/qml/dialogs/RoomMembers.qml index 95dc9fc34..f843fc9e0 100644 --- a/resources/qml/dialogs/RoomMembers.qml +++ b/resources/qml/dialogs/RoomMembers.qml @@ -108,6 +108,9 @@ ApplicationWindow { boundsBehavior: Flickable.StopAtBounds model: members + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } delegate: ItemDelegate { id: del diff --git a/resources/qml/dialogs/UserProfile.qml b/resources/qml/dialogs/UserProfile.qml index 6798bc791..735b55269 100644 --- a/resources/qml/dialogs/UserProfile.qml +++ b/resources/qml/dialogs/UserProfile.qml @@ -45,6 +45,10 @@ ApplicationWindow { anchors.margins: 10 footerPositioning: ListView.OverlayFooter + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } + header: ColumnLayout { id: contentL diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index b7721db64..aea169887 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -116,6 +116,10 @@ Menu { clip: true currentIndex: -1 // prevent sorting from stealing focus + Loader { + source: NHEKO_USE_KIRIGAMI ? "../components/KirigamiWheelHandler.qml" : "" + } + section.property: "packname" section.criteria: ViewSection.FullString section.delegate: Rectangle { diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 42a1521d8..bb4ff3f61 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -123,6 +124,12 @@ MainWindow::registerQmlTypes() nhlog::ui()->warn("Could not connect to D-Bus!"); } #endif + +#ifdef NHEKO_USE_KIRIGAMI + engine()->rootContext()->setContextProperty("NHEKO_USE_KIRIGAMI", QVariant(true)); +#else + engine()->rootContext()->setContextProperty("NHEKO_USE_KIRIGAMI", QVariant(false)); +#endif } void