@ -31,43 +31,23 @@ var badBadWindowsEffect = {
var screenGeo = effects . virtualScreenGeometry ;
var xOffset = screenGeo . width / 16 ;
var yOffset = screenGeo . height / 16 ;
for ( var i = 0 ; i < stackingOrder . length ; ++ i ) {
var w = stackingOrder [ i ] ;
if ( showing ) {
var closestWindows = [ undefined , undefined , undefined , undefined ] ;
var movedWindowsCount = 0 ;
for ( var i = 0 ; i < stackingOrder . length ; ++ i ) {
var w = stackingOrder [ i ] ;
// ignore windows above the desktop (when not showing, pretty much everything would be)
if ( w . desktopWindow && showing )
break ;
// ignore invisible windows and such that do not have to be restored
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 ;
}
if ( ! showing && w . offToCornerId === undefined ) {
continue ;
}
// ignore windows above the desktop
// (when not showing, pretty much everything would be)
if ( w . desktopWindow )
break ;
// keep windows above the desktop visually
effects . setElevatedWindow ( w , showing ) ;
// ignore invisible windows and such that do not have to be restored
if ( ! w . visible )
continue ;
// we just fade out docks - moving panels into edges looks dull
if ( w . dock ) {
if ( showing ) {
// we just fade out docks - moving panels into edges looks dull
if ( w . dock ) {
w . offToCornerId = set ( {
window : w ,
duration : badBadWindowsEffect . duration ,
@ -76,32 +56,101 @@ var badBadWindowsEffect = {
to : 0.0
} ]
} ) ;
} else {
cancel ( w . offToCornerId ) ;
delete w . offToCornerId ;
animate ( {
window : w ,
duration : badBadWindowsEffect . duration ,
animations : [ {
type : Effect . Opacity ,
from : 0.0
} ]
} ) ;
continue ;
}
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 ) ;
delete w . offToCornerId ;
delete w . apertureCorner ; // should not exist, but better safe than sorry.
animate ( {
window : w ,
duration : badBadWindowsEffect . duration ,
animations : [ {
type : Effect . Opacity ,
from : 0.0
} ]
} ) ;
continue ;
}
// calculate the closest corner
var anchor , tx , ty ;
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 ;
anchor = Effect . Left ;
} else {
tx = xOffset ;
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 ;
anchor |= Effect . Top ;
} else {
@ -126,22 +175,24 @@ var badBadWindowsEffect = {
} else {
cancel ( w . offToCornerId ) ;
delete w . offToCornerId ;
animate ( {
window : w ,
duration : badBadWindowsEffect . duration ,
curve : QEasingCurve . InOutQuad ,
animations : [ {
type : Effect . Position ,
sourceAnchor : anchor ,
from : { value1 : tx , value2 : ty }
} , {
type : Effect . Opacity ,
from : 0.2
} ]
} ) ;
delete w . apertureCorner ;
if ( w . visible ) { // could meanwhile have been hidden
animate ( {
window : w ,
duration : badBadWindowsEffect . duration ,
curve : QEasingCurve . InOutQuad ,
animations : [ {
type : Effect . Position ,
sourceAnchor : anchor ,
from : { value1 : tx , value2 : ty }
} , {
type : Effect . Opacity ,
from : 0.2
} ]
} ) ;
}
}
}
} ,
init : function ( ) {
"use strict" ;