Float as a KWin-managed window instead of a layer surface

The grab bar didn't move the window by mouse, and the corner grip never
resized it (the bar's handler took over its drag). The bar and grip now
start the window manager's move/resize, and Super+LMB/RMB work too.

A KWin rule in kwinrulesrc keeps the window above and unfocused, off the
taskbar, pager and switcher, and remembers its position. KWin now places
the window and keeps it on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 10:44:33 +02:00
co-authored by Claude Opus 5.5
parent daab2fe0ab
commit 6164839886
12 changed files with 105 additions and 131 deletions
+4 -10
View File
@@ -1,11 +1,11 @@
import QtQuick
// The grab bar under the floating keyboard. Emits how far it was dragged;
// moving the window is up to the owner.
// The grab bar under the floating keyboard. Moving the window is up to the
// owner (the window manager's move, so it works for mouse and touch alike).
Item {
id: handle
signal moved(real dx, real dy)
signal dragStarted()
implicitHeight: 22
@@ -19,12 +19,6 @@ Item {
DragHandler {
target: null
// The window follows the pointer, so the pointer stays near its press
// position in window coordinates: measure each step from there.
onCentroidChanged: {
if (active)
handle.moved(centroid.scenePosition.x - centroid.scenePressPosition.x,
centroid.scenePosition.y - centroid.scenePressPosition.y)
}
onActiveChanged: if (active) handle.dragStarted()
}
}
+2 -2
View File
@@ -63,7 +63,7 @@ Window {
DragHandle {
id: handle
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
onMoved: (dx, dy) => root.placement?.moveBy(dx, dy)
onDragStarted: root.startSystemMove()
}
SettingsButton {
@@ -74,7 +74,7 @@ Window {
ResizeHandle {
anchors { right: parent.right; bottom: parent.bottom }
onResized: (dw, dh) => root.placement?.resizeBy(dw, dh)
onDragStarted: root.startSystemResize(Qt.RightEdge | Qt.BottomEdge)
}
}
}
+5 -13
View File
@@ -1,11 +1,10 @@
import QtQuick
// Corner grip. The window grows from its top-left corner, so window
// coordinates stay put while resizing: report each step's delta.
// Corner grip. Resizing is up to the owner (the window manager's resize).
Item {
id: grip
signal resized(real dw, real dh)
signal dragStarted()
implicitWidth: 28
implicitHeight: 28
@@ -28,17 +27,10 @@ Item {
}
DragHandler {
property point last
target: null
// The grab bar lies underneath and would take the drag over.
grabPermissions: PointerHandler.TakeOverForbidden
cursorShape: Qt.SizeFDiagCursor
onActiveChanged: last = centroid.scenePressPosition
onCentroidChanged: {
if (!active)
return
const p = centroid.scenePosition
grip.resized(p.x - last.x, p.y - last.y)
last = p
}
onActiveChanged: if (active) grip.dragStarted()
}
}