diff --git a/modules/HoverPanel.qml b/modules/HoverPanel.qml index 59192fa..59f1e44 100644 --- a/modules/HoverPanel.qml +++ b/modules/HoverPanel.qml @@ -43,14 +43,16 @@ PanelWindow { property bool _winVisible: false property bool _pinned: false + property real _dragStartX: 0 - // When pinned, only the pin button area receives input — everything else passes through + // When pinned, only the header bar receives input — content passes through to desktop. + // Full header width allows drag-to-reposition; pin button tap is within that region too. mask: _pinned ? _pinMask : null property Region _pinMask: Region { - x: panelContainer.x + panelContainer.width - 28 + x: panelContainer.x y: 0 - width: 28 + width: panelContainer.width height: 24 } @@ -190,12 +192,21 @@ PanelWindow { } } - // Popup mode: click-outside dismiss (declared first = lowest z = below content) - MouseArea { + // Popup mode: click-outside dismiss. + // TapHandler fires for all taps; position check skips taps inside panelContainer. + // Gated on !_grace so spurious events during the 400ms opening window don't dismiss. + Item { anchors.fill: parent visible: root.popupMode - enabled: root.popupMode - onClicked: root.dismiss() + + TapHandler { + enabled: !root._grace + onTapped: { + const p = point.position; + if (p.x < panelContainer.x || p.x > panelContainer.x + panelContainer.width || p.y < panelContainer.y || p.y > panelContainer.y + panelContainer.height) + root.dismiss(); + } + } } M.PopupBackground { @@ -215,13 +226,6 @@ PanelWindow { height: _panelColumn.height opacity: 0 - // Popup mode: eat clicks on panel background so outer dismiss doesn't fire - MouseArea { - anchors.fill: parent - visible: root.popupMode - enabled: root.popupMode - } - HoverHandler { enabled: !root.popupMode && !root._pinned onHoveredChanged: if (!root.popupMode && !root._pinned) @@ -235,10 +239,31 @@ PanelWindow { // Header row: title + action buttons + pin — shown in hover mode always, // and in popup mode when a title or actions are provided. Item { + id: _headerItem visible: !root.popupMode || root.panelTitle !== "" || root.titleActionsComponent !== null width: parent.width height: 24 + // Drag header to reposition panel while pinned (hover mode only) + DragHandler { + enabled: root._pinned && !root.popupMode + yAxis.enabled: false + onActiveChanged: if (active) + root._dragStartX = panelContainer.x + onActiveTranslationChanged: { + if (active) { + const sw = root.screen?.width ?? 1920; + panelContainer.x = Math.max(0, Math.min(root._dragStartX + activeTranslation.x, sw - root.contentWidth)); + } + } + } + + // Show move cursor on header when pinned + HoverHandler { + enabled: root._pinned && !root.popupMode + cursorShape: Qt.SizeHorCursor + } + Text { visible: root.panelTitle !== "" anchors.left: parent.left