diff options
| author | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
|---|---|---|
| committer | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
| commit | 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch) | |
| tree | ab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-gnome-theme/theme-data/extensions/installed/drive-menu@gnome-shell-extensions.gcampax.github.com/extension.js | |
| parent | 5d94c0a7d44a2255b81815a52a7056a94a39842d (diff) | |
| download | RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip | |
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/drive-menu@gnome-shell-extensions.gcampax.github.com/extension.js')
| -rw-r--r-- | raveos-gnome-theme/theme-data/extensions/installed/drive-menu@gnome-shell-extensions.gcampax.github.com/extension.js | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/drive-menu@gnome-shell-extensions.gcampax.github.com/extension.js b/raveos-gnome-theme/theme-data/extensions/installed/drive-menu@gnome-shell-extensions.gcampax.github.com/extension.js new file mode 100644 index 0000000..bb18b0f --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/drive-menu@gnome-shell-extensions.gcampax.github.com/extension.js @@ -0,0 +1,211 @@ +// SPDX-FileCopyrightText: 2011 Giovanni Campagna <gcampagna@src.gnome.org> +// SPDX-FileCopyrightText: 2018 Florian Müllner <fmuellner@gnome.org> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +// Drive menu extension +import Clutter from 'gi://Clutter'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; +import Shell from 'gi://Shell'; +import St from 'gi://St'; + +import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js'; + +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'; +import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; +import * as ShellMountOperation from 'resource:///org/gnome/shell/ui/shellMountOperation.js'; + +Gio._promisify(Gio.File.prototype, 'query_filesystem_info_async'); + +class MountMenuItem extends PopupMenu.PopupBaseMenuItem { + static { + GObject.registerClass(this); + } + + constructor(mount) { + super({ + style_class: 'drive-menu-item', + }); + + this.label = new St.Label({ + text: mount.get_name(), + x_expand: true, + y_align: Clutter.ActorAlign.CENTER, + }); + this.add_child(this.label); + this.label_actor = this.label; + + this.mount = mount; + + const ejectIcon = new St.Icon({ + icon_name: 'media-eject-symbolic', + style_class: 'popup-menu-icon', + }); + const ejectButton = new St.Button({ + child: ejectIcon, + style_class: 'button', + }); + ejectButton.connect('clicked', this._eject.bind(this)); + this.add_child(ejectButton); + + this.hide(); + + mount.connectObject('changed', + () => this._syncVisibility(), this); + this._syncVisibility(); + } + + async _isInteresting() { + if (!this.mount.can_eject() && !this.mount.can_unmount()) + return false; + if (this.mount.is_shadowed()) + return false; + + const volume = this.mount.get_volume(); + + if (volume) + return volume.get_identifier('class') !== 'network'; + + const root = this.mount.get_root(); + + try { + const attr = Gio.FILE_ATTRIBUTE_FILESYSTEM_REMOTE; + const info = await root.query_filesystem_info_async(attr, null); + return !info.get_attribute_boolean(attr); + } catch (e) { + log(`Failed to query filesystem: ${e.message}`); + } + + // Hack, fall back to looking at GType + return Gio._LocalFilePrototype.isPrototypeOf(root); + } + + async _syncVisibility() { + this.visible = await this._isInteresting(); + } + + _eject() { + const unmountArgs = [ + Gio.MountUnmountFlags.NONE, + new ShellMountOperation.ShellMountOperation(this.mount).mountOp, + null, // Gio.Cancellable + ]; + + if (this.mount.can_eject()) { + this.mount.eject_with_operation(...unmountArgs, + this._ejectFinish.bind(this)); + } else { + this.mount.unmount_with_operation(...unmountArgs, + this._unmountFinish.bind(this)); + } + } + + _unmountFinish(mount, result) { + try { + mount.unmount_with_operation_finish(result); + } catch (e) { + this._reportFailure(e); + } + } + + _ejectFinish(mount, result) { + try { + mount.eject_with_operation_finish(result); + } catch (e) { + this._reportFailure(e); + } + } + + _reportFailure(exception) { + // TRANSLATORS: %s is the filesystem name + const msg = _('Ejecting drive “%s” failed:').format(this.mount.get_name()); + Main.notifyError(msg, exception.message); + } + + activate(event) { + const uri = this.mount.get_root().get_uri(); + const context = global.create_app_launch_context(event.get_time(), -1); + Gio.AppInfo.launch_default_for_uri(uri, context); + + super.activate(event); + } +} + +class DriveMenu extends PanelMenu.Button { + static { + GObject.registerClass(this); + } + + constructor() { + super(0.5, _('Removable devices')); + + const icon = new St.Icon({ + icon_name: 'media-eject-symbolic', + style_class: 'system-status-icon', + }); + + this.add_child(icon); + + this._monitor = Gio.VolumeMonitor.get(); + this._monitor.connectObject( + 'mount-added', (monitor, mount) => this._addMount(mount), + 'mount-removed', (monitor, mount) => { + this._removeMount(mount); + this._updateMenuVisibility(); + }, this); + + this._mounts = []; + + this._monitor.get_mounts().forEach(this._addMount.bind(this)); + + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this.menu.addAction(_('Open Files'), event => { + const appSystem = Shell.AppSystem.get_default(); + const app = appSystem.lookup_app('org.gnome.Nautilus.desktop'); + app.activate_full(-1, event.get_time()); + }); + + this._updateMenuVisibility(); + } + + _updateMenuVisibility() { + if (this._mounts.filter(i => i.visible).length > 0) + this.show(); + else + this.hide(); + } + + _addMount(mount) { + const item = new MountMenuItem(mount); + this._mounts.unshift(item); + this.menu.addMenuItem(item, 0); + + item.connect('notify::visible', () => this._updateMenuVisibility()); + } + + _removeMount(mount) { + for (let i = 0; i < this._mounts.length; i++) { + const item = this._mounts[i]; + if (item.mount === mount) { + item.destroy(); + this._mounts.splice(i, 1); + return; + } + } + log('Removing a mount that was never added to the menu'); + } +} + +export default class PlaceMenuExtension extends Extension { + enable() { + this._indicator = new DriveMenu(); + Main.panel.addToStatusArea('drive-menu', this._indicator); + } + + disable() { + this._indicator.destroy(); + delete this._indicator; + } +} |