mirror of
https://github.com/zoriya/fairy.git
synced 2025-12-06 05:36:09 +00:00
Add move/add tags for windows
This commit is contained in:
@@ -164,6 +164,81 @@
|
||||
<default><![CDATA[['<Super><Ctrl>9']]]></default>
|
||||
<summary>add the current's monitor tag to 9</summary>
|
||||
</key>
|
||||
<!-- TODO: Add fullscreen, monitors and tags key -->
|
||||
|
||||
<key type="as" name="moveto-tag-1">
|
||||
<default><![CDATA[['<Super><Shift>1']]]></default>
|
||||
<summary>Move the selected window to the tag 1</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-2">
|
||||
<default><![CDATA[['<Super><Shift>2']]]></default>
|
||||
<summary>Move the selected window to the tag 2</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-3">
|
||||
<default><![CDATA[['<Super><Shift>3']]]></default>
|
||||
<summary>Move the selected window to the tag 3</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-4">
|
||||
<default><![CDATA[['<Super><Shift>4']]]></default>
|
||||
<summary>Move the selected window to the tag 4</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-5">
|
||||
<default><![CDATA[['<Super><Shift>5']]]></default>
|
||||
<summary>Move the selected window to the tag 5</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-6">
|
||||
<default><![CDATA[['<Super><Shift>6']]]></default>
|
||||
<summary>Move the selected window to the tag 6</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-7">
|
||||
<default><![CDATA[['<Super><Shift>7']]]></default>
|
||||
<summary>Move the selected window to the tag 7</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-8">
|
||||
<default><![CDATA[['<Super><Shift>8']]]></default>
|
||||
<summary>Move the selected window to the tag 8</summary>
|
||||
</key>
|
||||
<key type="as" name="moveto-tag-9">
|
||||
<default><![CDATA[['<Super><Shift>9']]]></default>
|
||||
<summary>Move the selected window to the tag 9</summary>
|
||||
</key>
|
||||
|
||||
<key type="as" name="addto-tag-1">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>1']]]></default>
|
||||
<summary>Add the selected window to the tag 1</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-2">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>2']]]></default>
|
||||
<summary>Add the selected window to the tag 2</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-3">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>3']]]></default>
|
||||
<summary>Add the selected window to the tag 3</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-4">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>4']]]></default>
|
||||
<summary>Add the selected window to the tag 4</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-5">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>5']]]></default>
|
||||
<summary>Add the selected window to the tag 5</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-6">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>6']]]></default>
|
||||
<summary>Add the selected window to the tag 6</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-7">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>7']]]></default>
|
||||
<summary>Add the selected window to the tag 7</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-8">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>8']]]></default>
|
||||
<summary>Add the selected window to the tag 8</summary>
|
||||
</key>
|
||||
<key type="as" name="addto-tag-9">
|
||||
<default><![CDATA[['<Super><Ctrl><Shift>9']]]></default>
|
||||
<summary>Add the selected window to the tag 9</summary>
|
||||
</key>
|
||||
|
||||
<!-- TODO: Add fullscreen, monitors -->
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
||||
@@ -53,15 +53,10 @@ var KeyboardManager = GObject.registerClass(
|
||||
const state = this._state.monitors[mon];
|
||||
const idx = this._state.workIndexByHandle(state.focused);
|
||||
const newW = this._state.workIndex(mon, state.tags, idx + 1);
|
||||
this._state.focus(newW.handle);
|
||||
});
|
||||
this._addBinding("cycle-next", () => {
|
||||
const mon = global.display.get_current_monitor();
|
||||
const state = this._state.monitors[mon];
|
||||
const idx = this._state.workIndexByHandle(state.focused);
|
||||
const win = this._state.workIndex(mon, state.tags, idx - 1);
|
||||
this._state.focus(win.handle);
|
||||
if (newW && newW.handle !== state.focused)
|
||||
this._state.focus(newW.handle);
|
||||
});
|
||||
this._addBinding("cycle-next", () => this._focusNext());
|
||||
|
||||
this._addBinding("incrmfact", () => {
|
||||
const mon = global.display.get_current_monitor();
|
||||
@@ -114,14 +109,14 @@ var KeyboardManager = GObject.registerClass(
|
||||
this._renderer.render(mon);
|
||||
});
|
||||
|
||||
for (const tagNbr = 1; tagNbr < 10; tagNbr++) {
|
||||
for (let tagNbr = 0; tagNbr < 9; tagNbr++) {
|
||||
const tag = 0b1 << tagNbr;
|
||||
|
||||
this._addBinding(`set-tag-${tagNbr}`, () => {
|
||||
this._addBinding(`set-tag-${tagNbr + 1}`, () => {
|
||||
const mon = global.display.get_current_monitor();
|
||||
this._renderer.setTags(mon, tag);
|
||||
});
|
||||
this._addBinding(`add-tag-${tagNbr}`, () => {
|
||||
this._addBinding(`add-tag-${tagNbr + 1}`, () => {
|
||||
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
|
||||
@@ -133,12 +128,29 @@ var KeyboardManager = GObject.registerClass(
|
||||
: currTags | tag
|
||||
);
|
||||
});
|
||||
this._addBinding(`moveto-tag-${tagNbr + 1}`, () => {
|
||||
const mon = global.display.get_current_monitor();
|
||||
const handle = this._state.monitors[mon].focused;
|
||||
const window = this._state.windows.find((x) => x.handle === handle);
|
||||
this._focusNext();
|
||||
window.tags = tag;
|
||||
window.handle.change_workspace_by_index(tagNbr, false);
|
||||
this._renderer.renderAll();
|
||||
});
|
||||
this._addBinding(`addto-tag-${tagNbr + 1}`, () => {
|
||||
const mon = global.display.get_current_monitor();
|
||||
const handle = this._state.monitors[mon].focused;
|
||||
const window = this._state.windows.find((x) => x.handle === handle);
|
||||
if (window.tags & tag) window.tags &= ~tag;
|
||||
else window.tags |= tag;
|
||||
this._renderer.renderAll();
|
||||
});
|
||||
}
|
||||
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++)
|
||||
for (let i = 0; i < this._state.monitors.length; i++)
|
||||
takkenTags |= this._state.monitors[i];
|
||||
|
||||
this._state.monitors[mon].tags |= ~takkenTags;
|
||||
@@ -163,11 +175,14 @@ var KeyboardManager = GObject.registerClass(
|
||||
this._removeBinding("swap-prev");
|
||||
this._removeBinding("zoom");
|
||||
|
||||
for (const i = 1; i < 10; i++) {
|
||||
for (let i = 1; i < 10; i++) {
|
||||
this._removeBinding(`set-tag-${i}`);
|
||||
this._removeBinding(`add-tag-${i}`);
|
||||
this._removeBinding(`moveto-tag-${i}`);
|
||||
this._removeBinding(`addto-tag-${i}`);
|
||||
}
|
||||
this._removeBinding("set-tag-all");
|
||||
this._removeBinding("moveto-tag-all");
|
||||
}
|
||||
|
||||
_switchLayout(mode) {
|
||||
@@ -179,5 +194,13 @@ var KeyboardManager = GObject.registerClass(
|
||||
state.oldLayout = currentLayout;
|
||||
this._renderer.render(mon);
|
||||
}
|
||||
|
||||
_focusNext() {
|
||||
const mon = global.display.get_current_monitor();
|
||||
const state = this._state.monitors[mon];
|
||||
const idx = this._state.workIndexByHandle(state.focused);
|
||||
const win = this._state.workIndex(mon, state.tags, idx - 1);
|
||||
if (win && win.handle !== state.focused) this._state.focus(win.handle);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -141,11 +141,11 @@ 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.setTag(primaryMon, tags);
|
||||
this.setTags(primaryMon, tags);
|
||||
} else {
|
||||
for (let i = 0; i < this._state.monitors.length; i++) {
|
||||
this._state.monitors[i].tags = tags;
|
||||
this.render(i, tags);
|
||||
this.render(i);
|
||||
}
|
||||
}
|
||||
}),
|
||||
@@ -153,13 +153,13 @@ var Renderer = GObject.registerClass(
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Meta.Window} window
|
||||
* @param {Meta.Window} handle
|
||||
*/
|
||||
trackWindow(window) {
|
||||
if (!this._isValidWindow(window)) return;
|
||||
trackWindow(handle) {
|
||||
if (!this._isValidWindow(handle)) return;
|
||||
// Add window signals
|
||||
window._signals = [
|
||||
window.connect("unmanaging", (handle) => {
|
||||
handle._signals = [
|
||||
handle.connect("unmanaging", (handle) => {
|
||||
handle._isInvalid = true;
|
||||
const idx = this._state.workIndexByHandle(handle);
|
||||
const faWindow = this._state.popByHandle(handle);
|
||||
@@ -170,29 +170,34 @@ var Renderer = GObject.registerClass(
|
||||
const newWindow = this._state.workIndex(faWindow.monitor, tags, idx);
|
||||
if (newWindow) this._state.focus(newWindow.handle);
|
||||
|
||||
this.render(faWindow.monitor, tags);
|
||||
this.render(faWindow.monitor);
|
||||
}),
|
||||
window.connect("workspace-changed", (window) => {
|
||||
if (!this._isValidWindow(window)) return;
|
||||
const [oldW, newW] = this._state.updateByHandle(window);
|
||||
if (oldW) this.render(oldW.monitor, oldW.tags);
|
||||
if (newW) this.render(newW.monitor, newW.tags);
|
||||
handle.connect("workspace-changed", (handle) => {
|
||||
log("Workspace changed for window");
|
||||
if (handle._ignoreWorkspaceChange) {
|
||||
handle._ignoreWorkspaceChange = false;
|
||||
return;
|
||||
}
|
||||
if (!this._isValidWindow(handle)) return;
|
||||
const [oldW, newW] = this._state.updateByHandle(handle);
|
||||
if (oldW) this.render(oldW.monitor);
|
||||
if (newW) this.render(newW.monitor);
|
||||
}),
|
||||
window.connect("focus", (window) => {
|
||||
if (!this._isValidWindow(window)) return;
|
||||
this._state.monitors[window.get_monitor()].focused = window;
|
||||
handle.connect("focus", (handle) => {
|
||||
if (!this._isValidWindow(handle)) return;
|
||||
this._state.monitors[handle.get_monitor()].focused = handle;
|
||||
}),
|
||||
];
|
||||
|
||||
this._state.newWindow(window);
|
||||
this._state.newWindow(handle);
|
||||
}
|
||||
|
||||
setTag(mon, tags) {
|
||||
setTags(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++) {
|
||||
for (let 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.
|
||||
@@ -213,7 +218,8 @@ var Renderer = GObject.registerClass(
|
||||
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;
|
||||
const workspace = Math.log2(tag);
|
||||
console.log("Switching to", tags, tag, workspace)
|
||||
|
||||
global.display
|
||||
.get_workspace_manager()
|
||||
@@ -224,7 +230,7 @@ var Renderer = GObject.registerClass(
|
||||
renderAll() {
|
||||
const monN = global.display.get_n_monitors();
|
||||
for (let mon = 0; mon < monN; mon++) {
|
||||
this.render(mon, this._state.monitors[mon].tags);
|
||||
this.render(mon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,10 +241,9 @@ var Renderer = GObject.registerClass(
|
||||
|
||||
/**
|
||||
* @param {number} mon
|
||||
* @param {number?} tags
|
||||
*/
|
||||
render(mon, tags) {
|
||||
if (!tags) tags = this._state.monitors[mon].tags;
|
||||
render(mon) {
|
||||
const tags = this._state.monitors[mon].tags;
|
||||
|
||||
// We don't care which workspace it is, we just want the geometry
|
||||
// for the current monitor without the panel.
|
||||
@@ -246,10 +251,21 @@ var Renderer = GObject.registerClass(
|
||||
.get_workspace_manager()
|
||||
.get_active_workspace()
|
||||
.get_work_area_for_monitor(mon);
|
||||
const workIdx = global.display
|
||||
.get_workspace_manager()
|
||||
.get_active_workspace_index();
|
||||
|
||||
for (const window of this._state.render(mon, tags)) {
|
||||
if (window.handle.get_monitor() !== mon)
|
||||
window.handle.move_to_monitor(mon);
|
||||
// if (!(window.tags & 0b1 << workIdx) || window.currentWorkspace !== workIdx) {
|
||||
if (window.handle.get_workspace().index() !== workIdx) {
|
||||
// The window is visible because another tag as been bringed
|
||||
// so we need to ask gnome to move windows (temporarly to the current workspace)
|
||||
log("Invalid workspace", window.tags, 0b1 << workIdx);
|
||||
window.handle._ignoreWorkspaceChange = true;
|
||||
window.handle.change_workspace_by_index(workIdx, true);
|
||||
}
|
||||
|
||||
if (window.floating) continue;
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ const GObject = imports.gi.GObject;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
|
||||
var StateManager = GObject.registerClass(
|
||||
class StateManager extends GObject.Object {
|
||||
_init() {
|
||||
@@ -146,8 +145,8 @@ var StateManager = GObject.registerClass(
|
||||
if (newIdx < 0) newIdx = windows.length + newIdx;
|
||||
newIdx %= windows.length;
|
||||
|
||||
const gIdx = this.windows.findIndex(x => x === windows[idx]);
|
||||
const gNewIdx = this.windows.findIndex(x => x === windows[newIdx]);
|
||||
const gIdx = this.windows.findIndex((x) => x === windows[idx]);
|
||||
const gNewIdx = this.windows.findIndex((x) => x === windows[newIdx]);
|
||||
|
||||
const tmp = this.windows[gIdx];
|
||||
this.windows[gIdx] = this.windows[gNewIdx];
|
||||
@@ -180,9 +179,13 @@ var StateManager = GObject.registerClass(
|
||||
// TODO: Implement other layouts
|
||||
switch (layout) {
|
||||
case "monocle":
|
||||
const focused = this.windows.find(
|
||||
(x) => x.handle === this.monitors[mon].focused
|
||||
);
|
||||
return [
|
||||
{
|
||||
handle: this.monitors[mon].focused,
|
||||
...focused,
|
||||
handle: focused.hanlde,
|
||||
maximized: true,
|
||||
minimized: false,
|
||||
x: 0,
|
||||
@@ -199,6 +202,7 @@ var StateManager = GObject.registerClass(
|
||||
: windows.length - nmaster;
|
||||
const stackIndex = i < nmaster ? i : i - nmaster;
|
||||
return {
|
||||
...x,
|
||||
handle: x.handle,
|
||||
maximized: false,
|
||||
minimized: false,
|
||||
@@ -215,6 +219,7 @@ var StateManager = GObject.registerClass(
|
||||
});
|
||||
case "floating":
|
||||
return windows.map((x) => ({
|
||||
...x,
|
||||
handle: x.handle,
|
||||
floating: true,
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user