summaryrefslogtreecommitdiff
path: root/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/locations.js
diff options
context:
space:
mode:
authorAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
committerAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
commit70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch)
treeab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/locations.js
parent5d94c0a7d44a2255b81815a52a7056a94a39842d (diff)
downloadRaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz
RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/locations.js')
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/locations.js1535
1 files changed, 0 insertions, 1535 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/locations.js b/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/locations.js
deleted file mode 100644
index 534466c..0000000
--- a/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/locations.js
+++ /dev/null
@@ -1,1535 +0,0 @@
-// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
-
-import {
- Gio,
- GioUnix,
- GLib,
- GObject,
- Shell,
- St,
-} from './dependencies/gi.js';
-
-import {ShellMountOperation} from './dependencies/shell/ui.js';
-
-import {
- Docking,
- Utils,
-} from './imports.js';
-
-import {Extension} from './dependencies/shell/extensions/extension.js';
-
-// Use __ () and N__() for the extension gettext domain, and reuse
-// the shell domain with the default _() and N_()
-const {gettext: __} = Extension;
-
-const {signals: Signals} = imports;
-
-const FALLBACK_REMOVABLE_MEDIA_ICON = 'drive-removable-media';
-const FALLBACK_TRASH_ICON = 'user-trash';
-const FILE_MANAGER_DESKTOP_APP_ID = 'org.gnome.Nautilus.desktop';
-const ATTRIBUTE_METADATA_CUSTOM_ICON = 'metadata::custom-icon';
-const TRASH_URI = 'trash://';
-const UPDATE_TRASH_DELAY = 1000;
-const LAUNCH_HANDLER_MAX_WAIT = 200;
-
-const NautilusFileOperations2Interface = '<node>\
- <interface name="org.gnome.Nautilus.FileOperations2">\
- <method name="EmptyTrash">\
- <arg type="b" name="ask_confirmation" direction="in"/>\
- <arg type="a{sv}" name="platform_data" direction="in"/>\
- </method>\
- </interface>\
-</node>';
-
-const NautilusFileOperations2ProxyInterface =
- Gio.DBusProxy.makeProxyWrapper(NautilusFileOperations2Interface);
-
-const Labels = Object.freeze({
- LOCATION_WINDOWS: Symbol('location-windows'),
- WINDOWS_CHANGED: Symbol('windows-changed'),
-});
-
-const GJS_SUPPORTS_FILE_IFACE_PROMISES = imports.system.version >= 17101;
-
-if (GJS_SUPPORTS_FILE_IFACE_PROMISES) {
- Gio._promisify(Gio.File.prototype, 'query_info_async');
- Gio._promisify(Gio.File.prototype, 'query_default_handler_async');
-}
-
-
-/**
- *
- */
-function makeNautilusFileOperationsProxy() {
- const proxy = new NautilusFileOperations2ProxyInterface(
- Gio.DBus.session,
- 'org.gnome.Nautilus',
- '/org/gnome/Nautilus/FileOperations2', (_p, error) => {
- if (error)
- logError(error, 'Error connecting to Nautilus');
- }
- );
-
- proxy.platformData = params => {
- const defaultParams = {
- parentHandle: '',
- timestamp: global.get_current_time(),
- windowPosition: 'center',
- };
- const {parentHandle, timestamp, windowPosition} = {
- ...defaultParams,
- ...params,
- };
-
- return {
- 'parent-handle': new GLib.Variant('s', parentHandle),
- 'timestamp': new GLib.Variant('u', timestamp),
- 'window-position': new GLib.Variant('s', windowPosition),
- };
- };
-
- return proxy;
-}
-
-export const LocationAppInfo = GObject.registerClass({
- Implements: [Gio.AppInfo],
- Properties: {
- 'location': GObject.ParamSpec.object(
- 'location', 'location', 'location',
- GObject.ParamFlags.READWRITE,
- Gio.File.$gtype),
- 'name': GObject.ParamSpec.string(
- 'name', 'name', 'name',
- GObject.ParamFlags.READWRITE,
- null),
- 'icon': GObject.ParamSpec.object(
- 'icon', 'icon', 'icon',
- GObject.ParamFlags.READWRITE,
- Gio.Icon.$gtype),
- 'cancellable': GObject.ParamSpec.object(
- 'cancellable', 'cancellable', 'cancellable',
- GObject.ParamFlags.READWRITE,
- Gio.Cancellable.$gtype),
- },
-}, class LocationAppInfo extends GioUnix.DesktopAppInfo {
- static get GJS_BINARY_PATH() {
- if (!this._gjsBinaryPath)
- this._gjsBinaryPath = GLib.find_program_in_path('gjs');
-
- return this._gjsBinaryPath;
- }
-
- list_actions() {
- return [];
- }
-
- get_action_name() {
- return null;
- }
-
- get_boolean() {
- return false;
- }
-
- vfunc_dup() {
- return new LocationAppInfo({
- location: this.location,
- name: this.name,
- icon: this.icon,
- cancellable: this.cancellable,
- });
- }
-
- vfunc_equal(other) {
- if (this.location)
- return this.location.equal(other?.location);
-
- return this.name === other.name &&
- (this.icon ? this.icon.equal(other?.icon) : !other?.icon);
- }
-
- vfunc_get_id() {
- return 'location:%s'.format(this.location?.get_uri());
- }
-
- vfunc_get_name() {
- return this.name;
- }
-
- vfunc_get_description() {
- return null;
- }
-
- vfunc_get_executable() {
- return null;
- }
-
- vfunc_get_icon() {
- return this.icon;
- }
-
- vfunc_launch(files, context) {
- if (files?.length) {
- throw new GLib.Error(Gio.IOErrorEnum,
- Gio.IOErrorEnum.NOT_SUPPORTED, 'Launching with files not supported');
- }
-
- return this.getHandlerApp().launch_uris([this.location.get_uri()], context);
- }
-
- vfunc_supports_uris() {
- return false;
- }
-
- vfunc_supports_files() {
- return false;
- }
-
- vfunc_launch_uris(uris, context) {
- return this.launch(uris, context);
- }
-
- vfunc_should_show() {
- return true;
- }
-
- vfunc_set_as_default_for_type() {
- throw new GLib.Error(Gio.IOErrorEnum,
- Gio.IOErrorEnum.NOT_SUPPORTED, 'Not supported');
- }
-
- vfunc_set_as_default_for_extension() {
- throw new GLib.Error(Gio.IOErrorEnum,
- Gio.IOErrorEnum.NOT_SUPPORTED, 'Not supported');
- }
-
- vfunc_add_supports_type() {
- throw new GLib.Error(Gio.IOErrorEnum,
- Gio.IOErrorEnum.NOT_SUPPORTED, 'Not supported');
- }
-
- vfunc_can_remove_supports_type() {
- return false;
- }
-
- vfunc_remove_supports_type() {
- return false;
- }
-
- vfunc_can_delete() {
- return false;
- }
-
- vfunc_do_delete() {
- return false;
- }
-
- vfunc_get_commandline() {
- try {
- return this.getHandlerApp().get_commandline();
- } catch {
- return this._getFallbackCommandLine();
- }
- }
-
- vfunc_get_display_name() {
- return this.name;
- }
-
- vfunc_set_as_last_used_for_type() {
- throw new GLib.Error(Gio.IOErrorEnum,
- Gio.IOErrorEnum.NOT_SUPPORTED, 'Not supported');
- }
-
- vfunc_get_supported_types() {
- return [];
- }
-
- _getFallbackCommandLine() {
- return `gio open ${this.location?.get_uri()}`;
- }
-
- async _queryLocationIcons(params) {
- const icons = {standard: null, custom: null};
- if (!this.location)
- return icons;
-
- const cancellable = params.cancellable ?? this.cancellable;
- const iconsQuery = [];
- if (params?.standard)
- iconsQuery.push(Gio.FILE_ATTRIBUTE_STANDARD_ICON);
-
- if (params?.custom)
- iconsQuery.push(ATTRIBUTE_METADATA_CUSTOM_ICON);
-
- if (!iconsQuery.length)
- throw new Error('Invalid Query Location Icons parameters');
-
- let info;
- try {
- if (!GJS_SUPPORTS_FILE_IFACE_PROMISES) {
- Gio._promisify(this.location.constructor.prototype,
- 'query_info_async', 'query_info_finish');
- }
- info = await this.location.query_info_async(
- iconsQuery.join(','),
- Gio.FileQueryInfoFlags.NONE,
- GLib.PRIORITY_LOW, cancellable);
- if (info.has_attribute(Gio.FILE_ATTRIBUTE_STANDARD_ICON))
- icons.standard = info.get_icon();
- } catch (e) {
- if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) ||
- e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_MOUNTED))
- return icons;
- throw e;
- }
-
- const customIcon = info.get_attribute_string(ATTRIBUTE_METADATA_CUSTOM_ICON);
- if (customIcon) {
- const customIconFile = GLib.uri_parse_scheme(customIcon)
- ? Gio.File.new_for_uri(customIcon) : Gio.File.new_for_path(customIcon);
- const iconFileInfo = await customIconFile.query_info_async(
- Gio.FILE_ATTRIBUTE_STANDARD_TYPE,
- Gio.FileQueryInfoFlags.NONE,
- GLib.PRIORITY_LOW, cancellable);
-
- if (iconFileInfo.get_file_type() === Gio.FileType.REGULAR)
- icons.custom = Gio.FileIcon.new(customIconFile);
- }
-
- return icons;
- }
-
- async _updateLocationIcon(params = {standard: true, custom: true}) {
- const cancellable = new Utils.CancellableChild(this.cancellable);
-
- try {
- this._updateIconCancellable?.cancel();
- this._updateIconCancellable = cancellable;
-
- const icons = await this._queryLocationIcons({cancellable, ...params});
- const icon = icons.custom ?? icons.standard;
-
- if (icon && !icon.equal(this.icon))
- this.icon = icon;
- } catch (e) {
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- logError(e, 'Impossible to update icon for %s'.format(this.get_id()));
- } finally {
- cancellable.cancel();
- if (this._updateIconCancellable === cancellable)
- delete this._updateIconCancellable;
- }
- }
-
- async _getHandlerAppAsync(cancellable) {
- if (!this.location)
- return null;
-
- try {
- if (!GJS_SUPPORTS_FILE_IFACE_PROMISES) {
- Gio._promisify(this.location.constructor.prototype,
- 'query_default_handler_async',
- 'query_default_handler_finish');
- }
-
- return await this.location.query_default_handler_async(
- GLib.PRIORITY_DEFAULT, cancellable);
- } catch (e) {
- if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_MOUNTED))
- return getFileManagerApp()?.appInfo;
-
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
- logError(e, 'Impossible to find an URI handler for %s'.format(
- this.get_id()));
- }
-
- throw e;
- }
- }
-
- _getHandlerAppFromWorker(cancellable) {
- const locationsWorker = GLib.build_filenamev([
- Docking.DockManager.extension.path,
- 'locationsWorker.js',
- ]);
- const locationsWorkerArgs = [LocationAppInfo.GJS_BINARY_PATH, '-m',
- locationsWorker, 'handler', this.location.get_uri(),
- '--timeout', `${LAUNCH_HANDLER_MAX_WAIT}`];
- const subProcess = Gio.Subprocess.new(locationsWorkerArgs,
- Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE);
-
- try {
- const [, stdOut, stdErr] = subProcess.communicate(null, cancellable);
- subProcess.wait(cancellable);
- const errorCode = subProcess.get_exit_status();
- const textDecoder = new TextDecoder();
-
- if (errorCode) {
- const errorLines = textDecoder.decode(stdErr.toArray()).split('\n');
- const error = new GLib.Error(Gio.IOErrorEnum,
- errorCode === GLib.MAXUINT8 ? 0 : errorCode, errorLines[0]);
- error.stack = `${errorLines.slice(3).join('\n')}${error.stack}`;
- throw error;
- }
-
- const desktopId = textDecoder.decode(stdOut.toArray()).trim();
- const handlerApp = Shell.AppSystem.get_default().lookup_app(desktopId)?.appInfo;
- return handlerApp;
- } finally {
- subProcess.force_exit();
- }
- }
-
- getHandlerApp() {
- if (this._handlerApp)
- return this._handlerApp;
-
- if (!this.location)
- return null;
-
- const cancellable = new Utils.CancellableChild(this.cancellable);
-
- try {
- if (LocationAppInfo.GJS_BINARY_PATH)
- this._handlerApp = this._getHandlerAppFromWorker(cancellable);
- else
- this._handlerApp = this.location.query_default_handler(cancellable);
-
- if (!this._handlerApp) {
- throw new GLib.Error(Gio.IOErrorEnum,
- Gio.IOErrorEnum.NOT_FOUND, `Handler for ${this.location} not found`);
- }
- } catch (e) {
- if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_MOUNTED))
- return getFileManagerApp()?.appInfo;
-
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
- logError(e, 'Impossible to find an URI handler for %s'.format(
- this.get_id()));
- }
-
- throw e;
- }
-
- return this._handlerApp;
- }
-
- destroy() {
- this.location = null;
- this.icon = null;
- this.name = null;
- this._handlerApp = null;
- this.cancellable?.cancel();
- }
-});
-
-const RemovableAction = Object.freeze({
- MOUNT: 'mount',
- UNMOUNT: 'unmount',
- EJECT: 'eject',
-});
-
-const MountableVolumeAppInfo = GObject.registerClass({
- Implements: [Gio.AppInfo],
- Properties: {
- 'volume': GObject.ParamSpec.object(
- 'volume', 'volume', 'volume',
- GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
- Gio.Volume.$gtype),
- 'mount': GObject.ParamSpec.object(
- 'mount', 'mount', 'mount',
- GObject.ParamFlags.READWRITE,
- Gio.Mount.$gtype),
- 'busy': GObject.ParamSpec.boolean(
- 'busy', 'busy', 'busy',
- GObject.ParamFlags.READWRITE,
- false),
- },
-},
-class MountableVolumeAppInfo extends LocationAppInfo {
- _init(volume, cancellable = null) {
- super._init({
- volume,
- cancellable,
- });
-
- this._signalsHandler = new Utils.GlobalSignalsHandler();
-
- const updateAndMonitor = () => {
- this._update();
- this._monitorChanges();
- };
- updateAndMonitor();
- this._mountChanged = this.connect('notify::mount', updateAndMonitor);
-
- if (!this.mount && this.volume.get_identifier('class') === 'network') {
- // For some devices the mount point isn't advertised promptly
- // even if it's already existing, and there's no signaling about
- this._lazyUpdater = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, () => {
- this._update();
- delete this._lazyUpdater;
- return GLib.SOURCE_REMOVE;
- });
- }
- }
-
- get busy() {
- return !!this._currentAction;
- }
-
- get currentAction() {
- return this._currentAction;
- }
-
- destroy() {
- if (this._lazyUpdater) {
- GLib.source_remove(this._lazyUpdater);
- delete this._lazyUpdater;
- }
- this.disconnect(this._mountChanged);
- this.mount = null;
- this._signalsHandler.destroy();
-
- super.destroy();
- }
-
- vfunc_dup() {
- return new MountableVolumeAppInfo({
- volume: this.volume,
- cancellable: this.cancellable,
- });
- }
-
- vfunc_get_id() {
- const uuid = this.mount?.get_uuid() ?? this.volume.get_uuid();
- return uuid ? 'mountable-volume:%s'.format(uuid) : super.vfunc_get_id();
- }
-
- vfunc_equal(other) {
- if (this.volume === other?.volume && this.mount === other?.mount)
- return true;
-
- return this.get_id() === other?.get_id();
- }
-
- list_actions() {
- const actions = [];
- const {mount} = this;
-
- if (mount) {
- if (this.mount.can_unmount())
- actions.push(RemovableAction.UNMOUNT);
- if (this.mount.can_eject())
- actions.push(RemovableAction.EJECT);
-
- return actions;
- }
-
- if (this.volume.can_mount())
- actions.push(RemovableAction.MOUNT);
- if (this.volume.can_eject())
- actions.push(RemovableAction.EJECT);
-
- return actions;
- }
-
- get_action_name(action) {
- switch (action) {
- case RemovableAction.MOUNT:
- return __('Mount');
- case RemovableAction.UNMOUNT:
- return __('Unmount');
- case RemovableAction.EJECT:
- return __('Eject');
- default:
- return null;
- }
- }
-
- vfunc_launch(files, context) {
- if (this.mount || files?.length)
- return super.vfunc_launch(files, context);
-
- this.mountAndLaunch(files, context);
- return true;
- }
-
- _update() {
- this.mount = this.volume.get_mount();
-
- const removable = this.mount ?? this.volume;
- this.name = removable.get_name();
- this.icon = removable.get_icon();
-
- this.location = this.mount?.get_default_location() ??
- this.volume.get_activation_root();
-
- this._updateLocationIcon({custom: true});
- }
-
- _monitorChanges() {
- this._signalsHandler.destroy();
-
- const removable = this.mount ?? this.volume;
- this._signalsHandler.add(removable, 'changed', () => this._update());
-
- if (this.mount) {
- this._signalsHandler.add(this.mount, 'pre-unmount', () => this._update());
- this._signalsHandler.add(this.mount, 'unmounted', () => this._update());
- }
- }
-
- async mountAndLaunch(files, context) {
- if (this.mount)
- return super.vfunc_launch(files, context);
-
- try {
- await this.launchAction(RemovableAction.MOUNT);
- if (!this.mount) {
- throw new Error('No mounted location to open for %s'.format(
- this.get_id()));
- }
-
- return super.vfunc_launch(files, context);
- } catch (e) {
- logError(e, 'Mount and launch %s'.format(this.get_id()));
- return false;
- }
- }
-
- _notifyActionError(action, message) {
- switch (action) {
- case RemovableAction.MOUNT:
- global.notify_error(__('Failed to mount “%s”'.format(
- this.get_name())), message);
- break;
-
- case RemovableAction.UNMOUNT:
- global.notify_error(__('Failed to unmount “%s”'.format(
- this.get_name())), message);
- break;
-
- case RemovableAction.EJECT:
- global.notify_error(__('Failed to eject “%s”'.format(
- this.get_name())), message);
- break;
- }
- }
-
- async launchAction(action) {
- if (!this.list_actions().includes(action))
- throw new Error('Action %s is not supported by %s', action, this);
-
- switch (this._currentAction) {
- case RemovableAction.MOUNT:
- this._notifyActionError(action,
- __('Mount operation already in progress'));
- break;
-
- case RemovableAction.UNMOUNT:
- this._notifyActionError(action,
- __('Unmount operation already in progress'));
- break;
-
- case RemovableAction.EJECT:
- this._notifyActionError(action,
- __('Eject operation already in progress'));
- break;
-
- default:
- if (this._currentAction) {
- throw new Error('Another action %s is being performed in %s'.format(
- this._currentAction, this));
- }
- }
-
- this._currentAction = action;
- this.notify('busy');
- const removable = this.mount ?? this.volume;
- const operation = new ShellMountOperation.ShellMountOperation(removable);
- try {
- switch (action) {
- case RemovableAction.MOUNT:
- await this.volume.mount(Gio.MountMountFlags.NONE, operation.mountOp,
- this.cancellable);
- return true;
-
- case RemovableAction.UNMOUNT:
- await this.mount.unmount_with_operation(Gio.MountUnmountFlags.FORCE,
- operation.mountOp, this.cancellable);
- return true;
-
- case RemovableAction.EJECT:
- await removable.eject_with_operation(Gio.MountUnmountFlags.FORCE,
- operation.mountOp, this.cancellable);
- return true;
-
- default:
- logError(new Error(), 'No action %s on removable %s'.format(action,
- removable.get_name()));
- return false;
- }
- } catch (e) {
- if (action === RemovableAction.MOUNT &&
- e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.ALREADY_MOUNTED))
- return true;
- else if (action === RemovableAction.UNMOUNT &&
- e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_MOUNTED))
- return true;
-
- if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED))
- this._notifyActionError(action, e.message);
-
- if (action === RemovableAction.MOUNT && this._isEncryptedMountError(e)) {
- delete this._currentAction;
- operation.close();
- return this.launchAction(action);
- }
-
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
- logError(e, 'Impossible to %s removable %s'.format(action,
- removable.get_name()));
- }
-
- return false;
- } finally {
- delete this._currentAction;
- this.notify('busy');
- this._update();
- operation.close();
- }
- }
-
- _isEncryptedMountError(error) {
- // FIXME: we will always get G_IO_ERROR_FAILED from the gvfs udisks
- // backend, see https://bugs.freedesktop.org/show_bug.cgi?id=51271
-
- if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED))
- return false;
-
- // cryptsetup
- if (error.message.includes('No key available with this passphrase'))
- return true;
-
- // udisks (no password)
- if (error.message.includes('No key available to unlock device'))
- return true;
-
- // libblockdev wrong password opening LUKS device
- if (error.message.includes('Failed to activate device: Incorrect passphrase'))
- return true;
-
- // cryptsetup returns EINVAL in many cases, including wrong TCRYPT password/parameters
- if (error.message.includes('Failed to load device\'s parameters: Invalid argument') ||
- error.message.includes(`Failed to load device's parameters: ${GLib.strerror(22 /* EINVAL */)}`))
- return true;
-
- // cryptsetup returns EPERM when the TCRYPT header can't be decrypted
- // with the provided password/parameters.
- if (error.message.includes('Failed to load device\'s parameters: Operation not permitted') ||
- error.message.includes(`Failed to load device's parameters: ${GLib.strerror(1 /* EPERM */)}`))
- return true;
-
- return false;
- }
-});
-
-const TrashAppInfo = GObject.registerClass({
- Implements: [Gio.AppInfo],
- Properties: {
- 'empty': GObject.ParamSpec.boolean(
- 'empty', 'empty', 'empty',
- GObject.ParamFlags.READWRITE,
- true),
- },
-},
-class TrashAppInfo extends LocationAppInfo {
- static initPromises(file) {
- if (TrashAppInfo._promisified)
- return;
-
- const trashProto = file.constructor.prototype;
- Gio._promisify(Gio.FileEnumerator.prototype, 'close_async', 'close_finish');
- Gio._promisify(Gio.FileEnumerator.prototype, 'next_files_async', 'next_files_finish');
- Gio._promisify(trashProto, 'enumerate_children_async', 'enumerate_children_finish');
- Gio._promisify(trashProto, 'query_info_async', 'query_info_finish');
- TrashAppInfo._promisified = true;
- }
-
- _init(cancellable = null) {
- super._init({
- location: Gio.file_new_for_uri(TRASH_URI),
- name: __('Trash'),
- icon: Gio.ThemedIcon.new(FALLBACK_TRASH_ICON),
- cancellable,
- });
- TrashAppInfo.initPromises(this.location);
-
- try {
- this._monitor = this.location.monitor_directory(0, this.cancellable);
- this._schedUpdateId = 0;
- this._monitorChangedId = this._monitor.connect('changed', () =>
- this._onTrashChange());
- } catch (e) {
- if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- return;
- logError(e, 'Impossible to monitor trash');
- }
- this._updateTrash();
-
- this.connect('notify::empty', () => this._updateLocationIcon());
- this.notify('empty');
- }
-
- destroy() {
- if (this._schedUpdateId) {
- GLib.source_remove(this._schedUpdateId);
- this._schedUpdateId = 0;
- }
- this._updateTrashCancellable?.cancel();
- this._monitor?.disconnect(this._monitorChangedId);
- this._monitor = null;
-
- super.destroy();
- }
-
- list_actions() {
- return this.empty ? [] : ['empty-trash'];
- }
-
- get_action_name(action) {
- switch (action) {
- case 'empty-trash':
- return __('Empty Trash');
- default:
- return null;
- }
- }
-
- _onTrashChange() {
- if (this._schedUpdateId) {
- GLib.source_remove(this._schedUpdateId);
- this._schedUpdateId = 0;
- }
-
- if (this._monitor.is_cancelled())
- return;
-
- this._schedUpdateId = GLib.timeout_add(GLib.PRIORITY_LOW,
- UPDATE_TRASH_DELAY, () => {
- this._schedUpdateId = 0;
- this._updateTrash();
- return GLib.SOURCE_REMOVE;
- });
- }
-
- async _updateTrash() {
- const priority = GLib.PRIORITY_LOW;
- this._updateTrashCancellable?.cancel();
- const cancellable = new Utils.CancellableChild(this.cancellable);
- this._updateTrashCancellable = cancellable;
-
- try {
- const trashInfo = await this.location.query_info_async(
- Gio.FILE_ATTRIBUTE_TRASH_ITEM_COUNT,
- Gio.FileQueryInfoFlags.NONE,
- priority, cancellable);
- this.empty = !trashInfo.get_attribute_uint32(
- Gio.FILE_ATTRIBUTE_TRASH_ITEM_COUNT);
- return;
- } catch (e) {
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- logError(e, 'Impossible to get trash children from infos');
- } finally {
- cancellable.cancel();
- if (this._updateIconCancellable === cancellable)
- delete this._updateTrashCancellable;
- }
-
- try {
- const childrenEnumerator = await this.location.enumerate_children_async(
- Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE,
- priority, cancellable);
- const children = await childrenEnumerator.next_files_async(1,
- priority, cancellable);
- this.empty = !children.length;
-
- await childrenEnumerator.close_async(priority, null);
- } catch (e) {
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- logError(e, 'Impossible to enumerate trash children');
- } finally {
- cancellable.cancel();
- if (this._updateIconCancellable === cancellable)
- delete this._updateTrashCancellable;
- }
- }
-
- launchAction(action, timestamp) {
- if (!this.list_actions().includes(action))
- throw new Error('Action %s is not supported by %s', action, this);
-
- const nautilus = makeNautilusFileOperationsProxy();
- const askConfirmation = true;
- nautilus.EmptyTrashRemote(askConfirmation,
- nautilus.platformData({timestamp}), (_p, error) => {
- if (error)
- logError(error, 'Empty trash failed');
- }, this.cancellable);
- }
-});
-
-/**
- * @param shellApp
- */
-function wrapWindowsBackedApp(shellApp) {
- if (shellApp._dtdData)
- throw new Error('%s has been already wrapped'.format(shellApp));
-
- shellApp._dtdData = {
- windows: [],
- state: undefined,
- startingWorkspace: 0,
- isFocused: false,
- proxyProperties: [],
- sources: new Set(),
- signalConnections: new Utils.GlobalSignalsHandler(),
- methodInjections: new Utils.InjectionsHandler(),
- propertyInjections: new Utils.PropertyInjectionsHandler(),
- addProxyProperties(parent, proxyProperties) {
- Object.entries(proxyProperties).forEach(([p, o]) => {
- const publicProp = o.public ? p : `_${p}`;
- const get = o.getter && o.value instanceof Function
- ? () => this[p]() : () => this[p];
- Object.defineProperty(parent, publicProp, Object.assign({
- get,
- set: v => (this[p] = v),
- configurable: true,
- enumerable: !!o.enumerable,
- }, o.readOnly ? {set: undefined} : {}));
- if (o.value)
- this[p] = o.value;
- this.proxyProperties.push(publicProp);
- });
- },
- destroy() {
- this.windows = [];
- this.proxyProperties = [];
- this.sources.forEach(s => GLib.source_remove(s));
- this.sources.clear();
- this.signalConnections.destroy();
- this.methodInjections.destroy();
- this.propertyInjections.destroy();
- },
- };
-
- shellApp._dtdData.addProxyProperties(shellApp, {
- windows: {},
- state: {},
- startingWorkspace: {},
- isFocused: {public: true},
- signalConnections: {readOnly: true},
- sources: {readOnly: true},
- checkFocused: {},
- setDtdData: {},
- });
-
- shellApp._setDtdData = function (data, params = {}) {
- for (const [name, value] of Object.entries(data)) {
- if (params.readOnly && name in this._dtdData)
- throw new Error('Property %s is already defined'.format(name));
- const defaultParams = {public: true, readOnly: true};
- this._dtdData.addProxyProperties(this, {
- [name]: {...defaultParams, ...params, value},
- });
- }
- };
-
- const m = (...args) => shellApp._dtdData.methodInjections.add(shellApp, ...args);
- const p = (...args) => shellApp._dtdData.propertyInjections.add(shellApp, ...args);
-
- // mi is Method injector, pi is Property injector
- shellApp._setDtdData({mi: m, pi: p}, {public: false});
-
- m('get_state', () => shellApp._state ?? shellApp._getStateByWindows());
- p('state', {get: () => shellApp.get_state()});
-
- m('get_windows', () => shellApp._windows);
- m('get_n_windows', () => shellApp._windows.length);
- m('get_pids', () => shellApp._windows.reduce((pids, w) => {
- if (w.get_pid() > 0 && !pids.includes(w.get_pid()))
- pids.push(w.get_pid());
- return pids;
- }, []));
- m('is_on_workspace', (_om, workspace) => shellApp._windows.some(w =>
- w.get_workspace() === workspace) ||
- (shellApp.state === Shell.AppState.STARTING &&
- [-1, workspace.index()].includes(shellApp._startingWorkspace)));
- m('request_quit', () => shellApp._windows.filter(w =>
- w.can_close()).forEach(w => w.delete(global.get_current_time())));
-
- shellApp._setDtdData({
- _getStateByWindows() {
- return this.get_n_windows() ? Shell.AppState.RUNNING : Shell.AppState.STOPPED;
- },
-
- _updateWindows() {
- throw new GObject.NotImplementedError(`_updateWindows in ${this.constructor.name}`);
- },
-
- _notifyStateChanged() {
- Shell.AppSystem.get_default().emit('app-state-changed', this);
- this.notify('state');
- },
-
- _setState(state) {
- const oldState = this.state;
- this._state = state;
-
- if (this.state !== oldState)
- this._notifyStateChanged();
- },
-
- _setWindows(windows) {
- const oldState = this.state;
- const oldWindows = this._windows.slice();
- const result = {windowsChanged: false, stateChanged: false};
- this._state = undefined;
-
- if (windows.length !== oldWindows.length ||
- windows.some((win, index) => win !== oldWindows[index])) {
- this._windows = windows.filter(w => !w.is_override_redirect());
- this.emit('windows-changed');
- result.windowsChanged = true;
- }
-
- if (this.state !== oldState) {
- this._notifyStateChanged();
- this._checkFocused();
- result.stateChanged = true;
- }
-
- return result;
- },
- }, {readOnly: false});
-
- shellApp._sources.add(GLib.idle_add(GLib.DEFAULT_PRIORITY, () => {
- shellApp._updateWindows();
- shellApp._sources.delete(GLib.main_current_source().source_id);
- return GLib.SOURCE_REMOVE;
- }));
-
- const windowTracker = Shell.WindowTracker.get_default();
- shellApp._checkFocused = function () {
- if (this._windows.some(w => w.has_focus())) {
- this.isFocused = true;
- windowTracker.notify('focus-app');
- } else if (this.isFocused) {
- this.isFocused = false;
- windowTracker.notify('focus-app');
- }
- };
-
- shellApp._checkFocused();
- shellApp._signalConnections.add(global.display, 'notify::focus-window', () =>
- shellApp._checkFocused());
-
- // Re-implements shell_app_activate_window for generic activation and alt-tab support
- m('activate_window', function (_om, window, timestamp) {
- /* eslint-disable no-invalid-this */
- if (!window)
- [window] = this.get_windows();
- else if (!this._windows.includes(window))
- return;
-
- const currentWorkspace = global.workspace_manager.get_active_workspace();
- const workspace = window.get_workspace();
- const sameWorkspaceWindows = this.get_windows().filter(w =>
- w.get_workspace() === workspace);
- sameWorkspaceWindows.forEach(w => w.raise());
-
- if (workspace !== currentWorkspace)
- workspace.activate_with_focus(window, timestamp);
- else
- window.activate(timestamp);
- /* eslint-enable no-invalid-this */
- });
-
- // Re-implements shell_app_activate_full for generic activation and dash support
- m('activate_full', function (_om, workspace, timestamp) {
- /* eslint-disable no-invalid-this */
- if (!timestamp)
- timestamp = global.get_current_time();
-
- switch (this.state) {
- case Shell.AppState.STOPPED:
- try {
- this._startingWorkspace = workspace;
- this._setState(Shell.AppState.STARTING);
- this.launch(timestamp, workspace, Shell.AppLaunchGpu.APP_PREF);
- } catch (e) {
- logError(e);
- this._setState(Shell.AppState.STOPPED);
- global.notify_error(_('Failed to launch “%s”'.format(
- this.get_name())), e.message);
- }
- break;
- case Shell.AppState.RUNNING:
- this.activate_window(null, timestamp);
- break;
- }
- /* eslint-enable no-invalid-this */
- });
-
- m('activate', () => shellApp.activate_full(-1, 0));
-
- m('compare', (_om, other) => Utils.shellAppCompare(shellApp, other));
-
- const {destroy: defaultDestroy} = shellApp;
- shellApp.destroy = function () {
- /* eslint-disable no-invalid-this */
- this._dtdData.proxyProperties.forEach(prop => delete this[prop]);
- this._dtdData.destroy();
- this._dtdData = undefined;
- this.appInfo.destroy?.();
- this.destroy = defaultDestroy;
- defaultDestroy?.call(this);
- /* eslint-enable no-invalid-this */
- };
-
- return shellApp;
-}
-
-/**
- * We can't inherit from Shell.App as it's a final type, so let's patch it
- *
- * @param params
- */
-function makeLocationApp(params) {
- if (!(params?.appInfo instanceof LocationAppInfo))
- throw new TypeError('Invalid location');
-
- const {fallbackIconName} = params;
- delete params.fallbackIconName;
-
- const shellApp = new Shell.App(params);
- wrapWindowsBackedApp(shellApp);
-
- shellApp._setDtdData({
- location: () => shellApp.appInfo.location,
- isTrash: shellApp.appInfo instanceof TrashAppInfo,
- }, {getter: true, enumerable: true});
-
- shellApp._mi('toString', defaultToString =>
- '[LocationApp "%s" - %s]'.format(shellApp.get_id(),
- defaultToString.call(shellApp)));
-
- shellApp._mi('launch', (_om, timestamp, workspace, _gpuPref) =>
- shellApp.appInfo.launch([],
- global.create_app_launch_context(timestamp, workspace)));
-
- shellApp._mi('launch_action', (_om, actionName, ...args) =>
- shellApp.appInfo.launchAction(actionName, ...args));
-
- shellApp._mi('create_icon_texture', (_om, iconSize) => new St.Icon({
- iconSize,
- gicon: shellApp.icon,
- fallbackIconName,
- }));
-
- // FIXME: We need to add a new API to Nautilus to open new windows
- shellApp._mi('can_open_new_window', () => {
- try {
- if (!shellApp.get_n_windows())
- return true;
-
- const handlerApp = shellApp.appInfo.getHandlerApp();
-
- if (handlerApp.has_key('SingleMainWindow'))
- return !handlerApp.get_boolean('SingleMainWindow');
-
- if (handlerApp.has_key('X-GNOME-SingleWindow'))
- return !handlerApp.get_boolean('X-GNOME-SingleWindow');
-
- if (handlerApp.get_commandline()?.split(' ').includes('--new-window'))
- return true;
-
- const [window] = shellApp.get_windows();
- if (window && window.get_gtk_window_object_path())
- return window.get_gtk_application_id() === null;
-
- return true;
- } catch {
- return false;
- }
- });
-
- shellApp._mi('open_new_window', function (_om, workspace) {
- /* eslint-disable no-invalid-this */
- const context = global.create_app_launch_context(0, workspace);
- if (!this.get_n_windows()) {
- this.appInfo.launch([], context);
- return;
- }
- const appId = this.appInfo.get_id();
- Gio.AppInfo.create_from_commandline(this.appInfo.get_commandline(),
- this.appInfo.get_id(), appId
- ? Gio.AppInfoCreateFlags.SUPPORTS_STARTUP_NOTIFICATION
- : Gio.AppInfoCreateFlags.NONE).launch_uris(
- [this.appInfo.location.get_uri()], context);
- /* eslint-enable no-invalid-this */
- });
-
- if (shellApp.appInfo instanceof MountableVolumeAppInfo) {
- shellApp._mi('get_busy', function (parentGetBusy) {
- /* eslint-disable no-invalid-this */
- if (this.appInfo.busy)
- return true;
- return parentGetBusy.call(this);
- /* eslint-enable no-invalid-this */
- });
- shellApp._pi('busy', {get: () => shellApp.get_busy()});
- shellApp._signalConnections.add(shellApp.appInfo, 'notify::busy', _ =>
- shellApp.notify('busy'));
- }
-
- shellApp._mi('get_windows', function () {
- /* eslint-disable no-invalid-this */
- if (this._needsResort)
- this._sortWindows();
- return this._windows;
- /* eslint-enable no-invalid-this */
- });
-
- const {fm1Client} = Docking.DockManager.getDefault();
- shellApp._setDtdData({
- _needsResort: true,
-
- _windowsOrderChanged() {
- this._needsResort = true;
- this.emit('windows-changed');
- },
-
- _sortWindows() {
- this._windows.sort(Utils.shellWindowsCompare);
- this._needsResort = false;
- },
-
- _updateWindows() {
- const windows = fm1Client.getWindows(this.location?.get_uri()).sort(
- Utils.shellWindowsCompare);
- const {windowsChanged} = this._setWindows(windows);
-
- if (!windowsChanged)
- return;
-
- this._signalConnections.removeWithLabel(Labels.LOCATION_WINDOWS);
- windows.forEach(w =>
- this._signalConnections.addWithLabel(Labels.LOCATION_WINDOWS, w,
- 'notify::user-time', () => {
- if (w !== this._windows[0])
- this._windowsOrderChanged();
- }));
- },
- }, {readOnly: false});
-
- shellApp._signalConnections.add(fm1Client, 'windows-changed', () =>
- shellApp._updateWindows());
- shellApp._signalConnections.add(shellApp.appInfo, 'notify::icon', () =>
- shellApp.notify('icon'));
- shellApp._signalConnections.add(global.workspaceManager,
- 'workspace-switched', () => shellApp._windowsOrderChanged());
-
- return shellApp;
-}
-
-/**
- *
- */
-function getFileManagerApp() {
- return Shell.AppSystem.get_default().lookup_app(FILE_MANAGER_DESKTOP_APP_ID);
-}
-
-/**
- *
- */
-export function wrapFileManagerApp() {
- const fileManagerApp = getFileManagerApp();
- if (!fileManagerApp)
- return null;
-
- if (fileManagerApp._dtdData)
- return fileManagerApp;
-
- const originalGetWindows = fileManagerApp.get_windows;
- wrapWindowsBackedApp(fileManagerApp);
-
- const {removables, trash} = Docking.DockManager.getDefault();
- fileManagerApp._signalConnections.addWithLabel(Labels.WINDOWS_CHANGED,
- fileManagerApp, 'windows-changed', () => {
- fileManagerApp.stop_emission_by_name('windows-changed');
- // Let's wait for the location app to take control before of us
- const id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 50, () => {
- fileManagerApp._sources.delete(id);
- fileManagerApp._updateWindows();
- return GLib.SOURCE_REMOVE;
- });
- fileManagerApp._sources.add(id);
- });
-
- fileManagerApp._signalConnections.add(global.workspaceManager,
- 'workspace-switched', () => {
- fileManagerApp._signalConnections.blockWithLabel(Labels.WINDOWS_CHANGED);
- fileManagerApp.emit('windows-changed');
- fileManagerApp._signalConnections.unblockWithLabel(Labels.WINDOWS_CHANGED);
- });
-
- if (removables) {
- fileManagerApp._signalConnections.add(removables, 'changed', () =>
- fileManagerApp._updateWindows());
- fileManagerApp._signalConnections.add(removables, 'windows-changed', () =>
- fileManagerApp._updateWindows());
- }
-
- if (trash?.getApp()) {
- fileManagerApp._signalConnections.add(trash.getApp(), 'windows-changed', () =>
- fileManagerApp._updateWindows());
- }
-
- fileManagerApp._updateWindows = function () {
- const locationWindows = [];
- getRunningApps().forEach(a => locationWindows.push(...a.get_windows()));
- const windows = originalGetWindows.call(this).filter(w =>
- !locationWindows.includes(w));
-
- this._signalConnections.blockWithLabel(Labels.WINDOWS_CHANGED);
- this._setWindows(windows);
- this._signalConnections.unblockWithLabel(Labels.WINDOWS_CHANGED);
- };
-
- fileManagerApp._mi('toString', defaultToString =>
- '[FileManagerApp - %s]'.format(defaultToString.call(fileManagerApp)));
-
- return fileManagerApp;
-}
-
-/**
- *
- */
-export function unWrapFileManagerApp() {
- const fileManagerApp = getFileManagerApp();
- if (!fileManagerApp || !fileManagerApp._dtdData)
- return;
-
- fileManagerApp.destroy();
-}
-
-/**
- * This class maintains a Shell.App representing the Trash and keeps it
- * up-to-date as the trash fills and is emptied over time.
- */
-export class Trash {
- destroy() {
- this._trashApp?.destroy();
- }
-
- _ensureApp() {
- if (this._trashApp)
- return;
-
- this._trashApp = makeLocationApp({
- appInfo: new TrashAppInfo(new Gio.Cancellable()),
- fallbackIconName: FALLBACK_TRASH_ICON,
- });
- }
-
- getApp() {
- this._ensureApp();
- return this._trashApp;
- }
-}
-
-/**
- * This class maintains Shell.App representations for removable devices
- * plugged into the system, and keeps the list of Apps up-to-date as
- * devices come and go and are mounted and unmounted.
- */
-export class Removables {
- static initVolumePromises(object) {
- // TODO: This can be simplified using actual interface type when we
- // can depend on gjs 1.72
- if (!(object instanceof Gio.Volume) || object.constructor.prototype._d2dPromisified)
- return;
-
- Gio._promisify(object.constructor.prototype, 'mount', 'mount_finish');
- Gio._promisify(object.constructor.prototype, 'eject_with_operation',
- 'eject_with_operation_finish');
- object.constructor.prototype._d2dPromisified = true;
- }
-
- static initMountPromises(object) {
- // TODO: This can be simplified using actual interface type when we
- // can depend on gjs 1.72
- if (!(object instanceof Gio.Mount) || object.constructor.prototype._d2dPromisified)
- return;
-
- Gio._promisify(object.constructor.prototype, 'eject_with_operation',
- 'eject_with_operation_finish');
- Gio._promisify(object.constructor.prototype, 'unmount_with_operation',
- 'unmount_with_operation_finish');
- object.constructor.prototype._d2dPromisified = true;
- }
-
- constructor() {
- this._signalsHandler = new Utils.GlobalSignalsHandler();
-
- this._monitor = Gio.VolumeMonitor.get();
- this._cancellable = new Gio.Cancellable();
-
- this._monitor.get_mounts().forEach(m => Removables.initMountPromises(m));
- this._updateVolumes();
-
- this._signalsHandler.add([
- this._monitor,
- 'volume-added',
- (_, volume) => this._onVolumeAdded(volume),
- ], [
- this._monitor,
- 'volume-removed',
- (_, volume) => this._onVolumeRemoved(volume),
- ], [
- this._monitor,
- 'mount-added',
- (_, mount) => this._onMountAdded(mount),
- ], [
- Docking.DockManager.settings,
- 'changed::show-mounts-only-mounted',
- () => this._updateVolumes(),
- ], [
- Docking.DockManager.settings,
- 'changed::show-mounts-network',
- () => this._updateVolumes(),
- ]);
- }
-
- destroy() {
- this._volumeApps.forEach(a => a.destroy());
- this._volumeApps = [];
- this._cancellable.cancel();
- this._cancellable = null;
- this._signalsHandler.destroy();
- this._monitor = null;
- }
-
- _updateVolumes() {
- this._volumeApps?.forEach(a => a.destroy());
- this._volumeApps = [];
- this.emit('changed');
-
- this._monitor.get_volumes().forEach(v => this._onVolumeAdded(v));
- }
-
- _onVolumeAdded(volume) {
- Removables.initVolumePromises(volume);
-
- if (!Docking.DockManager.settings.showMountsNetwork &&
- volume.get_identifier('class') === 'network')
- return;
-
-
- const mount = volume.get_mount();
- if (mount) {
- if (mount.is_shadowed())
- return;
- if (!mount.can_eject() && !mount.can_unmount())
- return;
- } else {
- if (Docking.DockManager.settings.showMountsOnlyMounted)
- return;
- if (!volume.can_mount() && !volume.can_eject())
- return;
- }
-
- const appInfo = new MountableVolumeAppInfo(volume,
- new Utils.CancellableChild(this._cancellable));
- const volumeApp = makeLocationApp({
- appInfo,
- fallbackIconName: FALLBACK_REMOVABLE_MEDIA_ICON,
- });
-
- volumeApp._signalConnections.add(volumeApp, 'windows-changed',
- () => this.emit('windows-changed', volumeApp));
-
- if (Docking.DockManager.settings.showMountsOnlyMounted) {
- volumeApp._signalConnections.add(appInfo, 'notify::mount',
- () => !appInfo.mount && this._onVolumeRemoved(appInfo.volume));
- }
-
- this._volumeApps.push(volumeApp);
- this.emit('changed');
- }
-
- _onVolumeRemoved(volume) {
- const volumeIndex = this._volumeApps.findIndex(({appInfo}) =>
- appInfo.volume === volume);
- if (volumeIndex !== -1) {
- const [volumeApp] = this._volumeApps.splice(volumeIndex, 1);
- // We don't care about cancelling the ongoing operations from now on.
- volumeApp.appInfo.cancellable = null;
- volumeApp.destroy();
- this.emit('changed');
- }
- }
-
- _onMountAdded(mount) {
- Removables.initMountPromises(mount);
-
- if (!Docking.DockManager.settings.showMountsOnlyMounted)
- return;
-
- if (!this._volumeApps.find(({appInfo}) => appInfo.mount === mount)) {
- // In some Gio.Mount implementations the volume may be set after
- // mount is emitted, so we could just ignore it as we'll get it
- // later via volume-added
- const volume = mount.get_volume();
- if (volume)
- this._onVolumeAdded(volume);
- }
- }
-
- getApps() {
- return this._volumeApps;
- }
-}
-Signals.addSignalMethods(Removables.prototype);
-
-/**
- *
- */
-function getApps() {
- const dockManager = Docking.DockManager.getDefault();
- const locationApps = [];
-
- if (dockManager.removables)
- locationApps.push(...dockManager.removables.getApps());
-
- if (dockManager.trash)
- locationApps.push(dockManager.trash.getApp());
-
- return locationApps;
-}
-
-/**
- *
- */
-export function getRunningApps() {
- return getApps().filter(a => a.state === Shell.AppState.RUNNING);
-}
-
-/**
- *
- */
-export function getStartingApps() {
- return getApps().filter(a => a.state === Shell.AppState.STARTING);
-}