evenly distribute windows into all corners
If the user has only maximized windows or all windows crammed into one region of the screen the effect would not resemble an aperture at all this ensures a maximum amount of corners is used while seeking to still use shortest paths BUG: 348709 FIXED-IN: 5.4
This commit is contained in:
parent
e830f08def
commit
cc9a95df5d
1 changed files with 114 additions and 63 deletions
|
@ -31,43 +31,23 @@ var badBadWindowsEffect = {
|
||||||
var screenGeo = effects.virtualScreenGeometry;
|
var screenGeo = effects.virtualScreenGeometry;
|
||||||
var xOffset = screenGeo.width / 16;
|
var xOffset = screenGeo.width / 16;
|
||||||
var yOffset = screenGeo.height / 16;
|
var yOffset = screenGeo.height / 16;
|
||||||
|
if (showing) {
|
||||||
|
var closestWindows = [ undefined, undefined, undefined, undefined ];
|
||||||
|
var movedWindowsCount = 0;
|
||||||
for (var i = 0; i < stackingOrder.length; ++i) {
|
for (var i = 0; i < stackingOrder.length; ++i) {
|
||||||
var w = stackingOrder[i];
|
var w = stackingOrder[i];
|
||||||
|
|
||||||
// ignore windows above the desktop (when not showing, pretty much everything would be)
|
// ignore windows above the desktop
|
||||||
if (w.desktopWindow && showing)
|
// (when not showing, pretty much everything would be)
|
||||||
|
if (w.desktopWindow)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ignore invisible windows and such that do not have to be restored
|
// ignore invisible windows and such that do not have to be restored
|
||||||
if (!w.visible) {
|
if (!w.visible)
|
||||||
if (!(showing || w.offToCornerId === undefined)) { // we still need to stop this
|
|
||||||
cancel(w.offToCornerId);
|
|
||||||
delete w.offToCornerId;
|
|
||||||
effects.setElevatedWindow(w, false);
|
|
||||||
if (!w.dock) {
|
|
||||||
animate({
|
|
||||||
window: w,
|
|
||||||
duration: badBadWindowsEffect.duration,
|
|
||||||
animations: [{
|
|
||||||
type: Effect.Opacity,
|
|
||||||
from: 0.2,
|
|
||||||
to: 0.0
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (!showing && w.offToCornerId === undefined) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// keep windows above the desktop visually
|
|
||||||
effects.setElevatedWindow(w, showing);
|
|
||||||
|
|
||||||
// we just fade out docks - moving panels into edges looks dull
|
// we just fade out docks - moving panels into edges looks dull
|
||||||
if (w.dock) {
|
if (w.dock) {
|
||||||
if (showing) {
|
|
||||||
w.offToCornerId = set({
|
w.offToCornerId = set({
|
||||||
window: w,
|
window: w,
|
||||||
duration: badBadWindowsEffect.duration,
|
duration: badBadWindowsEffect.duration,
|
||||||
|
@ -76,9 +56,80 @@ var badBadWindowsEffect = {
|
||||||
to: 0.0
|
to: 0.0
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the corner distances
|
||||||
|
var geo = w.geometry;
|
||||||
|
var dl = geo.x + geo.width - screenGeo.x;
|
||||||
|
var dr = screenGeo.x + screenGeo.width - geo.x;
|
||||||
|
var dt = geo.y + geo.height - screenGeo.y;
|
||||||
|
var db = screenGeo.y + screenGeo.height - geo.y;
|
||||||
|
w.apertureDistances = [ dl + dt, dr + dt, dr + db, dl + db ];
|
||||||
|
movedWindowsCount += 1;
|
||||||
|
|
||||||
|
// if this window is the closest one to any corner, set it as preferred there
|
||||||
|
var nearest = 0;
|
||||||
|
for (var j = 1; j < 4; ++j) {
|
||||||
|
if (w.apertureDistances[j] < w.apertureDistances[nearest] ||
|
||||||
|
(w.apertureDistances[j] == w.apertureDistances[nearest] && closestWindows[j] === undefined)) {
|
||||||
|
nearest = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (closestWindows[nearest] === undefined ||
|
||||||
|
closestWindows[nearest].apertureDistances[nearest] > w.apertureDistances[nearest])
|
||||||
|
closestWindows[nearest] = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// second pass, select corners
|
||||||
|
|
||||||
|
// 1st off, move the nearest windows to their nearest corners
|
||||||
|
// this will ensure that if there's only on window in the lower right
|
||||||
|
// it won't be moved out to the upper left
|
||||||
|
var movedWindowsDec = [ 0, 0, 0, 0 ];
|
||||||
|
for (var i = 0; i < 4; ++i) {
|
||||||
|
if (closestWindows[i] === undefined)
|
||||||
|
continue;
|
||||||
|
closestWindows[i].apertureCorner = i;
|
||||||
|
delete closestWindows[i].apertureDistances;
|
||||||
|
movedWindowsDec[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2nd, distribute the remainders according to their preferences
|
||||||
|
// this doesn't exactly have heapsort performance ;-)
|
||||||
|
movedWindowsCount = Math.floor((movedWindowsCount + 3) / 4);
|
||||||
|
for (var i = 0; i < 4; ++i) {
|
||||||
|
for (var j = 0; j < movedWindowsCount - movedWindowsDec[i]; ++j) {
|
||||||
|
var bestWindow = undefined;
|
||||||
|
for (var k = 0; k < stackingOrder.length; ++k) {
|
||||||
|
if (stackingOrder[k].apertureDistances === undefined)
|
||||||
|
continue;
|
||||||
|
if (bestWindow === undefined ||
|
||||||
|
stackingOrder[k].apertureDistances[i] < bestWindow.apertureDistances[i])
|
||||||
|
bestWindow = stackingOrder[k];
|
||||||
|
}
|
||||||
|
if (bestWindow === undefined)
|
||||||
|
break;
|
||||||
|
bestWindow.apertureCorner = i;
|
||||||
|
delete bestWindow.apertureDistances;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually re/move windows from/to assigned corners
|
||||||
|
for (var i = 0; i < stackingOrder.length; ++i) {
|
||||||
|
var w = stackingOrder[i];
|
||||||
|
if (w.apertureCorner === undefined && w.offToCornerId === undefined)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// keep windows above the desktop visually
|
||||||
|
effects.setElevatedWindow(w, showing);
|
||||||
|
|
||||||
|
if (!showing && w.dock) {
|
||||||
cancel(w.offToCornerId);
|
cancel(w.offToCornerId);
|
||||||
delete w.offToCornerId;
|
delete w.offToCornerId;
|
||||||
|
delete w.apertureCorner; // should not exist, but better safe than sorry.
|
||||||
animate({
|
animate({
|
||||||
window: w,
|
window: w,
|
||||||
duration: badBadWindowsEffect.duration,
|
duration: badBadWindowsEffect.duration,
|
||||||
|
@ -87,21 +138,19 @@ var badBadWindowsEffect = {
|
||||||
from: 0.0
|
from: 0.0
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
}
|
continue;
|
||||||
continue; // ! ;-)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the closest corner
|
|
||||||
var anchor, tx, ty;
|
var anchor, tx, ty;
|
||||||
var geo = w.geometry;
|
var geo = w.geometry;
|
||||||
if (screenGeo.x + screenGeo.width - geo.x < geo.x + geo.width - screenGeo.x) {
|
if (w.apertureCorner == 1 || w.apertureCorner == 2) {
|
||||||
tx = screenGeo.x + screenGeo.width - xOffset;
|
tx = screenGeo.x + screenGeo.width - xOffset;
|
||||||
anchor = Effect.Left;
|
anchor = Effect.Left;
|
||||||
} else {
|
} else {
|
||||||
tx = xOffset;
|
tx = xOffset;
|
||||||
anchor = Effect.Right;
|
anchor = Effect.Right;
|
||||||
}
|
}
|
||||||
if (screenGeo.y + screenGeo.height - geo.y < geo.y + geo.height - screenGeo.y) {
|
if (w.apertureCorner > 1) {
|
||||||
ty = screenGeo.y + screenGeo.height - yOffset;
|
ty = screenGeo.y + screenGeo.height - yOffset;
|
||||||
anchor |= Effect.Top;
|
anchor |= Effect.Top;
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,6 +175,8 @@ var badBadWindowsEffect = {
|
||||||
} else {
|
} else {
|
||||||
cancel(w.offToCornerId);
|
cancel(w.offToCornerId);
|
||||||
delete w.offToCornerId;
|
delete w.offToCornerId;
|
||||||
|
delete w.apertureCorner;
|
||||||
|
if (w.visible) { // could meanwhile have been hidden
|
||||||
animate({
|
animate({
|
||||||
window: w,
|
window: w,
|
||||||
duration: badBadWindowsEffect.duration,
|
duration: badBadWindowsEffect.duration,
|
||||||
|
@ -141,7 +192,7 @@ var badBadWindowsEffect = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
init: function () {
|
init: function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
Loading…
Reference in a new issue