import GLib from "gi://GLib"; import Gio from "gi://Gio"; import Meta from "gi://Meta"; import St from "gi://St"; import Shell from "gi://Shell"; import * as Main from "resource:///org/gnome/shell/ui/main.js"; import { Extension } from "resource:///org/gnome/shell/extensions/extension.js"; import { Button as PanelMenuButton } from "resource:///org/gnome/shell/ui/panelMenu.js"; import { EventEmitter } from "resource:///org/gnome/shell/misc/signals.js"; import { SystemIndicator, QuickMenuToggle } from "resource:///org/gnome/shell/ui/quickSettings.js"; import GObject from "gi://GObject"; export default class MyExtension extends Extension { button?: PanelMenuButton; settings?: Gio.Settings; float: boolean = false; updateFloat: EventEmitter = new EventEmitter(); _actorSignalIds: Map = new Map(); _windowSignalIds: Map = new Map(); enable() { // 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); } this._actorSignalIds.set(global.window_group, [ global.window_group.connect("actor-added", this._onWindowActorAdded.bind(this)), global.window_group.connect("actor-removed", this._onWindowActorRemoved.bind(this)), ]); 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) { actor.disconnect(signalId); } } } this._actorSignalIds.clear(); this._windowSignalIds.clear(); this._setFloat(false); } _onWindowActorAdded(metaWindowActor: Meta.WindowActor) { this._windowSignalIds.set(metaWindowActor, [ metaWindowActor.connect("notify::allocation", this._updateFloating.bind(this)), metaWindowActor.connect("notify::visible", this._updateFloating.bind(this)), metaWindowActor.connect("destroy", () => this._onWindowActorRemoved.bind(this, metaWindowActor)), ]); } _onWindowActorRemoved(metaWindowActor: Meta.WindowActor) { for (const signalId of this._windowSignalIds.get(metaWindowActor)) { metaWindowActor.disconnect(signalId); } this._windowSignalIds.delete(metaWindowActor); this._updateFloating(); } _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(); }); for (let win of windows) { console.log("================== Window ================"); console.log(win.title); console.log(win.maximizedHorizontally); //switch } const maximized = windows.some((metaWindow) => { return metaWindow.maximizedHorizontally; }); this._setFloat(!maximized); } _setFloat(float: boolean) { console.log("Float: ", float); Main.panel.add_style_class_name(float ? "floating" : "solid"); Main.panel.remove_style_class_name(float ? "solid" : "floating"); } } const ToggleButton = GObject.registerClass( class ToggleButton extends PanelMenuButton { _extension: MyExtension; constructor(extension: MyExtension) { super(0.0, extension.metadata.name, false); let icon = new St.Icon({ icon_name: "face-laugh-symbolic", style_class: "system-status-icon", }); this._extension = extension; this.add_child(icon); this.connect("button-press-event", () => this.toggleFloat()); this.connect("touch-event", () => this.toggleFloat()); } toggleFloat() { this._extension.float = !this._extension.float; this._extension.updateFloat.emit("update"); this._extension._updateFloating(); // for (const window of global.get_window_actors()) { // console.log(window.get_parent()); // } } } );