If a windows tries to grow larger than the workarea, don't allow it to

do so, if size constraints allow it.
If resizing a window would make it get partially out of workarea,
move it so that it stays in workarea.

svn path=/trunk/kdebase/kwin/; revision=255616
This commit is contained in:
Luboš Luňák 2003-10-02 08:57:17 +00:00
parent 121c613228
commit 08bb12efcf
5 changed files with 56 additions and 27 deletions

View file

@ -246,9 +246,9 @@ void Client::updateDecoration( bool check_workspace_pos, bool force, bool delay_
int save_workarea_diff_y = workarea_diff_y;
move( calculateGravitation( false ));
if( !isShade())
resize( sizeForClientSize( clientSize()), IgnoreGravity, ForceGeometrySet );
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
else
resize( sizeForClientSize( QSize( clientSize().width(), 0 ), true ), IgnoreGravity, ForceGeometrySet );
plainResize( sizeForClientSize( QSize( clientSize().width(), 0 ), true ), ForceGeometrySet );
workarea_diff_x = save_workarea_diff_x;
workarea_diff_y = save_workarea_diff_y;
do_show = true;
@ -284,9 +284,9 @@ void Client::destroyDecoration( bool delay_delete )
int save_workarea_diff_y = workarea_diff_y;
move( grav );
if( !isShade())
resize( clientSize(), IgnoreGravity, ForceGeometrySet );
plainResize( clientSize(), ForceGeometrySet );
else
resize( QSize( clientSize().width(), 0 ), IgnoreGravity, ForceGeometrySet );
plainResize( QSize( clientSize().width(), 0 ), ForceGeometrySet );
workarea_diff_x = save_workarea_diff_x;
workarea_diff_y = save_workarea_diff_y;
}
@ -308,7 +308,7 @@ void Client::checkBorderSizes()
border_top = new_top;
border_bottom = new_bottom;
move( calculateGravitation( false ));
resize( sizeForClientSize( clientSize()), IgnoreGravity, ForceGeometrySet );
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
checkWorkspacePosition();
--block_geometry;
setGeometry( geometry(), ForceGeometrySet );
@ -735,7 +735,7 @@ void Client::setShade( ShadeMode mode )
// if ( !wasStaticContents )
// clearWFlags( WStaticContents );
shade_geometry_change = false;
resize( s, IgnoreGravity );
plainResize( s );
if( isActive())
workspace()->focusToNull();
}
@ -760,7 +760,7 @@ void Client::setShade( ShadeMode mode )
// if ( !wasStaticContents )
// clearWFlags( WStaticContents );
shade_geometry_change = false;
resize( s, IgnoreGravity );
plainResize( s );
if( shade_mode == ShadeHover || shade_mode == ShadeActivated )
setActive( TRUE );
XMapWindow( qt_xdisplay(), wrapperId());

View file

@ -192,8 +192,9 @@ class Client : public QObject, public KDecorationDefines
void setGeometry( const QRect& r, ForceGeometry_t force = NormalGeometrySet );
void move( int x, int y, ForceGeometry_t force = NormalGeometrySet );
void move( const QPoint & p, ForceGeometry_t force = NormalGeometrySet );
void resize( int w, int h, UseGravity_t use_gravity, ForceGeometry_t force = NormalGeometrySet );
void resize( const QSize& s, UseGravity_t use_gravity, ForceGeometry_t force = NormalGeometrySet );
// plainResize() simply resizes
void plainResize( int w, int h, ForceGeometry_t force = NormalGeometrySet );
void plainResize( const QSize& s, ForceGeometry_t force = NormalGeometrySet );
void growHorizontal();
void shrinkHorizontal();
@ -326,7 +327,9 @@ class Client : public QObject, public KDecorationDefines
void checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area );
static int computeWorkareaDiff( int left, int right, int a_left, int a_right );
void configureRequest( int value_mask, int rx, int ry, int rw, int rh, int gravity = 0 );
void resizeWithGravity( int w, int h, ForceGeometry_t force );
// resizeWithChecks() resizes according to gravity, and checks workarea position
void resizeWithChecks( int w, int h, ForceGeometry_t force = NormalGeometrySet );
void resizeWithChecks( const QSize& s, ForceGeometry_t force = NormalGeometrySet );
bool startMoveResize();
void finishMoveResize( bool cancel );
@ -774,9 +777,14 @@ inline void Client::move( const QPoint & p, ForceGeometry_t force )
move( p.x(), p.y(), force );
}
inline void Client::resize( const QSize& s, UseGravity_t use_gravity, ForceGeometry_t force )
inline void Client::plainResize( const QSize& s, ForceGeometry_t force )
{
resize( s.width(), s.height(), use_gravity, force );
plainResize( s.width(), s.height(), force );
}
inline void Client::resizeWithChecks( const QSize& s, ForceGeometry_t force )
{
resizeWithChecks( s.width(), s.height(), force );
}
inline bool Client::hasUserTimeSupport() const

