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

View File

@ -99,8 +99,7 @@ class Client : public QObject, public KDecorationDefines
SizemodeAny, SizemodeAny,
SizemodeFixedW, // try not to affect width SizemodeFixedW, // try not to affect width
SizemodeFixedH, // try not to affect height SizemodeFixedH, // try not to affect height
SizemodeMax, // try not to make it larger in either direction SizemodeMax // try not to make it larger in either direction
SizemodeShaded // shaded - height == 0
}; };
QSize adjustedSize( const QSize&, Sizemode mode = SizemodeAny ) const; 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 ASPECT_CHECK_GROW_H
break; break;
} }
case SizemodeShaded:
break;
} }
#undef ASPECT_CHECK_SHRINK_H_GROW_W #undef ASPECT_CHECK_SHRINK_H_GROW_W
#undef ASPECT_CHECK_SHRINK_W_GROW_H #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; w += border_left + border_right;
h += border_top + border_bottom; h += border_top + border_bottom;
} }
QSize ret = rules()->checkSize( QSize( w, h )); return rules()->checkSize( QSize( w, h ));
if ( mode == SizemodeShaded && wsize.height() == 0 )
ret.setHeight( noframe ? 0 : border_top + border_bottom );
return ret;
} }
/*! /*!
@ -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 ) 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 newx = x();
int newy = y(); int newy = y();
QRect area = workspace()->clientArea( WorkArea, this ); 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 ) 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 )) if( force == NormalGeometrySet && frame_geometry == QRect( x, y, w, h ))
return; return;
h = checkShadeGeometry( w, h );
frame_geometry = QRect( x, y, 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(); updateWorkareaDiffs();
if( postpone_geometry_updates != 0 ) 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 ) 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 ))) if( QSize( w, h ) != rules()->checkSize( QSize( w, h )))
{ {
kdDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl; 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 )) if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
return; return;
h = checkShadeGeometry( w, h );
frame_geometry.setSize( QSize( 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(); updateWorkareaDiffs();
if( postpone_geometry_updates != 0 ) if( postpone_geometry_updates != 0 )
{ {
@ -1671,24 +1715,6 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
checkMaximizeGeometry(); 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. 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( --postpone_geometry_updates == 0 )
{ {
if( pending_geometry_update ) 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(); updateAllowedActions();
if( decoration != NULL ) if( decoration != NULL )
decoration->borders( border_left, border_right, border_top, border_bottom ); 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 ) if( decoration != NULL )
decoration->maximizeChange(); decoration->maximizeChange();
} }

View File

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