From e06fd71f113f3a43f7099d833d70ff0ba1fe2861 Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 31 May 2026 13:58:21 +0200 Subject: [PATCH 1/6] initial refactor of Interactions.qml to add better support for touch screen gestures --- Drawers/Interactions.qml | 166 +++++++++++++++++++++++++-------------- Drawers/Windows.qml | 1 + 2 files changed, 107 insertions(+), 60 deletions(-) diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 553f52b..e7b68b9 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -1,15 +1,16 @@ import Quickshell import QtQuick +import QtTest import qs.Components import qs.Config +import qs.Helpers import qs.Modules as BarPopouts -CustomMouseArea { +Item { id: root required property Item bar property bool dashboardShortcutActive - property point dragStart required property Drawing drawing required property DrawingInput input property bool osdShortcutActive @@ -52,78 +53,124 @@ CustomMouseArea { } anchors.fill: parent - cursorShape: (pressed && dragStart.y < bar.implicitHeight) ? Qt.ClosedHandCursor : undefined - hoverEnabled: true - propagateComposedEvents: false - onContainsMouseChanged: { - if (!containsMouse) { - if (!osdShortcutActive) { - visibilities.osd = false; - root.panels.osd.hovered = false; - } + Timer { + interval: 5000 + running: true - if (!popouts.currentName.startsWith("traymenu")) { - popouts.hasCurrent = false; - } + onTriggered: root.runTest = true + } - if (Config.barConfig.autoHide) - bar.isHovered = false; + DragHandler { + id: multiHandler + + grabPermissions: PointerHandler.CanTakeOverFromAnything + maximumPointCount: 2 + minimumPointCount: 2 + target: null + + onCentroidChanged: { + const x = centroid.position.x; + const y = centroid.position.y; + const dragX = x - centroid.pressPosition.x; + const dragY = y - centroid.pressPosition.y; + + if (centroid.pressPosition.x > root.screen.width - Config.barConfig.border && dragX < -20) + root.visibilities.sidebar = true; } } - onPositionChanged: event => { - const x = event.x; - const y = event.y; - const dragX = x - dragStart.x; - const dragY = y - dragStart.y; - if (root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, x, y)) { - root.input.z = 2; - root.panels.drawing.expanded = false; - } + DragHandler { + id: pressHandler - if (!visibilities.bar && Config.barConfig.autoHide && y < bar.implicitHeight) - bar.isHovered = true; + cursorShape: (active && centroid.pressPosition.y < root.bar.implicitHeight) ? Qt.ClosedHandCursor : undefined + dragThreshold: 0 + maximumPointCount: 1 + minimumPointCount: 1 + target: null - if (pressed && dragStart.y < bar.implicitHeight) { - if (dragY > 20) - visibilities.settings = true; - else if (dragY < -20) - visibilities.settings = false; - } + onCentroidChanged: { + const x = centroid.position.x; + const y = centroid.position.y; + const dragX = x - centroid.pressPosition.x; + const dragY = y - centroid.pressPosition.y; - if (Config.dock.hoverToReveal && pressed && dragStart.y > root.screen.height - root.bar.implicitHeight) - if (dragY < -10) - visibilities.dock = true; - - if (panels.sidebar.width === 0) { - const showOsd = inRightPanel(panels.osdWrapper, x, y); - - if (showOsd) { - osdShortcutActive = false; - root.panels.osd.hovered = true; + if (centroid.pressPosition.y < root.bar.implicitHeight) { + if (dragY > 20) + root.visibilities.settings = true; + else if (dragY < -20) + root.visibilities.settings = false; } - } else { - const outOfSidebar = x < width - panels.sidebar.width; - const showOsd = outOfSidebar && inRightPanel(panels.osdWrapper, x, y); - if (!osdShortcutActive) { - visibilities.osd = showOsd; - root.panels.osd.hovered = showOsd; - } else if (showOsd) { - osdShortcutActive = false; - root.panels.osd.hovered = true; - } - } + if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.bar.implicitHeight) + if (dragY < -10) + root.visibilities.dock = true; - if (Config.dock.enable && !Config.dock.hoverToReveal && !visibilities.dock && !visibilities.launcher && inBottomPanel(panels.dock, x, y)) - visibilities.dock = true; + if (centroid.pressPosition.x >= root.screen.width - Config.barConfig.border && dragX < -20) + Hypr.dispatch(`hl.dsp.focus({ workspace = 'r+1', on_current_monitor = true })`); - if (y < root.bar.implicitHeight) { - root.bar.checkPopout(x); + if (centroid.pressPosition.x <= Config.barConfig.border && dragX > 20) + Hypr.dispatch(`hl.dsp.focus({ workspace = 'r-1', on_current_monitor = true })`); + } + } + + HoverHandler { + id: hoverHandler + + onHoveredChanged: { + if (!hovered) { + if (!root.osdShortcutActive) { + root.visibilities.osd = false; + root.panels.osd.hovered = false; + } + + if (!root.popouts.currentName.startsWith("traymenu")) { + root.popouts.hasCurrent = false; + } + + if (Config.barConfig.autoHide) + root.bar.isHovered = false; + } + } + onPointChanged: { + const x = point.position.x; + const y = point.position.y; + + if (root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, x, y)) { + root.input.z = 2; + root.panels.drawing.expanded = false; + } + + if (!root.visibilities.bar && Config.barConfig.autoHide && y < root.bar.implicitHeight) + root.bar.isHovered = true; + + if (root.panels.sidebar.width === 0) { + const showOsd = root.inRightPanel(root.panels.osdWrapper, x, y); + + if (showOsd) { + root.osdShortcutActive = false; + root.panels.osd.hovered = true; + } + } else { + const outOfSidebar = x < root.width - root.panels.sidebar.width; + const showOsd = outOfSidebar && root.inRightPanel(root.panels.osdWrapper, x, y); + + if (!root.osdShortcutActive) { + root.visibilities.osd = showOsd; + root.panels.osd.hovered = showOsd; + } else if (showOsd) { + root.osdShortcutActive = false; + root.panels.osd.hovered = true; + } + } + + if (Config.dock.enable && Config.dock.hoverToReveal && !root.visibilities.dock && !root.visibilities.launcher && root.inBottomPanel(root.panels.dock, x, y)) + root.visibilities.dock = true; + + if (y < root.bar.implicitHeight) + root.bar.checkPopout(x); } } - onPressed: event => dragStart = Qt.point(event.x, event.y) Connections { function onDashboardChanged() { @@ -164,7 +211,6 @@ CustomMouseArea { if (root.visibilities.launcher) { if (root.panels.dashboardWrapper.x < root.panels.launcher.x + root.panels.launcher.width) { - console.log("true"); root.visibilities.dashboard = false; } diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index d45b2cb..f417c43 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -341,6 +341,7 @@ Variants { anchors.fill: parent bar: bar drawing: drawingLoader.item + enabled: true input: inputLoader.item panels: panels popouts: panels.popouts -- 2.47.3 From c267dfb0c24f3fa342d521200067dca1404bbc5d Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 31 May 2026 14:16:36 +0200 Subject: [PATCH 2/6] remove leftover test timer and import --- Drawers/Interactions.qml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index e7b68b9..69292b7 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -1,6 +1,5 @@ import Quickshell import QtQuick -import QtTest import qs.Components import qs.Config import qs.Helpers @@ -54,13 +53,6 @@ Item { anchors.fill: parent - Timer { - interval: 5000 - running: true - - onTriggered: root.runTest = true - } - DragHandler { id: multiHandler -- 2.47.3 From cf22b41f075333c6ba2b5c212427d3c03ef4159e Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 31 May 2026 14:32:39 +0200 Subject: [PATCH 3/6] allow pointer takeover by anything, restrict takeover from items --- Drawers/Interactions.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 69292b7..5856657 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -56,7 +56,8 @@ Item { DragHandler { id: multiHandler - grabPermissions: PointerHandler.CanTakeOverFromAnything + dragThreshold: 0 + grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything maximumPointCount: 2 minimumPointCount: 2 target: null @@ -77,6 +78,7 @@ Item { cursorShape: (active && centroid.pressPosition.y < root.bar.implicitHeight) ? Qt.ClosedHandCursor : undefined dragThreshold: 0 + grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything maximumPointCount: 1 minimumPointCount: 1 target: null -- 2.47.3 From db6051457f154f330cff7bfa58abcd779eebd078 Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 31 May 2026 22:30:20 +0200 Subject: [PATCH 4/6] fix drag gestures firing more than once from one drag --- Drawers/Interactions.qml | 43 +++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 5856657..058a582 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -12,10 +12,12 @@ Item { property bool dashboardShortcutActive required property Drawing drawing required property DrawingInput input + property bool multiGestureTriggered: false property bool osdShortcutActive required property Panels panels required property BarPopouts.Wrapper popouts required property ShellScreen screen + property bool singleGestureTriggered: false property bool utilitiesShortcutActive required property PersistentProperties visibilities @@ -62,19 +64,28 @@ Item { minimumPointCount: 2 target: null + onActiveChanged: { + if (!active) + root.multiGestureTriggered = false; + } onCentroidChanged: { + if (root.multiGestureTriggered) + return; + const x = centroid.position.x; const y = centroid.position.y; const dragX = x - centroid.pressPosition.x; const dragY = y - centroid.pressPosition.y; - if (centroid.pressPosition.x > root.screen.width - Config.barConfig.border && dragX < -20) + if (centroid.pressPosition.x > root.screen.width - Config.barConfig.border && dragX < -20) { root.visibilities.sidebar = true; + root.multiGestureTriggered = true; + } } } DragHandler { - id: pressHandler + id: singleHandler cursorShape: (active && centroid.pressPosition.y < root.bar.implicitHeight) ? Qt.ClosedHandCursor : undefined dragThreshold: 0 @@ -83,28 +94,46 @@ Item { minimumPointCount: 1 target: null + onActiveChanged: { + if (!active) + root.singleGestureTriggered = false; + } onCentroidChanged: { + if (root.singleGestureTriggered) { + console.log(root.singleGestureTriggered); + return; + } + const x = centroid.position.x; const y = centroid.position.y; const dragX = x - centroid.pressPosition.x; const dragY = y - centroid.pressPosition.y; if (centroid.pressPosition.y < root.bar.implicitHeight) { - if (dragY > 20) + if (dragY > 20) { root.visibilities.settings = true; - else if (dragY < -20) + root.singleGestureTriggered = true; + } else if (dragY < -20) { root.visibilities.settings = false; + root.singleGestureTriggered = true; + } } if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.bar.implicitHeight) - if (dragY < -10) + if (dragY < -10) { root.visibilities.dock = true; + root.singleGestureTriggered = true; + } - if (centroid.pressPosition.x >= root.screen.width - Config.barConfig.border && dragX < -20) + if (centroid.pressPosition.x >= root.screen.width - Config.barConfig.border && dragX < -20) { Hypr.dispatch(`hl.dsp.focus({ workspace = 'r+1', on_current_monitor = true })`); + root.singleGestureTriggered = true; + } - if (centroid.pressPosition.x <= Config.barConfig.border && dragX > 20) + if (centroid.pressPosition.x <= Config.barConfig.border && dragX > 20) { Hypr.dispatch(`hl.dsp.focus({ workspace = 'r-1', on_current_monitor = true })`); + root.singleGestureTriggered = true; + } } } -- 2.47.3 From 1e1c90a0c5da75e0395e3701ea7a465c448b0455 Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 31 May 2026 22:45:32 +0200 Subject: [PATCH 5/6] remove redundant logging --- Drawers/Interactions.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 058a582..2fc2861 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -99,10 +99,8 @@ Item { root.singleGestureTriggered = false; } onCentroidChanged: { - if (root.singleGestureTriggered) { - console.log(root.singleGestureTriggered); + if (root.singleGestureTriggered) return; - } const x = centroid.position.x; const y = centroid.position.y; -- 2.47.3 From 6926880074dab7bf63b92e4c2a6d5bdc66e8577b Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 31 May 2026 23:05:31 +0200 Subject: [PATCH 6/6] remove multi-touch handlers, single point for sidebar --- Drawers/Interactions.qml | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 2fc2861..f99f3df 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -12,7 +12,6 @@ Item { property bool dashboardShortcutActive required property Drawing drawing required property DrawingInput input - property bool multiGestureTriggered: false property bool osdShortcutActive required property Panels panels required property BarPopouts.Wrapper popouts @@ -55,35 +54,6 @@ Item { anchors.fill: parent - DragHandler { - id: multiHandler - - dragThreshold: 0 - grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything - maximumPointCount: 2 - minimumPointCount: 2 - target: null - - onActiveChanged: { - if (!active) - root.multiGestureTriggered = false; - } - onCentroidChanged: { - if (root.multiGestureTriggered) - return; - - const x = centroid.position.x; - const y = centroid.position.y; - const dragX = x - centroid.pressPosition.x; - const dragY = y - centroid.pressPosition.y; - - if (centroid.pressPosition.x > root.screen.width - Config.barConfig.border && dragX < -20) { - root.visibilities.sidebar = true; - root.multiGestureTriggered = true; - } - } - } - DragHandler { id: singleHandler @@ -123,7 +93,12 @@ Item { root.singleGestureTriggered = true; } - if (centroid.pressPosition.x >= root.screen.width - Config.barConfig.border && dragX < -20) { + if (centroid.pressPosition.x > root.screen.width - Config.barConfig.border && centroid.pressPosition.y < (root.screen.height / 2) && dragX < -20) { + root.visibilities.sidebar = true; + root.singleGestureTriggered = true; + } + + if (centroid.pressPosition.x >= root.screen.width - Config.barConfig.border && centroid.pressPosition.y > (root.screen.height / 2) && dragX < -20) { Hypr.dispatch(`hl.dsp.focus({ workspace = 'r+1', on_current_monitor = true })`); root.singleGestureTriggered = true; } -- 2.47.3