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 _winVisible: false
|
||||||
property bool _pinned: false
|
property bool _pinned: false
|
||||||
property real _dragStartX: 0
|
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.
|
// When pinned: mask = full panel so content is interactive, desktop accessible outside.
|
||||||
// Full header width allows drag-to-reposition; pin button tap is within that region too.
|
// When dragging: mask = null (full screen) so Niri keeps delivering events when cursor
|
||||||
mask: _pinned ? _pinMask : null
|
// leaves the panel bounds mid-drag.
|
||||||
|
mask: (_pinned && !_dragging) ? _pinMask : null
|
||||||
|
|
||||||
property Region _pinMask: Region {
|
property Region _pinMask: Region {
|
||||||
x: panelContainer.x
|
x: panelContainer.x
|
||||||
y: 0
|
y: panelContainer.y
|
||||||
width: panelContainer.width
|
width: panelContainer.width
|
||||||
height: 24
|
height: panelContainer.height
|
||||||
}
|
}
|
||||||
|
|
||||||
WlrLayershell.layer: WlrLayer.Overlay
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
|
@ -84,10 +87,12 @@ PanelWindow {
|
||||||
|
|
||||||
// Grace period: after _show(), suppress auto-close briefly so Niri has time
|
// 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).
|
// 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
|
property bool _grace: false
|
||||||
Timer {
|
Timer {
|
||||||
id: _graceTimer
|
id: _graceTimer
|
||||||
interval: 400
|
interval: root.popupMode ? 1500 : 400
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root._grace = false;
|
root._grace = false;
|
||||||
if (!root.showPanel && !root._pinned)
|
if (!root.showPanel && !root._pinned)
|
||||||
|
|
@ -203,7 +208,8 @@ PanelWindow {
|
||||||
enabled: !root._grace
|
enabled: !root._grace
|
||||||
onTapped: {
|
onTapped: {
|
||||||
const p = point.position;
|
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();
|
root.dismiss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -244,16 +250,24 @@ PanelWindow {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 24
|
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 {
|
DragHandler {
|
||||||
enabled: root._pinned && !root.popupMode
|
enabled: root._pinned && !root.popupMode
|
||||||
yAxis.enabled: false
|
onActiveChanged: {
|
||||||
onActiveChanged: if (active)
|
root._dragging = active;
|
||||||
root._dragStartX = panelContainer.x
|
if (active) {
|
||||||
|
root._dragStartX = panelContainer.x;
|
||||||
|
root._dragStartY = panelContainer.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
onActiveTranslationChanged: {
|
onActiveTranslationChanged: {
|
||||||
if (active) {
|
if (active) {
|
||||||
const sw = root.screen?.width ?? 1920;
|
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.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
|
// Show move cursor on header when pinned
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
enabled: root._pinned && !root.popupMode
|
enabled: root._pinned && !root.popupMode
|
||||||
cursorShape: Qt.SizeHorCursor
|
cursorShape: Qt.SizeAllCursor
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue