An attempt to get the crazy shaded windows geometry handling right.

This fixes comment #10 in 96602, I don't know if it fixes as a whole,
but I'm quite sure people will complain again if not.
BUG: 96602


svn path=/trunk/KDE/kdebase/kwin/; revision=423512
icc-effect-5.14.5
Luboš Luňák 2005-06-08 18:07:27 +00:00
parent 5587e43337
commit da00272012
4 changed files with 82 additions and 53 deletions

View File

@ -280,10 +280,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
int save_workarea_diff_x = workarea_diff_x;
int save_workarea_diff_y = workarea_diff_y;
move( calculateGravitation( false ));
if( !isShade())
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
else
plainResize( sizeForClientSize( QSize( clientSize().width(), 0 ), SizemodeShaded ), ForceGeometrySet );
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
workarea_diff_x = save_workarea_diff_x;
workarea_diff_y = save_workarea_diff_y;
do_show = true;
@ -309,10 +306,7 @@ void Client::destroyDecoration()
setMask( QRegion()); // reset shape mask
int save_workarea_diff_x = workarea_diff_x;
int save_workarea_diff_y = workarea_diff_y;
if( !isShade())
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
else
plainResize( sizeForClientSize( QSize( clientSize().width(), 0 ), SizemodeShaded ), ForceGeometrySet );
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
move( grav );
workarea_diff_x = save_workarea_diff_x;
workarea_diff_y = save_workarea_diff_y;
@ -743,7 +737,8 @@ void Client::setShade( ShadeMode mode )
// shade
int h = height();
shade_geometry_change = true;
QSize s( sizeForClientSize( QSize( clientSize().width(), 0), SizemodeShaded ) );
QSize s( sizeForClientSize( QSize( clientSize())));
s.setHeight( border_top + border_bottom );
XSelectInput( qt_xdisplay(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
XUnmapWindow( qt_xdisplay(), wrapper );
XUnmapWindow( qt_xdisplay(), client );
@ -763,8 +758,8 @@ void Client::setShade( ShadeMode mode )
} while ( h > s.height() + step );
// if ( !wasStaticContents )
// clearWFlags( WStaticContents );
shade_geometry_change = false;
plainResize( s );
shade_geometry_change = false;
if( isActive())
{
if( was_shade_mode == ShadeHover )
@ -780,7 +775,7 @@ void Client::setShade( ShadeMode mode )
{
int h = height();
shade_geometry_change = true;
QSize s( sizeForClientSize( clientSize(), SizemodeShaded ));
QSize s( sizeForClientSize( clientSize()));
// FRAME bool wasStaticContents = testWFlags( WStaticContents );
// setWFlags( WStaticContents );
int step = QMAX( 4, QABS( h - s.height() ) / as )+1;

View File

@ -99,8 +99,7 @@ class Client : public QObject, public KDecorationDefines
SizemodeAny,
SizemodeFixedW, // try not to affect width
SizemodeFixedH, // try not to affect height
SizemodeMax, // try not to make it larger in either direction
SizemodeShaded // shaded - height == 0
SizemodeMax // try not to make it larger in either direction
};
QSize adjustedSize( const QSize&, Sizemode mode = SizemodeAny ) const;

View File

@ -1163,8 +1163,6 @@ QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode, bool noframe
ASPECT_CHECK_GROW_H
break;
}
case SizemodeShaded:
break;
}
#undef ASPECT_CHECK_SHRINK_H_GROW_W
#undef ASPECT_CHECK_SHRINK_W_GROW_H
@ -1187,10 +1185,7 @@ QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode, bool noframe
w += border_left + border_right;
h += border_top + border_bottom;
}
QSize ret = rules()->checkSize( QSize( w, h ));
if ( mode == SizemodeShaded && wsize.height() == 0 )
ret.setHeight( noframe ? 0 : border_top + border_bottom );
return ret;
return rules()->checkSize( QSize( w, h ));
}
/*!
@ -1445,6 +1440,16 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
void Client::resizeWithChecks( int w, int h, ForceGeometry_t force )
{
if( shade_geometry_change )
assert( false );
else if( isShade())
{
if( h == border_top + border_bottom )
{
kdDebug() << "Shaded geometry passed for size:" << endl;
kdDebug() << kdBacktrace() << endl;
}
}
int newx = x();
int newy = y();
QRect area = workspace()->clientArea( WorkArea, this );
@ -1599,14 +1604,38 @@ bool Client::isMaximizable() const
*/
void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
{
// this code is also duplicated in Client::plainResize()
// Ok, the shading geometry stuff. Generally, code doesn't care about shaded geometry,
// simply because there are too many places dealing with geometry. Those places
// ignore shaded state and use normal geometry, which they usually should get
// from adjustedSize(). Such geometry comes here, and if the window is shaded,
// the geometry is used only for client_size, since that one is not used when
// shading. Then the frame geometry is adjusted for the shaded geometry.
// This gets more complicated in the case the code does only something like
// setGeometry( geometry()) - geometry() will return the shaded frame geometry.
// Such code is wrong and should be changed to handle the case when the window is shaded.
if( shade_geometry_change )
; // nothing
else if( isShade())
{
if( h == border_top + border_bottom )
{
kdDebug() << "Shaded geometry passed for size:" << endl;
kdDebug() << kdBacktrace() << endl;
}
else
{
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
h = border_top + border_bottom;
}
}
else
{
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
}
if( force == NormalGeometrySet && frame_geometry == QRect( x, y, w, h ))
return;
h = checkShadeGeometry( w, h );
frame_geometry = QRect( x, y, w, h );
if( !isShade())
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
else
client_size = QSize( w - border_left - border_right, client_size.height());
updateWorkareaDiffs();
if( postpone_geometry_updates != 0 )
{
@ -1634,6 +1663,26 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
void Client::plainResize( int w, int h, ForceGeometry_t force )
{
// this code is also duplicated in Client::setGeometry()
if( shade_geometry_change )
; // nothing
else if( isShade())
{
if( h == border_top + border_bottom )
{
kdDebug() << "Shaded geometry passed for size:" << endl;
kdDebug() << kdBacktrace() << endl;
}
else
{
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
h = border_top + border_bottom;
}
}
else
{
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
}
if( QSize( w, h ) != rules()->checkSize( QSize( w, h )))
{
kdDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl;
@ -1641,12 +1690,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
}
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
return;
h = checkShadeGeometry( w, h );
frame_geometry.setSize( QSize( w, h ));
if( !isShade())
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
else
client_size = QSize( w - border_left - border_right, client_size.height());
updateWorkareaDiffs();
if( postpone_geometry_updates != 0 )
{
@ -1671,24 +1715,6 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
checkMaximizeGeometry();
}
// There may be cases when an application requests resizing while shaded,
// and even KWin itself may do so somewhere (too many places to check :-/ ).
// If the requested geometry doesn't fit shaded geometry, adjust the height
// of the requested geometry and return it.
int Client::checkShadeGeometry( int w, int h )
{
// check that the frame is not resized to full size when it should be shaded
if( isShade() && !shade_geometry_change && h != border_top + border_bottom )
{
kdDebug() << "Fixing shaded geometry:" << this << endl;
// adjust the client size to match the newly requested geometry
client_size = adjustedSize( QSize( w, h ));
// checkMaximizeGeometry(); // doesn't work, actual setting of geometry changes this again
h = border_top + border_bottom;
}
return h;
}
/*!
Reimplemented to inform the client about the new window position.
*/
@ -1723,8 +1749,13 @@ void Client::postponeGeometryUpdates( bool postpone )
if( --postpone_geometry_updates == 0 )
{
if( pending_geometry_update )
setGeometry( geometry(), ForceGeometrySet );
pending_geometry_update = false;
{
if( isShade())
setGeometry( QRect( pos(), sizeForClientSize( clientSize())), ForceGeometrySet );
else
setGeometry( geometry(), ForceGeometrySet );
pending_geometry_update = false;
}
}
}
}
@ -1901,7 +1932,10 @@ void Client::resetMaximize()
updateAllowedActions();
if( decoration != NULL )
decoration->borders( border_left, border_right, border_top, border_bottom );
setGeometry( geometry(), ForceGeometrySet );
if( isShade())
setGeometry( QRect( pos(), sizeForClientSize( clientSize())), ForceGeometrySet );
else
setGeometry( geometry(), ForceGeometrySet );
if( decoration != NULL )
decoration->maximizeChange();
}

View File

@ -800,8 +800,9 @@ void Client::applyWindowRules()
// apply force rules
// Placement - does need explicit update, just like some others below
// Geometry : setGeometry() doesn't check rules
QRect geom = client_rules.checkGeometry( geometry());
if( geom != geometry())
QRect orig_geom = QRect( pos(), sizeForClientSize( clientSize())); // handle shading
QRect geom = client_rules.checkGeometry( orig_geom );
if( geom != orig_geom )
setGeometry( geom );
// MinSize, MaxSize handled by Geometry
// IgnorePosition
@ -827,7 +828,7 @@ void Client::applyWindowRules()
workspace()->activateNextClient( this );
// MoveResizeMode
// Closeable
QSize s = adjustedSize( size());
QSize s = adjustedSize( sizeForClientSize( clientSize())); // handle shading
if( s != size())
resizeWithChecks( s );
setShortcut( rules()->checkShortcut( shortcut().toString()));