Skip to content

Commit

Permalink
refactor: refactor the dbus directory
Browse files Browse the repository at this point in the history
- Move the dbus directory to preferences/window_picker since it's only
  used for window picking within preferences.
- Simplify some of the code.
- Add documentation comments and explain the purpose of the dbus
  service.
  • Loading branch information
flexagoon committed Aug 19, 2024
1 parent 98096c7 commit 5018872
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 152 deletions.
47 changes: 0 additions & 47 deletions src/dbus/client.ts

This file was deleted.

94 changes: 0 additions & 94 deletions src/dbus/services.ts

This file was deleted.

12 changes: 6 additions & 6 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import {WindowPreview} from 'resource:///org/gnome/shell/ui/windowPreview.js';
import {WorkspaceAnimationController} from 'resource:///org/gnome/shell/ui/workspaceAnimation.js';

// local modules
import {Services} from './dbus/services.js';
import {LinearFilterEffect} from './effect/linear_filter_effect.js';
import {disableEffect, enableEffect} from './manager/event_manager.js';
import {WindowPicker} from './preferences/window_picker/service.js';
import {connections} from './utils/connections.js';
import {constants, SHADOW_PADDING} from './utils/constants.js';
import {_log, stackMsg} from './utils/log.js';
Expand All @@ -32,7 +32,7 @@ export default class RoundedWindowCornersReborn extends Extension {
private _orig_prep_workspace_swt!: (workspaceIndices: number[]) => void;
private _orig_finish_workspace_swt!: typeof WorkspaceAnimationController.prototype._finishWorkspaceSwitch;

private _services: Services | null = null;
private _windowPicker: WindowPicker | null = null;

enable() {
init_settings(this.getSettings());
Expand All @@ -45,9 +45,9 @@ export default class RoundedWindowCornersReborn extends Extension {
this._orig_finish_workspace_swt =
WorkspaceAnimationController.prototype._finishWorkspaceSwitch;

this._services = new Services();
this._windowPicker = new WindowPicker();

this._services.export();
this._windowPicker.export();

// Enable rounded corners effects when gnome-shell is ready
//
Expand Down Expand Up @@ -291,15 +291,15 @@ export default class RoundedWindowCornersReborn extends Extension {
// Remove the item to open preferences page in background menu
UI.RestoreBackgroundMenu();

this._services?.unexport();
this._windowPicker?.unexport();
disableEffect();

// Disconnect all signals in global connections.get()
connections.get().disconnect_all();
connections.del();

// Set all props to null
this._services = null;
this._windowPicker = null;

_log('Disabled');

Expand Down
4 changes: 2 additions & 2 deletions src/preferences/widgets/app_row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk';

import {gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
import {on_picked, pick} from '../../dbus/client.js';
import {onPicked, pick} from '../window_picker/client.js';
import {connections} from '../../utils/connections.js';

export class AppRowClass extends Adw.ExpanderRow {
Expand Down Expand Up @@ -84,7 +84,7 @@ export class AppRowClass extends Adw.ExpanderRow {
}

on_pick(entry: Adw.EntryRow) {
on_picked(wm_instance_class => {
onPicked(wm_instance_class => {
if (wm_instance_class === 'window-not-found') {
const win = this.root as unknown as Adw.PreferencesDialog;
win.add_toast(
Expand Down
21 changes: 21 additions & 0 deletions src/preferences/window_picker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# `window_picker`

The extensions preferences window runs in a separate isolated process which has
no access to GNOME Shell methods. However, the window picking functionality is
based on GNOME Shell's Looking Glass.

To allow the preferences window to communicate with the main process, the code
in this directory creates a DBus service, which has a method to open the window
picker and a signal to transmit the class of the selected window.

## `iface.xml`

Defines the DBus interface for the window picker.

## `service.ts`

Contains the implementation of the DBus interface.

## `client.ts`

Provides wrapper JavaScript functions around the DBus method calls.
49 changes: 49 additions & 0 deletions src/preferences/window_picker/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @file This file provides wrapper functions around the DBus window picker
* interface.
*/

import Gio from 'gi://Gio';

const connection = Gio.DBus.session;
const busName = 'org.gnome.Shell';
const interfaceName = 'org.gnome.Shell.Extensions.RoundedWindowCorners';
const objectPath = '/org/gnome/shell/extensions/RoundedWindowCorners';

/** Open the window picker and select a window. */
export function pick() {
connection.call(
busName,
objectPath,
interfaceName,
'pick',
null,
null,
Gio.DBusCallFlags.NO_AUTO_START,
-1,
null,
null,
);
}

/**
* Connect a callback to the `picked` signal, which is emitted when a window
* is picked.
*
* @param callback - The function to execute when the window is picked.
*/
export function onPicked(callback: (wmInstanceClass: string) => void) {
const id = connection.signal_subscribe(
busName,
interfaceName,
'picked',
objectPath,
null,
Gio.DBusSignalFlags.NONE,
(_conn, _sender, _objectPath, _iface, _signal, params) => {
const val = params.get_child_value(0);
callback(val.get_string()[0]);
connection.signal_unsubscribe(id);
},
);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<node>
<interface name="org.gnome.Shell.Extensions.RoundedWindowCorners">
<!-- This method is called in preferences to pick a window -->
<method name="pick" />
<!-- If window is picked, send a signal to preferences -->
<signal name="picked">
<arg name="window" type="s"/>
<arg name="window" type="s" />
</signal>
</interface>
</node>
91 changes: 91 additions & 0 deletions src/preferences/window_picker/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* @file This file contains the implementation of the DBus interface for the
* window picker. See the {@link WindowPicker} class for more information.
*/

import GLib from 'gi://GLib';
import Gio from 'gi://Gio';
import Meta from 'gi://Meta';

import {Inspector} from 'resource:///org/gnome/shell/ui/lookingGlass.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';

import {loadFile} from '../../utils/io.js';
import {_log} from '../../utils/log.js';

const iface = loadFile(import.meta.url, 'iface.xml');

/**
* This class provides the implementation of the DBus interface for the window
* picker. It implements a single method - `pick` - which opens the window picker
* and allows the user to select a window.
*/
export class WindowPicker {
#dbus = Gio.DBusExportedObject.wrapJSObject(iface, this);

/** Emit the wm_class of the picked window to the `picked` signal. */
#sendPickedWindow(wmClass: string) {
this.#dbus.emit_signal('picked', new GLib.Variant('(s)', [wmClass]));
}

/**
* Open the window picker and select a window.
*
* This uses the window picker from GNOME's Looking Glass. This is the
* easiest way to pick a window, and this is also what's used by other
* extensions such as Blur my Shell.
*/
pick() {
const lookingGlass = Main.createLookingGlass();
const inspector = new Inspector(lookingGlass);

inspector.connect('target', (me, target, x, y) => {
_log(`${me}: pick ${target} in ${x}, ${y}`);

// Remove the red border effect when the window is picked.
const effectName = 'lookingGlass_RedBorderEffect';
for (const effect of target.get_effects()) {
if (effect.toString().includes(effectName)) {
target.remove_effect(effect);
}
}

let actor = target;

// If the picked actor is not a Meta.WindowActor, which happens
// often since it's usually a Meta.SurfaceActor, try to find its
// parent which is a Meta.WindowActor.
for (let i = 0; i < 2; i++) {
if (actor == null || actor instanceof Meta.WindowActor) {
break;
}
actor = actor.get_parent();
}

if (!(actor instanceof Meta.WindowActor)) {
this.#sendPickedWindow('window-not-found');
return;
}

this.#sendPickedWindow(
actor.metaWindow.get_wm_class_instance() ?? 'window-not-found',
);
});

inspector.connect('closed', () => {
lookingGlass.close();
});
}

export() {
this.#dbus.export(
Gio.DBus.session,
'/org/gnome/shell/extensions/RoundedWindowCorners',
);
_log('DBus Service exported');
}

unexport() {
this.#dbus.unexport();
}
}

0 comments on commit 5018872

Please sign in to comment.