68 lines
2.5 KiB
JavaScript
68 lines
2.5 KiB
JavaScript
import Gio from 'gi://Gio';
|
|
import GLib from 'gi://GLib';
|
|
|
|
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
|
|
|
|
// GNOME lädt Extension-Code nur einmal pro Sitzung. Deshalb ist diese Datei nur ein Lader:
|
|
// Beim Einschalten kopiert er die Module in einen frischen Ordner und importiert sie von dort.
|
|
// Neuer Ordner heißt neue Adresse, also lädt GJS wirklich den aktuellen Code. Nach einer
|
|
// Änderung reicht so make update (kopiert, schaltet aus und ein), ohne Ab- und Anmelden.
|
|
// Nur diese Datei selbst wirkt erst nach dem nächsten Anmelden.
|
|
export default class DesktopExtension extends Extension {
|
|
_generation = 0;
|
|
|
|
enable() {
|
|
const generation = ++this._generation;
|
|
const dir = copyModules(this.dir);
|
|
import(`${dir.get_uri()}/app.js`)
|
|
.then(app => {
|
|
// Inzwischen aus- oder erneut eingeschaltet: dieser Stand ist überholt
|
|
if (this._generation !== generation)
|
|
return;
|
|
this._app = app;
|
|
app.enable(this);
|
|
})
|
|
.catch(e => console.error(`desktop@marha.de: Laden fehlgeschlagen: ${e.message}\n${e.stack}`));
|
|
}
|
|
|
|
disable() {
|
|
this._generation++;
|
|
this._app?.disable(this);
|
|
this._app = null;
|
|
}
|
|
}
|
|
|
|
// Alle Module außer dieser Datei nach ~/.cache/desktop-app/live-<Zeit> kopieren. Ältere Kopien
|
|
// sind schon geladen und werden gelöscht.
|
|
function copyModules(source) {
|
|
const base = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_cache_dir(), 'desktop-app']));
|
|
GLib.mkdir_with_parents(base.get_path(), 0o700);
|
|
for (const name of listNames(base)) {
|
|
if (name.startsWith('live-'))
|
|
removeDir(base.get_child(name));
|
|
}
|
|
const dest = base.get_child(`live-${GLib.get_real_time()}`);
|
|
dest.make_directory(null);
|
|
for (const name of listNames(source)) {
|
|
if (name.endsWith('.js') && name !== 'extension.js')
|
|
source.get_child(name).copy(dest.get_child(name), Gio.FileCopyFlags.OVERWRITE, null, null);
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
function listNames(dir) {
|
|
const names = [];
|
|
const children = dir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
|
|
let info;
|
|
while ((info = children.next_file(null)))
|
|
names.push(info.get_name());
|
|
children.close(null);
|
|
return names;
|
|
}
|
|
|
|
function removeDir(dir) {
|
|
for (const name of listNames(dir))
|
|
dir.get_child(name).delete(null);
|
|
dir.delete(null);
|
|
}
|