From 6382a5a7c370d5299985580d96d7fcb682b526be Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 14 May 2023 14:00:12 +0900 Subject: [PATCH] Add set/add tags keys --- ...g.gnome.shell.extensions.fairy.gschema.xml | 77 +++++++++++++++++++ sources/keybinds.js | 63 +++++++++++---- sources/renderer.js | 42 ++++++++-- 3 files changed, 162 insertions(+), 20 deletions(-) diff --git a/schemas/org.gnome.shell.extensions.fairy.gschema.xml b/schemas/org.gnome.shell.extensions.fairy.gschema.xml index 343da56..0652ad7 100644 --- a/schemas/org.gnome.shell.extensions.fairy.gschema.xml +++ b/schemas/org.gnome.shell.extensions.fairy.gschema.xml @@ -87,6 +87,83 @@ Swap the current window with the master + + 1']]]> + Set the current's monitor tag to 1 + + + 2']]]> + Set the current's monitor tag to 2 + + + 3']]]> + Set the current's monitor tag to 3 + + + 4']]]> + Set the current's monitor tag to 4 + + + 5']]]> + Set the current's monitor tag to 5 + + + 6']]]> + Set the current's monitor tag to 6 + + + 7']]]> + Set the current's monitor tag to 7 + + + 8']]]> + Set the current's monitor tag to 8 + + + 9']]]> + Set the current's monitor tag to 9 + + + 0']]]> + Activate all the tags available on the current monitor + + + + 1']]]> + add the current's monitor tag to 1 + + + 2']]]> + add the current's monitor tag to 2 + + + 3']]]> + add the current's monitor tag to 3 + + + 4']]]> + add the current's monitor tag to 4 + + + 5']]]> + add the current's monitor tag to 5 + + + 6']]]> + add the current's monitor tag to 6 + + + 7']]]> + add the current's monitor tag to 7 + + + 8']]]> + add the current's monitor tag to 8 + + + 9']]]> + add the current's monitor tag to 9 + diff --git a/sources/keybinds.js b/sources/keybinds.js index 79be195..de5340b 100644 --- a/sources/keybinds.js +++ b/sources/keybinds.js @@ -39,16 +39,6 @@ var KeyboardManager = GObject.registerClass( Main.wm.removeKeybinding(key); } - _switchLayout(mode) { - const mon = global.display.get_current_monitor(); - const state = this._state.monitors[mon]; - const currentLayout = state.layout; - if (state.layout === mode) state.layout = state.oldLayout; - else state.layout = mode; - state.oldLayout = currentLayout; - this._renderer.render(mon); - } - enable() { this._addBinding("set-layout-tiling", () => this._switchLayout("tiling")); this._addBinding("set-layout-monocle", () => @@ -118,13 +108,42 @@ var KeyboardManager = GObject.registerClass( const idx = this._state.workIndexByHandle(state.focused); // if the master is not focused - if (idx !== 0) - this._state.swap(mon, state.tags, idx, 0) - else - this._state.swap(mon, state.tags, idx, state.beforeZoom); + if (idx !== 0) this._state.swap(mon, state.tags, idx, 0); + else this._state.swap(mon, state.tags, idx, state.beforeZoom); state.beforeZoom = idx; this._renderer.render(mon); }); + + for (const tagNbr = 1; tagNbr < 10; tagNbr++) { + const tag = 0b1 << tagNbr; + + this._addBinding(`set-tag-${tagNbr}`, () => { + const mon = global.display.get_current_monitor(); + this._renderer.setTags(mon, tag); + }); + this._addBinding(`add-tag-${tagNbr}`, () => { + const mon = global.display.get_current_monitor(); + const currTags = this._state.monitors[mon].tags; + // Add the tag to the monitor but if the tag is already present, remove it + // Do not allow 0 tags to be present. + this._renderer.setTags( + mon, + currTags & tag && currTags !== tag + ? currTags & ~tag + : currTags | tag + ); + }); + } + this._addBinding("set-tag-all", () => { + const mon = global.display.get_current_monitor(); + + const takkenTags = 0; + for (const i = 0; i < this._state.monitors.length; i++) + takkenTags |= this._state.monitors[i]; + + this._state.monitors[mon].tags |= ~takkenTags; + this._renderer.render(mon); + }); } disable() { @@ -143,6 +162,22 @@ var KeyboardManager = GObject.registerClass( this._removeBinding("swap-next"); this._removeBinding("swap-prev"); this._removeBinding("zoom"); + + for (const i = 1; i < 10; i++) { + this._removeBinding(`set-tag-${i}`); + this._removeBinding(`add-tag-${i}`); + } + this._removeBinding("set-tag-all"); + } + + _switchLayout(mode) { + const mon = global.display.get_current_monitor(); + const state = this._state.monitors[mon]; + const currentLayout = state.layout; + if (state.layout === mode) state.layout = state.oldLayout; + else state.layout = mode; + state.oldLayout = currentLayout; + this._renderer.render(mon); } } ); diff --git a/sources/renderer.js b/sources/renderer.js index b2dcc04..9c5a92d 100644 --- a/sources/renderer.js +++ b/sources/renderer.js @@ -141,8 +141,7 @@ var Renderer = GObject.registerClass( log("Switch to tags", tags); if (Meta.prefs_get_workspaces_only_on_primary()) { const primaryMon = global.display.get_primary_monitor(); - this._state.monitors[primaryMon].tags = tags; - this.render(primaryMon, tags); + this.setTag(primaryMon, tags); } else { for (let i = 0; i < this._state.monitors.length; i++) { this._state.monitors[i].tags = tags; @@ -188,13 +187,44 @@ var Renderer = GObject.registerClass( this._state.newWindow(window); } + setTag(mon, tags) { + const currTags = this._state.monitors[mon].tags; + this._state.monitors[mon].tags = tags; + this._setGWorkspaceIfNeeded(mon); + + for (const i = 0; i < this._state.monitors.length; i++) { + if (this._state.monitors[i] & tags && mon !== i) { + // Remove the selected tag from other monitors. + // If the other monitor had only this tag, swap monitor's tags instead. + this._state.monitors[i] = this._state.monitors[i] & ~tags || currTags; + this._setGWorkspaceIfNeeded(i); + this.render(i); + } + } + + this.render(mon); + } + + _setGWorkspaceIfNeeded(mon) { + if (mon !== global.display.get_primary_monitor()) return; + + const tags = this._state.monitors[mon].tags; + // This retrieve the lower tag present in the tags set. + const tag = (tags & ~(tags - 1)); + if (tags !== tag) return; + // Retrieve the gnome workspace for the tag (inverse of 0b1 << tag) + const workspace = Math.log2(tag) + 1; + + global.display + .get_workspace_manager() + .get_workspace_by_index(workspace) + .activate(global.display.get_current_time()); + } + renderAll() { const monN = global.display.get_n_monitors(); - // TODO: Support different tags on different monitors. - const tags = - global.display.get_workspace_manager().get_active_workspace_index() + 1; for (let mon = 0; mon < monN; mon++) { - this.render(mon, tags); + this.render(mon, this._state.monitors[mon].tags); } }