From da002720122485bcf7e4e595db5794787d26dfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Wed, 8 Jun 2005 18:07:27 +0000 Subject: [PATCH] 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 --- client.cpp | 17 +++----- client.h | 3 +- geometry.cpp | 108 +++++++++++++++++++++++++++++++++------------------ rules.cpp | 7 ++-- 4 files changed, 82 insertions(+), 53 deletions(-) diff --git a/client.cpp b/client.cpp index e7b17a4d99..00aacf042b 100644 --- a/client.cpp +++ b/client.cpp @@ -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; diff --git a/client.h b/client.h index f2c2fbe93c..b955fcb0cd 100644 --- a/client.h +++ b/client.h @@ -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; diff --git a/geometry.cpp b/geometry.cpp index 807380c4c9..04fbbf497f 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -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(); } diff --git a/rules.cpp b/rules.cpp index da344fdc3e..91fcea17dc 100644 --- a/rules.cpp +++ b/rules.cpp @@ -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()));