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_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;
|
||||||
|
|
3
client.h
3
client.h
|
@ -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;
|
||||||
|
|
||||||
|
|
108
geometry.cpp
108
geometry.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
Loading…
Reference in a new issue