summaryrefslogtreecommitdiff
path: root/raveos-theme/gnome/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js')
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js320
1 files changed, 0 insertions, 320 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js b/raveos-theme/gnome/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js
deleted file mode 100644
index 2c5e54f..0000000
--- a/raveos-theme/gnome/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js
+++ /dev/null
@@ -1,320 +0,0 @@
-// This file is part of the AppIndicator/KStatusNotifierItem GNOME Shell extension
-//
-// This program 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 2
-// of the License, or (at your option) any later version.
-//
-// This program 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 this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-import Gio from 'gi://Gio';
-import GLib from 'gi://GLib';
-
-import * as AppIndicator from './appIndicator.js';
-import * as IndicatorStatusIcon from './indicatorStatusIcon.js';
-import * as Interfaces from './interfaces.js';
-import * as PromiseUtils from './promiseUtils.js';
-import * as Util from './util.js';
-import * as DBusUtils from './dbusUtils.js';
-import * as DBusMenu from './dbusMenu.js';
-
-import {DBusProxy} from './dbusProxy.js';
-
-Gio._promisify(Gio.Subprocess.prototype, 'wait_async');
-Gio._promisify(Gio.Subprocess.prototype, 'communicate_async');
-Gio._promisify(Gio.DataInputStream.prototype, 'read_line_async', 'read_line_finish_utf8');
-
-
-// TODO: replace with org.freedesktop and /org/freedesktop when approved
-const KDE_PREFIX = 'org.kde';
-
-export const WATCHER_BUS_NAME = `${KDE_PREFIX}.StatusNotifierWatcher`;
-const WATCHER_OBJECT = '/StatusNotifierWatcher';
-
-const DEFAULT_ITEM_OBJECT_PATH = '/StatusNotifierItem';
-
-/*
- * The StatusNotifierWatcher class implements the StatusNotifierWatcher dbus object
- */
-export class StatusNotifierWatcher {
- constructor(extension, watchDog) {
- this._watchDog = watchDog;
- this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(Interfaces.StatusNotifierWatcher, this);
- try {
- this._dbusImpl.export(Gio.DBus.session, WATCHER_OBJECT);
- } catch (e) {
- Util.Logger.warn(`Failed to export ${WATCHER_OBJECT}`);
- logError(e);
- }
- this._cancellable = new Gio.Cancellable();
- this._everAcquiredName = false;
- this._ownName = Gio.DBus.session.own_name(WATCHER_BUS_NAME,
- Gio.BusNameOwnerFlags.NONE,
- this._acquiredName.bind(this),
- this._lostName.bind(this));
- this._items = new Map();
-
- try {
- this._dbusImpl.emit_signal('StatusNotifierHostRegistered', null);
- } catch (e) {
- Util.Logger.warn(`Failed to notify registered host ${WATCHER_OBJECT}`);
- }
-
- this._seekStatusNotifierItems(extension).catch(e => {
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- logError(e, 'Looking for StatusNotifierItem\'s');
- });
- }
-
- _acquiredName() {
- this._everAcquiredName = true;
- this._watchDog.nameAcquired = true;
- }
-
- _lostName() {
- if (this._everAcquiredName)
- Util.Logger.debug(`Lost name${WATCHER_BUS_NAME}`);
- else
- Util.Logger.warn(`Failed to acquire ${WATCHER_BUS_NAME}`);
- this._watchDog.nameAcquired = false;
- }
-
- async _registerItem(service, busName, objPath) {
- const id = Util.indicatorId(service, busName, objPath);
-
- if (this._items.has(id)) {
- Util.Logger.warn(`Item ${id} is already registered`);
- return;
- }
-
- Util.Logger.debug(`Registering StatusNotifierItem ${id}`);
-
- try {
- const indicator = new AppIndicator.AppIndicator(service, busName, objPath);
- this._items.set(id, indicator);
- indicator.connect('destroy', () => this._onIndicatorDestroyed(indicator));
-
- indicator.connect('name-owner-changed', async () => {
- if (!indicator.hasNameOwner) {
- try {
- await new PromiseUtils.TimeoutPromise(500,
- GLib.PRIORITY_DEFAULT, this._cancellable);
- if (this._items.has(id) && !indicator.hasNameOwner)
- indicator.destroy();
- } catch (e) {
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- logError(e);
- }
- }
- });
-
- // if the desktop is not ready delay the icon creation and signal emissions
- await Util.waitForStartupCompletion(indicator.cancellable);
- const statusIcon = new IndicatorStatusIcon.IndicatorStatusIcon(indicator);
- IndicatorStatusIcon.addIconToPanel(statusIcon);
-
- this._dbusImpl.emit_signal('StatusNotifierItemRegistered',
- GLib.Variant.new('(s)', [indicator.uniqueId]));
- this._dbusImpl.emit_property_changed('RegisteredStatusNotifierItems',
- GLib.Variant.new('as', this.RegisteredStatusNotifierItems));
- } catch (e) {
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- logError(e);
- throw e;
- }
- }
-
- async _ensureItemRegistered(service, busName, objPath) {
- const id = Util.indicatorId(service, busName, objPath);
- const item = this._items.get(id);
-
- if (item) {
- // delete the old one and add the new indicator
- Util.Logger.debug(`Attempting to re-register ${id}; resetting instead`);
- item.reset();
- return;
- }
-
- await this._registerItem(service, busName, objPath);
- }
-
- async _seekStatusNotifierItems(extension) {
- // Some indicators (*coff*, dropbox, *coff*) do not re-register again
- // when the plugin is enabled/disabled, thus we need to manually look
- // for the objects in the session bus that implements the
- // StatusNotifierItem interface... However let's do it after a low
- // priority timeout, and using an external process so that it won't
- // affect startup or memory (as it seems that gjs is not great at
- // handling the memory of the bus analyzer async code).
- const cancellable = this._cancellable;
- await new PromiseUtils.TimeoutSecondsPromise(2, GLib.PRIORITY_LOW, cancellable);
- const busAnalyzer = GLib.build_filenamev([
- extension.path, 'tools', 'busAnalyzer.js',
- ]);
-
- const subProcess = Gio.Subprocess.new(['gjs', '-m', busAnalyzer],
- Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE);
-
- const stdOut = subProcess.get_stdout_pipe();
- const dataInputStream = new Gio.DataInputStream({base_stream: stdOut});
- const textDecoder = new TextDecoder();
-
- while (true) {
- // eslint-disable-next-line no-await-in-loop
- const [line] = await dataInputStream.read_line_async(GLib.PRIORITY_DEFAULT,
- cancellable);
- if (!line)
- break;
-
- try {
- const {services, name, path} = JSON.parse(textDecoder.decode(line));
- const ids = [null, ...services].map(s => Util.indicatorId(s, name, path));
-
- if (ids.every(id => !this._items.has(id))) {
- const service = services.find(s =>
- s && s.startsWith('org.kde.StatusNotifierItem')) || services[0];
- const id = Util.indicatorId(
- path === DEFAULT_ITEM_OBJECT_PATH ? service : null,
- name, path);
- Util.Logger.warn(`Using Brute-force mode for StatusNotifierItem ${id}`);
- // eslint-disable-next-line no-await-in-loop
- await this._registerItem(service, name, path);
- }
- } catch (e) {
- logError(e);
- }
- }
-
- const [, stdErr] = await subProcess.communicate_async(null, cancellable);
- await subProcess.wait_async(cancellable);
-
- if (subProcess.get_exit_status() !== 0) {
- const errorLines = textDecoder.decode(stdErr.toArray()).split('\n');
- const error = new GLib.Error(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED,
- errorLines[0]);
- error.stack = `${errorLines.slice(3).join('\n')}${error.stack}`;
- throw error;
- }
- }
-
- async RegisterStatusNotifierItemAsync(params, invocation) {
- // it would be too easy if all application behaved the same
- // instead, ayatana patched gnome apps to send a path
- // while kde apps send a bus name
- const [service] = params;
- let busName, objPath;
-
- if (service.charAt(0) === '/') { // looks like a path
- busName = invocation.get_sender();
- objPath = service;
- } else if (service.match(DBusUtils.BUS_ADDRESS_REGEX)) {
- try {
- busName = await DBusUtils.getUniqueBusName(invocation.get_connection(),
- service, this._cancellable);
- } catch (e) {
- logError(e);
- }
- objPath = DEFAULT_ITEM_OBJECT_PATH;
- }
-
- if (!busName || !objPath) {
- const error = `Impossible to register an indicator for parameters '${
- service.toString()}'`;
- Util.Logger.warn(error);
-
- invocation.return_dbus_error('org.gnome.gjs.JSError.ValueError',
- error);
- return;
- }
-
- try {
- await this._ensureItemRegistered(service, busName, objPath);
- invocation.return_value(null);
- } catch (e) {
- if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
- logError(e);
- invocation.return_dbus_error('org.gnome.gjs.JSError.ValueError',
- e.message);
- }
- }
-
- _onIndicatorDestroyed(indicator) {
- const {uniqueId} = indicator;
- this._items.delete(uniqueId);
-
- try {
- this._dbusImpl.emit_signal('StatusNotifierItemUnregistered',
- GLib.Variant.new('(s)', [uniqueId]));
- this._dbusImpl.emit_property_changed('RegisteredStatusNotifierItems',
- GLib.Variant.new('as', this.RegisteredStatusNotifierItems));
- } catch (e) {
- Util.Logger.warn(`Failed to emit signals: ${e}`);
- }
- }
-
- RegisterStatusNotifierHostAsync(_service, invocation) {
- invocation.return_error_literal(
- Gio.DBusError,
- Gio.DBusError.NOT_SUPPORTED,
- 'Registering additional notification hosts is not supported');
- }
-
- IsNotificationHostRegistered() {
- return true;
- }
-
- get RegisteredStatusNotifierItems() {
- return Array.from(this._items.values()).map(i => i.uniqueId);
- }
-
- get IsStatusNotifierHostRegistered() {
- return true;
- }
-
- get ProtocolVersion() {
- return 0;
- }
-
- destroy() {
- if (this._isDestroyed)
- return;
-
- // this doesn't do any sync operation and doesn't allow us to hook up
- // the event of being finished which results in our unholy debounce hack
- // (see extension.js)
- this._items.forEach(indicator => indicator.destroy());
- this._cancellable.cancel();
-
- try {
- this._dbusImpl.emit_signal('StatusNotifierHostUnregistered', null);
- } catch (e) {
- Util.Logger.warn(`Failed to emit uinregistered signal: ${e}`);
- }
-
- Gio.DBus.session.unown_name(this._ownName);
-
- try {
- this._dbusImpl.unexport();
- } catch (e) {
- Util.Logger.warn(`Failed to unexport watcher object: ${e}`);
- }
-
- DBusMenu.DBusClient.destroy();
- AppIndicator.AppIndicatorProxy.destroy();
- DBusProxy.destroy();
- Util.destroyDefaultTheme();
-
- this._dbusImpl.run_dispose();
- delete this._dbusImpl;
-
- delete this._items;
- this._isDestroyed = true;
- }
-}