Shrink to a floating button instead of hiding
With "Shrink to Button" on, the dismiss key shrinks the window to just itself: a see-through button that can be dragged anywhere. Tapping it grows the keyboard back around it, kept on screen. KWin moves and resizes the window through a one-off script, as Wayland clients can't place themselves. Also moves the window back on screen whenever it appears (KWin remembers where the button was), and releases the mouse after a window manager move or resize, which used to eat the next press on the grab bar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import QtQuick
|
||||
|
||||
// The dismiss key left floating while the keyboard is shrunk; see-through so
|
||||
// it hides less. Tap to bring the keyboard back; dragging is up to the owner
|
||||
// (the window manager's move).
|
||||
Item {
|
||||
id: button
|
||||
|
||||
signal tapped()
|
||||
signal dragStarted()
|
||||
|
||||
opacity: 0.6
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: qsTr("Show Keyboard")
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Theme.keyRadius
|
||||
color: tap.pressed ? Theme.characterKey : Theme.functionKey
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "⌨"
|
||||
font.pixelSize: button.height * 0.4
|
||||
color: Theme.text
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
id: tap
|
||||
// The move ends with a release that would otherwise count as a tap.
|
||||
property bool moved: false
|
||||
onPressedChanged: if (pressed) moved = false
|
||||
onTapped: if (!moved) button.tapped()
|
||||
}
|
||||
|
||||
DragHandler {
|
||||
target: null
|
||||
onActiveChanged: {
|
||||
if (!active)
|
||||
return;
|
||||
tap.moved = true;
|
||||
button.dragStarted();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,18 @@ import Sloposk
|
||||
KeyboardSurface {
|
||||
id: surface
|
||||
|
||||
// Window-relative rect of the first key of `type`; empty if there is none.
|
||||
function keyRect(type) {
|
||||
for (let i = 0; i < keys.count; ++i) {
|
||||
const key = keys.itemAt(i);
|
||||
if (key?.keyType === type)
|
||||
return key.mapToItem(null, 0, 0, key.width, key.height);
|
||||
}
|
||||
return Qt.rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: keys
|
||||
model: surface.model
|
||||
delegate: Key {
|
||||
shiftMode: surface.controller ? surface.controller.shiftMode : KeyboardController.Off
|
||||
|
||||
+30
-6
@@ -9,6 +9,8 @@ Window {
|
||||
required property Settings settings
|
||||
required property Diagnostics diagnostics
|
||||
property var placement: null // FloatingWindow, set from C++
|
||||
property var collapse: null // CollapseController, set from C++
|
||||
readonly property bool collapsed: collapse?.collapsed ?? false
|
||||
property bool settingsOpen: false
|
||||
// Height of the key area, for C++ keeping key sizes when rows change.
|
||||
readonly property real keysHeight: keyboard.height
|
||||
@@ -16,23 +18,31 @@ Window {
|
||||
// Transparent room above the keyboard for long-press popups on the top row.
|
||||
readonly property real popupMargin: 90
|
||||
// Outside this, input passes through to whatever is below the window.
|
||||
readonly property rect inputRegion: keyboard.alternates.open
|
||||
readonly property rect inputRegion: collapsed
|
||||
? Qt.rect(floatingButton.x, floatingButton.y, floatingButton.width, floatingButton.height)
|
||||
: keyboard.alternates.open
|
||||
? Qt.rect(0, 0, width, height)
|
||||
: Qt.rect(panel.x, panel.y, panel.width, panel.height)
|
||||
// Empty when nothing shows through, so the compositor skips the blur.
|
||||
readonly property rect blurRegion: settings.blurBackground && settings.backgroundOpacity < 1
|
||||
readonly property rect blurRegion: !collapsed && settings.blurBackground && settings.backgroundOpacity < 1
|
||||
? Qt.rect(panel.x, panel.y, panel.width, panel.height)
|
||||
: Qt.rect(0, 0, 0, 0)
|
||||
|
||||
width: 1000
|
||||
height: 340 + popupMargin
|
||||
minimumWidth: 480
|
||||
minimumHeight: 180 + popupMargin
|
||||
// None while shrunk to the floating button.
|
||||
minimumWidth: collapsed ? 0 : 480
|
||||
minimumHeight: collapsed ? 0 : 180 + popupMargin
|
||||
visible: false
|
||||
color: "transparent"
|
||||
|
||||
onInputRegionChanged: placement?.setInputRegion(inputRegion)
|
||||
onBlurRegionChanged: placement?.setBlurRegion(blurRegion, Theme.windowRadius)
|
||||
// For CollapseController.
|
||||
function dismissKeyRect() {
|
||||
return keyboard.keyRect("dismiss");
|
||||
}
|
||||
|
||||
onPlacementChanged: {
|
||||
placement?.setInputRegion(inputRegion);
|
||||
placement?.setBlurRegion(blurRegion, Theme.windowRadius);
|
||||
@@ -41,6 +51,7 @@ Window {
|
||||
Rectangle {
|
||||
id: panel
|
||||
anchors { fill: parent; topMargin: root.popupMargin }
|
||||
visible: !root.collapsed
|
||||
radius: Theme.windowRadius
|
||||
color: Qt.rgba(Theme.background.r, Theme.background.g, Theme.background.b, root.settings.backgroundOpacity)
|
||||
|
||||
@@ -66,7 +77,7 @@ Window {
|
||||
id: handle
|
||||
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
|
||||
pillWidth: Math.min(120, width - 2 * (quickToggles.x + quickToggles.width + 12))
|
||||
onDragStarted: root.startSystemMove()
|
||||
onDragStarted: root.placement.startMove()
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
@@ -86,7 +97,20 @@ Window {
|
||||
|
||||
ResizeHandle {
|
||||
anchors { right: parent.right; bottom: parent.bottom }
|
||||
onDragStarted: root.startSystemResize(Qt.RightEdge | Qt.BottomEdge)
|
||||
onDragStarted: root.placement.startResize(Qt.RightEdge | Qt.BottomEdge)
|
||||
}
|
||||
}
|
||||
|
||||
FloatingButton {
|
||||
id: floatingButton
|
||||
readonly property rect keyRect: root.collapse?.keyRect ?? Qt.rect(0, 0, 0, 0)
|
||||
// Over the key while the window is full size, then in the shrunk window.
|
||||
x: Math.max(0, Math.min(keyRect.x, root.width - width))
|
||||
y: Math.max(0, Math.min(keyRect.y, root.height - height))
|
||||
width: keyRect.width
|
||||
height: keyRect.height
|
||||
visible: root.collapsed
|
||||
onTapped: root.collapse.expand()
|
||||
onDragStarted: root.placement.startMove()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,14 @@ Flickable {
|
||||
onToggled: checked => panel.settings.alwaysVisible = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
width: parent.width
|
||||
text: qsTr("Shrink to Button")
|
||||
detail: qsTr("⌨ leaves a floating button instead of hiding; tap it to bring the keyboard back")
|
||||
checked: panel.settings.collapseToButton
|
||||
onToggled: checked => panel.settings.collapseToButton = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
width: parent.width
|
||||
text: qsTr("“.” Shortcut")
|
||||
|
||||
Reference in New Issue
Block a user