Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions lib/extension/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,40 @@ export class Node extends GObject.Object {
resetLayoutSingleChild() {
let tabbedOrStacked = this.isTabbed() || this.isStacked();
if (tabbedOrStacked && this.singleOrNoChild()) {
this.layout = LAYOUT_TYPES.HSPLIT;
this.restoreSplitLayout(LAYOUT_TYPES.HSPLIT);
}
}

get layout() {
return this._layout;
}

/**
* A split container that becomes a tabbed or stacked group remembers its split direction
* (`splitLayout`), wherever that happens, so that leaving the group can restore it.
*/
set layout(value) {
const split = this._layout === LAYOUT_TYPES.HSPLIT || this._layout === LAYOUT_TYPES.VSPLIT;
if (split && (value === LAYOUT_TYPES.TABBED || value === LAYOUT_TYPES.STACKED)) {
this.splitLayout = this._layout;
}
this._layout = value;
}

/**
* Make this container a tabbed or stacked group; `remember = false` for a container just
* created for the group, whose split direction means nothing yet.
*/
setGroupLayout(layout, remember = true) {
this.layout = layout;
if (!remember) this.splitLayout = null;
}

/** Leave a tabbed or stacked group: back to the split direction it had, else `fallback`. */
restoreSplitLayout(fallback) {
this.layout = this.splitLayout ?? fallback;
}

singleOrNoChild() {
return this.childNodes.length <= 1;
}
Expand Down Expand Up @@ -1256,7 +1286,7 @@ export class Tree extends Node {
parentNode.layout === LAYOUT_TYPES.TABBED &&
parentNode.childNodes.length === 1
) {
parentNode.layout = this.extWm.determineSplitLayout();
parentNode.restoreSplitLayout(this.extWm.determineSplitLayout());
this.resetSiblingPercent(parentNode);
parentNode.lastTabFocus = null;
}
Expand Down
32 changes: 21 additions & 11 deletions lib/extension/window.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,15 +321,15 @@ export class WindowManager extends GObject.Object {
let stackedNodes = this.tree.getNodeByLayout(LAYOUT_TYPES.STACKED);
stackedNodes.forEach((node) => {
node.prevLayout = node.layout;
node.layout = this.determineSplitLayout();
node.restoreSplitLayout(this.determineSplitLayout());
});
} else {
let hSplitNodes = this.tree.getNodeByLayout(LAYOUT_TYPES.HSPLIT);
let vSplitNodes = this.tree.getNodeByLayout(LAYOUT_TYPES.VSPLIT);
Array.prototype.push.apply(hSplitNodes, vSplitNodes);
hSplitNodes.forEach((node) => {
if (node.prevLayout && node.prevLayout === LAYOUT_TYPES.STACKED) {
node.layout = LAYOUT_TYPES.STACKED;
node.setGroupLayout(LAYOUT_TYPES.STACKED);
}
});
}
Expand All @@ -340,15 +340,15 @@ export class WindowManager extends GObject.Object {
let tabbedNodes = this.tree.getNodeByLayout(LAYOUT_TYPES.TABBED);
tabbedNodes.forEach((node) => {
node.prevLayout = node.layout;
node.layout = this.determineSplitLayout();
node.restoreSplitLayout(this.determineSplitLayout());
});
} else {
let hSplitNodes = this.tree.getNodeByLayout(LAYOUT_TYPES.HSPLIT);
let vSplitNodes = this.tree.getNodeByLayout(LAYOUT_TYPES.VSPLIT);
Array.prototype.push.apply(hSplitNodes, vSplitNodes);
hSplitNodes.forEach((node) => {
if (node.prevLayout && node.prevLayout === LAYOUT_TYPES.TABBED) {
node.layout = LAYOUT_TYPES.TABBED;
node.setGroupLayout(LAYOUT_TYPES.TABBED);
}
});
}
Expand Down Expand Up @@ -640,20 +640,25 @@ export class WindowManager extends GObject.Object {
if (!focusNodeWindow) return;
if (!this.ext.settings.get_boolean("stacked-tiling-mode-enabled")) return;

if (focusNodeWindow.parentNode.isMonitor()) {
// A window directly on the workspace gets a container of its own first; that container's
// direction isn't the user's, so it isn't remembered
const parentBefore = focusNodeWindow.parentNode;
if (parentBefore.isMonitor()) {
this.tree.split(focusNodeWindow, ORIENTATION_TYPES.HORIZONTAL, true);
}
// (a floating window isn't wrapped: then its parent, the monitor, keeps its direction)
const wrapped = focusNodeWindow.parentNode !== parentBefore;

currentLayout = focusNodeWindow.parentNode.layout;

if (currentLayout === LAYOUT_TYPES.STACKED) {
focusNodeWindow.parentNode.layout = this.determineSplitLayout();
focusNodeWindow.parentNode.restoreSplitLayout(this.determineSplitLayout());
this.tree.resetSiblingPercent(focusNodeWindow.parentNode);
} else {
if (currentLayout === LAYOUT_TYPES.TABBED) {
focusNodeWindow.parentNode.lastTabFocus = null;
}
focusNodeWindow.parentNode.layout = LAYOUT_TYPES.STACKED;
focusNodeWindow.parentNode.setGroupLayout(LAYOUT_TYPES.STACKED, !wrapped);
let lastChild = focusNodeWindow.parentNode.lastChild;
if (lastChild.nodeType === NODE_TYPES.WINDOW) {
lastChild.nodeValue.activate(global.display.get_current_time());
Expand All @@ -667,18 +672,23 @@ export class WindowManager extends GObject.Object {
if (!focusNodeWindow) return;
if (!this.ext.settings.get_boolean("tabbed-tiling-mode-enabled")) return;

if (focusNodeWindow.parentNode.isMonitor()) {
// A window directly on the workspace gets a container of its own first; that container's
// direction isn't the user's, so it isn't remembered
const parentBeforeTabs = focusNodeWindow.parentNode;
if (parentBeforeTabs.isMonitor()) {
this.tree.split(focusNodeWindow, ORIENTATION_TYPES.HORIZONTAL, true);
}
// (a floating window isn't wrapped: then its parent, the monitor, keeps its direction)
const wrappedForTabs = focusNodeWindow.parentNode !== parentBeforeTabs;

currentLayout = focusNodeWindow.parentNode.layout;

if (currentLayout === LAYOUT_TYPES.TABBED) {
focusNodeWindow.parentNode.layout = this.determineSplitLayout();
focusNodeWindow.parentNode.restoreSplitLayout(this.determineSplitLayout());
this.tree.resetSiblingPercent(focusNodeWindow.parentNode);
focusNodeWindow.parentNode.lastTabFocus = null;
} else {
focusNodeWindow.parentNode.layout = LAYOUT_TYPES.TABBED;
focusNodeWindow.parentNode.setGroupLayout(LAYOUT_TYPES.TABBED, !wrappedForTabs);
focusNodeWindow.parentNode.lastTabFocus = focusNodeWindow.nodeValue;
}
this.unfreezeRender();
Expand Down Expand Up @@ -2242,7 +2252,7 @@ export class WindowManager extends GObject.Object {
} else if (isTop || isBottom) {
childNode.layout = LAYOUT_TYPES.VSPLIT;
} else if (isCenter) {
childNode.layout = LAYOUT_TYPES[centerLayout];
childNode.setGroupLayout(LAYOUT_TYPES[centerLayout], false); // a new container
}
} else if (childNode.detachWindow) {
const orientation =
Expand Down