From e6fae13ee18361b62693d65491b678f7218cdedc Mon Sep 17 00:00:00 2001 From: wjyrich Date: Wed, 6 May 2026 11:15:15 +0800 Subject: [PATCH] fix: replace touch long press handling with TapHandler for better reliability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced the `onPressAndHold` event handler with a `TapHandler` component for touchscreen long press interactions across multiple QML files. This change prevents duplicate handling of touch events by introducing a flag `isTouchLongPressed` that blocks the subsequent `onClicked` execution. The old `onPressAndHold` approach was unreliable and caused duplicated menu triggers. Log: Improved touchscreen long press reliability by using TapHandler Influence: 1. Test touchscreen long press on icon items to trigger context menu 2. Verify that short tap still properly triggers the default action (e.g., launching app) 3. Ensure no duplicate menu popups occur during touch interaction 4. Test with mouse input to confirm no regression in right-click context menu 5. Verify drag-and-drop behavior remains unaffected on touch devices fix: 使用 TapHandler 替代触摸长按处理以提高可靠性 将多个 QML 文件中的 `onPressAndHold` 事件处理器替换为 `TapHandler` 组件 来处理触摸屏长按交互。此修改通过引入 `isTouchLongPressed` 标志位来阻止后 续的 `onClicked` 重复执行,解决了原有 `onPressAndHold` 方法不可靠导致的 菜单重复触发问题。 Log: 通过使用 TapHandler 提高触摸长按的可靠性 Influence: 1. 测试触摸屏长按图标项是否正常触发上下文菜单 2. 验证短触是否仍能正常触发默认操作(如启动应用) 3. 确保触摸交互期间不会出现重复的菜单弹窗 4. 测试鼠标输入,确认右键上下文菜单无回归问题 5. 验证触摸设备上的拖拽功能不受影响 PMS: BUG-358827 --- qml/IconItemDelegate.qml | 25 +++++++++++++++++++------ qml/windowed/AppListView.qml | 24 ++++++++++++++++++------ qml/windowed/FreeSortListView.qml | 31 +++++++++++++++++++++---------- qml/windowed/IconItemDelegate.qml | 25 +++++++++++++++++++------ 4 files changed, 77 insertions(+), 28 deletions(-) diff --git a/qml/IconItemDelegate.qml b/qml/IconItemDelegate.qml index 3c02c706..189335f9 100644 --- a/qml/IconItemDelegate.qml +++ b/qml/IconItemDelegate.qml @@ -118,7 +118,21 @@ Control { hoverEnabled: false drag.target: root.dndEnabled ? root : null drag.threshold: 1 + + // 记录是否是触摸长按导致的,防止在 onClicked 中重复处理 + property bool isTouchLongPressed: false + + TapHandler { + acceptedDevices: PointerDevice.TouchScreen + gesturePolicy: TapHandler.DragThreshold + onLongPressed: { + mouseArea.isTouchLongPressed = true + root.menuTriggered() + } + } + onPressed: function (mouse) { + isTouchLongPressed = false if (mouse.button === Qt.LeftButton && root.dndEnabled) { root.Drag.hotSpot = mapToItem(iconLoader, Qt.point(mouse.x, mouse.y)) iconLoader.grabToImage(function(result) { @@ -146,6 +160,11 @@ Control { } } onClicked: function(mouse) { + if (isTouchLongPressed) { + isTouchLongPressed = false + return + } + if (mouse.button === Qt.LeftButton) { if (model.itemType === ItemArrangementProxyModel.FolderItemType) { root.folderClicked() @@ -156,12 +175,6 @@ Control { root.menuTriggered() } } - // touchscreen long press. - onPressAndHold: function (mouse) { - if (mouse.button === Qt.NoButton) { - root.menuTriggered() - } - } } } diff --git a/qml/windowed/AppListView.qml b/qml/windowed/AppListView.qml index 866379c6..86dd48b9 100644 --- a/qml/windowed/AppListView.qml +++ b/qml/windowed/AppListView.qml @@ -225,7 +225,20 @@ FocusScope { // 当分类菜单打开时,禁用拖拽功能 enabled: !(ddeCategoryMenu.visible || alphabetCategoryPopup.visible) + // 记录是否是触摸长按导致的,防止在 onClicked 中重复处理 + property bool isTouchLongPressed: false + + TapHandler { + acceptedDevices: PointerDevice.TouchScreen + gesturePolicy: TapHandler.DragThreshold + onLongPressed: { + mouseArea.isTouchLongPressed = true + showContextMenu(itemDelegate, model) + } + } + onPressed: function (mouse) { + isTouchLongPressed = false if (mouse.button === Qt.LeftButton) { itemDelegate.contentItem.grabToImage(function(result) { itemDelegate.Drag.imageSource = result.url @@ -233,6 +246,11 @@ FocusScope { } } onClicked: function (mouse) { + if (isTouchLongPressed) { + isTouchLongPressed = false + return + } + if (mouse.button === Qt.RightButton) { showContextMenu(itemDelegate, model) baseLayer.focus = true @@ -240,12 +258,6 @@ FocusScope { launchApp(desktopId) } } - // touchscreen long press. - onPressAndHold: function (mouse) { - if (mouse.button === Qt.NoButton) { - showContextMenu(itemDelegate, model) - } - } } background: ItemBackground { implicitWidth: DStyle.Style.itemDelegate.width diff --git a/qml/windowed/FreeSortListView.qml b/qml/windowed/FreeSortListView.qml index 895736c2..26573d2e 100644 --- a/qml/windowed/FreeSortListView.qml +++ b/qml/windowed/FreeSortListView.qml @@ -332,7 +332,23 @@ Item { acceptedButtons: Qt.LeftButton | Qt.RightButton drag.target: itemDelegate + // 记录是否是触摸长按导致的,防止在 onClicked 中重复处理 + property bool isTouchLongPressed: false + + TapHandler { + acceptedDevices: PointerDevice.TouchScreen + gesturePolicy: TapHandler.DragThreshold + onLongPressed: { + mouseArea.isTouchLongPressed = true + showContextMenu(itemDelegate, model, { + hideMoveToTopMenu: index === 0 + }) + baseLayer.focus = true + } + } + onPressed: function (mouse) { + isTouchLongPressed = false if (mouse.button === Qt.LeftButton) { itemDelegate.contentItem.grabToImage(function(result) { itemDelegate.Drag.imageSource = result.url @@ -341,6 +357,11 @@ Item { } onClicked: function (mouse) { + if (isTouchLongPressed) { + isTouchLongPressed = false + return + } + if (mouse.button === Qt.RightButton) { showContextMenu(itemDelegate, model, { hideMoveToTopMenu: index === 0 @@ -350,16 +371,6 @@ Item { launchItem() } } - - // touchscreen long press. - onPressAndHold: function (mouse) { - if (mouse.button === Qt.NoButton) { - showContextMenu(itemDelegate, model, { - hideMoveToTopMenu: index === 0 - }) - baseLayer.focus = true - } - } } } diff --git a/qml/windowed/IconItemDelegate.qml b/qml/windowed/IconItemDelegate.qml index 628950f5..ef1ef0ff 100644 --- a/qml/windowed/IconItemDelegate.qml +++ b/qml/windowed/IconItemDelegate.qml @@ -52,7 +52,21 @@ Control { acceptedButtons: Qt.LeftButton enabled: true drag.target: root.dndEnabled ? root : null + + // 记录是否是触摸长按导致的,防止在 onClicked 中重复处理 + property bool isTouchLongPressed: false + + TapHandler { + acceptedDevices: PointerDevice.TouchScreen + gesturePolicy: TapHandler.DragThreshold + onLongPressed: { + mouseArea.isTouchLongPressed = true + root.menuTriggered() + } + } + onPressed: function (mouse) { + isTouchLongPressed = false if (mouse.button === Qt.LeftButton && root.dndEnabled) { appIcon.grabToImage(function(result) { root.Drag.imageSource = result.url; @@ -60,16 +74,15 @@ Control { } } onClicked: { + if (isTouchLongPressed) { + isTouchLongPressed = false + return + } + if (!drag.active) { root.itemClicked() } } - // touchscreen long press. - onPressAndHold: function (mouse) { - if (mouse.button === Qt.NoButton) { - root.menuTriggered() - } - } } contentItem: Column { anchors.fill: parent