Skip to content

Commit fe0214d

Browse files
bbedwarddms-ci[bot]
authored andcommitted
theme: prevent failed portal writes from reverting theme mode
related: #2786 port 1.5 (cherry picked from commit d82d86d)
1 parent fce1a09 commit fe0214d

3 files changed

Lines changed: 39 additions & 29 deletions

File tree

core/internal/matugen/matugen.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,15 @@ func Run(opts Options) error {
260260
return buildErr
261261
}
262262

263+
if opts.SyncModeWithPortal {
264+
syncColorScheme(opts.Mode)
265+
}
266+
263267
if !changed {
264268
log.Info("No color changes detected, skipping refresh")
265269
return ErrNoChanges
266270
}
267271

268-
if opts.SyncModeWithPortal {
269-
syncColorScheme(opts.Mode)
270-
}
271-
272272
log.Info("Done")
273273
return nil
274274
}
@@ -1006,6 +1006,13 @@ func syncColorScheme(mode ColorMode) {
10061006
scheme = "default"
10071007
}
10081008

1009+
if cur, err := utils.GsettingsGet("org.gnome.desktop.interface", "color-scheme"); err == nil {
1010+
cur = strings.Trim(cur, "'")
1011+
if cur == scheme || (mode == ColorModeLight && cur == "prefer-light") {
1012+
return
1013+
}
1014+
}
1015+
10091016
if err := utils.GsettingsSet("org.gnome.desktop.interface", "color-scheme", scheme); err != nil {
10101017
log.Warnf("Failed to sync color-scheme: %v", err)
10111018
}

quickshell/Common/Theme.qml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,9 +1336,7 @@ Singleton {
13361336
}
13371337

13381338
if (!isGreeterMode) {
1339-
if (!matugenAvailable) {
1340-
PortalService.setLightMode(light);
1341-
}
1339+
PortalService.setLightMode(light);
13421340
if (typeof SettingsData !== "undefined") {
13431341
SettingsData.updateCosmicThemeMode(light);
13441342
}

quickshell/Services/PortalService.qml

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Singleton {
1616
property string profileImage: ""
1717
property bool settingsPortalAvailable: false
1818
property int systemColorScheme: 0
19+
property bool colorSchemeInitialized: false
1920

2021
property bool freedeskAvailable: false
2122
property string colorSchemeCommand: ""
@@ -97,15 +98,24 @@ Singleton {
9798
return typeof Theme !== "undefined";
9899
}
99100

100-
// Only follow values stable for the settle window — the opt-in GTK4-refresh toggle reverts within ~400ms and following it would loop.
101-
function evaluateColorScheme() {
101+
// Follow only genuine portal transitions, debounced by the settle window — the
102+
// opt-in GTK4-refresh toggle reverts within ~400ms, and a stale portal value
103+
// (broken gsettings→portal bridge) must never revert a DMS-initiated change.
104+
function handlePortalColorScheme(scheme) {
105+
const isTransition = colorSchemeInitialized && scheme !== systemColorScheme;
106+
colorSchemeInitialized = true;
107+
systemColorScheme = scheme;
108+
102109
if (!canSyncColorScheme())
103110
return;
104-
const shouldBeLight = systemColorScheme !== 1;
111+
112+
const shouldBeLight = scheme !== 1;
105113
if (Theme.isLightMode === shouldBeLight) {
106114
colorSchemeSettleTimer.stop();
107115
return;
108116
}
117+
if (!isTransition)
118+
return;
109119
colorSchemeSettleTimer.restart();
110120
}
111121

@@ -138,13 +148,16 @@ Singleton {
138148
return;
139149
}
140150

141-
const targetScheme = isLightMode ? "default" : "prefer-dark";
151+
const preferLight = isLightMode && systemColorScheme === 2;
152+
const targetScheme = isLightMode ? (preferLight ? "prefer-light" : "default") : "prefer-dark";
142153

143-
if (colorSchemeCommand === "gsettings") {
154+
switch (colorSchemeCommand) {
155+
case "gsettings":
144156
Quickshell.execDetached(["gsettings", "set", "org.gnome.desktop.interface", "color-scheme", targetScheme]);
145-
}
146-
if (colorSchemeCommand === "dconf") {
157+
break;
158+
case "dconf":
147159
Quickshell.execDetached(["dconf", "write", "/org/gnome/desktop/interface/color-scheme", `'${targetScheme}'`]);
160+
break;
148161
}
149162
}
150163

@@ -206,8 +219,11 @@ Singleton {
206219
target: typeof SettingsData !== "undefined" ? SettingsData : null
207220

208221
function onSyncModeWithPortalChanged() {
209-
if (SettingsData.syncModeWithPortal)
210-
root.evaluateColorScheme();
222+
if (!SettingsData.syncModeWithPortal)
223+
return;
224+
if (typeof Theme === "undefined")
225+
return;
226+
root.setSystemColorScheme(Theme.isLightMode);
211227
}
212228
}
213229

@@ -218,17 +234,7 @@ Singleton {
218234
if (!data || !data.settings)
219235
return;
220236
root.settingsPortalAvailable = data.settings.available === true;
221-
root.systemColorScheme = data.settings.colorScheme || 0;
222-
root.evaluateColorScheme();
223-
}
224-
}
225-
226-
Connections {
227-
target: typeof Theme !== "undefined" ? Theme : null
228-
229-
function onWorkerRunningChanged() {
230-
if (!Theme.workerRunning)
231-
root.evaluateColorScheme();
237+
root.handlePortalColorScheme(data.settings.colorScheme || 0);
232238
}
233239
}
234240

@@ -288,8 +294,7 @@ Singleton {
288294
DMSService.sendRequest("freedesktop.getState", null, response => {
289295
if (response.result && response.result.settings) {
290296
settingsPortalAvailable = response.result.settings.available || false;
291-
systemColorScheme = response.result.settings.colorScheme || 0;
292-
evaluateColorScheme();
297+
handlePortalColorScheme(response.result.settings.colorScheme || 0);
293298
}
294299
});
295300
}

0 commit comments

Comments
 (0)