Skip to content

fix: add touchscreen long press support for app launcher#739

Merged
18202781743 merged 1 commit intolinuxdeepin:masterfrom
18202781743:master
Mar 17, 2026
Merged

fix: add touchscreen long press support for app launcher#739
18202781743 merged 1 commit intolinuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743
Copy link
Contributor

@18202781743 18202781743 commented Mar 17, 2026

Added touchscreen long press event handling to three QML components to
enable context menu activation on touch devices. Previously, only mouse
right-click triggered context menus, leaving touchscreen users unable to
access these features.

  1. Modified AppListView.qml to add onPressAndHold handler for
    touchscreen long press
  2. Modified FreeSortListView.qml to add onPressAndHold handler with
    additional logic for hiding "Move to Top" menu on first item
  3. Modified IconItemDelegate.qml to add onPressAndHold handler that
    triggers menu functionality
  4. All handlers check for Qt.NoButton to distinguish touch events from
    mouse events

Log: Touchscreen users can now long press on app icons to open context
menus

Influence:

  1. Test long press on app icons in both AppListView and FreeSortListView
    modes
  2. Verify context menu appears correctly on touchscreen devices
  3. Test that mouse right-click functionality remains unchanged
  4. Verify "Move to Top" menu item is hidden when long pressing first
    item in FreeSortListView
  5. Test that regular tap/click behavior remains unaffected
  6. Verify context menu options work correctly after touch activation

fix: 为应用启动器添加触摸屏长按支持

为三个QML组件添加了触摸屏长按事件处理,使触摸设备用户能够激活上下文菜
单。之前只有鼠标右键点击能触发上下文菜单,触摸屏用户无法使用这些功能。

  1. 修改AppListView.qml,为触摸屏长按添加onPressAndHold处理器
  2. 修改FreeSortListView.qml,添加onPressAndHold处理器,包含隐藏首项"移至
    顶部"菜单的额外逻辑
  3. 修改IconItemDelegate.qml,添加触发菜单功能的onPressAndHold处理器
  4. 所有处理器都检查Qt.NoButton以区分触摸事件和鼠标事件

Log: 触摸屏用户现在可以通过长按应用图标打开上下文菜单

Influence:

  1. 在AppListView和FreeSortListView模式下测试应用图标长按
  2. 验证在触摸屏设备上上下文菜单正确显示
  3. 测试鼠标右键点击功能保持不变
  4. 验证在FreeSortListView中长按第一项时"移至顶部"菜单项被隐藏
  5. 测试常规点击行为不受影响
  6. 验证通过触摸激活后上下文菜单选项正常工作

PMS: BUG-352989

Summary by Sourcery

Add touchscreen long-press support to app launcher list and icon views to open existing context menus on touch devices.

Bug Fixes:

  • Allow touchscreen users to open app launcher context menus via long press where previously only mouse right-click was supported.

Enhancements:

  • Ensure long-press context menus on touch respect existing behaviors, including hiding the "Move to Top" option for the first item in the free-sort list.

Added touchscreen long press event handling to three QML components to
enable context menu activation on touch devices. Previously, only mouse
right-click triggered context menus, leaving touchscreen users unable to
access these features.

1. Modified AppListView.qml to add onPressAndHold handler for
touchscreen long press
2. Modified FreeSortListView.qml to add onPressAndHold handler with
additional logic for hiding "Move to Top" menu on first item
3. Modified IconItemDelegate.qml to add onPressAndHold handler that
triggers menu functionality
4. All handlers check for Qt.NoButton to distinguish touch events from
mouse events

Log: Touchscreen users can now long press on app icons to open context
menus

Influence:
1. Test long press on app icons in both AppListView and FreeSortListView
modes
2. Verify context menu appears correctly on touchscreen devices
3. Test that mouse right-click functionality remains unchanged
4. Verify "Move to Top" menu item is hidden when long pressing first
item in FreeSortListView
5. Test that regular tap/click behavior remains unaffected
6. Verify context menu options work correctly after touch activation

fix: 为应用启动器添加触摸屏长按支持

为三个QML组件添加了触摸屏长按事件处理,使触摸设备用户能够激活上下文菜
单。之前只有鼠标右键点击能触发上下文菜单,触摸屏用户无法使用这些功能。

1. 修改AppListView.qml,为触摸屏长按添加onPressAndHold处理器
2. 修改FreeSortListView.qml,添加onPressAndHold处理器,包含隐藏首项"移至
顶部"菜单的额外逻辑
3. 修改IconItemDelegate.qml,添加触发菜单功能的onPressAndHold处理器
4. 所有处理器都检查Qt.NoButton以区分触摸事件和鼠标事件

Log: 触摸屏用户现在可以通过长按应用图标打开上下文菜单

Influence:
1. 在AppListView和FreeSortListView模式下测试应用图标长按
2. 验证在触摸屏设备上上下文菜单正确显示
3. 测试鼠标右键点击功能保持不变
4. 验证在FreeSortListView中长按第一项时"移至顶部"菜单项被隐藏
5. 测试常规点击行为不受影响
6. 验证通过触摸激活后上下文菜单选项正常工作

