From ca856c28e15b3d44063bb76aa58cb1e4f5621eb2 Mon Sep 17 00:00:00 2001 From: Philip Falkner Date: Sat, 10 Feb 2007 18:28:04 +0000 Subject: [PATCH] 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 --- geometry.cpp | 99 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 32 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 5b73f062a8..a35ac49bac 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -28,6 +28,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "notifications.h" #include "geometrytip.h" #include "rules.h" +#include "effects.h" #include #include @@ -48,8 +49,14 @@ void Workspace::desktopResized() desktop_geometry.width = geom.width(); desktop_geometry.height = geom.height(); rootInfo->setDesktopGeometry( -1, desktop_geometry ); + updateClientArea(); 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 ) desktop = currentDesktop(); QDesktopWidget *desktopwidget = KApplication::desktop(); - int screen = desktopwidget->isVirtualDesktop() ? desktopwidget->screenNumber( p ) : desktopwidget->primaryScreen(); + int screen = desktopwidget->screenNumber( p ); if( screen < 0 ) screen = desktopwidget->primaryScreen(); 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()) { QRect orig_geometry = geometry(); - GeometryUpdatesPostponer blocker( this ); + GeometryUpdatesBlocker blocker( this ); move( new_pos ); plainResize( ns ); 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 { QRect orig_geometry = geometry(); - GeometryUpdatesPostponer blocker( this ); + GeometryUpdatesBlocker blocker( this ); int save_gravity = xSizeHint.win_gravity; xSizeHint.win_gravity = gravity; 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 ); } - if( force == NormalGeometrySet && frame_geometry == QRect( x, y, w, h )) + if( force == NormalGeometrySet && geom == QRect( x, y, w, h )) return; - frame_geometry = QRect( x, y, w, h ); + geom = QRect( x, y, w, h ); updateWorkareaDiffs(); - if( postpone_geometry_updates != 0 ) + if( block_geometry_updates != 0 ) { pending_geometry_update = true; return; } - resizeDecoration( QSize( w, h )); - XMoveResizeWindow( display(), frameId(), x, y, w, h ); -// resizeDecoration( QSize( w, h )); - if( !isShade()) + if( geom_before_block.size() != geom.size()) { - QSize cs = clientSize(); - XMoveResizeWindow( display(), wrapperId(), clientPos().x(), clientPos().y(), - cs.width(), cs.height()); - XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height()); + resizeDecoration( QSize( w, h )); + XMoveResizeWindow( display(), frameId(), x, y, w, h ); + if( !isShade()) + { + 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? updateWorkareaDiffs(); sendSyntheticConfigureNotify(); updateWindowRules(); 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 ) @@ -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() << kBacktrace() << endl; } - if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h )) + if( force == NormalGeometrySet && geom.size() == QSize( w, h )) return; - frame_geometry.setSize( QSize( w, h )); + geom.setSize( QSize( w, h )); updateWorkareaDiffs(); - if( postpone_geometry_updates != 0 ) + if( block_geometry_updates != 0 ) { pending_geometry_update = true; return; @@ -1735,11 +1757,17 @@ void Client::plainResize( int w, int h, ForceGeometry_t force ) cs.width(), cs.height()); XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height()); } - updateShape(); + if( shape()) + updateShape(); updateWorkareaDiffs(); sendSyntheticConfigureNotify(); updateWindowRules(); 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 ) { - if( force == NormalGeometrySet && frame_geometry.topLeft() == QPoint( x, y )) + if( force == NormalGeometrySet && geom.topLeft() == QPoint( x, y )) return; - frame_geometry.moveTopLeft( QPoint( x, y )); + geom.moveTopLeft( QPoint( x, y )); updateWorkareaDiffs(); - if( postpone_geometry_updates != 0 ) + if( block_geometry_updates != 0 ) { pending_geometry_update = true; return; @@ -1760,20 +1788,22 @@ void Client::move( int x, int y, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + // client itself is not damaged + workspace()->addDamage( geom_before_block ); // TODO add damage only if not obscured + geom_before_block = geom; } - -void Client::postponeGeometryUpdates( bool postpone ) +void Client::blockGeometryUpdates( bool block ) { - if( postpone ) + if( block ) { - if( postpone_geometry_updates == 0 ) + if( block_geometry_updates == 0 ) pending_geometry_update = false; - ++postpone_geometry_updates; + ++block_geometry_updates; } else { - if( --postpone_geometry_updates == 0 ) + if( --block_geometry_updates == 0 ) { if( pending_geometry_update ) { @@ -1822,7 +1852,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust ) if( !adjust && max_mode == old_mode ) return; - GeometryUpdatesPostponer blocker( this ); + GeometryUpdatesBlocker blocker( this ); // maximing one way and unmaximizing the other way shouldn't happen Q_ASSERT( !( vertical && horizontal ) @@ -2074,7 +2104,7 @@ void Client::setFullScreen( bool set, bool user ) if( was_fs == isFullScreen()) return; StackingUpdatesBlocker blocker1( workspace()); - GeometryUpdatesPostponer blocker2( this ); + GeometryUpdatesBlocker blocker2( this ); workspace()->updateClientLayer( this ); // active fullscreens get different layer info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen ); updateDecoration( false, false ); @@ -2230,7 +2260,7 @@ bool Client::startMoveResize() XMapRaised( display(), move_resize_grab_window ); if( XGrabPointer( display(), move_resize_grab_window, False, 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; if( XGrabKeyboard( display(), frameId(), False, GrabModeAsync, GrabModeAsync, xTime() ) == Success ) has_grab = true; @@ -2260,6 +2290,8 @@ bool Client::startMoveResize() // not needed anymore? kapp->installEventFilter( eater ); } Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart ); + if( effects ) + effects->windowUserMovedResized( effectWindow(), true, false ); return true; } @@ -2273,6 +2305,8 @@ void Client::finishMoveResize( bool cancel ) checkMaximizeGeometry(); // FRAME update(); Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd ); + if( effects ) + effects->windowUserMovedResized( effectWindow(), false, true ); } void Client::leaveMoveResize() @@ -2536,7 +2570,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root ) } if ( isMove() ) workspace()->clientMoved(globalPos, xTime()); + if( effects ) + effects->windowUserMovedResized( effectWindow(), false, false ); } - } // namespace