.dotfiles/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/appsPage.js

221 lines
7.7 KiB
JavaScript

/*
This file is part of Caffeine (gnome-shell-extension-caffeine).
Caffeine 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.
Caffeine 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 Caffeine.
If not, see <https://www.gnu.org/licenses/>.
Copyright 2022 Pakaoraki
// From https://gitlab.com/skrewball/openweather/-/blob/master/src/prefs.js
*/
/* exported AppsPage */
'use strict';
import Adw from 'gi://Adw';
import Gtk from 'gi://Gtk';
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
export var AppsPage = GObject.registerClass(
class CaffeineAppsPage extends Adw.PreferencesPage {
_init(settings, settingsKey) {
super._init({
title: _('Apps'),
icon_name: 'applications-symbolic',
name: 'AppsPage'
});
this._settingsKey = settingsKey;
this._settings = settings;
this._listApps = [];
// Apps behavior group
// --------------
let appsBehaviorGroup = new Adw.PreferencesGroup({
title: _('Trigger mode')
});
// Apps behavior select mode
let appsTriggerMode = new Gtk.StringList();
appsTriggerMode.append(_('Running'));
appsTriggerMode.append(_('Focus'));
appsTriggerMode.append(_('Active workspace'));
let appsTriggerModeRow = new Adw.ComboRow({
title: _('Apps trigger Caffeine mode'),
subtitle: _('Choose the way apps will trigger Caffeine'),
model: appsTriggerMode,
selected: this._settings.get_enum(this._settingsKey.TRIGGER_APPS_MODE)
});
// Add elements
appsBehaviorGroup.add(appsTriggerModeRow);
this.add(appsBehaviorGroup);
// Apps list group
// --------------
let addAppsButton = new Gtk.Button({
child: new Adw.ButtonContent({
icon_name: 'list-add-symbolic',
label: _('Add')
})
});
this.appsGroup = new Adw.PreferencesGroup({
title: _('Apps that trigger Caffeine'),
header_suffix: addAppsButton
});
this._refreshApps();
// Add elements
this.add(this.appsGroup);
// Bind signals
addAppsButton.connect('clicked', this._onAddApp.bind(this));
appsTriggerModeRow.connect('notify::selected', (widget) => {
this._settings.set_enum(this._settingsKey.TRIGGER_APPS_MODE, widget.selected);
});
}
_refreshApps() {
const _apps = this._settings.get_strv(this._settingsKey.INHIBIT_APPS);
// Clear the Apps list
this._listApps.length = 0;
// Update the list & Check if app still exist
_apps.forEach((id) => {
const appInfo = Gio.DesktopAppInfo.new(id);
if (appInfo) {
this._listApps.push(id);
}
});
// Check if the apps list UI needs updating
if (this._appsListUi !== this._listApps) {
// Remove the old list
if (this._count) {
for (let i = 0; i < this._count; i++) {
this.appsGroup.remove(this.apps[i].Row);
}
this._count = null;
}
if (this._listApps.length > 0) {
this.apps = {};
// Build new apps UI list
for (let i in this._listApps) {
this.apps[i] = {};
this.apps[i].ButtonBox = new Gtk.Box({
orientation: Gtk.Orientation.HORIZONTAL,
halign: Gtk.Align.CENTER,
spacing: 5,
hexpand: false,
vexpand: false
});
this.apps[i].DeleteButton = new Gtk.Button({
icon_name: 'edit-delete-symbolic',
valign: Gtk.Align.CENTER,
css_classes: ['error'],
hexpand: false,
vexpand: false
});
// App info
let appInfo = Gio.DesktopAppInfo.new(this._listApps[i]);
const appIcon = new Gtk.Image({
gicon: appInfo.get_icon(),
pixel_size: 32
});
appIcon.get_style_context().add_class('icon-dropshadow');
this.apps[i].Row = new Adw.ActionRow({
title: appInfo.get_display_name(),
subtitle: this._listApps[i].replace('.desktop', ''),
activatable: true
});
// Add elements
this.apps[i].Row.add_prefix(appIcon);
this.apps[i].ButtonBox.append(this.apps[i].DeleteButton);
this.apps[i].Row.add_suffix(this.apps[i].ButtonBox);
this.appsGroup.add(this.apps[i].Row);
}
// Bind signals
for (let i in this.apps) {
this.apps[i].DeleteButton.connect('clicked', () => {
this._onRemoveApp(this._listApps[i]);
});
}
this._count = this._listApps.length;
}
this._appsListUi = [...this._listApps];
}
return 0;
}
_onAddApp() {
const dialog = new NewAppDialog(this.get_root(), this._settings, this._settingsKey);
dialog.connect('response', (dlg, id) => {
const appInfo = id === Gtk.ResponseType.OK
? dialog.get_widget().get_app_info() : null;
const apps = this._settings.get_strv(this._settingsKey.INHIBIT_APPS);
if (appInfo && !apps.some((a) => a === appInfo.get_id())) {
this._settings.set_strv(this._settingsKey.INHIBIT_APPS, [
...apps, appInfo.get_id()
]);
this._refreshApps();
}
dialog.destroy();
});
dialog.show();
}
_onRemoveApp(appId) {
this._settings.set_strv(this._settingsKey.INHIBIT_APPS,
this._settings.get_strv(this._settingsKey.INHIBIT_APPS).filter((id) => {
return id !== appId;
})
);
this._refreshApps();
}
});
const NewAppDialog = GObject.registerClass(
class NewAppDialog extends Gtk.AppChooserDialog {
_init(parent, settings, settingsKey) {
super._init({
transient_for: parent,
modal: true
});
this._settings = settings;
this._settingsKey = settingsKey;
this.get_widget().set({
show_all: true,
show_other: true // hide more button
});
this.get_widget().connect('application-selected',
this._updateSensitivity.bind(this));
this._updateSensitivity();
}
_updateSensitivity() {
const apps = this._settings.get_strv(this._settingsKey.INHIBIT_APPS);
const appInfo = this.get_widget().get_app_info();
this.set_response_sensitive(Gtk.ResponseType.OK,
appInfo && !apps.some((i) => i.startsWith(appInfo.get_id())));
}
});