PMS: BUG-352989
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 17, 2026

Reviewer's Guide

Adds touchscreen long-press handling to app launcher QML views and delegates so that touch users can open the same context menus previously available only via mouse right-click, including preserving existing menu behavior such as hiding "Move to Top" for the first item in the free-sort view.

Sequence diagram for touchscreen long-press handling in FreeSortListView

sequenceDiagram
    actor TouchUser
    participant FreeSortListView
    participant IconItemDelegate
    participant MouseArea
    participant ContextMenu

    TouchUser->>IconItemDelegate: long_press_on_app_icon
    IconItemDelegate->>MouseArea: emit_pressAndHold(mouse_button_NoButton)
    MouseArea->>FreeSortListView: onPressAndHold(mouse)
    FreeSortListView->>FreeSortListView: check_mouse_button_is_NoButton
    alt index_is_first_item
        FreeSortListView->>ContextMenu: showContextMenu(itemDelegate, model, hideMoveToTopMenu_true)
    else index_is_not_first_item
        FreeSortListView->>ContextMenu: showContextMenu(itemDelegate, model, hideMoveToTopMenu_false)
    end
    FreeSortListView->>FreeSortListView: baseLayer_focus_true
    ContextMenu-->>TouchUser: display_context_menu
Loading

Updated class diagram for app launcher QML components with touch long-press support

classDiagram
    class AppListView {
        +showContextMenu(itemDelegate, model)
        +onPressAndHold(mouse)
    }

    class FreeSortListView {
        +showContextMenu(itemDelegate, model, hideMoveToTopMenu)
        +onPressAndHold(mouse)
        +index
        +baseLayer_focus
    }

    class IconItemDelegate {
        +itemClicked()
        +menuTriggered()
        +onPressAndHold(mouse)
    }

    class MouseArea {
        +onClicked(mouse)
        +onPressAndHold(mouse)
    }

    class ContextMenuHelper {
        +showContextMenu(itemDelegate, model)
        +showContextMenu(itemDelegate, model, hideMoveToTopMenu)
    }

    AppListView --> IconItemDelegate : uses_delegate
    FreeSortListView --> IconItemDelegate : uses_delegate
    IconItemDelegate --> MouseArea : contains
    AppListView --> ContextMenuHelper : calls
    FreeSortListView --> ContextMenuHelper : calls
Loading

File-Level Changes

Change Details Files
Enable context menu activation via touchscreen long press in the free-sort app list view, including preserving special handling for the first item.
  • Attach an onPressAndHold handler to the list view delegate to capture long-press interactions.
  • Guard the handler to only react when the event originates from a touch interaction by checking for Qt.NoButton.
  • Invoke showContextMenu with a configuration object that sets hideMoveToTopMenu when the pressed item is at index 0.
  • Ensure baseLayer receives focus after opening the context menu triggered by a long press.
qml/windowed/FreeSortListView.qml
Enable context menu activation via touchscreen long press in the standard app list view.
  • Add an onPressAndHold handler to the app list item delegate to handle touch long presses.
  • Use a Qt.NoButton check to distinguish touch-based long presses from mouse events.
  • Call showContextMenu for the pressed item so touch users see the same context menu as on right-click.
qml/windowed/AppListView.qml
Wire up long-press on icon delegates to trigger existing menu logic.
  • Introduce an onPressAndHold handler on the icon delegate’s mouse area to react to touch long presses.
  • Filter events to touch-only by requiring mouse.button === Qt.NoButton.
  • Invoke the existing root.menuTriggered() method so the long-press path reuses the current menu behavior.
qml/windowed/IconItemDelegate.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

@deepin-ci-robot
Copy link

deepin pr auto review

这段代码 diff 主要是为了在三个不同的 QML 组件(AppListView.qmlFreeSortListView.qmlIconItemDelegate.qml)中添加对触摸屏长按(Long Press)事件的支持,以便触发上下文菜单或特定操作。

以下是对这段代码的详细审查和改进建议:

1. 语法与逻辑审查

  • 语法正确性:QML 语法是正确的。onPressAndHold 是标准的信号处理器,Qt.NoButton 也是 Qt 中有效的枚举值。
  • 逻辑分析
    • mouse.button === Qt.NoButton:在触摸屏交互中,触摸事件通常不关联鼠标按钮(左键、右键等),因此 mouse.button 往往是 Qt.NoButton。这个逻辑判断是合理的,用于区分是触摸长按还是鼠标长按(虽然鼠标长按通常也触发此信号,但按钮状态会不同)。
    • baseLayer.focus = true:在 FreeSortListView.qml 中,长按后强制将焦点设置回 baseLayer。这是一个很好的 UI 细节,防止焦点停留在触发菜单的委托项上,或者在菜单关闭后焦点丢失,符合用户交互预期。

