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:
parent
121c613228
commit
08bb12efcf
5 changed files with 56 additions and 27 deletions
14
client.cpp
14
client.cpp
|
@ -246,9 +246,9 @@ void Client::updateDecoration( bool check_workspace_pos, bool force, bool delay_
|
||||||
int save_workarea_diff_y = workarea_diff_y;
|
int save_workarea_diff_y = workarea_diff_y;
|
||||||
move( calculateGravitation( false ));
|
move( calculateGravitation( false ));
|
||||||
if( !isShade())
|
if( !isShade())
|
||||||
resize( sizeForClientSize( clientSize()), IgnoreGravity, ForceGeometrySet );
|
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
|
||||||
else
|
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_x = save_workarea_diff_x;
|
||||||
workarea_diff_y = save_workarea_diff_y;
|
workarea_diff_y = save_workarea_diff_y;
|
||||||
do_show = true;
|
do_show = true;
|
||||||
|
@ -284,9 +284,9 @@ void Client::destroyDecoration( bool delay_delete )
|
||||||
int save_workarea_diff_y = workarea_diff_y;
|
int save_workarea_diff_y = workarea_diff_y;
|
||||||
move( grav );
|
move( grav );
|
||||||
if( !isShade())
|
if( !isShade())
|
||||||
resize( clientSize(), IgnoreGravity, ForceGeometrySet );
|
plainResize( clientSize(), ForceGeometrySet );
|
||||||
else
|
else
|
||||||
resize( QSize( clientSize().width(), 0 ), IgnoreGravity, ForceGeometrySet );
|
plainResize( QSize( clientSize().width(), 0 ), ForceGeometrySet );
|
||||||
workarea_diff_x = save_workarea_diff_x;
|
workarea_diff_x = save_workarea_diff_x;
|
||||||
workarea_diff_y = save_workarea_diff_y;
|
workarea_diff_y = save_workarea_diff_y;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ void Client::checkBorderSizes()
|
||||||
border_top = new_top;
|
border_top = new_top;
|
||||||
border_bottom = new_bottom;
|
border_bottom = new_bottom;
|
||||||
move( calculateGravitation( false ));
|
move( calculateGravitation( false ));
|
||||||
resize( sizeForClientSize( clientSize()), IgnoreGravity, ForceGeometrySet );
|
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
|
||||||
checkWorkspacePosition();
|
checkWorkspacePosition();
|
||||||
--block_geometry;
|
--block_geometry;
|
||||||
setGeometry( geometry(), ForceGeometrySet );
|
setGeometry( geometry(), ForceGeometrySet );
|
||||||
|
@ -735,7 +735,7 @@ void Client::setShade( ShadeMode mode )
|
||||||
// if ( !wasStaticContents )
|
// if ( !wasStaticContents )
|
||||||
// clearWFlags( WStaticContents );
|
// clearWFlags( WStaticContents );
|
||||||
shade_geometry_change = false;
|
shade_geometry_change = false;
|
||||||
resize( s, IgnoreGravity );
|
plainResize( s );
|
||||||
if( isActive())
|
if( isActive())
|
||||||
workspace()->focusToNull();
|
workspace()->focusToNull();
|
||||||
}
|
}
|
||||||
|
@ -760,7 +760,7 @@ void Client::setShade( ShadeMode mode )
|
||||||
// if ( !wasStaticContents )
|
// if ( !wasStaticContents )
|
||||||
// clearWFlags( WStaticContents );
|
// clearWFlags( WStaticContents );
|
||||||
shade_geometry_change = false;
|
shade_geometry_change = false;
|
||||||
resize( s, IgnoreGravity );
|
plainResize( s );
|
||||||
if( shade_mode == ShadeHover || shade_mode == ShadeActivated )
|
if( shade_mode == ShadeHover || shade_mode == ShadeActivated )
|
||||||
setActive( TRUE );
|
setActive( TRUE );
|
||||||
XMapWindow( qt_xdisplay(), wrapperId());
|
XMapWindow( qt_xdisplay(), wrapperId());
|
||||||
|
|
18
client.h
18
client.h
|
@ -192,8 +192,9 @@ class Client : public QObject, public KDecorationDefines
|
||||||
void setGeometry( const QRect& r, ForceGeometry_t force = NormalGeometrySet );
|
void setGeometry( const QRect& r, ForceGeometry_t force = NormalGeometrySet );
|
||||||
void move( int x, int y, ForceGeometry_t force = NormalGeometrySet );
|
void move( int x, int y, ForceGeometry_t force = NormalGeometrySet );
|
||||||
void move( const QPoint & p, 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 );
|
// plainResize() simply resizes
|
||||||
void resize( const QSize& s, UseGravity_t use_gravity, ForceGeometry_t force = NormalGeometrySet );
|
void plainResize( int w, int h, ForceGeometry_t force = NormalGeometrySet );
|
||||||
|
void plainResize( const QSize& s, ForceGeometry_t force = NormalGeometrySet );
|
||||||
|
|
||||||
void growHorizontal();
|
void growHorizontal();
|
||||||
void shrinkHorizontal();
|
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 );
|
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 );
|
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 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();
|
bool startMoveResize();
|
||||||
void finishMoveResize( bool cancel );
|
void finishMoveResize( bool cancel );
|
||||||
|
@ -774,9 +777,14 @@ inline void Client::move( const QPoint & p, ForceGeometry_t force )
|
||||||
move( p.x(), p.y(), 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
|
inline bool Client::hasUserTimeSupport() const
|
||||||
|
|
48
geometry.cpp
48
geometry.cpp
|
@ -747,7 +747,7 @@ void Client::getWmNormalHints()
|
||||||
{ // update to match restrictions
|
{ // update to match restrictions
|
||||||
QSize new_size = adjustedSize( size());
|
QSize new_size = adjustedSize( size());
|
||||||
if( new_size != size())
|
if( new_size != size())
|
||||||
resize( new_size, UseGravity );
|
resizeWithChecks( new_size );
|
||||||
}
|
}
|
||||||
updateAllowedActions(); // affects isResizeable()
|
updateAllowedActions(); // affects isResizeable()
|
||||||
}
|
}
|
||||||
|
@ -885,7 +885,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|
||||||
resetMaximize();
|
resetMaximize();
|
||||||
++block_geometry;
|
++block_geometry;
|
||||||
move( new_pos );
|
move( new_pos );
|
||||||
resize( ns, IgnoreGravity ); // TODO must(?) resize before gravitating?
|
plainResize( ns ); // TODO must(?) resize before gravitating?
|
||||||
--block_geometry;
|
--block_geometry;
|
||||||
setGeometry( QRect( calculateGravitation( false, gravity ), size()), ForceGeometrySet );
|
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();
|
resetMaximize();
|
||||||
int save_gravity = xSizeHint.win_gravity;
|
int save_gravity = xSizeHint.win_gravity;
|
||||||
xSizeHint.win_gravity = gravity;
|
xSizeHint.win_gravity = gravity;
|
||||||
resize( ns, UseGravity );
|
resizeWithChecks( ns );
|
||||||
xSizeHint.win_gravity = save_gravity;
|
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.
|
// 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 newx = x();
|
||||||
int newy = y();
|
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 )
|
switch( xSizeHint.win_gravity )
|
||||||
{
|
{
|
||||||
case NorthWestGravity: // top left corner doesn't move
|
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;
|
newy = newy + height() - h;
|
||||||
break;
|
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 );
|
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
|
{ // TODO make this deffered with isResize() ? old kwin did
|
||||||
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
|
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
|
||||||
return;
|
return;
|
||||||
if( use_gravity == UseGravity )
|
|
||||||
{
|
|
||||||
resizeWithGravity( w, h, force );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
frame_geometry.setSize( QSize( w, h ));
|
frame_geometry.setSize( QSize( w, h ));
|
||||||
if( !isShade())
|
if( !isShade())
|
||||||
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
|
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 )
|
if( geom_restore.width() == 0 )
|
||||||
{ // needs placement
|
{ // needs placement
|
||||||
resize( adjustedSize(QSize(width(), clientArea.height())), IgnoreGravity );
|
plainResize( adjustedSize(QSize(width(), clientArea.height())));
|
||||||
workspace()->placeSmart( this );
|
workspace()->placeSmart( this );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1209,7 +1231,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
|
||||||
{
|
{
|
||||||
if( geom_restore.height() == 0 )
|
if( geom_restore.height() == 0 )
|
||||||
{ // needs placement
|
{ // needs placement
|
||||||
resize( adjustedSize(QSize(clientArea.width(), height())), IgnoreGravity );
|
plainResize( adjustedSize(QSize(clientArea.width(), height())));
|
||||||
workspace()->placeSmart( this );
|
workspace()->placeSmart( this );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1233,7 +1255,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
|
||||||
s.setWidth( geom_restore.width());
|
s.setWidth( geom_restore.width());
|
||||||
if( geom_restore.height() > 0 )
|
if( geom_restore.height() > 0 )
|
||||||
s.setHeight( geom_restore.height());
|
s.setHeight( geom_restore.height());
|
||||||
resize( adjustedSize( s ), IgnoreGravity );
|
plainResize( adjustedSize( s ));
|
||||||
workspace()->placeSmart( this );
|
workspace()->placeSmart( this );
|
||||||
restore = geometry();
|
restore = geometry();
|
||||||
if( geom_restore.width() > 0 )
|
if( geom_restore.width() > 0 )
|
||||||
|
|
|
@ -279,7 +279,7 @@ bool Client::manage( Window w, bool isMapped )
|
||||||
|
|
||||||
updateDecoration( false ); // also gravitates
|
updateDecoration( false ); // also gravitates
|
||||||
// TODO is CentralGravity right here, when resizing is done after gravitating?
|
// TODO is CentralGravity right here, when resizing is done after gravitating?
|
||||||
resize( sizeForClientSize( geom.size() ), IgnoreGravity );
|
plainResize( sizeForClientSize( geom.size()));
|
||||||
|
|
||||||
if( !placementDone )
|
if( !placementDone )
|
||||||
{ // placement needs to be after setting size
|
{ // placement needs to be after setting size
|
||||||
|
|
1
utils.h
1
utils.h
|
@ -73,7 +73,6 @@ inline void operator++( Layer& lay )
|
||||||
enum allowed_t { Allowed };
|
enum allowed_t { Allowed };
|
||||||
|
|
||||||
// some enums to have more readable code, instead of using bools
|
// some enums to have more readable code, instead of using bools
|
||||||
enum UseGravity_t { IgnoreGravity, UseGravity };
|
|
||||||
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
|
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
|
||||||
|
|
||||||
class Shape
|
class Shape
|
||||||
|
|
Loading…
Reference in a new issue