Fix compositing repaint bug where moving a window would not draw properly (especially noticeable when snapping to a border).
svn path=/branches/work/kwin_composite/; revision=632339
This commit is contained in:
parent
6c224134db
commit
ca856c28e1
1 changed files with 67 additions and 32 deletions
99
geometry.cpp
99
geometry.cpp
|
@ -28,6 +28,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#include "notifications.h"
|
#include "notifications.h"
|
||||||
#include "geometrytip.h"
|
#include "geometrytip.h"
|
||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
|
#include "effects.h"
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
|
||||||
|
@ -48,8 +49,14 @@ void Workspace::desktopResized()
|
||||||
desktop_geometry.width = geom.width();
|
desktop_geometry.width = geom.width();
|
||||||
desktop_geometry.height = geom.height();
|
desktop_geometry.height = geom.height();
|
||||||
rootInfo->setDesktopGeometry( -1, desktop_geometry );
|
rootInfo->setDesktopGeometry( -1, desktop_geometry );
|
||||||
|
|
||||||
updateClientArea();
|
updateClientArea();
|
||||||
checkElectricBorders( true );
|
checkElectricBorders( true );
|
||||||
|
if( compositing() )
|
||||||
|
{
|
||||||
|
finishCompositing();
|
||||||
|
QTimer::singleShot( 0, this, SLOT( setupCompositing() ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -215,7 +222,7 @@ QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop
|
||||||
if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 )
|
if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 )
|
||||||
desktop = currentDesktop();
|
desktop = currentDesktop();
|
||||||
QDesktopWidget *desktopwidget = KApplication::desktop();
|
QDesktopWidget *desktopwidget = KApplication::desktop();
|
||||||
int screen = desktopwidget->isVirtualDesktop() ? desktopwidget->screenNumber( p ) : desktopwidget->primaryScreen();
|
int screen = desktopwidget->screenNumber( p );
|
||||||
if( screen < 0 )
|
if( screen < 0 )
|
||||||
screen = desktopwidget->primaryScreen();
|
screen = desktopwidget->primaryScreen();
|
||||||
QRect sarea = screenarea // may be NULL during KWin initialization
|
QRect sarea = screenarea // may be NULL during KWin initialization
|
||||||
|
@ -1409,7 +1416,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|
||||||
|| ns != size())
|
|| ns != size())
|
||||||
{
|
{
|
||||||
QRect orig_geometry = geometry();
|
QRect orig_geometry = geometry();
|
||||||
GeometryUpdatesPostponer blocker( this );
|
GeometryUpdatesBlocker blocker( this );
|
||||||
move( new_pos );
|
move( new_pos );
|
||||||
plainResize( ns );
|
plainResize( ns );
|
||||||
setGeometry( QRect( calculateGravitation( false, gravity ), size()));
|
setGeometry( QRect( calculateGravitation( false, gravity ), size()));
|
||||||
|
@ -1442,7 +1449,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|
||||||
if( ns != size()) // don't restore if some app sets its own size again
|
if( ns != size()) // don't restore if some app sets its own size again
|
||||||
{
|
{
|
||||||
QRect orig_geometry = geometry();
|
QRect orig_geometry = geometry();
|
||||||
GeometryUpdatesPostponer blocker( this );
|
GeometryUpdatesBlocker blocker( this );
|
||||||
int save_gravity = xSizeHint.win_gravity;
|
int save_gravity = xSizeHint.win_gravity;
|
||||||
xSizeHint.win_gravity = gravity;
|
xSizeHint.win_gravity = gravity;
|
||||||
resizeWithChecks( ns );
|
resizeWithChecks( ns );
|
||||||
|
@ -1662,31 +1669,46 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
||||||
{
|
{
|
||||||
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
|
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 && geom == QRect( x, y, w, h ))
|
||||||
return;
|
return;
|
||||||
frame_geometry = QRect( x, y, w, h );
|
geom = QRect( x, y, w, h );
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
if( postpone_geometry_updates != 0 )
|
if( block_geometry_updates != 0 )
|
||||||
{
|
{
|
||||||
pending_geometry_update = true;
|
pending_geometry_update = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resizeDecoration( QSize( w, h ));
|
if( geom_before_block.size() != geom.size())
|
||||||
XMoveResizeWindow( display(), frameId(), x, y, w, h );
|
|
||||||
// resizeDecoration( QSize( w, h ));
|
|
||||||
if( !isShade())
|
|
||||||
{
|
{
|
||||||
QSize cs = clientSize();
|
resizeDecoration( QSize( w, h ));
|
||||||
XMoveResizeWindow( display(), wrapperId(), clientPos().x(), clientPos().y(),
|
XMoveResizeWindow( display(), frameId(), x, y, w, h );
|
||||||
cs.width(), cs.height());
|
if( !isShade())
|
||||||
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
{
|
||||||
|
QSize cs = clientSize();
|
||||||
|
XMoveResizeWindow( display(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||||
|
cs.width(), cs.height());
|
||||||
|
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
||||||
|
}
|
||||||
|
if( shape())
|
||||||
|
updateShape();
|
||||||
}
|
}
|
||||||
updateShape();
|
else
|
||||||
|
XMoveWindow( display(), frameId(), x, y );
|
||||||
// SELI TODO won't this be too expensive?
|
// SELI TODO won't this be too expensive?
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
sendSyntheticConfigureNotify();
|
sendSyntheticConfigureNotify();
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
|
if( geom_before_block.size() != geom.size())
|
||||||
|
{
|
||||||
|
addDamageFull(); // damage window only if it actually was a resize
|
||||||
|
if( scene != NULL )
|
||||||
|
scene->windowGeometryShapeChanged( this );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
workspace()->addDamage( geom ); // damage window's new location
|
||||||
|
workspace()->addDamage( geom_before_block ); // TODO add damage only if not obscured
|
||||||
|
geom_before_block = geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||||
|
@ -1716,11 +1738,11 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||||
kDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl;
|
kDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl;
|
||||||
kDebug() << kBacktrace() << endl;
|
kDebug() << kBacktrace() << endl;
|
||||||
}
|
}
|
||||||
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
|
if( force == NormalGeometrySet && geom.size() == QSize( w, h ))
|
||||||
return;
|
return;
|
||||||
frame_geometry.setSize( QSize( w, h ));
|
geom.setSize( QSize( w, h ));
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
if( postpone_geometry_updates != 0 )
|
if( block_geometry_updates != 0 )
|
||||||
{
|
{
|
||||||
pending_geometry_update = true;
|
pending_geometry_update = true;
|
||||||
return;
|
return;
|
||||||
|
@ -1735,11 +1757,17 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||||
cs.width(), cs.height());
|
cs.width(), cs.height());
|
||||||
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
||||||
}
|
}
|
||||||
updateShape();
|
if( shape())
|
||||||
|
updateShape();
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
sendSyntheticConfigureNotify();
|
sendSyntheticConfigureNotify();
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
|
addDamageFull(); // TODO add damage only in added area?
|
||||||
|
if( scene != NULL )
|
||||||
|
scene->windowGeometryShapeChanged( this );
|
||||||
|
workspace()->addDamage( geom_before_block ); // TODO add damage only if not obscured
|
||||||
|
geom_before_block = geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1747,11 +1775,11 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||||
*/
|
*/
|
||||||
void Client::move( int x, int y, ForceGeometry_t force )
|
void Client::move( int x, int y, ForceGeometry_t force )
|
||||||
{
|
{
|
||||||
if( force == NormalGeometrySet && frame_geometry.topLeft() == QPoint( x, y ))
|
if( force == NormalGeometrySet && geom.topLeft() == QPoint( x, y ))
|
||||||
return;
|
return;
|
||||||
frame_geometry.moveTopLeft( QPoint( x, y ));
|
geom.moveTopLeft( QPoint( x, y ));
|
||||||
updateWorkareaDiffs();
|
updateWorkareaDiffs();
|
||||||
if( postpone_geometry_updates != 0 )
|
if( block_geometry_updates != 0 )
|
||||||
{
|
{
|
||||||
pending_geometry_update = true;
|
pending_geometry_update = true;
|
||||||
return;
|
return;
|
||||||
|
@ -1760,20 +1788,22 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
||||||
sendSyntheticConfigureNotify();
|
sendSyntheticConfigureNotify();
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
|
// client itself is not damaged
|
||||||
|
workspace()->addDamage( geom_before_block ); // TODO add damage only if not obscured
|
||||||
|
geom_before_block = geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::blockGeometryUpdates( bool block )
|
||||||
void Client::postponeGeometryUpdates( bool postpone )
|
|
||||||
{
|
{
|
||||||
if( postpone )
|
if( block )
|
||||||
{
|
{
|
||||||
if( postpone_geometry_updates == 0 )
|
if( block_geometry_updates == 0 )
|
||||||
pending_geometry_update = false;
|
pending_geometry_update = false;
|
||||||
++postpone_geometry_updates;
|
++block_geometry_updates;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( --postpone_geometry_updates == 0 )
|
if( --block_geometry_updates == 0 )
|
||||||
{
|
{
|
||||||
if( pending_geometry_update )
|
if( pending_geometry_update )
|
||||||
{
|
{
|
||||||
|
@ -1822,7 +1852,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
|
||||||
if( !adjust && max_mode == old_mode )
|
if( !adjust && max_mode == old_mode )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GeometryUpdatesPostponer blocker( this );
|
GeometryUpdatesBlocker blocker( this );
|
||||||
|
|
||||||
// maximing one way and unmaximizing the other way shouldn't happen
|
// maximing one way and unmaximizing the other way shouldn't happen
|
||||||
Q_ASSERT( !( vertical && horizontal )
|
Q_ASSERT( !( vertical && horizontal )
|
||||||
|
@ -2074,7 +2104,7 @@ void Client::setFullScreen( bool set, bool user )
|
||||||
if( was_fs == isFullScreen())
|
if( was_fs == isFullScreen())
|
||||||
return;
|
return;
|
||||||
StackingUpdatesBlocker blocker1( workspace());
|
StackingUpdatesBlocker blocker1( workspace());
|
||||||
GeometryUpdatesPostponer blocker2( this );
|
GeometryUpdatesBlocker blocker2( this );
|
||||||
workspace()->updateClientLayer( this ); // active fullscreens get different layer
|
workspace()->updateClientLayer( this ); // active fullscreens get different layer
|
||||||
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
|
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
|
||||||
updateDecoration( false, false );
|
updateDecoration( false, false );
|
||||||
|
@ -2230,7 +2260,7 @@ bool Client::startMoveResize()
|
||||||
XMapRaised( display(), move_resize_grab_window );
|
XMapRaised( display(), move_resize_grab_window );
|
||||||
if( XGrabPointer( display(), move_resize_grab_window, False,
|
if( XGrabPointer( display(), move_resize_grab_window, False,
|
||||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask,
|
ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask,
|
||||||
GrabModeAsync, GrabModeAsync, move_resize_grab_window, cursor.handle(), xTime() ) == Success )
|
GrabModeAsync, GrabModeAsync, None, cursor.handle(), xTime() ) == Success )
|
||||||
has_grab = true;
|
has_grab = true;
|
||||||
if( XGrabKeyboard( display(), frameId(), False, GrabModeAsync, GrabModeAsync, xTime() ) == Success )
|
if( XGrabKeyboard( display(), frameId(), False, GrabModeAsync, GrabModeAsync, xTime() ) == Success )
|
||||||
has_grab = true;
|
has_grab = true;
|
||||||
|
@ -2260,6 +2290,8 @@ bool Client::startMoveResize()
|
||||||
// not needed anymore? kapp->installEventFilter( eater );
|
// not needed anymore? kapp->installEventFilter( eater );
|
||||||
}
|
}
|
||||||
Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
|
Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
|
||||||
|
if( effects )
|
||||||
|
effects->windowUserMovedResized( effectWindow(), true, false );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2273,6 +2305,8 @@ void Client::finishMoveResize( bool cancel )
|
||||||
checkMaximizeGeometry();
|
checkMaximizeGeometry();
|
||||||
// FRAME update();
|
// FRAME update();
|
||||||
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
|
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
|
||||||
|
if( effects )
|
||||||
|
effects->windowUserMovedResized( effectWindow(), false, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::leaveMoveResize()
|
void Client::leaveMoveResize()
|
||||||
|
@ -2536,7 +2570,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
||||||
}
|
}
|
||||||
if ( isMove() )
|
if ( isMove() )
|
||||||
workspace()->clientMoved(globalPos, xTime());
|
workspace()->clientMoved(globalPos, xTime());
|
||||||
|
if( effects )
|
||||||
|
effects->windowUserMovedResized( effectWindow(), false, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in a new issue