2. 代码质量

  • 注释:添加了 // touchscreen long press. 注释,清晰地说明了代码意图,值得肯定。
  • 代码重复:在三个文件中添加了几乎完全相同的逻辑。虽然这在 QML 开发中很常见(因为组件职责不同),但如果未来长按逻辑变得复杂(例如增加震动反馈),可能需要考虑封装成通用的行为或 mixin。

3. 代码性能

  • 性能影响onPressAndHold 是由底层输入系统在长按阈值(通常为 800ms)触发后发送的信号。这本身不会影响常规点击或滚动的性能。
  • 函数调用:调用的 showContextMenuroot.menuTriggered() 是 UI 响应操作,性能开销主要在于菜单的创建和渲染,这是必要的开销。

4. 代码安全与健壮性

  • 潜在问题:鼠标事件干扰
    • 目前的逻辑 if (mouse.button === Qt.NoButton) 确保了只有触摸事件(或没有按键的模拟事件)才会触发。但是,这可能会屏蔽掉鼠标右键长按的行为。
    • 在桌面环境中,用户可能习惯使用鼠标右键点击(onClicked 中的 mouse.button === Qt.RightButton)来唤起上下文菜单。
    • 如果应用仅依赖触摸长按逻辑,且未在 onClicked 中处理右键点击,那么鼠标用户将无法通过右键唤出菜单。
    • 建议:检查 onClicked 中是否已经处理了 Qt.RightButton。如果希望长按功能同时支持鼠标左键长按和触摸长按,建议修改判断条件。

5. 改进建议

建议 1:增强对鼠标长按的支持(可选)

如果希望鼠标左键长按也能触发菜单,建议修改判断逻辑,或者移除 mouse.button 的严格限制(除非有特定原因排除鼠标)。通常触摸事件和鼠标左键事件在 QML 中可以通过 source 属性区分,但简单起见,可以放宽条件:

// 建议修改后的逻辑(如果希望支持鼠标长按)
onPressAndHold: function (mouse) {
    // 接受触摸(NoButton)和鼠标左键(LeftButton)的长按
    // 或者直接不判断 button,取决于具体需求
    if (mouse.button === Qt.NoButton || mouse.button === Qt.LeftButton) {
        showContextMenu(itemDelegate, model)
    }
}

建议 2:防止事件冲突

FreeSortListView.qml 中,launchItem() 是在 onClicked 中触发的。需要确保 onPressAndHold 触发后,随后的 onClicked 不会被意外触发(即长按结束时不应触发点击事件)。

  • 现状:通常 MouseArea 的机制是,如果 onPressAndHold 被触发,onClicked 就不会触发。但为了保险起见,或者如果使用了自定义的交互逻辑,建议测试长按后是否会误触 launchItem()

建议 3:代码一致性

AppListView.qmlFreeSortListView.qml 中,函数调用是 showContextMenu(...),而在 IconItemDelegate.qml 中是 root.menuTriggered()

  • 建议:确认 root.menuTriggered() 内部是否也处理了 mouse.button === Qt.NoButton 的逻辑?如果 IconItemDelegate 是被上述两个组件使用的通用组件,请确保逻辑的一致性。通常在委托项内部处理原始输入信号更好,这样可以统一管理输入逻辑。

总结

这段代码的实现是正确且有效的,专门针对触摸屏长按场景进行了适配。主要的改进点在于是否需要兼容鼠标长按操作以及确保与点击事件不冲突。如果这是一个纯触摸屏应用,当前代码完全没问题;如果是混合输入设备应用,建议考虑建议 1。

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

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 found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="qml/windowed/FreeSortListView.qml" line_range="354-356" />
<code_context>
                             launchApp(desktopId)
                         }
                     }
+                    // touchscreen long press.
+                    onPressAndHold: function (mouse) {
+                        if (mouse.button === Qt.NoButton) {
+                            showContextMenu(itemDelegate, model)
+                        }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Guarding onPressAndHold with `mouse.button === Qt.NoButton` might miss some legitimate long-press events.

Using `mouse.button === Qt.NoButton` as a proxy for touch vs mouse is likely to be inconsistent across platforms and devices (e.g., some touch or stylus events can still report `Qt.LeftButton`). If you just want to ignore mouse long-press, prefer using `mouse.source` (where supported) or handle both input types uniformly and differentiate behavior at a higher level. Also confirm the actual event values on your target platforms to ensure this condition behaves as expected.

Suggested implementation:

```
                    // long press (mouse or touch).
                    onPressAndHold: function (mouse) {
                        showContextMenu(itemDelegate, model, {
                            hideMoveToTopMenu: index === 0
                        })
                        baseLayer.focus = true
                    }

```

If you later need to differentiate mouse vs touch behavior:
1. Inspect `mouse.source` in this handler (e.g., `mouse.source === Qt.MouseEventSynthesizedBySystem` for some touch-generated events) and log actual values on your target platforms.
2. Adjust the condition accordingly or route the event information upward so a higher-level component can decide how to handle different input sources.
</issue_to_address>

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.

@18202781743 18202781743 merged commit 21cce1f into linuxdeepin:master Mar 17, 2026
10 of 11 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