Allow moving and resizing above the top of the screen again when doing

an unrestricted move or resize.

svn path=/trunk/KDE/kdebase/workspace/; revision=940697
icc-effect-5.14.5
Lucas Murray 2009-03-18 02:34:07 +00:00
parent 8c5e524769
commit c21bed5890
1 changed files with 119 additions and 113 deletions

View File

@ -2916,103 +2916,106 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
// adjust new size to snap to other windows/borders // adjust new size to snap to other windows/borders
moveResizeGeom = workspace()->adjustClientSize( this, moveResizeGeom, mode ); moveResizeGeom = workspace()->adjustClientSize( this, moveResizeGeom, mode );
// Make sure the titlebar isn't behind a restricted area. We don't need to restrict if(!unrestrictedMoveResize)
// the other directions. If not visible enough, move the window to the closest valid
// point. We bruteforce this by slowly moving the window back to its previous position.
for(;;)
{ {
QRegion titlebarRegion( moveResizeGeom.left(), moveResizeGeom.top(), // Make sure the titlebar isn't behind a restricted area. We don't need to restrict
moveResizeGeom.width(), frameTop ); // the other directions. If not visible enough, move the window to the closest valid
titlebarRegion &= workspace()->clientArea( FullArea, -1, 0 ); // On the screen // point. We bruteforce this by slowly moving the window back to its previous position.
titlebarRegion -= workspace()->restrictedMoveArea( desktop() ); // Strut areas for(;;)
// Now we have a region of all the visible areas of the titlebar
// Count the visible pixels and check to see if it's enough
int visiblePixels = 0;
foreach( const QRect& rect, titlebarRegion.rects() )
if( rect.height() >= frameTop ) // Only the full height regions, prevents long slim areas
visiblePixels += rect.width() * rect.height();
if( visiblePixels >= titlebarArea )
break; // We have reached a valid position
// Not visible enough, move the window to the closest valid point. We bruteforce
// this by slowly moving the window back to its previous position.
if( previousMoveResizeGeom.y() != moveResizeGeom.y() )
{ {
if( previousMoveResizeGeom.y() > moveResizeGeom.y() ) QRegion titlebarRegion( moveResizeGeom.left(), moveResizeGeom.top(),
moveResizeGeom.setTop( moveResizeGeom.y() + 1 ); moveResizeGeom.width(), frameTop );
else titlebarRegion &= workspace()->clientArea( FullArea, -1, 0 ); // On the screen
moveResizeGeom.setTop( moveResizeGeom.y() - 1 ); titlebarRegion -= workspace()->restrictedMoveArea( desktop() ); // Strut areas
} // Now we have a region of all the visible areas of the titlebar
else // Our heights match but we still don't have a valid area, maybe // Count the visible pixels and check to see if it's enough
{ // we are trying to resize in from the side? int visiblePixels = 0;
bool breakLoop = false; foreach( const QRect& rect, titlebarRegion.rects() )
switch( mode ) if( rect.height() >= frameTop ) // Only the full height regions, prevents long slim areas
visiblePixels += rect.width() * rect.height();
if( visiblePixels >= titlebarArea )
break; // We have reached a valid position
// Not visible enough, move the window to the closest valid point. We bruteforce
// this by slowly moving the window back to its previous position.
if( previousMoveResizeGeom.y() != moveResizeGeom.y() )
{ {
case PositionTopLeft: if( previousMoveResizeGeom.y() > moveResizeGeom.y() )
case PositionLeft: moveResizeGeom.setTop( moveResizeGeom.y() + 1 );
if( previousMoveResizeGeom.x() >= moveResizeGeom.x() ) else
{ moveResizeGeom.setTop( moveResizeGeom.y() - 1 );
breakLoop = true;
break;
}
moveResizeGeom.setLeft( moveResizeGeom.x() - 1 );
break;
case PositionTopRight:
case PositionRight:
if( previousMoveResizeGeom.right() <= moveResizeGeom.right() )
{
breakLoop = true;
break;
}
moveResizeGeom.setRight( moveResizeGeom.x() + moveResizeGeom.width() );
break;
default:
breakLoop = true;
} }
if( breakLoop ) else // Our heights match but we still don't have a valid area, maybe
{ // we are trying to resize in from the side?
bool breakLoop = false;
switch( mode )
{
case PositionTopLeft:
case PositionLeft:
if( previousMoveResizeGeom.x() >= moveResizeGeom.x() )
{
breakLoop = true;
break;
}
moveResizeGeom.setLeft( moveResizeGeom.x() - 1 );
break;
case PositionTopRight:
case PositionRight:
if( previousMoveResizeGeom.right() <= moveResizeGeom.right() )
{
breakLoop = true;
break;
}
moveResizeGeom.setRight( moveResizeGeom.x() + moveResizeGeom.width() );
break;
default:
breakLoop = true;
}
if( breakLoop )
break;
}
}
QSize size = adjustedSize( moveResizeGeom.size(), sizemode );
// the new topleft and bottomright corners (after checking size constrains), if they'll be needed
topleft = QPoint( moveResizeGeom.right() - size.width() + 1, moveResizeGeom.bottom() - size.height() + 1 );
bottomright = QPoint( moveResizeGeom.left() + size.width() - 1, moveResizeGeom.top() + size.height() - 1 );
orig = moveResizeGeom;
switch ( mode )
{ // these 4 corners ones are copied from above
case PositionTopLeft:
moveResizeGeom = QRect( topleft, orig.bottomRight() ) ;
break;
case PositionBottomRight:
moveResizeGeom = QRect( orig.topLeft(), bottomright ) ;
break;
case PositionBottomLeft:
moveResizeGeom = QRect( QPoint( topleft.x(), orig.y() ), QPoint( orig.right(), bottomright.y()) ) ;
break;
case PositionTopRight:
moveResizeGeom = QRect( QPoint( orig.x(), topleft.y() ), QPoint( bottomright.x(), orig.bottom()) ) ;
break;
// The side ones can't be copied exactly - if aspect ratios are specified, both dimensions may change.
// Therefore grow to the right/bottom if needed.
// TODO it should probably obey gravity rather than always using right/bottom ?
case PositionTop:
moveResizeGeom = QRect( QPoint( orig.left(), topleft.y() ), QPoint( bottomright.x(), orig.bottom()) ) ;
break;
case PositionBottom:
moveResizeGeom = QRect( orig.topLeft(), QPoint( bottomright.x(), bottomright.y() ) ) ;
break;
case PositionLeft:
moveResizeGeom = QRect( QPoint( topleft.x(), orig.top() ), QPoint( orig.right(), bottomright.y()));
break;
case PositionRight:
moveResizeGeom = QRect( orig.topLeft(), QPoint( bottomright.x(), bottomright.y() ) ) ;
break;
case PositionCenter:
default:
abort();
break; break;
} }
} }
QSize size = adjustedSize( moveResizeGeom.size(), sizemode );
// the new topleft and bottomright corners (after checking size constrains), if they'll be needed
topleft = QPoint( moveResizeGeom.right() - size.width() + 1, moveResizeGeom.bottom() - size.height() + 1 );
bottomright = QPoint( moveResizeGeom.left() + size.width() - 1, moveResizeGeom.top() + size.height() - 1 );
orig = moveResizeGeom;
switch ( mode )
{ // these 4 corners ones are copied from above
case PositionTopLeft:
moveResizeGeom = QRect( topleft, orig.bottomRight() ) ;
break;
case PositionBottomRight:
moveResizeGeom = QRect( orig.topLeft(), bottomright ) ;
break;
case PositionBottomLeft:
moveResizeGeom = QRect( QPoint( topleft.x(), orig.y() ), QPoint( orig.right(), bottomright.y()) ) ;
break;
case PositionTopRight:
moveResizeGeom = QRect( QPoint( orig.x(), topleft.y() ), QPoint( bottomright.x(), orig.bottom()) ) ;
break;
// The side ones can't be copied exactly - if aspect ratios are specified, both dimensions may change.
// Therefore grow to the right/bottom if needed.
// TODO it should probably obey gravity rather than always using right/bottom ?
case PositionTop:
moveResizeGeom = QRect( QPoint( orig.left(), topleft.y() ), QPoint( bottomright.x(), orig.bottom()) ) ;
break;
case PositionBottom:
moveResizeGeom = QRect( orig.topLeft(), QPoint( bottomright.x(), bottomright.y() ) ) ;
break;
case PositionLeft:
moveResizeGeom = QRect( QPoint( topleft.x(), orig.top() ), QPoint( orig.right(), bottomright.y()));
break;
case PositionRight:
moveResizeGeom = QRect( orig.topLeft(), QPoint( bottomright.x(), bottomright.y() ) ) ;
break;
case PositionCenter:
default:
abort();
break;
}
if( moveResizeGeom.size() != previousMoveResizeGeom.size()) if( moveResizeGeom.size() != previousMoveResizeGeom.size())
update = true; update = true;
} }
@ -3031,31 +3034,34 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
moveResizeGeom.moveTopLeft( workspace()->adjustClientPosition( this, moveResizeGeom.topLeft(), moveResizeGeom.moveTopLeft( workspace()->adjustClientPosition( this, moveResizeGeom.topLeft(),
unrestrictedMoveResize )); unrestrictedMoveResize ));
// Make sure the titlebar isn't behind a restricted area. if(!unrestrictedMoveResize)
for(;;)
{ {
QRegion titlebarRegion( moveResizeGeom.left(), moveResizeGeom.top(), // Make sure the titlebar isn't behind a restricted area.
moveResizeGeom.width(), frameTop ); for(;;)
titlebarRegion &= workspace()->clientArea( FullArea, -1, 0 ); // On the screen {
titlebarRegion -= workspace()->restrictedMoveArea( desktop() ); // Strut areas QRegion titlebarRegion( moveResizeGeom.left(), moveResizeGeom.top(),
// Now we have a region of all the visible areas of the titlebar moveResizeGeom.width(), frameTop );
// Count the visible pixels and check to see if it's enough titlebarRegion &= workspace()->clientArea( FullArea, -1, 0 ); // On the screen
int visiblePixels = 0; titlebarRegion -= workspace()->restrictedMoveArea( desktop() ); // Strut areas
foreach( const QRect& rect, titlebarRegion.rects() ) // Now we have a region of all the visible areas of the titlebar
if( rect.height() >= frameTop ) // Only the full height regions, prevents long slim areas // Count the visible pixels and check to see if it's enough
visiblePixels += rect.width() * rect.height(); int visiblePixels = 0;
if( visiblePixels >= titlebarArea ) foreach( const QRect& rect, titlebarRegion.rects() )
break; // We have reached a valid position if( rect.height() >= frameTop ) // Only the full height regions, prevents long slim areas
visiblePixels += rect.width() * rect.height();
if( visiblePixels >= titlebarArea )
break; // We have reached a valid position
// Move it (Favour vertically) // Move it (Favour vertically)
if( previousMoveResizeGeom.y() != moveResizeGeom.y() ) if( previousMoveResizeGeom.y() != moveResizeGeom.y() )
moveResizeGeom.translate( 0, moveResizeGeom.translate( 0,
previousMoveResizeGeom.y() > moveResizeGeom.y() ? 1 : -1 ); previousMoveResizeGeom.y() > moveResizeGeom.y() ? 1 : -1 );
else else
moveResizeGeom.translate( previousMoveResizeGeom.x() > moveResizeGeom.x() ? 1 : -1, moveResizeGeom.translate( previousMoveResizeGeom.x() > moveResizeGeom.x() ? 1 : -1,
0 ); 0 );
if( moveResizeGeom == previousMoveResizeGeom ) if( moveResizeGeom == previousMoveResizeGeom )
break; // Prevent lockup break; // Prevent lockup
}
} }
} }
if( moveResizeGeom.topLeft() != previousMoveResizeGeom.topLeft()) if( moveResizeGeom.topLeft() != previousMoveResizeGeom.topLeft())