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
This commit is contained in:
parent
5587e43337
commit
da00272012
4 changed files with 82 additions and 53 deletions
17
client.cpp
17
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;
|
||||
|
|
3
client.h
3
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;
|
||||
|
||||
|
|
108
geometry.cpp
108
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();
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
|
|
Loading…
Reference in a new issue