259 lines
9.2 KiB
JavaScript
259 lines
9.2 KiB
JavaScript
|
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
||
|
// Adapted from auto-move-windows@gnome-shell-extensions.gcampax.github.com
|
||
|
|
||
|
const Gio = imports.gi.Gio;
|
||
|
const Gtk = imports.gi.Gtk;
|
||
|
const GObject = imports.gi.GObject;
|
||
|
const Config = imports.misc.config;
|
||
|
|
||
|
const Gettext = imports.gettext.domain('gnome-shell-extension-caffeine');
|
||
|
const _ = Gettext.gettext;
|
||
|
|
||
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||
|
const Me = ExtensionUtils.getCurrentExtension();
|
||
|
const Convenience = Me.imports.convenience;
|
||
|
|
||
|
const INHIBIT_APPS_KEY = 'inhibit-apps';
|
||
|
const SHOW_INDICATOR_KEY = 'show-indicator';
|
||
|
const SHOW_NOTIFICATIONS_KEY = 'show-notifications';
|
||
|
const FULLSCREEN_KEY = 'enable-fullscreen';
|
||
|
const RESTORE_KEY = 'restore-state';
|
||
|
|
||
|
const Columns = {
|
||
|
APPINFO: 0,
|
||
|
DISPLAY_NAME: 1,
|
||
|
ICON: 2
|
||
|
};
|
||
|
|
||
|
let ShellVersion = parseInt(Config.PACKAGE_VERSION.split(".")[1]);
|
||
|
|
||
|
class CaffeineWidget {
|
||
|
constructor(params) {
|
||
|
this.w = new Gtk.Grid(params);
|
||
|
this.w.set_orientation(Gtk.Orientation.VERTICAL);
|
||
|
|
||
|
this._settings = Convenience.getSettings();
|
||
|
this._settings.connect('changed', this._refresh.bind(this));
|
||
|
this._changedPermitted = false;
|
||
|
|
||
|
|
||
|
let showCaffeineBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL,
|
||
|
margin: 7});
|
||
|
|
||
|
let showCaffeineLabel = new Gtk.Label({label: _("Show Caffeine in top panel"),
|
||
|
xalign: 0});
|
||
|
|
||
|
let showCaffeineSwitch = new Gtk.Switch({active: this._settings.get_boolean(SHOW_INDICATOR_KEY)});
|
||
|
showCaffeineSwitch.connect('notify::active', button => {
|
||
|
this._settings.set_boolean(SHOW_INDICATOR_KEY, button.active);
|
||
|
});
|
||
|
|
||
|
showCaffeineBox.pack_start(showCaffeineLabel, true, true, 0);
|
||
|
showCaffeineBox.add(showCaffeineSwitch);
|
||
|
|
||
|
this.w.add(showCaffeineBox);
|
||
|
|
||
|
if (ShellVersion > 6) {
|
||
|
const gtkhbox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL,
|
||
|
margin: 7});
|
||
|
|
||
|
const enableFullscreenLabel = new Gtk.Label({label: _("Enable when a fullscreen application is running"),
|
||
|
xalign: 0});
|
||
|
|
||
|
const enableFullscreenSwitch = new Gtk.Switch({active: this._settings.get_boolean(FULLSCREEN_KEY)});
|
||
|
enableFullscreenSwitch.connect('notify::active', button => {
|
||
|
this._settings.set_boolean(FULLSCREEN_KEY, button.active);
|
||
|
});
|
||
|
|
||
|
gtkhbox.pack_start(enableFullscreenLabel, true, true, 0);
|
||
|
gtkhbox.add(enableFullscreenSwitch);
|
||
|
|
||
|
this.w.add(gtkhbox);
|
||
|
}
|
||
|
|
||
|
const stateBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL,
|
||
|
margin: 7});
|
||
|
|
||
|
const stateLabel = new Gtk.Label({label: _("Restore state across reboots"),
|
||
|
xalign: 0});
|
||
|
|
||
|
const stateSwitch = new Gtk.Switch({active: this._settings.get_boolean(RESTORE_KEY)});
|
||
|
stateSwitch.connect('notify::active', button => {
|
||
|
this._settings.set_boolean(RESTORE_KEY, button.active);
|
||
|
});
|
||
|
|
||
|
stateBox.pack_start(stateLabel, true, true, 0);
|
||
|
stateBox.add(stateSwitch);
|
||
|
|
||
|
this.w.add(stateBox);
|
||
|
|
||
|
const notificationsBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL,
|
||
|
margin: 7});
|
||
|
|
||
|
const notificationsLabel = new Gtk.Label({label: _("Enable notifications"),
|
||
|
xalign: 0});
|
||
|
|
||
|
const notificationsSwitch = new Gtk.Switch({active: this._settings.get_boolean(SHOW_NOTIFICATIONS_KEY)});
|
||
|
notificationsSwitch.connect('notify::active', button => {
|
||
|
this._settings.set_boolean(SHOW_NOTIFICATIONS_KEY, button.active);
|
||
|
});
|
||
|
|
||
|
notificationsBox.pack_start(notificationsLabel, true, true, 0);
|
||
|
notificationsBox.add(notificationsSwitch);
|
||
|
|
||
|
this.w.add(notificationsBox);
|
||
|
|
||
|
this._store = new Gtk.ListStore();
|
||
|
this._store.set_column_types([Gio.AppInfo, GObject.TYPE_STRING, Gio.Icon]);
|
||
|
|
||
|
this._treeView = new Gtk.TreeView({ model: this._store,
|
||
|
hexpand: true, vexpand: true });
|
||
|
this._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE);
|
||
|
|
||
|
const appColumn = new Gtk.TreeViewColumn({ expand: true, sort_column_id: Columns.DISPLAY_NAME,
|
||
|
title: _("Applications which enable Caffeine automatically") });
|
||
|
const iconRenderer = new Gtk.CellRendererPixbuf;
|
||
|
appColumn.pack_start(iconRenderer, false);
|
||
|
appColumn.add_attribute(iconRenderer, "gicon", Columns.ICON);
|
||
|
const nameRenderer = new Gtk.CellRendererText;
|
||
|
appColumn.pack_start(nameRenderer, true);
|
||
|
appColumn.add_attribute(nameRenderer, "text", Columns.DISPLAY_NAME);
|
||
|
this._treeView.append_column(appColumn);
|
||
|
|
||
|
this.w.add(this._treeView);
|
||
|
|
||
|
const toolbar = new Gtk.Toolbar();
|
||
|
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);
|
||
|
this.w.add(toolbar);
|
||
|
|
||
|
const newButton = new Gtk.ToolButton({ stock_id: Gtk.STOCK_NEW,
|
||
|
label: _("Add application"),
|
||
|
is_important: true });
|
||
|
newButton.connect('clicked', this._createNew.bind(this));
|
||
|
toolbar.add(newButton);
|
||
|
|
||
|
const delButton = new Gtk.ToolButton({ stock_id: Gtk.STOCK_DELETE });
|
||
|
delButton.connect('clicked', this._deleteSelected.bind(this));
|
||
|
toolbar.add(delButton);
|
||
|
|
||
|
this._changedPermitted = true;
|
||
|
this._refresh();
|
||
|
}
|
||
|
|
||
|
_createNew() {
|
||
|
const dialog = new Gtk.Dialog({ title: _("Create new matching rule"),
|
||
|
transient_for: this.w.get_toplevel(),
|
||
|
modal: true });
|
||
|
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
|
||
|
dialog.add_button(_("Add"), Gtk.ResponseType.OK);
|
||
|
dialog.set_default_response(Gtk.ResponseType.OK);
|
||
|
|
||
|
const grid = new Gtk.Grid({ column_spacing: 10,
|
||
|
row_spacing: 15,
|
||
|
margin: 10 });
|
||
|
dialog._appChooser = new Gtk.AppChooserWidget({ show_all: true });
|
||
|
grid.attach(dialog._appChooser, 0, 0, 2, 1);
|
||
|
dialog.get_content_area().add(grid);
|
||
|
|
||
|
dialog.connect('response', (dialog, id) => {
|
||
|
if (id != Gtk.ResponseType.OK) {
|
||
|
dialog.destroy();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const appInfo = dialog._appChooser.get_app_info();
|
||
|
if (!appInfo)
|
||
|
return;
|
||
|
|
||
|
this._changedPermitted = false;
|
||
|
if (!this._appendItem(appInfo.get_id())) {
|
||
|
this._changedPermitted = true;
|
||
|
return;
|
||
|
}
|
||
|
let iter = this._store.append();
|
||
|
|
||
|
this._store.set(iter,
|
||
|
[Columns.APPINFO, Columns.ICON, Columns.DISPLAY_NAME],
|
||
|
[appInfo, appInfo.get_icon(), appInfo.get_display_name()]);
|
||
|
this._changedPermitted = true;
|
||
|
|
||
|
dialog.destroy();
|
||
|
});
|
||
|
dialog.show_all();
|
||
|
}
|
||
|
|
||
|
_deleteSelected() {
|
||
|
const [any, , iter] = this._treeView.get_selection().get_selected();
|
||
|
|
||
|
if (any) {
|
||
|
const appInfo = this._store.get_value(iter, Columns.APPINFO);
|
||
|
|
||
|
this._changedPermitted = false;
|
||
|
this._removeItem(appInfo.get_id());
|
||
|
this._store.remove(iter);
|
||
|
this._changedPermitted = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_refresh() {
|
||
|
if (!this._changedPermitted)
|
||
|
// Ignore this notification, model is being modified outside
|
||
|
return;
|
||
|
|
||
|
this._store.clear();
|
||
|
|
||
|
const currentItems = this._settings.get_strv(INHIBIT_APPS_KEY);
|
||
|
const validItems = [ ];
|
||
|
for (let i = 0; i < currentItems.length; i++) {
|
||
|
const id = currentItems[i];
|
||
|
const appInfo = Gio.DesktopAppInfo.new(id);
|
||
|
if (!appInfo)
|
||
|
continue;
|
||
|
validItems.push(currentItems[i]);
|
||
|
|
||
|
const iter = this._store.append();
|
||
|
this._store.set(iter,
|
||
|
[Columns.APPINFO, Columns.ICON, Columns.DISPLAY_NAME],
|
||
|
[appInfo, appInfo.get_icon(), appInfo.get_display_name()]);
|
||
|
}
|
||
|
|
||
|
if (validItems.length != currentItems.length) // some items were filtered out
|
||
|
this._settings.set_strv(INHIBIT_APPS_KEY, validItems);
|
||
|
}
|
||
|
|
||
|
_appendItem(id) {
|
||
|
const currentItems = this._settings.get_strv(INHIBIT_APPS_KEY);
|
||
|
|
||
|
if (currentItems.includes(id)) {
|
||
|
printerr("Already have an item for this id");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
currentItems.push(id);
|
||
|
this._settings.set_strv(INHIBIT_APPS_KEY, currentItems);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
_removeItem(id) {
|
||
|
const currentItems = this._settings.get_strv(INHIBIT_APPS_KEY);
|
||
|
const index = currentItems.indexOf(id);
|
||
|
|
||
|
if (index < 0)
|
||
|
return;
|
||
|
|
||
|
currentItems.splice(index, 1);
|
||
|
this._settings.set_strv(INHIBIT_APPS_KEY, currentItems);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function init() {
|
||
|
Convenience.initTranslations();
|
||
|
}
|
||
|
|
||
|
function buildPrefsWidget() {
|
||
|
const widget = new CaffeineWidget();
|
||
|
widget.w.show_all();
|
||
|
|
||
|
return widget.w;
|
||
|
}
|