From 73d13d1bfee620c76709ea39a9b7948323887059 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 22 Feb 2022 09:44:55 +0000 Subject: [PATCH] redo the stackorder based on where the item is. With the keyboard navigation patch there is the issue that sometimes, due to sorting by SortFilterModel, the stack order of the items doesn't correspond to the visual order of the items. This is a problem wrt the recently introduced keyboard navigation, as the tab order of items in qml is completely tied to the stack order, resulting in an erratic tab navigation order (usually happens with device notifier or bluetooth applets for instance) --- .../package/contents/ui/items/ItemLoader.qml | 1 + .../systemtray/package/contents/ui/main.qml | 18 +++++++++++++++++- applets/systemtray/systemtray.cpp | 16 ++++++++++++++++ applets/systemtray/systemtray.h | 7 +++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/applets/systemtray/package/contents/ui/items/ItemLoader.qml b/applets/systemtray/package/contents/ui/items/ItemLoader.qml index 40141fe9a..0135ff705 100644 --- a/applets/systemtray/package/contents/ui/items/ItemLoader.qml +++ b/applets/systemtray/package/contents/ui/items/ItemLoader.qml @@ -9,6 +9,7 @@ import QtQuick 2.0 Loader { id: itemLoader + z: x property var itemModel: model onActiveFocusChanged: { if (activeFocus && item) { diff --git a/applets/systemtray/package/contents/ui/main.qml b/applets/systemtray/package/contents/ui/main.qml index e437a871e..7ef26defb 100644 --- a/applets/systemtray/package/contents/ui/main.qml +++ b/applets/systemtray/package/contents/ui/main.qml @@ -159,7 +159,23 @@ MouseArea { } } - delegate: ItemLoader {} + delegate: ItemLoader { + id: delegate + // We need to recalculate the stacking order of the z values due to how keyboard navigation works + // the tab order depends exclusively from this, so we redo it as the position in the list + // ensuring tab navigation focuses the expected items + Component.onCompleted: { + let item = tasksGrid.itemAtIndex(index - 1); + if (item) { + plasmoid.nativeInterface.stackItemBefore(delegate, item) + } else { + item = tasksGrid.itemAtIndex(index + 1); + } + if (item) { + plasmoid.nativeInterface.stackItemAfter(delegate, item) + } + } + } add: Transition { enabled: itemSize > 0 diff --git a/applets/systemtray/systemtray.cpp b/applets/systemtray/systemtray.cpp index dbc23e652..f1af1e60c 100644 --- a/applets/systemtray/systemtray.cpp +++ b/applets/systemtray/systemtray.cpp @@ -366,6 +366,22 @@ void SystemTray::stopApplet(const QString &pluginId) } } +void SystemTray::stackItemBefore(QQuickItem *newItem, QQuickItem *beforeItem) +{ + if (!newItem || !beforeItem) { + return; + } + newItem->stackBefore(beforeItem); +} + +void SystemTray::stackItemAfter(QQuickItem *newItem, QQuickItem *afterItem) +{ + if (!newItem || !afterItem) { + return; + } + newItem->stackAfter(afterItem); +} + K_PLUGIN_CLASS_WITH_JSON(SystemTray, "package/metadata.json") #include "systemtray.moc" diff --git a/applets/systemtray/systemtray.h b/applets/systemtray/systemtray.h index 28708ea8b..9fe70e288 100644 --- a/applets/systemtray/systemtray.h +++ b/applets/systemtray/systemtray.h @@ -67,6 +67,13 @@ public: */ Q_INVOKABLE bool isSystemTrayApplet(const QString &appletId); + /** + * Needed to preserve keyboard navigation + */ + Q_INVOKABLE void stackItemBefore(QQuickItem *newItem, QQuickItem *beforeItem); + + Q_INVOKABLE void stackItemAfter(QQuickItem *newItem, QQuickItem *afterItem); + private Q_SLOTS: // synchronizes with configuration and deletes not allowed applets void onEnabledAppletsChanged();