fix: per monitor props not having ancestor scope

This commit is contained in:
2 * r + 2 * t 2026-04-13 00:06:48 +10:00
parent 2f5fcfa2fb
commit 7e4b14f6ba
22 changed files with 74 additions and 69 deletions

View file

@ -80,11 +80,11 @@ ColumnLayout {
const ch = childAt(width / 2, y) as WrappedLoader;
if (ch?.id === "workspaces" && Config.bar.scrollActions.workspaces) {
// Workspace scroll
const mon = (Config.bar.workspaces.perMonitorWorkspaces ? Hypr.monitorFor(screen) : Hypr.focusedMonitor);
const mon = (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? Hypr.monitorFor(screen) : Hypr.focusedMonitor);
const specialWs = mon?.lastIpcObject.specialWorkspace.name;
if (specialWs?.length > 0)
Hypr.dispatch(`togglespecialworkspace ${specialWs.slice(8)}`);
else if (angleDelta.y < 0 || (Config.bar.workspaces.perMonitorWorkspaces ? mon.activeWorkspace?.id : Hypr.activeWsId) > 1)
else if (angleDelta.y < 0 || (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? mon.activeWorkspace?.id : Hypr.activeWsId) > 1)
Hypr.dispatch(`workspace r${angleDelta.y > 0 ? "-" : "+"}1`);
} else if (y < screen.height / 2 && Config.bar.scrollActions.volume) {
// Volume scroll on top half
@ -96,9 +96,9 @@ ColumnLayout {
// Brightness scroll on bottom half
const monitor = Brightness.getMonitorForScreen(screen);
if (angleDelta.y > 0)
monitor.setBrightness(monitor.brightness + Config.services.brightnessIncrement);
monitor.setBrightness(monitor.brightness + GlobalConfig.services.brightnessIncrement);
else if (angleDelta.y < 0)
monitor.setBrightness(monitor.brightness - Config.services.brightnessIncrement);
monitor.setBrightness(monitor.brightness - GlobalConfig.services.brightnessIncrement);
}
}

View file

@ -86,8 +86,8 @@ Item {
id: metrics
text: root.windowTitle
font.pointSize: Tokens.font.size.smaller
font.family: Tokens.font.family.mono
font.pointSize: root.Tokens.font.size.smaller
font.family: root.Tokens.font.family.mono
elide: Qt.ElideRight
elideWidth: root.maxHeight - icon.height
@ -120,10 +120,10 @@ Item {
transform: [
Translate {
x: Config.bar.activeWindow.inverted ? -text.implicitWidth + text.implicitHeight : 0
x: root.Config.bar.activeWindow.inverted ? -text.implicitWidth + text.implicitHeight : 0
},
Rotation {
angle: Config.bar.activeWindow.inverted ? 270 : 90
angle: root.Config.bar.activeWindow.inverted ? 270 : 90
origin.x: text.implicitHeight / 2
origin.y: text.implicitHeight / 2
}

View file

@ -68,7 +68,7 @@ StyledRect {
id: items
model: ScriptModel {
values: SystemTray.items.values.filter(i => !Config.bar.tray.hiddenIcons.includes(i.id))
values: SystemTray.items.values.filter(i => !GlobalConfig.bar.tray.hiddenIcons.includes(i.id))
}
TrayItem {}

View file

@ -1,3 +1,5 @@
pragma ComponentBehavior: Bound
import QtQuick
import Caelestia.Config
import qs.components
@ -61,13 +63,13 @@ StyledRect {
}
Behavior on leading {
enabled: Config.bar.workspaces.activeTrail
enabled: root.Config.bar.workspaces.activeTrail
EAnim {}
}
Behavior on trailing {
enabled: Config.bar.workspaces.activeTrail
enabled: root.Config.bar.workspaces.activeTrail
EAnim {
duration: Tokens.anim.durations.normal * 2
@ -75,19 +77,19 @@ StyledRect {
}
Behavior on currentSize {
enabled: Config.bar.workspaces.activeTrail
enabled: root.Config.bar.workspaces.activeTrail
EAnim {}
}
Behavior on offset {
enabled: !Config.bar.workspaces.activeTrail
enabled: !root.Config.bar.workspaces.activeTrail
EAnim {}
}
Behavior on size {
enabled: !Config.bar.workspaces.activeTrail
enabled: !root.Config.bar.workspaces.activeTrail
EAnim {}
}

View file

@ -15,7 +15,7 @@ Item {
required property ShellScreen screen
readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen)
readonly property string activeSpecial: (Config.bar.workspaces.perMonitorWorkspaces ? monitor : Hypr.focusedMonitor)?.lastIpcObject.specialWorkspace?.name ?? ""
readonly property string activeSpecial: (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? monitor : Hypr.focusedMonitor)?.lastIpcObject.specialWorkspace?.name ?? ""
layer.enabled: true
layer.effect: OpacityMask {
@ -95,7 +95,7 @@ Item {
onCurrentIndexChanged: currentIndex = Qt.binding(() => model.values.findIndex(w => w.name === root.activeSpecial))
model: ScriptModel {
values: Hypr.workspaces.values.filter(w => w.name.startsWith("special:") && (!Config.bar.workspaces.perMonitorWorkspaces || w.monitor === root.monitor))
values: Hypr.workspaces.values.filter(w => w.name.startsWith("special:") && (!GlobalConfig.bar.workspaces.perMonitorWorkspaces || w.monitor === root.monitor))
}
preferredHighlightBegin: 0
@ -347,7 +347,7 @@ Item {
model: ScriptModel {
values: {
const windows = Hypr.toplevels.values.filter(c => c.workspace?.id === ws.wsId);
const maxIcons = Config.bar.workspaces.maxWindowIcons;
const maxIcons = root.Config.bar.workspaces.maxWindowIcons;
return maxIcons > 0 ? windows.slice(0, maxIcons) : windows;
}
}

View file

@ -94,7 +94,7 @@ ColumnLayout {
values: {
const ws = root.ws;
const windows = Hypr.toplevels.values.filter(c => c.workspace?.id === ws);
const maxIcons = Config.bar.workspaces.maxWindowIcons;
const maxIcons = root.Config.bar.workspaces.maxWindowIcons;
return maxIcons > 0 ? windows.slice(0, maxIcons) : windows;
}
}

View file

@ -14,8 +14,8 @@ StyledClippingRect {
required property ShellScreen screen
required property bool fullscreen
readonly property bool onSpecial: (Config.bar.workspaces.perMonitorWorkspaces ? Hypr.monitorFor(screen) : Hypr.focusedMonitor)?.lastIpcObject.specialWorkspace?.name !== ""
readonly property int activeWsId: Config.bar.workspaces.perMonitorWorkspaces ? (Hypr.monitorFor(screen).activeWorkspace?.id ?? 1) : Hypr.activeWsId
readonly property bool onSpecial: (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? Hypr.monitorFor(screen) : Hypr.focusedMonitor)?.lastIpcObject.specialWorkspace?.name !== ""
readonly property int activeWsId: GlobalConfig.bar.workspaces.perMonitorWorkspaces ? (Hypr.monitorFor(screen).activeWorkspace?.id ?? 1) : Hypr.activeWsId
readonly property var occupied: {
const occ = {};

View file

@ -128,7 +128,7 @@ Item {
Repeater {
model: ScriptModel {
values: SystemTray.items.values.filter(i => !Config.bar.tray.hiddenIcons.includes(i.id))
values: SystemTray.items.values.filter(i => !GlobalConfig.bar.tray.hiddenIcons.includes(i.id))
}
Popout {

View file

@ -43,7 +43,7 @@ Item {
property bool workspacesOccupiedBg: Config.bar.workspaces.occupiedBg ?? false
property bool workspacesShowWindows: Config.bar.workspaces.showWindows ?? false
property int workspacesMaxWindowIcons: Config.bar.workspaces.maxWindowIcons ?? 0
property bool workspacesPerMonitor: Config.bar.workspaces.perMonitorWorkspaces ?? true
property bool workspacesPerMonitor: GlobalConfig.bar.workspaces.perMonitorWorkspaces ?? true
property bool scrollWorkspaces: Config.bar.scrollActions.workspaces ?? true
property bool scrollVolume: Config.bar.scrollActions.volume ?? true
property bool scrollBrightness: Config.bar.scrollActions.brightness ?? true

View file

@ -122,7 +122,7 @@ Item {
id: visualiserBars
model: Array.from({
length: Config.services.visualiserBars
length: GlobalConfig.services.visualiserBars
}, (_, i) => i)
ShapePath {
@ -131,13 +131,13 @@ Item {
required property int modelData
readonly property real value: Math.max(1e-3, Math.min(1, Audio.cava.values[modelData]))
readonly property real angle: modelData * 2 * Math.PI / Config.services.visualiserBars
readonly property real angle: modelData * 2 * Math.PI / GlobalConfig.services.visualiserBars
readonly property real magnitude: value * Tokens.sizes.dashboard.mediaVisualiserSize
readonly property real cos: Math.cos(angle)
readonly property real sin: Math.sin(angle)
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
strokeWidth: 360 / Config.services.visualiserBars - Tokens.spacing.small / 4
strokeWidth: 360 / GlobalConfig.services.visualiserBars - Tokens.spacing.small / 4
strokeColor: Colours.palette.m3primary
startX: visualiser.centerX + (visualiser.innerX + strokeWidth / 2) * cos

View file

@ -12,22 +12,25 @@ Region {
required property Panels panels
required property var win
readonly property real borderThickness: win.configScope.Config.border.thickness
readonly property real clampedThickness: win.configScope.Config.border.clampedThickness
x: bar.clampedWidth + win.dragMaskPadding
y: Config.border.clampedThickness + win.dragMaskPadding
width: win.width - bar.clampedWidth - Config.border.clampedThickness - win.dragMaskPadding * 2
height: win.height - Config.border.clampedThickness * 2 - win.dragMaskPadding * 2
y: clampedThickness + win.dragMaskPadding
width: win.width - bar.clampedWidth - clampedThickness - win.dragMaskPadding * 2
height: win.height - clampedThickness * 2 - win.dragMaskPadding * 2
intersection: Intersection.Xor
R {
panel: root.panels.dashboard
y: 0
height: panel.height * (1 - root.panels.dashboard.offsetScale) + Config.border.thickness
height: panel.height * (1 - root.panels.dashboard.offsetScale) + root.borderThickness
}
R {
panel: root.panels.launcher
y: root.win.height - height
height: panel.height * (1 - root.panels.launcher.offsetScale) + Config.border.thickness
height: panel.height * (1 - root.panels.launcher.offsetScale) + root.borderThickness
}
R {
@ -35,7 +38,7 @@ Region {
panel: root.panels.sessionWrapper
x: root.win.width - width
width: panel.width * (1 - root.panels.session.offsetScale) + Config.border.thickness + sidebarRegion.width
width: panel.width * (1 - root.panels.session.offsetScale) + root.borderThickness + sidebarRegion.width
}
R {
@ -43,25 +46,25 @@ Region {
panel: root.panels.sidebar
x: root.win.width - width
width: panel.width * (1 - root.panels.sidebar.offsetScale) + Config.border.thickness
width: panel.width * (1 - root.panels.sidebar.offsetScale) + root.borderThickness
}
R {
panel: root.panels.osdWrapper
x: root.win.width - width
width: panel.width * (1 - root.panels.osd.offsetScale) + Config.border.thickness + sessionRegion.width
width: panel.width * (1 - root.panels.osd.offsetScale) + root.borderThickness + sessionRegion.width
}
R {
panel: root.panels.notifications
y: 0
height: panel.height + Config.border.thickness
height: panel.height + root.borderThickness
}
R {
panel: root.panels.utilities
y: root.win.height - height
height: panel.height * (1 - root.panels.utilities.offsetScale) + Config.border.thickness
height: panel.height * (1 - root.panels.utilities.offsetScale) + root.borderThickness
}
R {
@ -73,7 +76,7 @@ Region {
required property Item panel
x: panel.x + root.bar.implicitWidth
y: panel.y + Config.border.thickness
y: panel.y + root.borderThickness
width: panel.width
height: panel.height
intersection: Intersection.Subtract

View file

@ -87,9 +87,9 @@ Item {
if (!monitor)
return;
if (event.angleDelta.y > 0)
monitor.setBrightness(monitor.brightness + Config.services.brightnessIncrement);
monitor.setBrightness(monitor.brightness + GlobalConfig.services.brightnessIncrement);
else if (event.angleDelta.y < 0)
monitor.setBrightness(monitor.brightness - Config.services.brightnessIncrement);
monitor.setBrightness(monitor.brightness - GlobalConfig.services.brightnessIncrement);
}
implicitWidth: Tokens.sizes.osd.sliderWidth

View file

@ -33,31 +33,31 @@ Singleton {
function setVolume(newVolume: real): void {
if (sink?.ready && sink?.audio) {
sink.audio.muted = false;
sink.audio.volume = Math.max(0, Math.min(Config.services.maxVolume, newVolume));
sink.audio.volume = Math.max(0, Math.min(GlobalConfig.services.maxVolume, newVolume));
}
}
function incrementVolume(amount: real): void {
setVolume(volume + (amount || Config.services.audioIncrement));
setVolume(volume + (amount || GlobalConfig.services.audioIncrement));
}
function decrementVolume(amount: real): void {
setVolume(volume - (amount || Config.services.audioIncrement));
setVolume(volume - (amount || GlobalConfig.services.audioIncrement));
}
function setSourceVolume(newVolume: real): void {
if (source?.ready && source?.audio) {
source.audio.muted = false;
source.audio.volume = Math.max(0, Math.min(Config.services.maxVolume, newVolume));
source.audio.volume = Math.max(0, Math.min(GlobalConfig.services.maxVolume, newVolume));
}
}
function incrementSourceVolume(amount: real): void {
setSourceVolume(sourceVolume + (amount || Config.services.audioIncrement));
setSourceVolume(sourceVolume + (amount || GlobalConfig.services.audioIncrement));
}
function decrementSourceVolume(amount: real): void {
setSourceVolume(sourceVolume - (amount || Config.services.audioIncrement));
setSourceVolume(sourceVolume - (amount || GlobalConfig.services.audioIncrement));
}
function setAudioSink(newSink: PwNode): void {
@ -80,7 +80,7 @@ Singleton {
function setStreamVolume(stream: PwNode, newVolume: real): void {
if (stream?.ready && stream?.audio) {
stream.audio.muted = false;
stream.audio.volume = Math.max(0, Math.min(Config.services.maxVolume, newVolume));
stream.audio.volume = Math.max(0, Math.min(GlobalConfig.services.maxVolume, newVolume));
}
}
@ -166,7 +166,7 @@ Singleton {
CavaProvider {
id: cava
bars: Config.services.visualiserBars
bars: GlobalConfig.services.visualiserBars
}
BeatTracker {

View file

@ -50,13 +50,13 @@ Singleton {
function increaseBrightness(): void {
const monitor = getMonitor("active");
if (monitor)
monitor.setBrightness(monitor.brightness + Config.services.brightnessIncrement);
monitor.setBrightness(monitor.brightness + GlobalConfig.services.brightnessIncrement);
}
function decreaseBrightness(): void {
const monitor = getMonitor("active");
if (monitor)
monitor.setBrightness(monitor.brightness - Config.services.brightnessIncrement);
monitor.setBrightness(monitor.brightness - GlobalConfig.services.brightnessIncrement);
}
onMonitorsChanged: {

View file

@ -15,17 +15,17 @@ Singleton {
property int currentIndex: -1
property bool loading: false
property bool isManualSeeking: false
property bool lyricsVisible: Config.services.showLyrics
property bool lyricsVisible: GlobalConfig.services.showLyrics
property string backend: "Local"
property string preferredBackend: Config.services.lyricsBackend
property string preferredBackend: GlobalConfig.services.lyricsBackend
property real currentSongId: 0
property string loadedLocalFile: ""
property real offset
property int currentRequestId: 0
property var lyricsMap: ({})
readonly property string lyricsDir: Paths.absolutePath(Config.paths.lyricsDir)
readonly property string lyricsMapFile: Paths.absolutePath(Config.paths.lyricsDir) + "/lyrics_map.json"
readonly property string lyricsDir: Paths.absolutePath(GlobalConfig.paths.lyricsDir)
readonly property string lyricsMapFile: lyricsDir + "/lyrics_map.json"
readonly property alias model: lyricsModel
readonly property alias candidatesModel: fetchedCandidatesModel
readonly property var _netEaseHeaders: ({
@ -68,7 +68,7 @@ Singleton {
}
function toggleVisibility() {
GlobalConfig.services.showLyrics = !Config.services.showLyrics;
GlobalConfig.services.showLyrics = !GlobalConfig.services.showLyrics;
}
function loadLyrics() {
@ -271,7 +271,7 @@ Singleton {
}
onPreferredBackendChanged: {
if (Config.services.lyricsBackend !== preferredBackend) {
if (GlobalConfig.services.lyricsBackend !== preferredBackend) {
GlobalConfig.services.lyricsBackend = preferredBackend;
}
}

View file

@ -12,11 +12,11 @@ Singleton {
id: root
readonly property list<MprisPlayer> list: Mpris.players.values
readonly property MprisPlayer active: props.manualActive ?? list.find(p => getIdentity(p) === Config.services.defaultPlayer) ?? list[0] ?? null
readonly property MprisPlayer active: props.manualActive ?? list.find(p => getIdentity(p) === GlobalConfig.services.defaultPlayer) ?? list[0] ?? null
property alias manualActive: props.manualActive
function getIdentity(player: MprisPlayer): string {
const alias = Config.services.playerAliases.find(a => a.from === player.identity);
const alias = GlobalConfig.services.playerAliases.find(a => a.from === player.identity);
return alias?.to ?? player.identity;
}

View file

@ -14,7 +14,7 @@ Singleton {
property real cpuTemp
// GPU properties
readonly property string gpuType: Config.services.gpuType.toUpperCase() || autoGpuType
readonly property string gpuType: GlobalConfig.services.gpuType.toUpperCase() || autoGpuType
property string autoGpuType: "NONE"
property string gpuName: ""
property real gpuPerc
@ -251,7 +251,7 @@ Singleton {
Process {
id: gpuTypeCheck
running: !Config.services.gpuType
running: !GlobalConfig.services.gpuType
command: ["sh", "-c", "if command -v nvidia-smi &>/dev/null && nvidia-smi -L &>/dev/null; then echo NVIDIA; elif ls /sys/class/drm/card*/device/gpu_busy_percent 2>/dev/null | grep -q .; then echo GENERIC; else echo NONE; fi"]
stdout: StdioCollector {
onStreamFinished: root.autoGpuType = text.trim()

View file

@ -11,7 +11,7 @@ Singleton {
readonly property int minutes: clock.minutes
readonly property int seconds: clock.seconds
readonly property string timeStr: format(Config.services.useTwelveHourClock ? "hh:mm:A" : "hh:mm")
readonly property string timeStr: format(GlobalConfig.services.useTwelveHourClock ? "hh:mm:A" : "hh:mm")
readonly property list<string> timeComponents: timeStr.split(":")
readonly property string hourStr: timeComponents[0] ?? ""
readonly property string minuteStr: timeComponents[1] ?? ""

View file

@ -12,7 +12,7 @@ Searcher {
id: root
readonly property string currentNamePath: `${Paths.state}/wallpaper/path.txt`
readonly property list<string> smartArg: Config.services.smartScheme ? [] : ["--no-smart"]
readonly property list<string> smartArg: GlobalConfig.services.smartScheme ? [] : ["--no-smart"]
property bool showPreview: false
readonly property string current: showPreview ? previewPath : actualCurrent

View file

@ -27,7 +27,7 @@ Singleton {
readonly property var cachedCities: new Map()
function reload(): void {
const configLocation = Config.services.weatherLocation;
const configLocation = GlobalConfig.services.weatherLocation;
if (configLocation) {
if (configLocation.indexOf(",") !== -1 && !isNaN(parseFloat(configLocation.split(",")[0]))) {
@ -215,7 +215,7 @@ Singleton {
root.reload();
}
target: Config.services
target: GlobalConfig.services
}
Timer {

View file

@ -107,7 +107,7 @@ Singleton {
}
function getAppCategoryIcon(name: string, fallback: string): string {
for (const iconConfig of Config.bar.workspaces.windowIcons)
for (const iconConfig of GlobalConfig.bar.workspaces.windowIcons)
if (matchIconConfig(name, iconConfig))
return iconConfig.icon;
@ -212,7 +212,7 @@ Singleton {
function getSpecialWsIcon(name: string): string {
name = name.toLowerCase().slice("special:".length);
for (const iconConfig of Config.bar.workspaces.specialWorkspaceIcons)
for (const iconConfig of GlobalConfig.bar.workspaces.specialWorkspaceIcons)
if (matchIconConfig(name, iconConfig))
return iconConfig.icon;
@ -230,7 +230,7 @@ Singleton {
}
function getTrayIcon(id: string, icon: string): string {
for (const sub of Config.bar.tray.iconSubs)
for (const sub of GlobalConfig.bar.tray.iconSubs)
if (sub.id === id)
return sub.image ? Qt.resolvedUrl(sub.image) : Quickshell.iconPath(sub.icon);

View file

@ -36,11 +36,11 @@ Singleton {
root.osIdLike = fd("ID_LIKE").split(" ");
const logo = Quickshell.iconPath(fd("LOGO"), true);
if (Config.general.logo === "caelestia") {
if (GlobalConfig.general.logo === "caelestia") {
root.osLogo = Qt.resolvedUrl(`${Quickshell.shellDir}/assets/logo.svg`);
root.isDefaultLogo = true;
} else if (Config.general.logo) {
root.osLogo = Quickshell.iconPath(Config.general.logo, true) || "file://" + Paths.absolutePath(Config.general.logo);
} else if (GlobalConfig.general.logo) {
root.osLogo = Quickshell.iconPath(GlobalConfig.general.logo, true) || "file://" + Paths.absolutePath(GlobalConfig.general.logo);
root.isDefaultLogo = false;
} else if (logo) {
root.osLogo = logo;
@ -54,7 +54,7 @@ Singleton {
osRelease.reload();
}
target: Config.general
target: GlobalConfig.general
}
Timer {