Extension: Remove theme switching
This commit is contained in:
@@ -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