Skip to content

fix: improve notification center keyboard navigation#1521

Merged
wjyrich merged 1 commit intolinuxdeepin:masterfrom
wjyrich:fix-actionNotifyFocus
Mar 23, 2026
Merged

fix: improve notification center keyboard navigation#1521
wjyrich merged 1 commit intolinuxdeepin:masterfrom
wjyrich:fix-actionNotifyFocus

Conversation

@wjyrich
Copy link
Contributor

@wjyrich wjyrich commented Mar 23, 2026

Added resetFocus() function to all notification item types (GroupNotify, NormalNotify, OverlapNotify) to ensure consistent focus management. Modified focus navigation logic in NotifyView and NotifyViewDelegate to call resetFocus() before attempting to focus items. Enhanced keyboard navigation from action buttons to previous items by prioritizing close button focus when available.

The changes ensure that when navigating between notification items using keyboard shortcuts, focus is properly reset to the item's main implementation before attempting to focus specific buttons. This prevents focus issues where keyboard navigation could get stuck or behave inconsistently. The onGotoPrevItem handler now checks for an enabled close button before navigating to the previous notification item, improving the user experience when navigating backward through notifications.

Log: Improved keyboard navigation in notification center for better accessibility

Influence:

  1. Test Tab/Shift+Tab navigation between notification items
  2. Verify arrow key navigation between notifications works correctly
  3. Test focus behavior when moving from action buttons to previous items
  4. Verify close button receives focus when navigating backward from action buttons
  5. Test navigation with different notification types (group, normal, overlap)
  6. Verify focus is properly reset when switching between notifications

fix: 改进通知中心键盘导航

为所有通知项类型(GroupNotify、NormalNotify、OverlapNotify)添
加了resetFocus()函数,以确保一致性的焦点管理。修改了NotifyView和
NotifyViewDelegate中的焦点导航逻辑,在尝试聚焦项之前调用resetFocus()。增 强了从操作按钮到前一项的键盘导航,优先考虑关闭按钮焦点(如果可用)。

这些更改确保在使用键盘快捷键在通知项之间导航时,在尝试聚焦特定按钮之前,
焦点被正确重置到项的主实现。这防止了键盘导航可能卡住或行为不一致的焦点
问题。onGotoPrevItem处理程序现在在导航到前一个通知项之前检查启用的关闭按
钮,改善了向后浏览通知时的用户体验。

Log: 改进了通知中心的键盘导航,提升可访问性

Influence:

  1. 测试Tab/Shift+Tab在通知项之间的导航
  2. 验证箭头键在通知之间的导航工作正常
  3. 测试从操作按钮移动到前一项时的焦点行为
  4. 验证从操作按钮向后导航时关闭按钮获得焦点
  5. 测试不同类型通知(群组、普通、重叠)的导航
  6. 验证在通知之间切换时焦点被正确重置

Summary by Sourcery

Improve keyboard focus management and navigation between notification items in the notification center.

Bug Fixes:

  • Ensure keyboard navigation between notification items does not get stuck by resetting focus before moving focus into buttons.
  • Prioritize focusing the close button when navigating backward from action buttons, falling back to the previous notification item when unavailable.

Enhancements:

  • Add a resetFocus() helper to all notification item types and integrate it into notification view navigation logic for consistent focus behavior.

Added resetFocus() function to all notification item types (GroupNotify,
NormalNotify, OverlapNotify) to ensure consistent focus management.
Modified focus navigation logic in NotifyView and NotifyViewDelegate to
call resetFocus() before attempting to focus items. Enhanced keyboard
navigation from action buttons to previous items by prioritizing close
button focus when available.

The changes ensure that when navigating between notification items
using keyboard shortcuts, focus is properly reset to the item's main
implementation before attempting to focus specific buttons. This
prevents focus issues where keyboard navigation could get stuck or
behave inconsistently. The onGotoPrevItem handler now checks for an
enabled close button before navigating to the previous notification
item, improving the user experience when navigating backward through
notifications.

