From bb7739e5537a3774a82fb47f13b7c3730cff812c Mon Sep 17 00:00:00 2001 From: wjyrich Date: Fri, 20 Mar 2026 17:18:07 +0800 Subject: [PATCH] fix: fix warning with closebtn and binding loop. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新了 closebtn的未定义问题,修复了hover通知,循环依赖问题。 更新通知焦点循环一次后,第二次循环无法经过overlapnotify,从而无法给到焦点到后面其他的通知上。 以及修复 shift+tab 保证跟tab的逻辑一致,能够正常响应焦点处理。 还需修复: 带有action的通知焦点处理。 --- panels/notification/center/GroupNotify.qml | 3 +-- panels/notification/center/NormalNotify.qml | 18 +++++++----------- panels/notification/center/NotifyHeader.qml | 1 - panels/notification/center/NotifyView.qml | 4 +++- .../center/NotifyViewDelegate.qml | 11 ++--------- panels/notification/center/OverlapNotify.qml | 19 ++++++++----------- .../notification/plugin/NotifyItemContent.qml | 6 +++--- 7 files changed, 24 insertions(+), 38 deletions(-) diff --git a/panels/notification/center/GroupNotify.qml b/panels/notification/center/GroupNotify.qml index c4d0b1fe7..6e6187024 100644 --- a/panels/notification/center/GroupNotify.qml +++ b/panels/notification/center/GroupNotify.qml @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -111,7 +111,6 @@ NotifyItem { icon.name: "clean-group" text: qsTr("Clear All") Keys.onTabPressed: function(event) { - groupClearBtn.focus = false // Clear focus before signal to prevent focus state residue root.gotoNextItem() event.accepted = true } diff --git a/panels/notification/center/NormalNotify.qml b/panels/notification/center/NormalNotify.qml index 64fd89dc3..9637b7664 100644 --- a/panels/notification/center/NormalNotify.qml +++ b/panels/notification/center/NormalNotify.qml @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -13,7 +13,6 @@ NotifyItem { id: root implicitWidth: impl.implicitWidth implicitHeight: impl.implicitHeight - property bool shouldShowClose: false // True when item gets focus from keyboard navigation signal gotoNextItem() signal gotoPrevItem() @@ -32,19 +31,16 @@ NotifyItem { focus: true Keys.onTabPressed: function(event) { - // Mark that this item got focus from Tab navigation - root.shouldShowClose = true - if (notifyContent.focusFirstButton()) { - event.accepted = true - } else { + if (!notifyContent.focusFirstButton()) { root.gotoNextItem() - event.accepted = true } + event.accepted = true } Keys.onBacktabPressed: function(event) { - root.shouldShowClose = true - root.gotoPrevItem() + if (!notifyContent.focusLastButton()) { + root.gotoPrevItem() + } event.accepted = true } @@ -59,7 +55,7 @@ NotifyItem { actions: root.actions defaultAction: root.defaultAction // Show close button when: mouse hovers, or item has focus from keyboard navigation - parentHovered: impl.hovered || (root.activeFocus && root.shouldShowClose) + parentHovered: impl.hovered || root.activeFocus strongInteractive: root.strongInteractive contentIcon: root.contentIcon contentRowCount: root.contentRowCount diff --git a/panels/notification/center/NotifyHeader.qml b/panels/notification/center/NotifyHeader.qml index 035a61031..fdb279085 100644 --- a/panels/notification/center/NotifyHeader.qml +++ b/panels/notification/center/NotifyHeader.qml @@ -150,7 +150,6 @@ FocusScope { text: qsTr("Clear All") Layout.alignment: Qt.AlignRight Keys.onTabPressed: function(event) { - clearAllBtn.focus = false // Clear focus before signal to prevent focus state residue root.gotoFirstNotify() event.accepted = true } diff --git a/panels/notification/center/NotifyView.qml b/panels/notification/center/NotifyView.qml index 63b7234c5..cf041c06e 100644 --- a/panels/notification/center/NotifyView.qml +++ b/panels/notification/center/NotifyView.qml @@ -38,7 +38,9 @@ Control { function tryFocus(retries) { let item = view.itemAtIndex(idx) if (item && item.enabled) { - item.forceActiveFocus() + if (!item.focusFirstButton()) { + item.forceActiveFocus() + } } else if (retries > 0) { Qt.callLater(function() { tryFocus(retries - 1) }) } diff --git a/panels/notification/center/NotifyViewDelegate.qml b/panels/notification/center/NotifyViewDelegate.qml index a97db3326..a03bff0d8 100644 --- a/panels/notification/center/NotifyViewDelegate.qml +++ b/panels/notification/center/NotifyViewDelegate.qml @@ -26,7 +26,6 @@ DelegateChooser { Qt.callLater(function() { let nextItem = view.itemAtIndex(currentIndex + 1) if (nextItem && nextItem.enabled) { - // Focus on the item itself first, not directly to buttons nextItem.forceActiveFocus() } }) @@ -43,7 +42,6 @@ DelegateChooser { Qt.callLater(function() { let prevItem = view.itemAtIndex(currentIndex - 1) if (prevItem && prevItem.enabled) { - // Focus on the item itself first, not directly to buttons prevItem.forceActiveFocus() } }) @@ -177,8 +175,8 @@ DelegateChooser { activeFocusOnTab: false focusBorderVisible: activeFocus Keys.onTabPressed: function(event) { - // Try to focus first action button - if (overlapNotify.focusFirstButton()) { + // Try to focus first action button (skip clear button to avoid loop) + if (notifyContent.focusFirstActionOnly()) { event.accepted = true return } @@ -196,11 +194,6 @@ DelegateChooser { } } - Component.onCompleted: { - // Pass clear button reference to OverlapNotify - overlapNotify.clearButton = clearBtn - } - TapHandler { acceptedButtons: Qt.RightButton onPressedChanged: function () { diff --git a/panels/notification/center/OverlapNotify.qml b/panels/notification/center/OverlapNotify.qml index c5700145b..0b4a2109c 100644 --- a/panels/notification/center/OverlapNotify.qml +++ b/panels/notification/center/OverlapNotify.qml @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -17,7 +17,6 @@ NotifyItem { property int count: 1 readonly property int overlapItemRadius: 12 property bool enableDismissed: true - property bool shouldShowClose: false // True when item gets focus from keyboard navigation property var removedCallback property alias notifyContent: notifyContent @@ -25,7 +24,7 @@ NotifyItem { signal gotoNextItem() signal gotoPrevItem() - property var clearButton: null // Reference to the externally defined clear button + property var clearButton: notifyContent.clearButtonItem function focusFirstButton() { // Focus clear button first, then action buttons @@ -77,18 +76,16 @@ NotifyItem { focus: true Keys.onTabPressed: function(event) { - root.shouldShowClose = true - if (notifyContent.focusFirstButton()) { - event.accepted = true - } else { + if (!notifyContent.focusFirstButton()) { root.gotoNextItem() - event.accepted = true } + event.accepted = true } Keys.onBacktabPressed: function(event) { - root.shouldShowClose = true - root.gotoPrevItem() + if (!notifyContent.focusLastButton()) { + root.gotoPrevItem() + } event.accepted = true } @@ -106,7 +103,7 @@ NotifyItem { actions: root.actions defaultAction: root.defaultAction // Show close button when: mouse hovers, or item has focus from keyboard navigation - parentHovered: impl.hovered || (root.activeFocus && root.shouldShowClose) + parentHovered: impl.hovered || root.activeFocus strongInteractive: root.strongInteractive contentIcon: root.contentIcon contentRowCount: root.contentRowCount diff --git a/panels/notification/plugin/NotifyItemContent.qml b/panels/notification/plugin/NotifyItemContent.qml index 743da1741..bd49c9001 100644 --- a/panels/notification/plugin/NotifyItemContent.qml +++ b/panels/notification/plugin/NotifyItemContent.qml @@ -16,10 +16,11 @@ NotifyItem { // Maximum retry attempts for focus operations when loader content is pending readonly property int maxFocusRetries: 5 property bool parentHovered: false // External hover state from parent component - property bool closeVisible: activeFocus || impl.hovered || parentHovered || (clearLoader.item && clearLoader.item.activeFocus) + property bool closeVisible: activeFocus || impl.hovered || parentHovered property int miniContentHeight: NotifyStyle.contentItem.miniHeight property bool enableDismissed: true property alias clearButton: clearLoader.sourceComponent + readonly property alias clearButtonItem: clearLoader.item signal gotoNextItem() // Signal to navigate to next notify item signal gotoPrevItem() // Signal to navigate to previous notify item @@ -111,8 +112,7 @@ NotifyItem { id: clearLoader anchors.right: parent.right // Show when mouse hovers or notification item has focus - // Keep active when button itself has focus to prevent unloading during Tab navigation - active: !(root.strongInteractive && root.actions.length > 0) && (root.closeVisible || closePlaceHolder.hovered || (clearLoader.item && clearLoader.item.activeFocus)) + active: !(root.strongInteractive && root.actions.length > 0) && (root.closeVisible || closePlaceHolder.hovered) sourceComponent: SettingActionButton { id: closeBtn objectName: "closeNotify-" + root.appName