hoverpanel: free-floating drag (2d, drop mask during drag), extend popup grace to 1500ms, loosen click-outside bounds
This commit is contained in:
parent
434f8f8ffd
commit
2e881de130
1 changed files with 26 additions and 12 deletions
|
|
@ -44,16 +44,19 @@ PanelWindow {
|
|||
property bool _winVisible: false
|
||||
property bool _pinned: false
|
||||
property real _dragStartX: 0
|
||||
property real _dragStartY: 0
|
||||
property bool _dragging: false
|
||||
|
||||
// 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
|
||||
// When pinned: mask = full panel so content is interactive, desktop accessible outside.
|
||||
// When dragging: mask = null (full screen) so Niri keeps delivering events when cursor
|
||||
// leaves the panel bounds mid-drag.
|
||||
mask: (_pinned && !_dragging) ? _pinMask : null
|
||||
|
||||
property Region _pinMask: Region {
|
||||
x: panelContainer.x
|
||||
y: 0
|
||||
y: panelContainer.y
|
||||
width: panelContainer.width
|
||||
height: 24
|
||||
height: panelContainer.height
|
||||
}
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
|
|
@ -84,10 +87,12 @@ PanelWindow {
|
|||
|
||||
// Grace period: after _show(), suppress auto-close briefly so Niri has time
|
||||
// to route wl_pointer.enter to the new overlay surface (cursor may be stationary).
|
||||
// Popup mode gets a longer window (1500ms) so the user can move the cursor to the
|
||||
// panel content after clicking the bar without accidentally dismissing it.
|
||||
property bool _grace: false
|
||||
Timer {
|
||||
id: _graceTimer
|
||||
interval: 400
|
||||
interval: root.popupMode ? 1500 : 400
|
||||
onTriggered: {
|
||||
root._grace = false;
|
||||
if (!root.showPanel && !root._pinned)
|
||||
|
|
@ -203,7 +208,8 @@ PanelWindow {
|
|||
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)
|
||||
const pad = 8;
|
||||
if (p.x < panelContainer.x - pad || p.x > panelContainer.x + panelContainer.width + pad || p.y < panelContainer.y - pad || p.y > panelContainer.y + panelContainer.height + pad)
|
||||
root.dismiss();
|
||||
}
|
||||
}
|
||||
|
|
@ -244,16 +250,24 @@ PanelWindow {
|
|||
width: parent.width
|
||||
height: 24
|
||||
|
||||
// Drag header to reposition panel while pinned (hover mode only)
|
||||
// Drag header to freely reposition panel while pinned (hover mode only).
|
||||
// _dragging clears the input mask so Niri keeps delivering events when the
|
||||
// cursor leaves the panel bounds during a fast drag.
|
||||
DragHandler {
|
||||
enabled: root._pinned && !root.popupMode
|
||||
yAxis.enabled: false
|
||||
onActiveChanged: if (active)
|
||||
root._dragStartX = panelContainer.x
|
||||
onActiveChanged: {
|
||||
root._dragging = active;
|
||||
if (active) {
|
||||
root._dragStartX = panelContainer.x;
|
||||
root._dragStartY = panelContainer.y;
|
||||
}
|
||||
}
|
||||
onActiveTranslationChanged: {
|
||||
if (active) {
|
||||
const sw = root.screen?.width ?? 1920;
|
||||
const sh = root.screen?.height ?? 1080;
|
||||
panelContainer.x = Math.max(0, Math.min(root._dragStartX + activeTranslation.x, sw - root.contentWidth));
|
||||
panelContainer.y = Math.max(0, Math.min(root._dragStartY + activeTranslation.y, sh - panelContainer.height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -261,7 +275,7 @@ PanelWindow {
|
|||
// Show move cursor on header when pinned
|
||||
HoverHandler {
|
||||
enabled: root._pinned && !root.popupMode
|
||||
cursorShape: Qt.SizeHorCursor
|
||||
cursorShape: Qt.SizeAllCursor
|
||||
}
|
||||
|
||||
Text {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue