Extension: Add settings for day and night color scheme

This commit is contained in:
Romain Vigier
2024-03-04 15:17:43 +00:00
parent ea7a83c596
commit 2ae6d00c56
11 changed files with 160 additions and 19 deletions
+11
View File
@@ -88,3 +88,14 @@ If you know your coordinates, you can enter them in a hidden setting, and the ex
```
gsettings --schemadir ~/.local/share/gnome-shell/extensions/nightthemeswitcher@romainvigier.fr/schemas/ set org.gnome.shell.extensions.nightthemeswitcher.time location '($LATITUDE,$LONGITUDE)'
```
### I want to use the `prefer-light` color scheme or change the color scheme used during the day/night
There are two hidden settings to change the color scheme used during the day or night:
```
gsettings --schemadir ~/.local/share/gnome-shell/extensions/nightthemeswitcher@romainvigier.fr/schemas/ set org.gnome.shell.extensions.nightthemeswitcher.color-scheme day $DESIRED_COLORSCHEME
gsettings --schemadir ~/.local/share/gnome-shell/extensions/nightthemeswitcher@romainvigier.fr/schemas/ set org.gnome.shell.extensions.nightthemeswitcher.color-scheme night $DESIRED_COLORSCHEME
```
With `$DESIRED_COLORSCHEME` one of `default`, `prefer-dark` or `prefer-light`.
@@ -4,6 +4,11 @@ SPDX-FileCopyrightText: Night Theme Switcher Contributors
SPDX-License-Identifier: GPL-3.0-or-later
-->
<schemalist gettext-domain="nightthemeswitcher@romainvigier.fr">
<enum id="org.gnome.shell.extensions.nightthemeswitcher.color-scheme-enum">
<value nick="default" value="0"/>
<value nick="prefer-dark" value="1"/>
<value nick="prefer-light" value="2"/>
</enum>
<schema id="org.gnome.shell.extensions.nightthemeswitcher" path="/org/gnome/shell/extensions/nightthemeswitcher/">
<key name="settings-version" type="i">
<default>0</default>
@@ -87,4 +92,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
<default>0.4</default>
</key>
</schema>
<schema id="org.gnome.shell.extensions.nightthemeswitcher.color-scheme" path="/org/gnome/shell/extensions/nightthemeswitcher/color-scheme/">
<key name="day" enum="org.gnome.shell.extensions.nightthemeswitcher.color-scheme-enum">
<default>"default"</default>
</key>
<key name="night" enum="org.gnome.shell.extensions.nightthemeswitcher.color-scheme-enum">
<default>"prefer-dark"</default>
</key>
</schema>
</schemalist>
+14
View File
@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Night Theme Switcher Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
/**
* Color Schemes.
*
* @readonly
* @enum {string}
*/
export const ColorScheme = {
DEFAULT: 'default',
PREFER_DARK: 'prefer-dark',
PREFER_LIGHT: 'prefer-night',
};
+7 -1
View File
@@ -7,6 +7,7 @@ import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js';
import * as debug from './debug.js';
import { ColorSchemeSwitcher } from './modules/ColorSchemeSwitcher.js';
import { SwitcherCommands } from './modules/SwitcherCommands.js';
import { SwitcherThemeCursor, SwitcherThemeGtk, SwitcherThemeIcon, SwitcherThemeShell } from './modules/SwitcherTheme.js';
import { Timer } from './modules/Timer.js';
@@ -20,10 +21,15 @@ export default class NightThemeSwitcher extends Extension {
debug.message('Enabling extension...');
const timer = new Timer({ settings: this.getSettings(`${this.metadata['settings-schema']}.time`), openPrefs: this.openPrefs });
const timer = new Timer({
settings: this.getSettings(`${this.metadata['settings-schema']}.time`),
colorSchemeSettings: this.getSettings(`${this.metadata['settings-schema']}.color-scheme`),
openPrefs: this.openPrefs,
});
this.#modules.push(timer);
[
new ColorSchemeSwitcher({ timer, settings: this.getSettings(`${this.metadata['settings-schema']}.color-scheme`) }),
new SwitcherThemeGtk({ timer, settings: this.getSettings(`${this.metadata['settings-schema']}.gtk-variants`) }),
new SwitcherThemeIcon({ timer, settings: this.getSettings(`${this.metadata['settings-schema']}.icon-variants`) }),
new SwitcherThemeShell({ timer, settings: this.getSettings(`${this.metadata['settings-schema']}.shell-variants`) }),
+2
View File
@@ -20,12 +20,14 @@ main = [
'utils.js',
]
enums = [
'enums/ColorScheme.js',
'enums/Time.js',
]
icons = [
'data/icons/nightthemeswitcher-symbolic.svg',
]
modules = [
'modules/ColorSchemeSwitcher.js',
'modules/Switcher.js',
'modules/SwitcherCommands.js',
'modules/SwitcherTheme.js',
+83
View File
@@ -0,0 +1,83 @@
// SPDX-FileCopyrightText: Night Theme Switcher Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
import Gio from 'gi://Gio';
import * as debug from '../debug.js';
import { Time } from '../enums/Time.js';
import { Switcher } from './Switcher.js';
/**
* The Color Scheme Switcher changes the system color scheme according to the time.
*/
export class ColorSchemeSwitcher extends Switcher {
#settings;
#interfaceSettings;
#timer;
#settingsConnections = [];
constructor({ timer, settings }) {
super({
name: 'Color Scheme',
timer,
settings,
callback: time => this.#onTimeChanged(time),
});
this.#timer = timer;
this.#settings = settings;
this.#interfaceSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
}
enable() {
super.enable();
this.#connectSettings();
}
disable() {
super.disable();
this.#disconnectSettings();
}
#connectSettings() {
debug.message('Connecting Color Scheme Switcher to settings...');
this.#settingsConnections.push({
settings: this.#settings,
id: this.#settings.connect('changed::day', this.#onColorSchemeChanged.bind(this)),
});
this.#settingsConnections.push({
settings: this.#settings,
id: this.#settings.connect('changed::night', this.#onColorSchemeChanged.bind(this)),
});
this.#settingsConnections.push({
settings: this.#interfaceSettings,
id: this.#interfaceSettings.connect('changed::color-scheme', this.#onSystemColorSchemeChanged.bind(this)),
});
}
#disconnectSettings() {
this.#settingsConnections.forEach(({ settings, id }) => settings.disconnect(id));
this.#settingsConnections = [];
debug.message('Disconnected Color Scheme Switcher from settings.');
}
#onTimeChanged(time) {
const colorScheme = time === Time.NIGHT ? this.#settings.get_string('night') : this.#settings.get_string('day');
this.#interfaceSettings.set_string('color-scheme', colorScheme);
}
#onColorSchemeChanged(_settings, time) {
const colorScheme = this.#settings.get_string(time);
debug.message(`${time} color scheme changed to ${colorScheme}.`);
if (time === this.#timer.time)
this.#interfaceSettings.set_string('color-scheme', colorScheme);
}
#onSystemColorSchemeChanged() {
const colorScheme = this.#interfaceSettings.get_string('color-scheme');
debug.message(`System color scheme changed to ${colorScheme}.`);
this.#timer.syncTimeToColorScheme(colorScheme);
}
}
+10 -5
View File
@@ -21,6 +21,7 @@ export class Switcher {
#timer;
#settings;
#callback;
#disableable;
#statusConnection = null;
#timerConnection = null;
@@ -29,20 +30,23 @@ export class Switcher {
* @param {object} params Params object.
* @param {string} params.name Name of the switcher.
* @param {Timer} params.timer Timer to listen to.
* @param {Gio.Settings} params.settings Settings with the `enabled` key.
* @param {Gio.Settings} params.settings Settings.
* @param {TimeChangedCallback} params.callback Callback function.
* @param {boolean} params.disableable If the switcher can be disabled using an `enabled` key in the settings.
*/
constructor({ name, timer, settings, callback }) {
constructor({ name, timer, settings, callback, disableable = false }) {
this.#name = name;
this.#timer = timer;
this.#settings = settings;
this.#callback = callback;
this.#disableable = disableable;
}
enable() {
debug.message(`Enabling ${this.#name} switcher...`);
this.#watchStatus();
if (this.#settings.get_boolean('enabled')) {
if (this.#disableable)
this.#watchStatus();
if (!this.#disableable || this.#settings.get_boolean('enabled')) {
this.#connectTimer();
this.#onTimeChanged();
}
@@ -52,7 +56,8 @@ export class Switcher {
disable() {
debug.message(`Disabling ${this.#name} switcher...`);
this.#disconnectTimer();
this.#unwatchStatus();
if (this.#disableable)
this.#unwatchStatus();
debug.message(`${this.#name} switcher disabled.`);
}
+1
View File
@@ -27,6 +27,7 @@ export class SwitcherCommands extends Switcher {
timer,
settings,
callback: time => this.#onTimeChanged(time),
disableable: true,
});
this.#settings = settings;
}
+1
View File
@@ -54,6 +54,7 @@ export class SwitcherTheme extends Switcher {
timer,
settings,
callback: time => this.#onTimeChanged(time),
disableable: true,
});
this.#name = name;
this.#timer = timer;
+16 -13
View File
@@ -14,6 +14,7 @@ import * as MessageTray from 'resource:///org/gnome/shell/ui/messageTray.js';
import * as debug from '../debug.js';
import { ColorScheme } from '../enums/ColorScheme.js'; // eslint-disable-line no-unused-vars
import { Time } from '../enums/Time.js';
@@ -28,6 +29,7 @@ import { Time } from '../enums/Time.js';
*/
export class Timer extends GObject.Object {
#settings;
#colorSchemeSettings;
#interfaceSettings;
#locationSettings;
#openPrefs;
@@ -54,11 +56,13 @@ export class Timer extends GObject.Object {
/**
* @param {object} params Params object.
* @param {Gio.Settings} params.settings Timer settings.
* @param {Gio.Settings} params.colorSchemeSettings Color Scheme settings.
* @param {Function} params.openPrefs Function opening the extension preferences.
*/
constructor({ settings, openPrefs }) {
constructor({ settings, colorSchemeSettings, openPrefs }) {
super();
this.#settings = settings;
this.#colorSchemeSettings = colorSchemeSettings;
this.#interfaceSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
this.#locationSettings = new Gio.Settings({ schema: 'org.gnome.system.location' });
this.#openPrefs = openPrefs;
@@ -92,6 +96,13 @@ export class Timer extends GObject.Object {
debug.message('Timer disabled.');
}
/**
* @param {ColorScheme} colorScheme Color scheme to sync the time to.
*/
syncTimeToColorScheme(colorScheme) {
this.#changeTime(this.#colorSchemeToTime(colorScheme), true);
}
get time() {
return this.#time || Time.UNKNOWN;
@@ -113,7 +124,7 @@ export class Timer extends GObject.Object {
debug.message(manual ? `Time manually set to ${time}.` : `Time changed to ${time}.`);
layoutManager.screenTransition.run();
this.#interfaceSettings.set_string('color-scheme', time === Time.NIGHT ? 'prefer-dark' : 'default');
this.notify('time');
}
@@ -132,10 +143,6 @@ export class Timer extends GObject.Object {
settings: this.#settings,
id: this.#settings.connect('changed::nightthemeswitcher-ondemand-keybinding', this.#onOndemandKeybindingChanged.bind(this)),
});
this.#settingsConnections.push({
settings: this.#interfaceSettings,
id: this.#interfaceSettings.connect('changed::color-scheme', this.#onColorSchemeChanged.bind(this)),
});
// Only listen to the offset setting when not using a manual schedule
if (!this.#settings.get_boolean('manual-schedule')) {
this.#settingsConnections.push({
@@ -234,8 +241,8 @@ export class Timer extends GObject.Object {
}
#colorSchemeToTime() {
return this.#interfaceSettings.get_string('color-scheme') === 'prefer-dark' ? Time.NIGHT : Time.DAY;
#colorSchemeToTime(colorScheme) {
return colorScheme === this.#colorSchemeSettings.get_string('night') ? Time.NIGHT : Time.DAY;
}
@@ -258,10 +265,6 @@ export class Timer extends GObject.Object {
this.#addKeybinding();
}
#onColorSchemeChanged() {
this.#changeTime(this.#colorSchemeToTime(), true);
}
#onGeoclueReady(_geoclue, result) {
try {
this.#geoclue = Geoclue.Simple.new_finish(result);
@@ -325,7 +328,7 @@ export class Timer extends GObject.Object {
return hour >= sunrise || hour < sunset ? Time.DAY : Time.NIGHT;
// Sunset and Sunrise times are identical; preserve current theme
else
return this.#time || this.#colorSchemeToTime();
return this.#time || this.#colorSchemeToTime(this.#interfaceSettings.get_string('color-scheme'));
}
#updateSuntimes() {
+2
View File
@@ -17,8 +17,10 @@ src/data/ui/ShortcutButton.ui
src/data/ui/ThemesPage.ui
src/data/ui/TimeChooser.ui
src/enums/ColorScheme.js
src/enums/Time.js
src/modules/ColorSchemeSwitcher.js
src/modules/Switcher.js
src/modules/SwitcherCommands.js
src/modules/SwitcherTheme.js