diff --git a/Makefile b/Makefile
index 99efa37..a9e0996 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,7 @@ build: build-clean
mkdir -p ./build
gnome-extensions pack \
--extra-source=../LICENSE \
+ --extra-source=./compat.js \
--extra-source=./config.js \
--extra-source=./convenience.js \
--extra-source=./utils.js \
diff --git a/src/compat.js b/src/compat.js
new file mode 100644
index 0000000..a3cf22b
--- /dev/null
+++ b/src/compat.js
@@ -0,0 +1,42 @@
+/*
+Night Theme Switcher Gnome Shell extension
+
+Copyright (C) 2020 Romain Vigier
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see .
+*/
+
+const Meta = imports.gi.Meta;
+
+const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
+
+
+function key_binding_auto_repeat() {
+ // if version is less then 3.30 the keybinding flags are NONE
+ if (shell_minor_version < 30) {
+ return Meta.KeyBindingFlags.NONE;
+ }
+ else {
+ return Meta.KeyBindingFlags.IGNORE_AUTOREPEAT;
+ }
+};
+
+
+function get_actor(subject) {
+ if (shell_minor_version > 34) {
+ return subject;
+ }
+ else {
+ return subject.actor;
+ }
+};
diff --git a/src/modules/SettingsManager.js b/src/modules/SettingsManager.js
index 358ac4e..7c2cbd9 100644
--- a/src/modules/SettingsManager.js
+++ b/src/modules/SettingsManager.js
@@ -296,6 +296,17 @@ var SettingsManager = class {
}
}
+ get ondemand_time() {
+ return this._extensionsSettings.get_string('ondemand-time');
+ }
+
+ set ondemand_time(value) {
+ if ( value !== this.ondemand_time ) {
+ this._extensionsSettings.set_string('ondemand-time', value);
+ log_debug(`The on-demand time has been set to ${value}.`);
+ }
+ }
+
get schedule_sunrise() {
return this._extensionsSettings.get_double('schedule-sunrise');
}
diff --git a/src/modules/Timer.js b/src/modules/Timer.js
index e5695b9..f511242 100644
--- a/src/modules/Timer.js
+++ b/src/modules/Timer.js
@@ -26,6 +26,7 @@ const { log_debug } = Me.imports.utils;
const { TimerNightlight } = Me.imports.modules.TimerNightlight;
const { TimerLocation } = Me.imports.modules.TimerLocation;
const { TimerSchedule } = Me.imports.modules.TimerSchedule;
+const { TimerOndemand } = Me.imports.modules.TimerOndemand;
/**
@@ -112,6 +113,9 @@ var Timer = class {
case 'schedule':
this._source = new TimerSchedule();
break;
+ case 'ondemand':
+ this._source = new TimerOndemand();
+ break;
}
}
diff --git a/src/modules/TimerOndemand.js b/src/modules/TimerOndemand.js
new file mode 100644
index 0000000..cf1bc7e
--- /dev/null
+++ b/src/modules/TimerOndemand.js
@@ -0,0 +1,120 @@
+/*
+Night Theme Switcher Gnome Shell extension
+
+Copyright (C) 2020 Romain Vigier
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see .
+*/
+
+const { GLib, Shell, St } = imports.gi;
+const { extensionUtils } = imports.misc;
+const Signals = imports.signals;
+
+const { main, panelMenu } = imports.ui;
+
+const Me = extensionUtils.getCurrentExtension();
+
+const e = Me.imports.extension;
+const { log_debug } = Me.imports.utils;
+const { key_binding_auto_repeat, get_actor } = Me.imports.compat;
+
+/**
+ * The On-demand Timer allows the user to manually switch between the day and
+ * night variants with a button in the top bar and a keybinding.
+ *
+ * The user can change the key combination in the extension's preferences.
+ */
+var TimerOndemand = class {
+
+ constructor() {
+ this._button = null;
+ this._icon = null;
+ }
+
+ enable() {
+ log_debug('Enabling On-demand Timer ...');
+ this._add_keybinding();
+ this._add_button();
+ log_debug('On-demand Timer enabled.');
+ }
+
+ disable() {
+ log_debug('Disabling On-demand Timer ...');
+ this._remove_keybinding();
+ this._remove_button();
+ log_debug('On-demand Timer disabled.');
+ }
+
+
+ get time() {
+ return e.settingsManager.ondemand_time;
+ }
+
+ _add_keybinding() {
+ log_debug('Adding On-demand Timer keybinding...');
+ // add our own keybinging handler
+ main.wm.addKeybinding(
+ 'nightthemeswitcher-ondemand-keybinding',
+ e.settingsManager._extensionsSettings,
+ key_binding_auto_repeat(),
+ Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
+ this._toggle_time.bind(this)
+ );
+ log_debug('Added On-demand Timer keybinding.');
+ }
+
+ _remove_keybinding() {
+ log_debug('Removing On-demand Timer keybinding...');
+ main.wm.removeKeybinding('nightthemeswitcher-ondemand-keybinding');
+ log_debug('Removed On-demand Timer keybinding.');
+ }
+
+ _add_button() {
+ log_debug('Adding On-demand Timer button...');
+
+ this._icon = new St.Icon({
+ icon_name: this._get_icon_name_for_current_time(),
+ style_class: 'system-status-icon'
+ });
+
+ this._button = new panelMenu.Button(0.0);
+ let button_actor = get_actor(this._button);
+ button_actor.add_actor(this._icon);
+ this._button.connect(
+ 'button-press-event',
+ this._toggle_time.bind(this)
+ );
+ main.panel.addToStatusArea('NightThemeSwitcherButton', this._button);
+
+ log_debug('Added On-demand Timer button.');
+ }
+
+ _remove_button() {
+ log_debug('Removing On-demand Timer button...');
+ this._button.destroy();
+ log_debug('Removed On-demand Timer button.');
+ }
+
+ _toggle_time() {
+ e.settingsManager.ondemand_time = e.timer.time === 'day' ? 'night' : 'day';
+ this.emit('time-changed', this.time);
+ this._icon.icon_name = this._get_icon_name_for_current_time();
+
+ }
+
+ _get_icon_name_for_current_time() {
+ return e.timer.time === 'day' ? 'weather-clear-symbolic' : 'weather-clear-night-symbolic';
+ }
+
+}
+Signals.addSignalMethods(TimerOndemand.prototype);
diff --git a/src/preferences/Schedule.js b/src/preferences/Schedule.js
index 07bd3d0..becd1c5 100644
--- a/src/preferences/Schedule.js
+++ b/src/preferences/Schedule.js
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
this program. If not, see .
*/
-const { Gio, Gtk } = imports.gi;
+const { Gio, GObject, Gtk } = imports.gi;
const { extensionUtils } = imports.misc;
const Me = extensionUtils.getCurrentExtension();
@@ -42,6 +42,7 @@ var SchedulePreferences = class {
content.add_row(new SettingsListRow(_('Manual time source'), new ManualTimeSourceControl()));
content.add_row(new SettingsListRow(_('Time source'), new TimeSourceControl()));
+ content.add_row(new SettingsListRow(_('Shortcut'), new KeyBindingControl()));
content.add_row(new SettingsListRow(_('Sunrise'), new SuntimeControl('sunrise')));
content.add_row(new SettingsListRow(_('Sunset'), new SuntimeControl('sunset')));
@@ -51,6 +52,61 @@ var SchedulePreferences = class {
}
+class KeyBindingControl {
+
+ constructor() {
+ const settings = extensionUtils.getSettings();
+ const KEYBINDING_KEY = 'nightthemeswitcher-ondemand-keybinding';
+ const COLUMN_KEY = 0;
+ const COLUMN_MODS = 1;
+
+ const list_store = new Gtk.ListStore();
+ list_store.set_column_types([GObject.TYPE_INT, GObject.TYPE_INT]);
+ const tree_view = new Gtk.TreeView({model: list_store});
+ tree_view.set_headers_visible(false);
+
+ const renderer = new Gtk.CellRendererAccel({ editable: true});
+ const column = new Gtk.TreeViewColumn();
+ const iter = list_store.append();
+
+ const update_shortcut_row = (accel) => {
+ const [key, mods] = accel ? Gtk.accelerator_parse(accel) : [0, 0];
+ list_store.set(iter, [COLUMN_KEY, COLUMN_MODS], [key, mods]);
+ };
+
+ renderer.connect('accel-edited', (renderer, path, key, mods) => {
+ const accel = Gtk.accelerator_name(key, mods);
+ update_shortcut_row(accel);
+ settings.set_strv(KEYBINDING_KEY, [accel]);
+ });
+
+ renderer.connect('accel-cleared', () => {
+ update_shortcut_row(null);
+ settings.set_strv(KEYBINDING_KEY, []);
+ });
+
+ settings.connect(`changed::${KEYBINDING_KEY}`, () => {
+ update_shortcut_row(settings.get_strv(KEYBINDING_KEY)[0]);
+ });
+
+ column.pack_start(renderer, true);
+ column.add_attribute(renderer, 'accel-key', COLUMN_KEY);
+ column.add_attribute(renderer, 'accel-mods', COLUMN_MODS);
+
+ tree_view.append_column(column);
+ update_shortcut_row(settings.get_strv(KEYBINDING_KEY)[0]);
+
+ const update_treeview_sensitivity = (tree_view) => {
+ tree_view.set_sensitive(!!(settings.get_string('time-source') === 'ondemand'));
+ }
+ settings.connect('changed::time-source', () => update_treeview_sensitivity(tree_view));
+ update_treeview_sensitivity(tree_view)
+
+ return tree_view;
+ }
+
+}
+
class ManualTimeSourceControl {
constructor() {
@@ -132,6 +188,23 @@ class TimeSourceControl {
});
box.pack_start(schedule_radio, false, false, 0);
+ const ondemand_radio = new Gtk.RadioButton({
+ label: _('On-demand'),
+ group: nightlight_radio,
+ active: (settings.get_string('time-source') === 'ondemand')
+ });
+ settings.bind(
+ 'manual-time-source',
+ ondemand_radio,
+ 'sensitive',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ ondemand_radio.connect('toggled', () => {
+ settings.set_string('time-source', 'ondemand')
+ });
+ box.pack_start(ondemand_radio, false, false, 0);
+
+
return box;
}
diff --git a/src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml b/src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml
index 457418d..25e97ed 100644
--- a/src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml
+++ b/src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml
@@ -86,11 +86,26 @@
+
"schedule"
Time source
The source used to check current time
+
+
+
+
+
+ "day"
+ On-demand time
+ The current time used in on-demand mode
+
+
+ t']]]>
+ Key combination to toggle time
+ The key combination that will toggle time in on-demand mode
+
false
Use manual time source