97 lines
3.0 KiB
QML
97 lines
3.0 KiB
QML
pragma Singleton
|
|
|
|
// Pointer size and text scale.
|
|
//
|
|
// These are the two settings that must agree across three consumers that do not
|
|
// share a configuration system: the compositor draws the cursor, GTK
|
|
// applications read gsettings, and the shell renders its own text. Panama's
|
|
// store is the source of truth, and this pushes the value out to the other two
|
|
// so they cannot disagree.
|
|
//
|
|
// pointer size -> gsettings (GTK) + `hyprctl setcursor` (compositor)
|
|
// text scale -> gsettings (GTK)
|
|
//
|
|
// The shell's own font size is not scaled here. Theme.qml's sizes are part of
|
|
// the design rather than a user preference, and scaling them at runtime would
|
|
// reflow every panel against layouts that were tuned at the design size. Text
|
|
// scale therefore affects applications, which is where it matters, and the
|
|
// page says so rather than implying it does more.
|
|
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
import qs.config
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
property string lastError: ""
|
|
|
|
readonly property bool busy: runner.running || root.pending.length > 0
|
|
|
|
readonly property string cursorTheme: DesktopPreferences.get("cursorTheme")
|
|
readonly property int cursorSize: DesktopPreferences.get("cursorSize")
|
|
readonly property real textScale: DesktopPreferences.get("textScale")
|
|
|
|
// A short queue, because applying one setting takes several commands and
|
|
// Process runs one at a time.
|
|
property var pending: []
|
|
|
|
Process {
|
|
id: runner
|
|
onExited: (exitCode, exitStatus) => {
|
|
if (exitCode !== 0)
|
|
root.lastError = "That accessibility setting could not be applied.";
|
|
root.drain();
|
|
}
|
|
}
|
|
|
|
function drain(): void {
|
|
if (runner.running || root.pending.length === 0)
|
|
return;
|
|
const next = root.pending[0];
|
|
root.pending = root.pending.slice(1);
|
|
runner.exec(next);
|
|
}
|
|
|
|
function enqueue(commands: var): void {
|
|
root.pending = root.pending.concat(commands);
|
|
root.drain();
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
settle.restart();
|
|
}
|
|
|
|
// Push the stored values outward once at startup, so a value changed in a
|
|
// previous session is in effect in this one even though gsettings and the
|
|
// compositor do not read Panama's store.
|
|
Timer {
|
|
id: settle
|
|
interval: 1200
|
|
onTriggered: root.applyAll()
|
|
}
|
|
|
|
Connections {
|
|
target: DesktopPreferences
|
|
function onRevisionChanged(): void { coalesce.restart(); }
|
|
}
|
|
|
|
Timer {
|
|
id: coalesce
|
|
interval: 250
|
|
onTriggered: root.applyAll()
|
|
}
|
|
|
|
function applyAll(): void {
|
|
root.lastError = "";
|
|
const size = String(root.cursorSize);
|
|
const commands = [
|
|
["gsettings", "set", "org.gnome.desktop.interface", "cursor-size", size],
|
|
["gsettings", "set", "org.gnome.desktop.interface", "text-scaling-factor", String(root.textScale)]
|
|
];
|
|
commands.push(["hyprctl", "setcursor", root.cursorTheme, size]);
|
|
root.enqueue(commands);
|
|
}
|
|
}
|