[gnome] Update extensions
This commit is contained in:
@ -0,0 +1,121 @@
|
||||
// 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 {Logger} from './logger.js';
|
||||
|
||||
export const BUS_ADDRESS_REGEX = /([a-zA-Z0-9._-]+\.[a-zA-Z0-9.-]+)|(:[0-9]+\.[0-9]+)$/;
|
||||
|
||||
Gio._promisify(Gio.DBusConnection.prototype, 'call');
|
||||
|
||||
export async function getUniqueBusName(bus, name, cancellable) {
|
||||
if (name[0] === ':')
|
||||
return name;
|
||||
|
||||
if (!bus)
|
||||
bus = Gio.DBus.session;
|
||||
|
||||
const variantName = new GLib.Variant('(s)', [name]);
|
||||
const [unique] = (await bus.call('org.freedesktop.DBus', '/', 'org.freedesktop.DBus',
|
||||
'GetNameOwner', variantName, new GLib.VariantType('(s)'),
|
||||
Gio.DBusCallFlags.NONE, -1, cancellable)).deep_unpack();
|
||||
|
||||
return unique;
|
||||
}
|
||||
|
||||
export async function getBusNames(bus, cancellable) {
|
||||
if (!bus)
|
||||
bus = Gio.DBus.session;
|
||||
|
||||
const [names] = (await bus.call('org.freedesktop.DBus', '/', 'org.freedesktop.DBus',
|
||||
'ListNames', null, new GLib.VariantType('(as)'), Gio.DBusCallFlags.NONE,
|
||||
-1, cancellable)).deep_unpack();
|
||||
|
||||
const uniqueNames = new Map();
|
||||
const requests = names.map(name => getUniqueBusName(bus, name, cancellable));
|
||||
const results = await Promise.allSettled(requests);
|
||||
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
const result = results[i];
|
||||
if (result.status === 'fulfilled') {
|
||||
let namesForBus = uniqueNames.get(result.value);
|
||||
if (!namesForBus) {
|
||||
namesForBus = new Set();
|
||||
uniqueNames.set(result.value, namesForBus);
|
||||
}
|
||||
if (result.value !== names[i])
|
||||
namesForBus.add(names[i]);
|
||||
} else if (!result.reason.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||
Logger.debug(`Impossible to get the unique name of ${names[i]}: ${result.reason}`);
|
||||
}
|
||||
}
|
||||
|
||||
return uniqueNames;
|
||||
}
|
||||
|
||||
async function getProcessId(connectionName, cancellable = null, bus = Gio.DBus.session) {
|
||||
const res = await bus.call('org.freedesktop.DBus', '/',
|
||||
'org.freedesktop.DBus', 'GetConnectionUnixProcessID',
|
||||
new GLib.Variant('(s)', [connectionName]),
|
||||
new GLib.VariantType('(u)'),
|
||||
Gio.DBusCallFlags.NONE,
|
||||
-1,
|
||||
cancellable);
|
||||
const [pid] = res.deepUnpack();
|
||||
return pid;
|
||||
}
|
||||
|
||||
export async function getProcessName(connectionName, cancellable = null,
|
||||
priority = GLib.PRIORITY_DEFAULT, bus = Gio.DBus.session) {
|
||||
const pid = await getProcessId(connectionName, cancellable, bus);
|
||||
const cmdFile = Gio.File.new_for_path(`/proc/${pid}/cmdline`);
|
||||
const inputStream = await cmdFile.read_async(priority, cancellable);
|
||||
const bytes = await inputStream.read_bytes_async(2048, priority, cancellable);
|
||||
const textDecoder = new TextDecoder();
|
||||
return textDecoder.decode(bytes.toArray().map(v => !v ? 0x20 : v));
|
||||
}
|
||||
|
||||
export async function* introspectBusObject(bus, name, cancellable,
|
||||
interfaces = undefined, path = undefined) {
|
||||
if (!path)
|
||||
path = '/';
|
||||
|
||||
const [introspection] = (await bus.call(name, path, 'org.freedesktop.DBus.Introspectable',
|
||||
'Introspect', null, new GLib.VariantType('(s)'), Gio.DBusCallFlags.NONE,
|
||||
5000, cancellable)).deep_unpack();
|
||||
|
||||
const nodeInfo = Gio.DBusNodeInfo.new_for_xml(introspection);
|
||||
|
||||
if (!interfaces || dbusNodeImplementsInterfaces(nodeInfo, interfaces))
|
||||
yield {nodeInfo, path};
|
||||
|
||||
if (path === '/')
|
||||
path = '';
|
||||
|
||||
for (const subNodeInfo of nodeInfo.nodes) {
|
||||
const subPath = `${path}/${subNodeInfo.path}`;
|
||||
yield* introspectBusObject(bus, name, cancellable, interfaces, subPath);
|
||||
}
|
||||
}
|
||||
|
||||
function dbusNodeImplementsInterfaces(nodeInfo, interfaces) {
|
||||
if (!(nodeInfo instanceof Gio.DBusNodeInfo) || !Array.isArray(interfaces))
|
||||
return false;
|
||||
|
||||
return interfaces.some(iface => nodeInfo.lookup_interface(iface));
|
||||
}
|
||||
Reference in New Issue
Block a user