Log: Improved keyboard navigation in notification center for better
accessibility

Influence:
1. Test Tab/Shift+Tab navigation between notification items
2. Verify arrow key navigation between notifications works correctly
3. Test focus behavior when moving from action buttons to previous items
4. Verify close button receives focus when navigating backward from
action buttons
5. Test navigation with different notification types (group, normal,
overlap)
6. Verify focus is properly reset when switching between notifications

fix: 改进通知中心键盘导航

为所有通知项类型(GroupNotify、NormalNotify、OverlapNotify)添
加了resetFocus()函数,以确保一致性的焦点管理。修改了NotifyView和
NotifyViewDelegate中的焦点导航逻辑,在尝试聚焦项之前调用resetFocus()。增
强了从操作按钮到前一项的键盘导航,优先考虑关闭按钮焦点(如果可用)。

这些更改确保在使用键盘快捷键在通知项之间导航时,在尝试聚焦特定按钮之前,
焦点被正确重置到项的主实现。这防止了键盘导航可能卡住或行为不一致的焦点
问题。onGotoPrevItem处理程序现在在导航到前一个通知项之前检查启用的关闭按
钮,改善了向后浏览通知时的用户体验。

Log: 改进了通知中心的键盘导航,提升可访问性

Influence:
1. 测试Tab/Shift+Tab在通知项之间的导航
2. 验证箭头键在通知之间的导航工作正常
3. 测试从操作按钮移动到前一项时的焦点行为
4. 验证从操作按钮向后导航时关闭按钮获得焦点
5. 测试不同类型通知(群组、普通、重叠)的导航
6. 验证在通知之间切换时焦点被正确重置
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 23, 2026

Reviewer's Guide

This PR standardizes focus management across notification item types and adjusts keyboard navigation so that focus is reset to each item’s main implementation before button focusing, and backward navigation from action buttons prefers the close button when available.

Sequence diagram for NotifyView focusing a notification item with resetFocus

sequenceDiagram
    actor User
    participant NotifyView
    participant ListView_view as ListView_view
    participant NotifyItem as NotifyItem_subclass
    participant Impl as impl_component

    User->>NotifyView: triggerKeyboardNavigation()
    NotifyView->>ListView_view: itemAtIndex(idx)
    ListView_view-->>NotifyView: NotifyItem_subclass
    NotifyView->>NotifyItem: tryFocus(retries)
    NotifyView->>NotifyItem: resetFocus()
    NotifyItem->>Impl: forceActiveFocus()
    NotifyView->>NotifyItem: focusFirstButton()
    alt first button exists
        NotifyItem-->>NotifyView: true
        NotifyItem->>NotifyItem: firstButton.forceActiveFocus()
    else no first button
        NotifyItem-->>NotifyView: false
        NotifyView->>NotifyItem: forceActiveFocus()
    end
Loading

Sequence diagram for backward navigation from action buttons prioritizing close button

sequenceDiagram
    actor User
    participant ActionButtons as ActionButtons_row
    participant NotifyItemContent as NotifyItemContent_root
    participant ClearLoader as clearLoader
    participant CloseButton as clearLoader_item
    participant NotifyView as NotifyView

    User->>ActionButtons: pressShiftTabOrPrevShortcut()
    ActionButtons->>NotifyItemContent: gotoPrevItem
    alt close button available and enabled
        NotifyItemContent->>ClearLoader: access item
        ClearLoader-->>NotifyItemContent: clearLoader.item
        NotifyItemContent->>CloseButton: forceActiveFocus()
    else no enabled close button
        NotifyItemContent->>NotifyView: gotoPrevItem()
        NotifyView->>NotifyView: moveFocusToPreviousItem()
    end
Loading

Class diagram for notification items and focus management changes

