dots-hyprland/.config/quickshell/modules/onScreenKeyboard/OnScreenKeyboard.qml
2025-05-31 22:34:29 +02:00

169 lines
5.1 KiB
QML

import "root:/"
import "root:/services"
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import QtQuick.Layouts
import Quickshell.Io
import Quickshell
import Quickshell.Widgets
import Quickshell.Wayland
import Quickshell.Hyprland
Scope { // Scope
id: root
property bool pinned: ConfigOptions?.osk.pinnedOnStartup ?? false
component OskControlButton: GroupButton { // Pin button
baseWidth: 40
baseHeight: 40
clickedWidth: baseWidth
clickedHeight: baseHeight + 20
buttonRadius: Appearance.rounding.normal
}
Loader {
id: oskLoader
active: false
onActiveChanged: {
if (!oskLoader.active) {
Ydotool.releaseAllKeys();
}
}
sourceComponent: PanelWindow { // Window
id: oskRoot
visible: oskLoader.active
anchors {
bottom: true
left: true
right: true
}
function hide() {
oskLoader.active = false
}
exclusiveZone: root.pinned ? implicitHeight - Appearance.sizes.hyprlandGapsOut : 0
implicitWidth: oskBackground.width + Appearance.sizes.elevationMargin * 2
implicitHeight: oskBackground.height + Appearance.sizes.elevationMargin * 2
WlrLayershell.namespace: "quickshell:osk"
WlrLayershell.layer: WlrLayer.Overlay
// Hyprland 0.49: Focus is always exclusive and setting this breaks mouse focus grab
// WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
color: "transparent"
mask: Region {
item: oskBackground
}
// Background
StyledRectangularShadow {
target: oskBackground
}
Rectangle {
id: oskBackground
anchors.centerIn: parent
color: Appearance.colors.colLayer0
radius: Appearance.rounding.windowRounding
property real padding: 10
implicitWidth: oskRowLayout.implicitWidth + padding * 2
implicitHeight: oskRowLayout.implicitHeight + padding * 2
Keys.onPressed: (event) => { // Esc to close
if (event.key === Qt.Key_Escape) {
oskRoot.hide()
}
}
RowLayout {
id: oskRowLayout
anchors.centerIn: parent
spacing: 5
VerticalButtonGroup {
OskControlButton { // Pin button
toggled: root.pinned
onClicked: root.pinned = !root.pinned
contentItem: MaterialSymbol {
text: "keep"
horizontalAlignment: Text.AlignHCenter
iconSize: Appearance.font.pixelSize.larger
color: root.pinned ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer0
}
}
OskControlButton {
onClicked: () => {
oskRoot.hide()
}
contentItem: MaterialSymbol {
horizontalAlignment: Text.AlignHCenter
text: "keyboard_hide"
iconSize: Appearance.font.pixelSize.larger
}
}
}
Rectangle {
Layout.topMargin: 20
Layout.bottomMargin: 20
Layout.fillHeight: true
implicitWidth: 1
color: Appearance.m3colors.m3outlineVariant
}
OskContent {
id: oskContent
Layout.fillWidth: true
}
}
}
}
}
IpcHandler {
target: "osk"
function toggle(): void {
oskLoader.active = !oskLoader.active
}
function close(): void {
oskLoader.active = false
}
function open(): void {
oskLoader.active = true
}
}
GlobalShortcut {
name: "oskToggle"
description: qsTr("Toggles on screen keyboard on press")
onPressed: {
oskLoader.active = !oskLoader.active;
}
}
GlobalShortcut {
name: "oskOpen"
description: qsTr("Opens on screen keyboard on press")
onPressed: {
oskLoader.active = true;
}
}
GlobalShortcut {
name: "oskClose"
description: qsTr("Closes on screen keyboard on press")
onPressed: {
oskLoader.active = false;
}
}
}