.dotfiles/.local/share/gnome-shell/extensions/blur-my-shell@aunetx/dbus/services.js

91 lines
3.0 KiB
JavaScript

import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as LookingGlass from 'resource:///org/gnome/shell/ui/lookingGlass.js';
export const ApplicationsService = class ApplicationsService {
constructor() {
let decoder = new TextDecoder();
let path = GLib.filename_from_uri(GLib.uri_resolve_relative(
import.meta.url, 'iface.xml', GLib.UriFlags.NONE)
)[0];
let [, buffer] = GLib.file_get_contents(path);
let iface = decoder.decode(buffer);
GLib.free(buffer);
this.DBusImpl = Gio.DBusExportedObject.wrapJSObject(iface, this);
}
/// Pick Window for Preferences Page, exported to DBus client.
pick() {
// emit `picking` signal to know we are listening
const send_picking_signal = _ =>
this.DBusImpl.emit_signal(
'picking',
null
);
// emit `picked` signal to send wm_class
const send_picked_signal = wm_class =>
this.DBusImpl.emit_signal(
'picked',
new GLib.Variant('(s)', [wm_class])
);
// notify the preferences that we are listening
send_picking_signal();
// A very interesting way to pick a window:
// 1. Open LookingGlass to mask all event handles of window
// 2. Use inspector to pick window, thats is also lookingGlass do
// 3. Close LookingGlass when done
// It will restore event handles of window
// open then hide LookingGlass
const looking_class = Main.createLookingGlass();
looking_class.open();
looking_class.hide();
// inspect window now
const inspector = new LookingGlass.Inspector(Main.createLookingGlass());
inspector.connect('target', (me, target, x, y) => {
// remove border effect when window is picked.
const effect_name = 'lookingGlass_RedBorderEffect';
target
.get_effects()
.filter(e => e.toString().includes(effect_name))
.forEach(e => target.remove_effect(e));
// get wm_class_instance property of window, then pass it to DBus
// client
const type_str = target.toString();
let actor = target;
if (type_str.includes('MetaSurfaceActor'))
actor = target.get_parent();
if (!actor.toString().includes('WindowActor'))
return send_picked_signal('window-not-found');
send_picked_signal(
actor.meta_window.get_wm_class() ?? 'window-not-found'
);
});
// close LookingGlass when we're done
inspector.connect('closed', _ => looking_class.close());
}
export() {
this.DBusImpl.export(
Gio.DBus.session,
'/dev/aunetx/BlurMyShell'
);
};
unexport() {
this.DBusImpl.unexport();
}
};