From 7286c71da5caad5e37a068e36a6660f6da643313 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 13 May 2023 15:58:13 +0900 Subject: [PATCH] Add floating layout --- prefs.js | 4 +++ ...g.gnome.shell.extensions.fairy.gschema.xml | 12 ++++----- sources/keybinds.js | 25 +++++++++++++++-- sources/renderer.js | 27 ++++++++++++++----- sources/state.js | 12 +++++++-- 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/prefs.js b/prefs.js index 60eda68..d2568f5 100644 --- a/prefs.js +++ b/prefs.js @@ -51,6 +51,10 @@ function fillPreferencesWindow(window) { const tileBindings = new Adw.PreferencesGroup(); keybinds.add(tileBindings); + tileBindings.add(_createKeybind(settings, "set-layout-tiling")); + tileBindings.add(_createKeybind(settings, "set-layout-monocle")); + tileBindings.add(_createKeybind(settings, "set-layout-floating")); + tileBindings.add(_createKeybind(settings, "incrmfact")); tileBindings.add(_createKeybind(settings, "decmfact")); tileBindings.add(_createKeybind(settings, "incrnmaster")); diff --git a/schemas/org.gnome.shell.extensions.fairy.gschema.xml b/schemas/org.gnome.shell.extensions.fairy.gschema.xml index 35d4244..826a494 100644 --- a/schemas/org.gnome.shell.extensions.fairy.gschema.xml +++ b/schemas/org.gnome.shell.extensions.fairy.gschema.xml @@ -55,6 +55,11 @@ j']]]> Cycle prev + + ']]]> + Swap the current window with the master + + l']]]> @@ -70,15 +75,10 @@ Increase the number of windows in the master area - d']]]> + o']]]> Decrease the number of windows in the master area - - ']]]> - Swap the current window with the master - - diff --git a/sources/keybinds.js b/sources/keybinds.js index ad76fed..55efeab 100644 --- a/sources/keybinds.js +++ b/sources/keybinds.js @@ -12,7 +12,6 @@ var KeyboardManager = GObject.registerClass( super._init(); this._state = state; this._renderer = renderer; - // TODO: Handle rerender from here. } /** @@ -41,6 +40,25 @@ var KeyboardManager = GObject.registerClass( } enable() { + this._addBinding("set-layout-tiling", () => { + const mon = global.display.get_current_monitor(); + const state = this._state.monitors[mon]; + state.layout = "tiling"; + this._renderer.render(mon); + }); + this._addBinding("set-layout-monocle", () => { + const mon = global.display.get_current_monitor(); + const state = this._state.monitors[mon]; + state.layout = "monocle"; + this._renderer.render(mon); + }); + this._addBinding("set-layout-floating", () => { + const mon = global.display.get_current_monitor(); + const state = this._state.monitors[mon]; + state.layout = "floating"; + this._renderer.render(mon); + }); + this._addBinding("incrmfact", () => { const mon = global.display.get_current_monitor(); const state = this._state.monitors[mon]; @@ -68,9 +86,12 @@ var KeyboardManager = GObject.registerClass( } disable() { + this._removeBinding("set-layout-tiling"); + this._removeBinding("set-layout-monocle"); + this._removeBinding("set-layout-floating"); + this._removeBinding("incrmfact"); this._removeBinding("decrmfact"); - this._removeBinding("incrnmaster"); this._removeBinding("decrnmaster"); } diff --git a/sources/renderer.js b/sources/renderer.js index 0551984..e113e8f 100644 --- a/sources/renderer.js +++ b/sources/renderer.js @@ -161,6 +161,8 @@ var Renderer = GObject.registerClass( window._signals = [ window.connect("unmanaging", (window) => { window._isInvalid = true; + const faWindow = this._state.popByActor(actor); + if (faWindow) this.render(faWindow.monitor, faWindow.tags); }), window.connect("workspace-changed", (window) => { if (!this._isValidWindow(window)) return; @@ -168,14 +170,18 @@ var Renderer = GObject.registerClass( if (oldW) this.render(oldW.monitor, oldW.tags); if (newW) this.render(newW.monitor, newW.tags); }), - ]; - const actor = window.get_compositor_private(); - actor._signals = [ - actor.connect("destroy", (actor) => { - const faWindow = this._state.popByActor(actor); - if (faWindow) this.render(faWindow.monitor, faWindow.tags); + window.connect("focus", (window) => { + if (!this._isValidWindow(window)) return; + this._state.monitors[window.get_monitor()].focused = window; }), ]; + const actor = window.get_compositor_private(); + // actor._signals = [ + // actor.connect("destroy", (actor) => { + // const faWindow = this._state.popByActor(actor); + // if (faWindow) this.render(faWindow.monitor, faWindow.tags); + // }), + // ]; this._state.newWindow(window); } @@ -212,6 +218,9 @@ var Renderer = GObject.registerClass( for (const window of this._state.render(mon, tags)) { if (window.handle.get_monitor() !== mon) window.handle.move_to_monitor(mon); + + if (window.floating) continue; + if (window.handle.minimized !== window.minimized) { if (window.minimized) window.handle.minimize(); else window.handle.unminimize(); @@ -221,7 +230,11 @@ var Renderer = GObject.registerClass( window.handle["maximized-horizontally"] || window.handle["maximized-vertically"] != window.maximized ) { - if (window.maximized) window.handle.maximize(Meta.MaximizeFlags.BOTH); + if (window.maximized) { + window.handle.maximize(Meta.MaximizeFlags.BOTH); + // Do not resize if maximizing to keep the overview tiled. + continue; + } else window.handle.unmaximize(Meta.MaximizeFlags.BOTH); } diff --git a/sources/state.js b/sources/state.js index 129b369..fff60b4 100644 --- a/sources/state.js +++ b/sources/state.js @@ -13,7 +13,7 @@ var StateManager = GObject.registerClass( */ focused: null, tags: 1, - layout: "tiled", + layout: "tiling", nmaster: 1, mfact: 55, })); @@ -79,6 +79,9 @@ var StateManager = GObject.registerClass( * @property {number} y - in percentage from the top left * @property {number} width - in percentage (0-100) * @property {number} height - in percentage + * @property {boolean} minimized + * @property {boolean} maximized + * @property {boolean} floating * @returns WindowGeometry[] */ render(mon, tags) { @@ -102,7 +105,7 @@ var StateManager = GObject.registerClass( height: 100, }, ]; - case "tiled": + case "tiling": return windows.map((x, i) => { const stackLength = i < nmaster @@ -124,6 +127,11 @@ var StateManager = GObject.registerClass( height: 100 / stackLength, }; }); + case "floating": + return windows.map((x) => ({ + handle: x.handle, + floating: true, + })); default: return []; }