View file

@ -747,7 +747,7 @@ void Client::getWmNormalHints()
{ // update to match restrictions
QSize new_size = adjustedSize( size());
if( new_size != size())
resize( new_size, UseGravity );
resizeWithChecks( new_size );
}
updateAllowedActions(); // affects isResizeable()
}
@ -885,7 +885,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
resetMaximize();
++block_geometry;
move( new_pos );
resize( ns, IgnoreGravity ); // TODO must(?) resize before gravitating?
plainResize( ns ); // TODO must(?) resize before gravitating?
--block_geometry;
setGeometry( QRect( calculateGravitation( false, gravity ), size()), ForceGeometrySet );
}
@ -907,7 +907,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
resetMaximize();
int save_gravity = xSizeHint.win_gravity;
xSizeHint.win_gravity = gravity;
resize( ns, UseGravity );
resizeWithChecks( ns );
xSizeHint.win_gravity = save_gravity;
}
}
@ -916,10 +916,19 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
// Handling of the real ConfigureRequest event forces sending it, as there it's necessary.
}
void Client::resizeWithGravity( int w, int h, ForceGeometry_t force )
void Client::resizeWithChecks( int w, int h, ForceGeometry_t force )
{
int newx = x();
int newy = y();
QRect area = workspace()->clientArea( geometry().center(), desktop());
// don't allow growing larger than workarea
if( w > area.width())
w = area.width();
if( h > area.height())
h = area.height();
QSize tmp = adjustedSize( QSize( w, h )); // checks size constraints, including min/max size
w = tmp.width();
h = tmp.height();
switch( xSizeHint.win_gravity )
{
case NorthWestGravity: // top left corner doesn't move
@ -957,6 +966,24 @@ void Client::resizeWithGravity( int w, int h, ForceGeometry_t force )
newy = newy + height() - h;
break;
}
// if it would be moved outside of workarea, keep it inside,
// see also Client::computeWorkareaDiff()
if( workarea_diff_x != INT_MIN ) // was inside
{
if( newx < area.left())
newx = area.left();
if( newx + w > area.right() + 1 )
newx = area.right() + 1 - w;
assert( newx >= area.left() && newx + w <= area.right() + 1 ); // width was checked above
}
if( workarea_diff_y != INT_MIN ) // was inside
{
if( newy < area.top())
newy = area.top();
if( newy + h > area.bottom() + 1 )
newy = area.bottom() + 1 - h;
assert( newy >= area.top() && newy + h <= area.bottom() + 1 ); // height was checked above
}
setGeometry( newx, newy, w, h, force );
}
@ -1047,15 +1074,10 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
}
}
void Client::resize( int w, int h, UseGravity_t use_gravity, ForceGeometry_t force )
void Client::plainResize( int w, int h, ForceGeometry_t force )
{ // TODO make this deffered with isResize() ? old kwin did
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
return;
if( use_gravity == UseGravity )
{
resizeWithGravity( w, h, force );
return;
}
frame_geometry.setSize( QSize( w, h ));
if( !isShade())
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
@ -1189,7 +1211,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
{
if( geom_restore.width() == 0 )
{ // needs placement
resize( adjustedSize(QSize(width(), clientArea.height())), IgnoreGravity );
plainResize( adjustedSize(QSize(width(), clientArea.height())));
workspace()->placeSmart( this );
}
else
@ -1209,7 +1231,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
{
if( geom_restore.height() == 0 )
{ // needs placement
resize( adjustedSize(QSize(clientArea.width(), height())), IgnoreGravity );
plainResize( adjustedSize(QSize(clientArea.width(), height())));
workspace()->placeSmart( this );
}
else
@ -1233,7 +1255,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
s.setWidth( geom_restore.width());
if( geom_restore.height() > 0 )
s.setHeight( geom_restore.height());
resize( adjustedSize( s ), IgnoreGravity );
plainResize( adjustedSize( s ));
workspace()->placeSmart( this );
restore = geometry();
if( geom_restore.width() > 0 )

View file

@ -279,7 +279,7 @@ bool Client::manage( Window w, bool isMapped )
updateDecoration( false ); // also gravitates
// TODO is CentralGravity right here, when resizing is done after gravitating?
resize( sizeForClientSize( geom.size() ), IgnoreGravity );
plainResize( sizeForClientSize( geom.size()));
if( !placementDone )
{ // placement needs to be after setting size

View file

@ -73,7 +73,6 @@ inline void operator++( Layer& lay )
enum allowed_t { Allowed };
// some enums to have more readable code, instead of using bools
enum UseGravity_t { IgnoreGravity, UseGravity };
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
class Shape