- activeWindow: shows the focused toplevel title from Quickshell.Wayland ToplevelManager. Left-click activates, middle-click closes, right-click killactive. Hidden in vertical bars to avoid title rotation noise. - nightLight: toggles omarchy-toggle-nightlight; status detected via pgrep hyprsunset. Hides when hyprsunset isn't installed. - keyboardLayout: shows current xkb layout short code, click cycles via hyprctl switchxkblayout. Refreshes on Hyprland activelayout events. - lockKeys: caps/num/scroll lock indicators read from /sys/class/leds. Uses plain A/1/S letters; hides each indicator when off. - spacer: configurable blank space (size) for layout tuning. Defaults add activeWindow to the left section and nightLight to the right section between audioPanel and brightness.
85 lines
1.9 KiB
QML
85 lines
1.9 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Hyprland
|
|
import Quickshell.Io
|
|
import "../common" as Common
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property QtObject bar: null
|
|
property string moduleName: "keyboardLayout"
|
|
property var settings: ({})
|
|
|
|
property string layoutLabel: ""
|
|
property string layoutFull: ""
|
|
|
|
function setting(name, fallback) {
|
|
var value = settings ? settings[name] : undefined
|
|
return value === undefined || value === null ? fallback : value
|
|
}
|
|
|
|
function refresh() {
|
|
if (!queryProc.running) queryProc.running = true
|
|
}
|
|
|
|
function cycleLayout() {
|
|
Hyprland.dispatch("switchxkblayout current next")
|
|
refreshTimer.restart()
|
|
}
|
|
|
|
Component.onCompleted: refresh()
|
|
|
|
Connections {
|
|
target: Hyprland
|
|
function onRawEvent(event) {
|
|
if (!event || !event.name) return
|
|
if (String(event.name).indexOf("activelayout") !== -1) root.refresh()
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: queryProc
|
|
command: ["bash", "-lc", "hyprctl -j devices 2>/dev/null | sed -n '/keyboards/,$p' | head -200"]
|
|
stdout: StdioCollector {
|
|
waitForEnd: true
|
|
onStreamFinished: {
|
|
var match = String(text || "").match(/"active_keymap":\s*"([^"]+)"/)
|
|
if (!match) return
|
|
var full = match[1]
|
|
root.layoutFull = full
|
|
var token = full.split(/\s+/)[0]
|
|
root.layoutLabel = token.substring(0, 3).toUpperCase()
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: refreshTimer
|
|
interval: 600
|
|
onTriggered: root.refresh()
|
|
}
|
|
|
|
Timer {
|
|
interval: 10000
|
|
running: true
|
|
repeat: true
|
|
onTriggered: root.refresh()
|
|
}
|
|
|
|
visible: layoutLabel !== ""
|
|
implicitWidth: button.implicitWidth
|
|
implicitHeight: button.implicitHeight
|
|
|
|
Common.WidgetButton {
|
|
id: button
|
|
anchors.fill: parent
|
|
bar: root.bar
|
|
text: root.layoutLabel
|
|
fontSize: 10
|
|
horizontalMargin: 6
|
|
tooltipText: root.layoutFull
|
|
onPressed: function() { root.cycleLayout() }
|
|
}
|
|
}
|