Extension: Remove theme switching
This commit is contained in:
@@ -65,7 +65,11 @@ You're welcome to contribute to the code or the translations! See [CONTRIBUTING.
|
||||
|
||||
Like GNOME's built-in dark mode, the extension switches the standard freedesktop.org color scheme preference. Older applications might not follow this preference.
|
||||
|
||||
It is possible to force a GTK theme in the extension preferences, but please note that this can visually break applications. It is better to ask the developers of the applications to support the standard preference.
|
||||
It is possible to force a GTK theme by running commands in the extension preferences, but please note that this can visually break applications. It is better to ask the developers of the applications to support the standard preference.
|
||||
|
||||
```
|
||||
gsettings set org.gnome.desktop.interface gtk-theme $THEME_NAME
|
||||
```
|
||||
|
||||
### Something doesn't work on Ubuntu
|
||||
|
||||
|
||||
@@ -14,50 +14,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<default>0</default>
|
||||
</key>
|
||||
</schema>
|
||||
<schema id="org.gnome.shell.extensions.nightthemeswitcher.gtk-variants" path="/org/gnome/shell/extensions/nightthemeswitcher/gtk-variants/">
|
||||
<key name="enabled" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
<key name="day" type="s">
|
||||
<default>"Adwaita"</default>
|
||||
</key>
|
||||
<key name="night" type="s">
|
||||
<default>"Adwaita-dark"</default>
|
||||
</key>
|
||||
</schema>
|
||||
<schema id="org.gnome.shell.extensions.nightthemeswitcher.shell-variants" path="/org/gnome/shell/extensions/nightthemeswitcher/shell-variants/">
|
||||
<key name="enabled" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
<key name="day" type="s">
|
||||
<default>""</default>
|
||||
</key>
|
||||
<key name="night" type="s">
|
||||
<default>""</default>
|
||||
</key>
|
||||
</schema>
|
||||
<schema id="org.gnome.shell.extensions.nightthemeswitcher.icon-variants" path="/org/gnome/shell/extensions/nightthemeswitcher/icon-variants/">
|
||||
<key name="enabled" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
<key name="day" type="s">
|
||||
<default>"Adwaita"</default>
|
||||
</key>
|
||||
<key name="night" type="s">
|
||||
<default>"Adwaita"</default>
|
||||
</key>
|
||||
</schema>
|
||||
<schema id="org.gnome.shell.extensions.nightthemeswitcher.cursor-variants" path="/org/gnome/shell/extensions/nightthemeswitcher/cursor-variants/">
|
||||
<key name="enabled" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
<key name="day" type="s">
|
||||
<default>"Adwaita"</default>
|
||||
</key>
|
||||
<key name="night" type="s">
|
||||
<default>"Adwaita"</default>
|
||||
</key>
|
||||
</schema>
|
||||
<schema id="org.gnome.shell.extensions.nightthemeswitcher.commands" path="/org/gnome/shell/extensions/nightthemeswitcher/commands/">
|
||||
<key name="enabled" type="b">
|
||||
<default>false</default>
|
||||
|
||||
@@ -20,7 +20,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<file compressed="true" preprocess="xml-stripblanks">ui/ContributePage.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">ui/SchedulePage.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">ui/ShortcutButton.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">ui/ThemesPage.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">ui/TimeChooser.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
SPDX-FileCopyrightText: Night Theme Switcher Contributors
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-->
|
||||
<interface domain="nightthemeswitcher@romainvigier.fr">
|
||||
<template class="ThemesPage" parent="AdwPreferencesPage">
|
||||
<property name="name">themes</property>
|
||||
<property name="title" translatable="yes">Themes</property>
|
||||
<property name="icon-name">nightthemeswitcher-themes-symbolic</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">GNOME has a built-in dark mode that the extension uses. Manually switching themes is discouraged and is only here for legacy reasons.</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
<class name="error"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="AdwExpanderRow" id="gtk_row">
|
||||
<property name="title" translatable="yes">Switch GTK theme</property>
|
||||
<property name="subtitle" translatable="yes">Forcing a dark theme on applications not designed to support it can have undesirable side-effects such as unreadable text or invisible icons.</property>
|
||||
<property name="show-enable-switch">True</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="gtk_day_variant_combo_row">
|
||||
<property name="title" translatable="yes">Day variant</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="gtk_night_variant_combo_row">
|
||||
<property name="title" translatable="yes">Night variant</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwExpanderRow" id="shell_row">
|
||||
<property name="title" translatable="yes">Switch Shell theme</property>
|
||||
<property name="show-enable-switch">True</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="shell_day_variant_combo_row">
|
||||
<property name="title" translatable="yes">Day variant</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="shell_night_variant_combo_row">
|
||||
<property name="title" translatable="yes">Night variant</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwExpanderRow" id="icon_row">
|
||||
<property name="title" translatable="yes">Switch icon theme</property>
|
||||
<property name="show-enable-switch">True</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="icon_day_variant_combo_row">
|
||||
<property name="title" translatable="yes">Day variant</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="icon_night_variant_combo_row">
|
||||
<property name="title" translatable="yes">Night variant</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwExpanderRow" id="cursor_row">
|
||||
<property name="title" translatable="yes">Switch cursor theme</property>
|
||||
<property name="show-enable-switch">True</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="cursor_day_variant_combo_row">
|
||||
<property name="title" translatable="yes">Day variant</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="cursor_night_variant_combo_row">
|
||||
<property name="title" translatable="yes">Night variant</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -9,7 +9,6 @@ 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';
|
||||
|
||||
|
||||
@@ -30,10 +29,6 @@ export default class NightThemeSwitcher extends Extension {
|
||||
|
||||
[
|
||||
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`) }),
|
||||
new SwitcherThemeCursor({ timer, settings: this.getSettings(`${this.metadata['settings-schema']}.cursor-variants`) }),
|
||||
new SwitcherCommands({ timer, settings: this.getSettings(`${this.metadata['settings-schema']}.commands`) }),
|
||||
].forEach(module => this.#modules.push(module));
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ main = [
|
||||
'debug.js',
|
||||
'extension.js',
|
||||
'prefs.js',
|
||||
'utils.js',
|
||||
]
|
||||
enums = [
|
||||
'enums/ColorScheme.js',
|
||||
@@ -30,7 +29,6 @@ modules = [
|
||||
'modules/ColorSchemeSwitcher.js',
|
||||
'modules/Switcher.js',
|
||||
'modules/SwitcherCommands.js',
|
||||
'modules/SwitcherTheme.js',
|
||||
'modules/Timer.js',
|
||||
]
|
||||
preferences = [
|
||||
@@ -39,10 +37,8 @@ preferences = [
|
||||
'preferences/ClearableEntry.js',
|
||||
'preferences/CommandsPage.js',
|
||||
'preferences/ContributePage.js',
|
||||
'preferences/DropDownChoice.js',
|
||||
'preferences/SchedulePage.js',
|
||||
'preferences/ShortcutButton.js',
|
||||
'preferences/ThemesPage.js',
|
||||
'preferences/TimeChooser.js',
|
||||
]
|
||||
|
||||
|
||||
@@ -1,314 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Night Theme Switcher Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
|
||||
import { ExtensionState } from 'resource:///org/gnome/shell/misc/extensionUtils.js';
|
||||
import { extensionManager, setThemeStylesheet, loadTheme } from 'resource:///org/gnome/shell/ui/main.js';
|
||||
|
||||
import * as debug from '../debug.js';
|
||||
import * as utils from '../utils.js';
|
||||
|
||||
import { Time } from '../enums/Time.js';
|
||||
|
||||
import { Switcher } from './Switcher.js';
|
||||
|
||||
|
||||
/**
|
||||
* Function called to update the system theme when no settings exist.
|
||||
*
|
||||
* @callback noSettingsUpdateSystemThemeCallback
|
||||
* @param {Time} time New time.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The Theme Switcher sets the system theme according to the time, either via
|
||||
* provided settings or by running a callback function.
|
||||
*
|
||||
* It also listens to system theme changes to update the current variant setting.
|
||||
*/
|
||||
export class SwitcherTheme extends Switcher {
|
||||
#name;
|
||||
#timer;
|
||||
#settings;
|
||||
#systemSettings;
|
||||
#themeKey;
|
||||
#noSettingsUpdateSystemThemeCallback;
|
||||
|
||||
#settingsConnections = [];
|
||||
|
||||
/**
|
||||
* @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`, `day` and `night` keys.
|
||||
* @param {Gio.Settings} [params.systemSettings] System settings containing the theme name.
|
||||
* @param {string} params.themeKey Settings key of the theme name.
|
||||
* @param {noSettingsUpdateSystemThemeCallback} params.noSettingsUpdateSystemThemeCallback function.
|
||||
*/
|
||||
constructor({ name, timer, settings, systemSettings = null, themeKey, noSettingsUpdateSystemThemeCallback = null }) {
|
||||
super({
|
||||
name,
|
||||
timer,
|
||||
settings,
|
||||
callback: time => this.#onTimeChanged(time),
|
||||
disableable: true,
|
||||
});
|
||||
this.#name = name;
|
||||
this.#timer = timer;
|
||||
this.#settings = settings;
|
||||
this.#systemSettings = systemSettings;
|
||||
this.#themeKey = themeKey;
|
||||
this.#noSettingsUpdateSystemThemeCallback = noSettingsUpdateSystemThemeCallback;
|
||||
}
|
||||
|
||||
enable() {
|
||||
if (this.#settings.get_boolean('enabled'))
|
||||
this.#connectSettings();
|
||||
super.enable();
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.#disconnectSettings();
|
||||
super.disable();
|
||||
}
|
||||
|
||||
set systemSettings(settings) {
|
||||
if (settings === this.#systemSettings)
|
||||
return;
|
||||
this.#systemSettings = settings;
|
||||
this.disable();
|
||||
this.enable();
|
||||
}
|
||||
|
||||
#connectSettings() {
|
||||
debug.message(`Connecting ${this.#name} switcher to settings...`);
|
||||
this.#settingsConnections.push({
|
||||
settings: this.#settings,
|
||||
id: this.#settings.connect('changed::day', this.#onDayVariantChanged.bind(this)),
|
||||
});
|
||||
this.#settingsConnections.push({
|
||||
settings: this.#settings,
|
||||
id: this.#settings.connect('changed::night', this.#onNightVariantChanged.bind(this)),
|
||||
});
|
||||
if (!this.#systemSettings)
|
||||
return;
|
||||
this.#settingsConnections.push({
|
||||
settings: this.#systemSettings,
|
||||
id: this.#systemSettings.connect(`changed::${this.#themeKey}`, this.#onSystemThemeChanged.bind(this)),
|
||||
});
|
||||
}
|
||||
|
||||
#disconnectSettings() {
|
||||
this.#settingsConnections.forEach(({ settings, id }) => settings.disconnect(id));
|
||||
this.#settingsConnections = [];
|
||||
debug.message(`Disconnected ${this.#name} switcher from settings.`);
|
||||
}
|
||||
|
||||
|
||||
#onDayVariantChanged() {
|
||||
debug.message(`Day ${this.#name} variant changed to '${this.#settings.get_string('day')}'.`);
|
||||
this.#updateSystemTheme();
|
||||
}
|
||||
|
||||
#onNightVariantChanged() {
|
||||
debug.message(`Night ${this.#name} variant changed to '${this.#settings.get_string('night')}'.`);
|
||||
this.#updateSystemTheme();
|
||||
}
|
||||
|
||||
#onSystemThemeChanged() {
|
||||
debug.message(`System ${this.#name} changed to '${this.#systemSettings.get_string(this.#themeKey)}'.`);
|
||||
this.#updateCurrentVariant();
|
||||
}
|
||||
|
||||
#onTimeChanged(_time) {
|
||||
this.#updateSystemTheme();
|
||||
}
|
||||
|
||||
|
||||
#updateCurrentVariant() {
|
||||
if (this.#timer.time === Time.UNKNOWN || !this.#systemSettings)
|
||||
return;
|
||||
this.#settings.set_string(this.#timer.time, this.#systemSettings.get_string(this.#themeKey));
|
||||
}
|
||||
|
||||
#updateSystemTheme() {
|
||||
if (this.#timer.time === Time.UNKNOWN)
|
||||
return;
|
||||
debug.message(`Setting the ${this.#timer.time} ${this.#name} variant...`);
|
||||
if (this.#systemSettings)
|
||||
this.#systemSettings.set_string(this.#themeKey, this.#settings.get_string(this.#timer.time));
|
||||
else if (this.#noSettingsUpdateSystemThemeCallback)
|
||||
this.#noSettingsUpdateSystemThemeCallback(this.#timer.time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class SwitcherThemeCursor extends SwitcherTheme {
|
||||
/**
|
||||
* @param {object} params Params object.
|
||||
* @param {Timer} params.timer Timer to listen to.
|
||||
* @param {Gio.Settings} params.settings Cursor theme settings.
|
||||
*/
|
||||
constructor({ timer, settings }) {
|
||||
super({
|
||||
name: 'Cursor theme',
|
||||
timer,
|
||||
settings,
|
||||
systemSettings: new Gio.Settings({ schema: 'org.gnome.desktop.interface' }),
|
||||
themeKey: 'cursor-theme',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class SwitcherThemeGtk extends SwitcherTheme {
|
||||
/**
|
||||
* @param {object} params Params object.
|
||||
* @param {Timer} params.timer Timer to listen to.
|
||||
* @param {Gio.Settings} params.settings GTK theme settings.
|
||||
*/
|
||||
constructor({ timer, settings }) {
|
||||
super({
|
||||
name: 'GTK theme',
|
||||
timer,
|
||||
settings,
|
||||
systemSettings: new Gio.Settings({ schema: 'org.gnome.desktop.interface' }),
|
||||
themeKey: 'gtk-theme',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class SwitcherThemeIcon extends SwitcherTheme {
|
||||
/**
|
||||
* @param {object} params Params object.
|
||||
* @param {Timer} params.timer Timer to listen to.
|
||||
* @param {Gio.Settings} params.settings Icon theme settings.
|
||||
*/
|
||||
constructor({ timer, settings }) {
|
||||
super({
|
||||
name: 'Icon theme',
|
||||
timer,
|
||||
settings,
|
||||
systemSettings: new Gio.Settings({ schema: 'org.gnome.desktop.interface' }),
|
||||
themeKey: 'icon-theme',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class SwitcherThemeShell extends SwitcherTheme {
|
||||
#settings;
|
||||
#extensionManagerConnection = null;
|
||||
|
||||
/**
|
||||
* @param {object} params Params object.
|
||||
* @param {Timer} params.timer Timer to listen to.
|
||||
* @param {Gio.Settings} params.settings Shell theme settings.
|
||||
*/
|
||||
constructor({ timer, settings }) {
|
||||
super({
|
||||
name: 'Shell theme',
|
||||
timer,
|
||||
settings,
|
||||
systemSettings: getUserthemesSettings(),
|
||||
themeKey: 'name',
|
||||
noSettingsUpdateSystemThemeCallback: time => this.#noSettingsUpdateSystemThemeCallback(time),
|
||||
});
|
||||
this.#settings = settings;
|
||||
}
|
||||
|
||||
enable() {
|
||||
super.enable();
|
||||
this.#extensionManagerConnection = extensionManager.connect('extension-state-changed', this.#onExtensionStateChanged.bind(this));
|
||||
}
|
||||
|
||||
disable() {
|
||||
super.disable();
|
||||
if (this.#extensionManagerConnection) {
|
||||
extensionManager.disconnect(this.#extensionManagerConnection);
|
||||
this.#extensionManagerConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
#noSettingsUpdateSystemThemeCallback(time) {
|
||||
const shellTheme = this.#settings.get_string(time);
|
||||
const stylesheet = getShellThemeStylesheet(shellTheme);
|
||||
applyShellStylesheet(stylesheet);
|
||||
}
|
||||
|
||||
#onExtensionStateChanged() {
|
||||
this.systemSettings = getUserthemesSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the User Themes extension.
|
||||
*
|
||||
* @returns {object|undefined} The User Themes extension object or undefined if
|
||||
* it isn't installed.
|
||||
*/
|
||||
function getUserthemesExtension() {
|
||||
try {
|
||||
return extensionManager.lookup('user-theme@gnome-shell-extensions.gcampax.github.com');
|
||||
} catch (_e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User Themes extension settings.
|
||||
*
|
||||
* @returns {Gio.Settings|null} The User Themes extension settings or null if
|
||||
* the extension isn't installed.
|
||||
*/
|
||||
function getUserthemesSettings() {
|
||||
let extension = getUserthemesExtension();
|
||||
if (!extension || extension.state !== ExtensionState.ENABLED)
|
||||
return null;
|
||||
const schemaDir = extension.dir.get_child('schemas');
|
||||
const GioSSS = Gio.SettingsSchemaSource;
|
||||
let schemaSource;
|
||||
if (schemaDir.query_exists(null))
|
||||
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(), GioSSS.get_default(), false);
|
||||
else
|
||||
schemaSource = GioSSS.get_default();
|
||||
const schemaObj = schemaSource.lookup('org.gnome.shell.extensions.user-theme', true);
|
||||
return new Gio.Settings({ settings_schema: schemaObj });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shell theme stylesheet.
|
||||
*
|
||||
* @param {string} theme The shell theme name.
|
||||
* @returns {string|null} Path to the shell theme stylesheet.
|
||||
*/
|
||||
function getShellThemeStylesheet(theme) {
|
||||
const themeName = theme ? `'${theme}'` : 'default';
|
||||
debug.message(`Getting the ${themeName} theme shell stylesheet...`);
|
||||
let stylesheet = null;
|
||||
if (theme) {
|
||||
const stylesheetPaths = utils.getResourcesDirsPaths('themes').map(path => GLib.build_filenamev([path, theme, 'gnome-shell', 'gnome-shell.css']));
|
||||
stylesheet = stylesheetPaths.find(path => {
|
||||
const file = Gio.file_new_for_path(path);
|
||||
return file.query_exists(null);
|
||||
});
|
||||
}
|
||||
return stylesheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a stylesheet to the shell.
|
||||
*
|
||||
* @param {string} stylesheet The shell stylesheet to apply.
|
||||
*/
|
||||
function applyShellStylesheet(stylesheet) {
|
||||
debug.message('Applying shell stylesheet...');
|
||||
setThemeStylesheet(stylesheet);
|
||||
loadTheme();
|
||||
debug.message('Shell stylesheet applied.');
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
src/extension.js
|
||||
src/prefs.js
|
||||
src/utils.js
|
||||
|
||||
src/data/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml
|
||||
|
||||
@@ -14,7 +13,6 @@ src/data/ui/CommandsPage.ui
|
||||
src/data/ui/ContributePage.ui
|
||||
src/data/ui/SchedulePage.ui
|
||||
src/data/ui/ShortcutButton.ui
|
||||
src/data/ui/ThemesPage.ui
|
||||
src/data/ui/TimeChooser.ui
|
||||
|
||||
src/enums/ColorScheme.js
|
||||
@@ -23,7 +21,6 @@ src/enums/Time.js
|
||||
src/modules/ColorSchemeSwitcher.js
|
||||
src/modules/Switcher.js
|
||||
src/modules/SwitcherCommands.js
|
||||
src/modules/SwitcherTheme.js
|
||||
src/modules/Timer.js
|
||||
|
||||
src/preferences/BackgroundButton.js
|
||||
@@ -31,8 +28,6 @@ src/preferences/BackgroundsPage.js
|
||||
src/preferences/ClearableEntry.js
|
||||
src/preferences/CommandsPage.js
|
||||
src/preferences/ContributePage.js
|
||||
src/preferences/DropDownChoice.js
|
||||
src/preferences/SchedulePage.js
|
||||
src/preferences/ShortcutButton.js
|
||||
src/preferences/ThemesPage.js
|
||||
src/preferences/TimeChooser.js
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Night Theme Switcher Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import GObject from 'gi://GObject';
|
||||
|
||||
|
||||
export class DropDownChoice extends GObject.Object {
|
||||
static {
|
||||
GObject.registerClass({
|
||||
GTypeName: 'DropDownChoice',
|
||||
Properties: {
|
||||
id: GObject.ParamSpec.string(
|
||||
'id',
|
||||
'ID',
|
||||
'Identifier',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
null
|
||||
),
|
||||
title: GObject.ParamSpec.string(
|
||||
'title',
|
||||
'Title',
|
||||
'Displayed title',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
null
|
||||
),
|
||||
enabled: GObject.ParamSpec.boolean(
|
||||
'enabled',
|
||||
'Enabled',
|
||||
'If the choice is enabled',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
true
|
||||
),
|
||||
},
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Night Theme Switcher Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import Adw from 'gi://Adw';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Gtk from 'gi://Gtk';
|
||||
|
||||
import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
|
||||
|
||||
import * as utils from '../utils.js';
|
||||
|
||||
import { DropDownChoice } from './DropDownChoice.js';
|
||||
|
||||
|
||||
export class ThemesPage extends Adw.PreferencesPage {
|
||||
static {
|
||||
GObject.registerClass({
|
||||
GTypeName: 'ThemesPage',
|
||||
Template: 'resource:///org/gnome/Shell/Extensions/nightthemeswitcher/preferences/ui/ThemesPage.ui',
|
||||
InternalChildren: [
|
||||
'gtk_row',
|
||||
'gtk_day_variant_combo_row',
|
||||
'gtk_night_variant_combo_row',
|
||||
'shell_row',
|
||||
'shell_day_variant_combo_row',
|
||||
'shell_night_variant_combo_row',
|
||||
'icon_row',
|
||||
'icon_day_variant_combo_row',
|
||||
'icon_night_variant_combo_row',
|
||||
'cursor_row',
|
||||
'cursor_day_variant_combo_row',
|
||||
'cursor_night_variant_combo_row',
|
||||
],
|
||||
}, this);
|
||||
}
|
||||
|
||||
constructor({ gtkSettings, shellSettings, iconSettings, cursorSettings, ...params } = {}) {
|
||||
super(params);
|
||||
|
||||
gtkSettings.bind('enabled', this._gtk_row, 'enable-expansion', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
const gtkThemesStore = Gio.ListStore.new(DropDownChoice);
|
||||
gtkThemesStore.splice(0, 0, Array.from(utils.getInstalledGtkThemes()).sort().map(theme => new DropDownChoice({ id: theme, title: theme })));
|
||||
_setupComboRow(this._gtk_day_variant_combo_row, gtkThemesStore, gtkSettings, 'day');
|
||||
_setupComboRow(this._gtk_night_variant_combo_row, gtkThemesStore, gtkSettings, 'night');
|
||||
|
||||
shellSettings.bind('enabled', this._shell_row, 'enable-expansion', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
const shellThemesStore = Gio.ListStore.new(DropDownChoice);
|
||||
shellThemesStore.splice(0, 0, Array.from(utils.getInstalledShellThemes()).sort().map(theme => new DropDownChoice({ id: theme, title: theme || _('Default') })));
|
||||
_setupComboRow(this._shell_day_variant_combo_row, shellThemesStore, shellSettings, 'day');
|
||||
_setupComboRow(this._shell_night_variant_combo_row, shellThemesStore, shellSettings, 'night');
|
||||
|
||||
iconSettings.bind('enabled', this._icon_row, 'enable-expansion', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
const iconThemesStore = Gio.ListStore.new(DropDownChoice);
|
||||
iconThemesStore.splice(0, 0, Array.from(utils.getInstalledIconThemes()).sort().map(theme => new DropDownChoice({ id: theme, title: theme })));
|
||||
_setupComboRow(this._icon_day_variant_combo_row, iconThemesStore, iconSettings, 'day');
|
||||
_setupComboRow(this._icon_night_variant_combo_row, iconThemesStore, iconSettings, 'night');
|
||||
|
||||
cursorSettings.bind('enabled', this._cursor_row, 'enable-expansion', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
const cursorThemesStore = Gio.ListStore.new(DropDownChoice);
|
||||
cursorThemesStore.splice(0, 0, Array.from(utils.getInstalledCursorThemes()).sort().map(theme => new DropDownChoice({ id: theme, title: theme })));
|
||||
_setupComboRow(this._cursor_day_variant_combo_row, cursorThemesStore, cursorSettings, 'day');
|
||||
_setupComboRow(this._cursor_night_variant_combo_row, cursorThemesStore, cursorSettings, 'night');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set up the model of a combo row.
|
||||
*
|
||||
* @param {Adw.ComboRow} row The row to set up.
|
||||
* @param {Gio.ListModel} model A list model of DropDownChoice.
|
||||
* @param {Gio.Settings} settings The settings to connect.
|
||||
* @param {str} key The key to update.
|
||||
*/
|
||||
function _setupComboRow(row, model, settings, key) {
|
||||
row.model = model;
|
||||
row.expression = Gtk.PropertyExpression.new(DropDownChoice, null, 'title');
|
||||
row.connect('notify::selected-item', () => settings.set_string(key, row.selected_item.id));
|
||||
const updateComboRowSelected = () => {
|
||||
row.selected = utils.findItemPositionInModel(row.model, item => item.id === settings.get_string(key));
|
||||
};
|
||||
settings.connect(`changed::${key}`, () => updateComboRowSelected());
|
||||
updateComboRowSelected();
|
||||
}
|
||||
@@ -42,10 +42,8 @@ export default class NightThemeSwitcherPreferences extends ExtensionPreferences
|
||||
const { ClearableEntry } = await import('./preferences/ClearableEntry.js');
|
||||
const { CommandsPage } = await import('./preferences/CommandsPage.js');
|
||||
const { ContributePage } = await import('./preferences/ContributePage.js');
|
||||
const { DropDownChoice } = await import('./preferences/DropDownChoice.js');
|
||||
const { SchedulePage } = await import('./preferences/SchedulePage.js');
|
||||
const { ShortcutButton } = await import('./preferences/ShortcutButton.js');
|
||||
const { ThemesPage } = await import('./preferences/ThemesPage.js');
|
||||
const { TimeChooser } = await import('./preferences/TimeChooser.js');
|
||||
|
||||
// Make sure all GObjects are registered
|
||||
@@ -54,10 +52,8 @@ export default class NightThemeSwitcherPreferences extends ExtensionPreferences
|
||||
GObject.type_ensure(ClearableEntry);
|
||||
GObject.type_ensure(CommandsPage);
|
||||
GObject.type_ensure(ContributePage);
|
||||
GObject.type_ensure(DropDownChoice);
|
||||
GObject.type_ensure(SchedulePage);
|
||||
GObject.type_ensure(ShortcutButton);
|
||||
GObject.type_ensure(ThemesPage);
|
||||
GObject.type_ensure(TimeChooser);
|
||||
|
||||
// Remove the dummy page
|
||||
@@ -68,12 +64,6 @@ export default class NightThemeSwitcherPreferences extends ExtensionPreferences
|
||||
new SchedulePage({ settings: this.getSettings(`${this.metadata['settings-schema']}.time`) }),
|
||||
new BackgroundsPage(),
|
||||
new CommandsPage({ settings: this.getSettings(`${this.metadata['settings-schema']}.commands`) }),
|
||||
new ThemesPage({
|
||||
gtkSettings: this.getSettings(`${this.metadata['settings-schema']}.gtk-variants`),
|
||||
shellSettings: this.getSettings(`${this.metadata['settings-schema']}.shell-variants`),
|
||||
iconSettings: this.getSettings(`${this.metadata['settings-schema']}.icon-variants`),
|
||||
cursorSettings: this.getSettings(`${this.metadata['settings-schema']}.cursor-variants`),
|
||||
}),
|
||||
new ContributePage(),
|
||||
].forEach(page => window.add(page));
|
||||
}
|
||||
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Night Theme Switcher Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import Gtk from 'gi://Gtk';
|
||||
|
||||
|
||||
/**
|
||||
* Get all the directories of the system for a resource.
|
||||
*
|
||||
* @param {string} resource The resource to get the directories.
|
||||
* @returns {string[]} An array of paths.
|
||||
*/
|
||||
export function getResourcesDirsPaths(resource) {
|
||||
return [
|
||||
GLib.build_filenamev([GLib.get_home_dir(), `.${resource}`]),
|
||||
GLib.build_filenamev([GLib.get_user_data_dir(), resource]),
|
||||
...GLib.get_system_data_dirs().map(path => GLib.build_filenamev([path, resource])),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the resources installed on the system.
|
||||
*
|
||||
* @param {string} type The resources to get.
|
||||
* @returns {Set} A set of installed resources.
|
||||
*/
|
||||
function getInstalledResources(type) {
|
||||
const installedResources = new Set();
|
||||
getResourcesDirsPaths(type).forEach(resourcesDirPath => {
|
||||
const resourcesDir = Gio.File.new_for_path(resourcesDirPath);
|
||||
if (resourcesDir.query_file_type(Gio.FileQueryInfoFlags.NONE, null) !== Gio.FileType.DIRECTORY)
|
||||
return;
|
||||
const resourcesDirsEnumerator = resourcesDir.enumerate_children('standard::', Gio.FileQueryInfoFlags.NONE, null);
|
||||
while (true) {
|
||||
let resourceDirInfo = resourcesDirsEnumerator.next_file(null);
|
||||
if (resourceDirInfo === null)
|
||||
break;
|
||||
const resourceDir = resourcesDirsEnumerator.get_child(resourceDirInfo);
|
||||
if (resourceDir === null)
|
||||
continue;
|
||||
const resource = new Map([
|
||||
['name', resourceDir.get_basename()],
|
||||
['path', resourceDir.get_path()],
|
||||
]);
|
||||
installedResources.add(resource);
|
||||
}
|
||||
resourcesDirsEnumerator.close(null);
|
||||
});
|
||||
return installedResources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the installed GTK themes on the system.
|
||||
*
|
||||
* @returns {Set<string>} A set containing all the installed GTK themes names.
|
||||
*/
|
||||
export function getInstalledGtkThemes() {
|
||||
const themes = new Set();
|
||||
getInstalledResources('themes').forEach(theme => {
|
||||
const version = [0, Gtk.MINOR_VERSION].find(gtkVersion => {
|
||||
if (gtkVersion % 2)
|
||||
gtkVersion += 1;
|
||||
const cssFile = Gio.File.new_for_path(GLib.build_filenamev([theme.get('path'), `gtk-3.${gtkVersion}`, 'gtk.css']));
|
||||
return cssFile.query_exists(null);
|
||||
});
|
||||
if (version !== undefined)
|
||||
themes.add(theme.get('name'));
|
||||
});
|
||||
return themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the installed shell themes on the system.
|
||||
*
|
||||
* @returns {Set<string>} A set containing all the installed shell themes names.
|
||||
*/
|
||||
export function getInstalledShellThemes() {
|
||||
const themes = new Set(['']);
|
||||
getInstalledResources('themes').forEach(theme => {
|
||||
const themeFile = Gio.File.new_for_path(GLib.build_filenamev([theme.get('path'), 'gnome-shell', 'gnome-shell.css']));
|
||||
if (themeFile.query_exists(null))
|
||||
themes.add(theme.get('name'));
|
||||
});
|
||||
return themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the installed icon themes on the system.
|
||||
*
|
||||
* @returns {Set<string>} A set containing all the installed icon themes names.
|
||||
*/
|
||||
export function getInstalledIconThemes() {
|
||||
const themes = new Set();
|
||||
getInstalledResources('icons').forEach(theme => {
|
||||
const themeFile = Gio.File.new_for_path(GLib.build_filenamev([theme.get('path'), 'index.theme']));
|
||||
if (themeFile.query_exists(null))
|
||||
themes.add(theme.get('name'));
|
||||
});
|
||||
themes.delete('default');
|
||||
return themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the installed cursor themes on the system.
|
||||
*
|
||||
* @returns {Set<string>} A set containing all the installed cursor themes names.
|
||||
*/
|
||||
export function getInstalledCursorThemes() {
|
||||
const themes = new Set();
|
||||
getInstalledResources('icons').forEach(theme => {
|
||||
const themeFile = Gio.File.new_for_path(GLib.build_filenamev([theme.get('path'), 'cursors']));
|
||||
if (themeFile.query_exists(null))
|
||||
themes.add(theme.get('name'));
|
||||
});
|
||||
return themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an item in a `Gio.ListModel`.
|
||||
*
|
||||
* @param {Gio.ListModel} model The ListModel to search.
|
||||
* @param {Function} findFunction The function used to find the item. Gets the item as argument.
|
||||
* @returns {(*|undefined)} The found item or `undefined`.
|
||||
*/
|
||||
export function findItemPositionInModel(model, findFunction) {
|
||||
const nItems = model.get_n_items();
|
||||
for (let i = 0; i < nItems; i++) {
|
||||
if (findFunction(model.get_item(i)))
|
||||
return i;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user