On-demand scheduling with topbar button and keybinding
This commit is contained in:
@@ -28,6 +28,7 @@ build: build-clean
|
|||||||
mkdir -p ./build
|
mkdir -p ./build
|
||||||
gnome-extensions pack \
|
gnome-extensions pack \
|
||||||
--extra-source=../LICENSE \
|
--extra-source=../LICENSE \
|
||||||
|
--extra-source=./compat.js \
|
||||||
--extra-source=./config.js \
|
--extra-source=./config.js \
|
||||||
--extra-source=./convenience.js \
|
--extra-source=./convenience.js \
|
||||||
--extra-source=./utils.js \
|
--extra-source=./utils.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 <http s ://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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() {
|
get schedule_sunrise() {
|
||||||
return this._extensionsSettings.get_double('schedule-sunrise');
|
return this._extensionsSettings.get_double('schedule-sunrise');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const { log_debug } = Me.imports.utils;
|
|||||||
const { TimerNightlight } = Me.imports.modules.TimerNightlight;
|
const { TimerNightlight } = Me.imports.modules.TimerNightlight;
|
||||||
const { TimerLocation } = Me.imports.modules.TimerLocation;
|
const { TimerLocation } = Me.imports.modules.TimerLocation;
|
||||||
const { TimerSchedule } = Me.imports.modules.TimerSchedule;
|
const { TimerSchedule } = Me.imports.modules.TimerSchedule;
|
||||||
|
const { TimerOndemand } = Me.imports.modules.TimerOndemand;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,6 +113,9 @@ var Timer = class {
|
|||||||
case 'schedule':
|
case 'schedule':
|
||||||
this._source = new TimerSchedule();
|
this._source = new TimerSchedule();
|
||||||
break;
|
break;
|
||||||
|
case 'ondemand':
|
||||||
|
this._source = new TimerOndemand();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 <http s ://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
|
|||||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { Gio, Gtk } = imports.gi;
|
const { Gio, GObject, Gtk } = imports.gi;
|
||||||
const { extensionUtils } = imports.misc;
|
const { extensionUtils } = imports.misc;
|
||||||
|
|
||||||
const Me = extensionUtils.getCurrentExtension();
|
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(_('Manual time source'), new ManualTimeSourceControl()));
|
||||||
content.add_row(new SettingsListRow(_('Time source'), new TimeSourceControl()));
|
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(_('Sunrise'), new SuntimeControl('sunrise')));
|
||||||
content.add_row(new SettingsListRow(_('Sunset'), new SuntimeControl('sunset')));
|
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 {
|
class ManualTimeSourceControl {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -132,6 +188,23 @@ class TimeSourceControl {
|
|||||||
});
|
});
|
||||||
box.pack_start(schedule_radio, false, false, 0);
|
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;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,11 +86,26 @@
|
|||||||
<choice value="nightlight"/>
|
<choice value="nightlight"/>
|
||||||
<choice value="location"/>
|
<choice value="location"/>
|
||||||
<choice value="schedule"/>
|
<choice value="schedule"/>
|
||||||
|
<choice value="ondemand"/>
|
||||||
</choices>
|
</choices>
|
||||||
<default>"schedule"</default>
|
<default>"schedule"</default>
|
||||||
<summary>Time source</summary>
|
<summary>Time source</summary>
|
||||||
<description>The source used to check current time</description>
|
<description>The source used to check current time</description>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="ondemand-time" type="s">
|
||||||
|
<choices>
|
||||||
|
<choice value="day"/>
|
||||||
|
<choice value="night"/>
|
||||||
|
</choices>
|
||||||
|
<default>"day"</default>
|
||||||
|
<summary>On-demand time</summary>
|
||||||
|
<description>The current time used in on-demand mode</description>
|
||||||
|
</key>
|
||||||
|
<key name="nightthemeswitcher-ondemand-keybinding" type="as">
|
||||||
|
<default><![CDATA[['<Shift><Super>t']]]></default>
|
||||||
|
<summary>Key combination to toggle time</summary>
|
||||||
|
<description>The key combination that will toggle time in on-demand mode</description>
|
||||||
|
</key>
|
||||||
<key name="manual-time-source" type="b">
|
<key name="manual-time-source" type="b">
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
<summary>Use manual time source</summary>
|
<summary>Use manual time source</summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user