From c7a59ca04896ec92d08c8b2704fc916f585c166a Mon Sep 17 00:00:00 2001 From: tom Date: Mon, 1 Jul 2024 08:17:15 +0100 Subject: [PATCH] CHANGE: working detection of maximised, no auto add of windows --- Makefile | 5 +- extension.ts | 166 +++++++++++++++++++++++++++++++------------------ floatbar.zip | Bin 3039 -> 3665 bytes stylesheet.css | 9 +++ 4 files changed, 117 insertions(+), 63 deletions(-) create mode 100644 stylesheet.css diff --git a/Makefile b/Makefile index 7d9ae7f..c9c1b0f 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,13 @@ node_modules: package.json dist/extension.js dist/prefs.js: node_modules tsc +dist/stylesheet.css: stylesheet.css + cp stylesheet.css dist/ + schemas/gschemas.compiled: schemas/org.gnome.shell.extensions.$(NAME).gschema.xml glib-compile-schemas schemas -$(NAME).zip: dist/extension.js dist/prefs.js schemas/gschemas.compiled +$(NAME).zip: dist/extension.js dist/prefs.js dist/stylesheet.css schemas/gschemas.compiled @cp -r schemas dist/ @cp metadata.json dist/ @(cd dist && zip ../$(NAME).zip -9r .) diff --git a/extension.ts b/extension.ts index 1656f20..14f1825 100644 --- a/extension.ts +++ b/extension.ts @@ -5,82 +5,124 @@ 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"; -import { Button as PanelMenuButton } from "resource:///org/gnome/shell/ui/panelMenu.js"; - -const MyIndicator = GObject.registerClass( - class MyIndicator extends SystemIndicator { - _indicator: any; - _settings?: Gio.Settings; - constructor(extensioObject: Extension) { - super(); - - this._indicator = this._addIndicator(); - this._indicator.icon_name = "selection-mode-symbolic"; - - this._settings = extensioObject.getSettings(); - this._settings!.bind("float", this._indicator, "active", Gio.SettingsBindFlags.DEFAULT); - - this.quickSettingsItems.push(this._indicator); - } - } -); - -const ExampleToggle = GObject.registerClass( - class ExampleToggle extends QuickMenuToggle { - _settings: Gio.Settings; - constructor(extensionObject: Extension) { - super({ - title: "Float", - subtitle: "Floating Window", - iconName: "selection-mode-symbolic", - toggleMode: true, - }); - - this._settings = extensionObject.getSettings(); - this._settings.bind("float", this, "checked", Gio.SettingsBindFlags.DEFAULT); - } - } -); export default class MyExtension extends Extension { - _button?: PanelMenuButton; - indicator?: SystemIndicator; + button?: PanelMenuButton; settings?: Gio.Settings; + float: boolean = false; + updateFloat: EventEmitter = new EventEmitter(); + + _actorSignalIds: Map = new Map(); + _windowSignalIds: Map = new Map(); enable() { - const icon = new St.Icon({ - icon_name: "face-laugh-symbolic", - style_class: "system-status-icon", - }); + // this.button = new ToggleButton(this); - this._button = new PanelMenuButton(0.0, this.metadata.name, false); - this._button.add_child(icon); - this.settings = this.getSettings(); + // 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._button.connect("button-press-event", () => this.toggleFloat()); - this._button.connect("touch-event", () => this.toggleFloat()); + this._actorSignalIds.set(Main.sessionMode, [Main.sessionMode.connect("updated", () => this._updateFloating.bind(this))]); - // this._button.addChild(); - // this.indicator = new MyIndicator(this); - // this.indicator.quickSettingsItems.push(new ExampleToggle(this)); + for (const window_actor of global.get_window_actors()) { + this._onWindowActorAdded(window_actor); + } - // Main.panel.statusArea.quickSettings.addExternalIndicator(this.indicator); - Main.panel.addToStatusArea(this.uuid, this._button); - } + 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)), + ]); - toggleFloat() { - let bool = this.getSettings().get_boolean("float"); - console.log(bool); - this.getSettings().set_boolean("float", !bool); + this._actorSignalIds.set(global.window_manager, [global.window_manager.connect("switch-workspace", this._updateFloating.bind(this))]); } disable() { - this._button?.destroy(); - this._button = undefined; - // this.indicator?.quickSettingsItems.forEach((item) => item.destroy()); - // this.indicator?.destroy(); - // this.indicator = undefined; + 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()); + // } + } + } +); diff --git a/floatbar.zip b/floatbar.zip index deca3d323bd188c62cf002fe1b26037edd02a3b7..0eda8a0b4df2caaaa99bd6f06c4acd981a6b7414 100644 GIT binary patch delta 1809 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 PU;{!~V9B$F6T|}mfP?|y diff --git a/stylesheet.css b/stylesheet.css new file mode 100644 index 0000000..11b31f5 --- /dev/null +++ b/stylesheet.css @@ -0,0 +1,9 @@ +#panel.floating { + margin: 3px; + border-radius: 9999px; +} + +#panel.solid { + margin: 0; + border-radius: 0; +}