Skip to content
Draft
2 changes: 2 additions & 0 deletions scratch.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ function makeScratch(metaWindow) {

metaWindow[float] = true;
metaWindow.make_above();
let space = Tiling.spaces.spaceOfWindow(metaWindow);
space.removeWindow(metaWindow);
metaWindow.stick(); // NB! Removes the window from the tiling (synchronously)

if (!metaWindow.minimized)
Expand Down
107 changes: 85 additions & 22 deletions tiling.js
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,20 @@ class Space extends Array {
}

addWindow(metaWindow, index, row) {
log(`add window`, metaWindow.title);
if (!this.selectedWindow)
this.selectedWindow = metaWindow;
if (this.indexOf(metaWindow) !== -1)
if (this.indexOf(metaWindow) !== -1) {
log(`already added window`, metaWindow.title);
return false;
}

let space = spaces.spaceOfWindow(metaWindow);
if (space.indexOf(metaWindow) !== -1 && space._populated) {
space.removeWindow(metaWindow);
}

metaWindow._workspace = this.workspace;

if (row !== undefined && this[index]) {
let column = this[index];
Expand All @@ -588,6 +598,7 @@ class Space extends Array {
let index = this.indexOf(metaWindow);
if (index === -1)
return this.removeFloating(metaWindow);
metaWindow._workspace = null;

let selected = this.selectedWindow;
if (selected === metaWindow) {
Expand Down Expand Up @@ -616,12 +627,12 @@ class Space extends Array {
if (actor)
actor.remove_clip();

this.layout();
if (selected) {
ensureViewport(selected, this);
this.selectedWindow = selected;
} else {
this.selectedWindow = null;
}
this.layout();

this.emit('window-removed', metaWindow, index, row);
return true;
Expand Down Expand Up @@ -762,6 +773,10 @@ class Space extends Array {
return -1;
}

includes(metaWindow) {
return metaWindow._workspace === this.workspace;
}

rowOf(metaWindow) {
let column = this[this.indexOf(metaWindow)];
return column.indexOf(metaWindow);
Expand All @@ -771,7 +786,6 @@ class Space extends Array {
if (this.cloneContainer.x !== this.targetX ||
this.actor.y !== 0 ||
Navigator.navigating || inPreview ||
Main.overview.visible ||
// Only block on grab if we haven't detached the window yet
(inGrab && !inGrab.workspace)
) {
Expand Down Expand Up @@ -819,7 +833,7 @@ class Space extends Array {
const ch = Math.max(0, monitor.y + monitor.height - b.y - y);
actor.set_clip(x, y, cw, ch);

showWindow(w);
!Main.overview.visible && showWindow(w);
});

this._floating.forEach(showWindow);
Expand Down Expand Up @@ -1114,16 +1128,20 @@ box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, .7);
Scratch.makeScratch(meta_window);
return;
}
if(this.indexOf(meta_window) < 0 && add_filter(meta_window)) {
if(this.includes(meta_window) && add_filter(meta_window)) {
this.addWindow(meta_window, this.length);
}
})

let tabList = display.get_tab_list(Meta.TabList.NORMAL, workspace)
.filter(metaWindow => { return this.indexOf(metaWindow) !== -1; });
if (tabList[0]) {
this.selectedWindow = tabList[0]
// ensureViewport(space.selectedWindow, space);
if (oldSpace) {
this.selectedWindow = oldSpace.selectedWindow;
} else {
let tabList = display.get_tab_list(Meta.TabList.NORMAL, workspace)
.filter(metaWindow => { return this.indexOf(metaWindow) !== -1; });
if (tabList[0]) {
this.selectedWindow = tabList[0]
// ensureViewport(space.selectedWindow, space);
}
}
}

Expand Down Expand Up @@ -1420,6 +1438,9 @@ class Spaces extends Map {
for (let [workspace, space] of this) {
if (workspaces[space.workspace] !== true) {
debug('workspace removed', space.workspace);
space.getWindows().forEach(mw => {
space.removeWindow(mw);
});
this.removeSpace(space);

// Maps in javascript (and thus Spaces) remember insertion order
Expand Down Expand Up @@ -1746,7 +1767,10 @@ class Spaces extends Map {
};

spaceOfWindow(meta_window) {
return this.get(meta_window.get_workspace());
let workspace = meta_window._workspace;
if (!workspace)
workspace = meta_window.get_workspace();
return this.get(workspace);
};

spaceOf(workspace) {
Expand Down Expand Up @@ -2018,16 +2042,16 @@ function add_filter(meta_window) {
Handle windows leaving workspaces.
*/
function remove_handler(workspace, meta_window) {
debug("window-removed", meta_window, meta_window.title, workspace.index());
log("window-removed", meta_window, meta_window.title, workspace.index());
// Note: If `meta_window` was closed and had focus at the time, the next
// window has already received the `focus` signal at this point.
// Not sure if we can check directly if _this_ window had focus when closed.

let space = spaces.spaceOf(workspace);
space.removeWindow(meta_window);

let actor = meta_window.get_compositor_private();
if (!actor) {
let space = spaces.spaceOf(workspace);
space.removeWindow(meta_window);

signals.disconnect(meta_window);
if (meta_window.clone && meta_window.clone.mapped) {
meta_window.clone.destroy();
Expand Down Expand Up @@ -2065,13 +2089,15 @@ function add_handler(ws, metaWindow) {
created to ensure that the WindowActor exists.
*/
function insertWindow(metaWindow, {existing}) {
log("insert-window", metaWindow.title, metaWindow.on_all_workspaces, existing);

// Add newly created windows to the space being previewed
if (!existing &&
!metaWindow.is_on_all_workspaces() &&
metaWindow.get_workspace() !== spaces.selectedSpace.workspace) {
metaWindow.redirected = true;
metaWindow.change_workspace(spaces.selectedSpace.workspace);
log(`redirect`, metaWindow.title);
return;
}

Expand All @@ -2086,6 +2112,7 @@ function insertWindow(metaWindow, {existing}) {
};

if (!existing) {

// Note: Can't trust global.display.focus_window to determine currently focused window.
// The mru is more flexible. (global.display.focus_window does not always agree with mru[0])
let mru = display.get_tab_list(Meta.TabList.NORMAL_ALL, null);
Expand Down Expand Up @@ -2122,20 +2149,39 @@ function insertWindow(metaWindow, {existing}) {
}
}

if (metaWindow.is_on_all_workspaces()) {
// Windows on all workspaces are a bit wonky
if (metaWindow.on_all_workspaces) {
// Only connect the necessary signals and show windows on shared
// secondary monitors.
log(metaWindow.title, 'on all', metaWindow.on_all_workspaces);
let space = spaces.spaceOfWindow(metaWindow);
if (space.includes(metaWindow)) {
return;
}
connectSizeChanged();
showWindow(metaWindow);
return;
} else if (Scratch.isScratchWindow(metaWindow)){
log(`make scratch stuck`);
// And make sure scratch windows are stuck
Scratch.makeScratch(metaWindow);
return;
}

let space = spaces.spaceOfWindow(metaWindow);
// We now handle windows that are on only one workspace

/*
The window might have moved workspaces, while still being tiled on an old
space.

Since we delay removing tiled windows until it's added to another space we
need to look at what _workspace_ the window is on, not which _space_.
*/
let workspace = metaWindow.get_workspace();
let space = spaces.spaceOf(workspace);
log(`workspace`, space.actor, workspace.index());
if (!add_filter(metaWindow)) {
log('add floating', metaWindow.title);
connectSizeChanged();
space.addFloating(metaWindow);
showWindow(metaWindow);
Expand All @@ -2144,8 +2190,10 @@ function insertWindow(metaWindow, {existing}) {
return;
}

if (space.indexOf(metaWindow) !== -1)
if (space.indexOf(metaWindow) !== -1) {
log(`window already tiled on`, space.actor);
return;
}

let clone = metaWindow.clone;
let ok, x, y;
Expand Down Expand Up @@ -2355,6 +2403,7 @@ function grabBegin(metaWindow, type) {
return;
let space = spaces.spaceOfWindow(metaWindow);
inGrab = {window: metaWindow};
metaWindow.raise();
if (!space || space.indexOf(metaWindow) === -1)
return;
space.startAnimate();
Expand Down Expand Up @@ -2410,7 +2459,7 @@ function getGrab(space, anchor) {

// `MetaWindow::focus` handling
function focus_handler(metaWindow, user_data) {
debug("focus:", metaWindow.title, utils.framestr(metaWindow.get_frame_rect()));
log("focus:", metaWindow.title, utils.framestr(metaWindow.get_frame_rect()));

if (metaWindow.fullscreen) {
TopBar.hide();
Expand All @@ -2431,6 +2480,12 @@ function focus_handler(metaWindow, user_data) {
}

let space = spaces.spaceOfWindow(metaWindow);
// Do not act on stuck windows when switching to an empty workspace
if (metaWindow.on_all_workspaces && space !== spaces.selectedSpace &&
space.indexOf(metaWindow) !== -1)
{
return;
}
space.monitor.clickOverlay.show();

/**
Expand Down Expand Up @@ -2491,9 +2546,9 @@ var minimizeWrapper = utils.dynamic_function_ref('minimizeHandler', Me);
*/
function showHandler(actor) {
let metaWindow = actor.meta_window;
let onActive = metaWindow.get_workspace() === workspaceManager.get_active_workspace();
let onActive = spaces.spaceOfWindow(metaWindow).workspace === workspaceManager.get_active_workspace();

if (!metaWindow.clone.get_parent() && !metaWindow.unmapped)
if (!metaWindow.clone || (!metaWindow.clone.get_parent() && !metaWindow.unmapped))
return;

// HACK: use opacity instead of hidden on new windows
Expand Down Expand Up @@ -2939,3 +2994,11 @@ function cycleWorkspaceSettings(dir=1) {
function defwinprop(...args) {
return Settings.defwinprop(...args);
}


function repl() {
metaWindow.get_workspace().index()
spaces.spaceOfWindow()
metaWindow._workspace.index()
metaWindow._workspace.index()
}