107 lines
3.7 KiB
TypeScript
107 lines
3.7 KiB
TypeScript
import Gio from "gi://Gio";
|
|
import Meta from "gi://Meta";
|
|
import Clutter from "gi://Clutter";
|
|
import { Extension } from "resource:///org/gnome/shell/extensions/extension.js";
|
|
import { EventEmitter } from "resource:///org/gnome/shell/misc/signals.js";
|
|
import * as Main from "resource:///org/gnome/shell/ui/main.js";
|
|
import { Button as PanelMenuButton } from "resource:///org/gnome/shell/ui/panelMenu.js";
|
|
|
|
export default class MyExtension extends Extension {
|
|
button?: PanelMenuButton;
|
|
settings?: Gio.Settings;
|
|
float: boolean = false;
|
|
updateFloat: EventEmitter = new EventEmitter();
|
|
|
|
_actorSignalIds?: Map<any, any>;
|
|
_windowSignalIds?: Map<string, any>;
|
|
|
|
_workspace?: Meta.Workspace;
|
|
|
|
enable() {
|
|
this._workspace = global.workspaceManager.get_active_workspace();
|
|
|
|
this._windowSignalIds = new Map();
|
|
this._actorSignalIds = new Map();
|
|
|
|
// this.button = new ToggleButton(this);
|
|
|
|
// Main.panel.addToStatusArea(this.uuid, this.button);
|
|
this._actorSignalIds.set(Main.overview, [
|
|
Main.overview.connect("showing", () => this._updateFloating.bind(this)),
|
|
Main.overview.connect("hiding", () => this._updateFloating.bind(this)),
|
|
]);
|
|
|
|
this._actorSignalIds.set(Main.sessionMode, [Main.sessionMode.connect("updated", () => this._updateFloating.bind(this))]);
|
|
|
|
for (const window_actor of global.get_window_actors()) {
|
|
this._onWindowActorAdded(window_actor.get_parent(), window_actor);
|
|
}
|
|
|
|
this._workspace.connect("window-added", (workspace, window) => {
|
|
setTimeout(() => {
|
|
console.log("window-added ", window.title);
|
|
this._onWindowActorAdded.bind(this)(workspace, window.get_compositor_private());
|
|
}, 10);
|
|
});
|
|
this._workspace.connect("window-removed", (workspace, window) => {
|
|
setTimeout(() => {
|
|
console.log("window-removed ", window.title);
|
|
this._onWindowActorRemoved.bind(this)(workspace, window.get_compositor_private());
|
|
}, 10);
|
|
});
|
|
|
|
this._actorSignalIds.set(global.window_manager, [global.window_manager.connect("switch-workspace", this._updateFloating.bind(this))]);
|
|
}
|
|
|
|
disable() {
|
|
// for (const actorSignalIds of [this._actorSignalIds, this._windowSignalIds]) {
|
|
// for (const [actor, signalIds] of actorSignalIds!) {
|
|
// for (const signalId of signalIds) {
|
|
// console.log("SignalID ", signalId);
|
|
// console.log("Actor ", actor instanceof Clutter.Actor);
|
|
// }
|
|
// }
|
|
// }
|
|
this._actorSignalIds?.clear();
|
|
this._windowSignalIds?.clear();
|
|
|
|
this._setFloat(false);
|
|
}
|
|
|
|
_onWindowActorAdded(container: any, metaWindowActor: Meta.WindowActor) {
|
|
if (metaWindowActor.metaWindow.skipTaskbar) return;
|
|
if (this._windowSignalIds === undefined) return;
|
|
this._windowSignalIds.set(metaWindowActor.metaWindow.title, [
|
|
metaWindowActor.connect("notify::allocation", this._updateFloating.bind(this)),
|
|
metaWindowActor.connect("notify::visible", this._updateFloating.bind(this)),
|
|
]);
|
|
}
|
|
|
|
_onWindowActorRemoved(container: any, metaWindowActor: Meta.WindowActor) {
|
|
if (this._windowSignalIds === undefined) return;
|
|
this._updateFloating();
|
|
for (const signalId of this._windowSignalIds.get(metaWindowActor.metaWindow.title)) {
|
|
metaWindowActor.disconnect(signalId);
|
|
}
|
|
this._windowSignalIds.delete("test");
|
|
}
|
|
|
|
_updateFloating() {
|
|
const workspace_manager = global.workspaceManager;
|
|
const active_workspace = workspace_manager.get_active_workspace();
|
|
const windows = active_workspace.list_windows().filter((metaWindow) => {
|
|
return !metaWindow.skip_taskbar && metaWindow.showing_on_its_workspace() && !metaWindow.is_hidden();
|
|
});
|
|
const maximized = windows.some((metaWindow) => {
|
|
return metaWindow.maximizedHorizontally;
|
|
});
|
|
|
|
this._setFloat(!maximized);
|
|
}
|
|
|
|
_setFloat(float: boolean) {
|
|
Main.panel.add_style_class_name(float ? "floating" : "solid");
|
|
Main.panel.remove_style_class_name(float ? "solid" : "floating");
|
|
}
|
|
}
|