classDiagram
    class NotifyItem {
    }

    class GroupNotify {
      +signal gotoNextItem()
      +signal gotoPrevItem()
      +function resetFocus()
      +function focusFirstButton()
    }

    class NormalNotify {
      +signal gotoNextItem()
      +signal gotoPrevItem()
      +function resetFocus()
      +function focusFirstButton()
    }

    class OverlapNotify {
      +signal gotoNextItem()
      +signal gotoPrevItem()
      +property var clearButton
      +function resetFocus()
      +function focusFirstButton()
    }

    class NotifyView {
      +property int idx
      +function tryFocus(retries)
    }

    class NotifyViewDelegate {
      +property int currentIndex
      +function onGotoNextItem()
    }

    class NotifyItemContent {
      +property var clearLoader
      +function onGotoNextItem()
      +function onGotoPrevItem()
    }

    class ImplComponent {
      +function forceActiveFocus()
    }

    NotifyItem <|-- GroupNotify
    NotifyItem <|-- NormalNotify
    NotifyItem <|-- OverlapNotify

    GroupNotify --> ImplComponent : uses impl
    NormalNotify --> ImplComponent : uses impl
    OverlapNotify --> ImplComponent : uses impl

    NotifyView --> NotifyItem : itemAtIndex
    NotifyViewDelegate --> NotifyView : view_reference
    NotifyViewDelegate --> NotifyItem : nextItem

    NotifyItemContent --> NotifyView : gotoNextItem\ngotoPrevItem
    NotifyItemContent --> OverlapNotify : clearLoader_item_may_be_clearButton
Loading

File-Level Changes

Change Details Files
Add a resetFocus() API to all notification item types and integrate it into the list view focus logic.
  • Introduce resetFocus() function on GroupNotify to focus the main impl item
  • Introduce resetFocus() function on NormalNotify to focus the main impl item
  • Introduce resetFocus() function on OverlapNotify to focus the main impl item
  • Update NotifyView to call resetFocus() on the target item before attempting focusFirstButton() or forceActiveFocus()
  • Update NotifyViewDelegate to call resetFocus() on the next item before focusing it when navigating forward
panels/notification/center/GroupNotify.qml
panels/notification/center/NormalNotify.qml
panels/notification/center/OverlapNotify.qml
panels/notification/center/NotifyView.qml
panels/notification/center/NotifyViewDelegate.qml
Improve backward keyboard navigation from action buttons so the close button is focused before moving to the previous notification item.
  • Change onGotoPrevItem handler to first try to focus the clear/close button if it exists and is enabled
  • Fall back to navigating to the previous notification item if the clear/close button cannot be focused
panels/notification/plugin/NotifyItemContent.qml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In NotifyView.qml and NotifyViewDelegate.qml you now assume all items implement resetFocus(), so consider adding a default resetFocus implementation on the base NotifyItem (or a type check/guard) to avoid runtime errors if a different item type is ever used in the view.
  • The new resetFocus() helpers call impl.forceActiveFocus() directly; it would be safer to guard against impl being null/undefined to prevent runtime errors in edge cases where the implementation component fails to load.
  • In NotifyItemContent.qml the onGotoPrevItem handler only checks clearLoader.item && clearLoader.item.enabled before focusing; consider also checking visibility and focusability (e.g. visible, activeFocusOnTab) to avoid sending focus to a non-interactive or hidden close button.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `NotifyView.qml` and `NotifyViewDelegate.qml` you now assume all items implement `resetFocus()`, so consider adding a default `resetFocus` implementation on the base `NotifyItem` (or a type check/guard) to avoid runtime errors if a different item type is ever used in the view.
- The new `resetFocus()` helpers call `impl.forceActiveFocus()` directly; it would be safer to guard against `impl` being null/undefined to prevent runtime errors in edge cases where the implementation component fails to load.
- In `NotifyItemContent.qml` the `onGotoPrevItem` handler only checks `clearLoader.item && clearLoader.item.enabled` before focusing; consider also checking visibility and focusability (e.g. `visible`, `activeFocusOnTab`) to avoid sending focus to a non-interactive or hidden close button.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@wjyrich wjyrich requested a review from 18202781743 March 23, 2026 08:21
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, wjyrich

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@wjyrich wjyrich merged commit 7faca50 into linuxdeepin:master Mar 23, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants