Each `bash -lc` starts a login shell that re-sources the profile (mise activation, /etc/profile.d) on every invocation — ~16 forks per call versus ~2 for `bash -c` — which taxes every menu/panel/launcher action the shell shells out for. The session already exports PATH and env to the shell, so omarchy commands resolve fine under `bash -c`. Switch the internal/omarchy-owned spawns (theme+background switches, brightness, monitor scaling, DNS, lock/fingerprint, keyboard-layout probe, voxtype status, and the `:`/printf state-file writes) to `bash -c`. Leave `bash -lc` on the sites that run user-configurable commands (custom bar-widget exec, menu provider/guard scripts, launcher scan commands, configurable idle/screensaver command), where a user's command may rely on their login environment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
79 lines
1.7 KiB
QML
79 lines
1.7 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Hyprland
|
|
import Quickshell.Io
|
|
import qs.Ui
|
|
import qs.Commons
|
|
|
|
BarWidget {
|
|
id: root
|
|
moduleName: "omarchy.keyboard-layout"
|
|
|
|
|
|
property string layoutLabel: ""
|
|
property string layoutFull: ""
|
|
|
|
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", "-c", "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
|
|
|
|
WidgetButton {
|
|
id: button
|
|
anchors.fill: parent
|
|
bar: root.bar
|
|
text: root.layoutLabel
|
|
fontSize: Style.font.caption
|
|
horizontalMargin: 6
|
|
tooltipText: root.layoutFull
|
|
onPressed: function() { root.cycleLayout() }
|
|
}
|
|
}
|