Looks like using XserverRegion for keeping damage regions
wasn't that good idea. Changed to QRegion. svn path=/branches/work/kwin_composite/; revision=590648
This commit is contained in:
parent
f3119d2550
commit
649887d6c2
16 changed files with 258 additions and 222 deletions
140
composite.cpp
140
composite.cpp
|
@ -69,9 +69,7 @@ void Workspace::finishCompositing()
|
|||
effects = NULL;
|
||||
delete scene;
|
||||
scene = NULL;
|
||||
if( damage_region != None )
|
||||
XFixesDestroyRegion( display(), damage_region );
|
||||
damage_region = None;
|
||||
damage_region = QRegion();
|
||||
for( ClientList::ConstIterator it = clients.begin();
|
||||
it != clients.end();
|
||||
++it )
|
||||
|
@ -84,107 +82,41 @@ void Workspace::finishCompositing()
|
|||
}
|
||||
}
|
||||
|
||||
void Workspace::addDamage( const QRect& r )
|
||||
{
|
||||
addDamage( r.x(), r.y(), r.width(), r.height());
|
||||
}
|
||||
|
||||
void Workspace::addDamage( int x, int y, int w, int h )
|
||||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
XRectangle r;
|
||||
r.x = x;
|
||||
r.y = y;
|
||||
r.width = w;
|
||||
r.height = h;
|
||||
addDamage( XFixesCreateRegion( display(), &r, 1 ), true );
|
||||
damage_region += QRegion( x, y, w, h );
|
||||
}
|
||||
|
||||
void Workspace::addDamage( XserverRegion r, bool destroy )
|
||||
void Workspace::addDamage( const QRect& r )
|
||||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
if( damage_region != None )
|
||||
{
|
||||
XFixesUnionRegion( display(), damage_region, damage_region, r );
|
||||
if( destroy )
|
||||
XFixesDestroyRegion( display(), r );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( destroy )
|
||||
damage_region = r;
|
||||
else
|
||||
{
|
||||
damage_region = XFixesCreateRegion( display(), NULL, 0 );
|
||||
XFixesCopyRegion( display(), damage_region, r );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::addDamage( Toplevel* c, const QRect& r )
|
||||
{
|
||||
addDamage( c, r.x(), r.y(), r.width(), r.height());
|
||||
damage_region += r;
|
||||
}
|
||||
|
||||
void Workspace::addDamage( Toplevel* c, int x, int y, int w, int h )
|
||||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
XRectangle r;
|
||||
r.x = x;
|
||||
r.y = y;
|
||||
r.width = w;
|
||||
r.height = h;
|
||||
addDamage( c, XFixesCreateRegion( display(), &r, 1 ), true );
|
||||
addDamage( c, QRect( x, y, w, h ));
|
||||
}
|
||||
|
||||
void Workspace::addDamage( Toplevel* c, XserverRegion r, bool destroy )
|
||||
void Workspace::addDamage( Toplevel* c, const QRect& r )
|
||||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
if( !destroy )
|
||||
{
|
||||
XserverRegion r2 = XFixesCreateRegion( display(), NULL, 0 );
|
||||
XFixesCopyRegion( display(), r2, r );
|
||||
r = r2;
|
||||
destroy = true;
|
||||
}
|
||||
scene->transformWindowDamage( c, r );
|
||||
if( damage_region != None )
|
||||
{
|
||||
XFixesUnionRegion( display(), damage_region, damage_region, r );
|
||||
XFixesDestroyRegion( display(), r );
|
||||
}
|
||||
else
|
||||
damage_region = r;
|
||||
QRegion r2( r );
|
||||
scene->transformWindowDamage( c, r2 );
|
||||
damage_region += r2;
|
||||
}
|
||||
|
||||
void Workspace::compositeTimeout()
|
||||
{
|
||||
ToplevelList windows;
|
||||
foreach( Toplevel* c, clients )
|
||||
windows.append( c );
|
||||
foreach( Toplevel* c, unmanaged )
|
||||
windows.append( c );
|
||||
foreach( Toplevel* c, windows )
|
||||
{
|
||||
if( c->damage() != None )
|
||||
{
|
||||
if( damage_region == None )
|
||||
damage_region = XFixesCreateRegion( display(), NULL, 0 );
|
||||
XserverRegion r = XFixesCreateRegion( display(), NULL, 0 );
|
||||
XFixesCopyRegion( display(), r, c->damage());
|
||||
scene->transformWindowDamage( c, r );
|
||||
XFixesUnionRegion( display(), damage_region, damage_region, r );
|
||||
XFixesDestroyRegion( display(), r );
|
||||
c->resetDamage();
|
||||
}
|
||||
}
|
||||
if( damage_region == None ) // no damage
|
||||
if( damage_region.isEmpty()) // no damage
|
||||
return;
|
||||
windows.clear();
|
||||
ToplevelList windows;
|
||||
Window* children;
|
||||
unsigned int children_count;
|
||||
Window dummy;
|
||||
|
@ -202,8 +134,7 @@ void Workspace::compositeTimeout()
|
|||
windows.append( c );
|
||||
}
|
||||
scene->paint( damage_region, windows );
|
||||
XFixesDestroyRegion( display(), damage_region );
|
||||
damage_region = None;
|
||||
damage_region = QRegion();
|
||||
}
|
||||
|
||||
//****************************************
|
||||
|
@ -217,6 +148,7 @@ void Toplevel::setupCompositing()
|
|||
if( damage_handle != None )
|
||||
return;
|
||||
damage_handle = XDamageCreate( display(), handle(), XDamageReportRawRectangles );
|
||||
damage_region = QRegion( 0, 0, width(), height());
|
||||
}
|
||||
|
||||
void Toplevel::finishCompositing()
|
||||
|
@ -228,9 +160,7 @@ void Toplevel::finishCompositing()
|
|||
if( window_pixmap != None )
|
||||
XFreePixmap( display(), window_pixmap );
|
||||
window_pixmap = None;
|
||||
if( damage_region != None )
|
||||
XFixesDestroyRegion( display(), damage_region );
|
||||
damage_region = None;
|
||||
damage_region = QRegion();
|
||||
}
|
||||
|
||||
void Toplevel::resetWindowPixmap()
|
||||
|
@ -251,8 +181,7 @@ Pixmap Toplevel::windowPixmap() const
|
|||
|
||||
void Toplevel::damageNotifyEvent( XDamageNotifyEvent* e )
|
||||
{
|
||||
XserverRegion r = XFixesCreateRegion( display(), &e->area, 1 );
|
||||
addDamage( r, true );
|
||||
addDamage( e->area.x, e->area.y, e->area.width, e->area.height );
|
||||
}
|
||||
|
||||
void Toplevel::addDamage( const QRect& r )
|
||||
|
@ -264,41 +193,18 @@ void Toplevel::addDamage( int x, int y, int w, int h )
|
|||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
XRectangle r;
|
||||
r.x = x;
|
||||
r.y = y;
|
||||
r.width = w;
|
||||
r.height = h;
|
||||
addDamage( XFixesCreateRegion( display(), &r, 1 ), true );
|
||||
}
|
||||
|
||||
void Toplevel::addDamage( XserverRegion r, bool destroy )
|
||||
{
|
||||
if( !compositing())
|
||||
return;
|
||||
if( damage_region != None )
|
||||
{
|
||||
XFixesUnionRegion( display(), damage_region, damage_region, r );
|
||||
if( destroy )
|
||||
XFixesDestroyRegion( display(), r );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( destroy )
|
||||
damage_region = r;
|
||||
else
|
||||
{
|
||||
damage_region = XFixesCreateRegion( display(), NULL, 0 );
|
||||
XFixesCopyRegion( display(), damage_region, r );
|
||||
}
|
||||
}
|
||||
QRect r( x, y, w, h );
|
||||
damage_region += r;
|
||||
r.translate( this->x(), this->y());
|
||||
// this could be possibly optimized to damage Workspace only if the toplevel
|
||||
// is actually visible there and not obscured by something, but I guess
|
||||
// that's not really worth it
|
||||
workspace()->addDamage( this, r );
|
||||
}
|
||||
|
||||
void Toplevel::resetDamage()
|
||||
{
|
||||
if( damage_region != None )
|
||||
XFixesDestroyRegion( display(), damage_region );
|
||||
damage_region = None;
|
||||
damage_region = QRegion();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
105
events.cpp
105
events.cpp
|
@ -21,6 +21,8 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "tabbox.h"
|
||||
#include "group.h"
|
||||
#include "rules.h"
|
||||
#include "unmanaged.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include <QWhatsThis>
|
||||
#include <QApplication>
|
||||
|
@ -262,6 +264,11 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
if( c->windowEvent( e ))
|
||||
return true;
|
||||
}
|
||||
else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( e->xany.window )))
|
||||
{
|
||||
if( c->windowEvent( e ))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Window special = findSpecialEventWindow( e );
|
||||
|
@ -319,13 +326,8 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt
|
||||
}
|
||||
case MapNotify:
|
||||
|
||||
return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt
|
||||
|
||||
case ReparentNotify:
|
||||
{
|
||||
//do not confuse Qt with these events. After all, _we_ are the
|
||||
|
@ -375,6 +377,22 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MapNotify:
|
||||
{
|
||||
if( e->xmap.override_redirect )
|
||||
{
|
||||
Unmanaged* c = findUnmanaged( HandleMatchPredicate( e->xmap.window ));
|
||||
if( c == NULL )
|
||||
c = createUnmanaged( e->xmap.window );
|
||||
if( c )
|
||||
{
|
||||
c->windowEvent( e );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt
|
||||
}
|
||||
|
||||
case EnterNotify:
|
||||
{
|
||||
if ( QWhatsThis::inWhatsThisMode() )
|
||||
|
@ -455,6 +473,10 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
XRefreshKeyboardMapping( &e->xmapping );
|
||||
tab_box->updateKeyMapping();
|
||||
break;
|
||||
case Expose:
|
||||
if( e->xexpose.window == rootWindow() && compositing()) // root window needs repainting
|
||||
addDamage( e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -551,6 +573,19 @@ bool Client::windowEvent( XEvent* e )
|
|||
if( demandAttentionKNotifyTimer != NULL )
|
||||
demandAttentionKNotify();
|
||||
}
|
||||
if( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
|
||||
{
|
||||
if( compositing())
|
||||
{
|
||||
addDamage( rect());
|
||||
scene->windowOpacityChanged( this );
|
||||
}
|
||||
else
|
||||
{ // forward to the frame if there's possibly another compositing manager running
|
||||
NETWinInfo i( display(), frameId(), rootWindow(), 0 );
|
||||
i.setOpacity( info->opacity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO move all focus handling stuff to separate file?
|
||||
|
@ -637,12 +672,17 @@ bool Client::windowEvent( XEvent* e )
|
|||
default:
|
||||
if( e->xany.window == window())
|
||||
{
|
||||
if( e->type == Shape::shapeEvent() )
|
||||
if( e->type == Extensions::shapeNotifyEvent() )
|
||||
{
|
||||
is_shape = Shape::hasShape( window()); // workaround for #19644
|
||||
is_shape = hasShape( window()); // workaround for #19644
|
||||
updateShape();
|
||||
}
|
||||
}
|
||||
if( e->xany.window == frameId())
|
||||
{
|
||||
if( e->type == Extensions::damageNotifyEvent())
|
||||
damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e ));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true; // eat all events
|
||||
|
@ -1562,6 +1602,57 @@ void Client::keyPressEvent( uint key_code )
|
|||
QCursor::setPos( pos );
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Unmanaged
|
||||
// ****************************************
|
||||
|
||||
bool Unmanaged::windowEvent( XEvent* e )
|
||||
{
|
||||
unsigned long dirty[ 2 ];
|
||||
info->event( e, dirty, 2 ); // pass through the NET stuff
|
||||
if( dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
|
||||
{
|
||||
scene->windowOpacityChanged( this );
|
||||
addDamage( rect());
|
||||
}
|
||||
switch (e->type)
|
||||
{
|
||||
case UnmapNotify:
|
||||
unmapNotifyEvent( &e->xunmap );
|
||||
break;
|
||||
case MapNotify:
|
||||
mapNotifyEvent( &e->xmap );
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
configureNotifyEvent( &e->xconfigure );
|
||||
break;
|
||||
default:
|
||||
if( e->type == Extensions::damageNotifyEvent())
|
||||
damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e ));
|
||||
break;
|
||||
}
|
||||
return true; // eat all events
|
||||
}
|
||||
|
||||
void Unmanaged::mapNotifyEvent( XMapEvent* )
|
||||
{
|
||||
}
|
||||
|
||||
void Unmanaged::unmapNotifyEvent( XUnmapEvent* )
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
void Unmanaged::configureNotifyEvent( XConfigureEvent* e )
|
||||
{
|
||||
resetWindowPixmap();
|
||||
// TODO add damage only if the window is not obscured
|
||||
workspace()->addDamage( this, geometry());
|
||||
geom = QRect( e->x, e->y, e->width, e->height );
|
||||
// TODO maybe only damage changed area
|
||||
addDamage( rect());
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Group
|
||||
// ****************************************
|
||||
|
|
34
geometry.cpp
34
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 <QX11Info>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
|
@ -1657,9 +1658,11 @@ 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 );
|
||||
// TODO add damage only if not obscured
|
||||
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||
geom = QRect( x, y, w, h );
|
||||
updateWorkareaDiffs();
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
|
@ -1676,12 +1679,15 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
|||
cs.width(), cs.height());
|
||||
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
// SELI TODO won't this be too expensive?
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
resetWindowPixmap();
|
||||
addDamage( rect());
|
||||
}
|
||||
|
||||
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||
|
@ -1711,9 +1717,10 @@ 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 ));
|
||||
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||
geom.setSize( QSize( w, h ));
|
||||
updateWorkareaDiffs();
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
|
@ -1730,11 +1737,15 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|||
cs.width(), cs.height());
|
||||
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
resetWindowPixmap();
|
||||
// TODO add damage only in added area?
|
||||
addDamage( rect());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1742,9 +1753,10 @@ 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 ));
|
||||
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||
geom.moveTopLeft( QPoint( x, y ));
|
||||
updateWorkareaDiffs();
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
|
@ -1755,9 +1767,10 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
|||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
// client itself is not damaged
|
||||
workspace()->addDamage( this, geometry());
|
||||
}
|
||||
|
||||
|
||||
void Client::postponeGeometryUpdates( bool postpone )
|
||||
{
|
||||
if( postpone )
|
||||
|
@ -2255,6 +2268,8 @@ bool Client::startMoveResize()
|
|||
// not needed anymore? kapp->installEventFilter( eater );
|
||||
}
|
||||
Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
|
||||
if( effects )
|
||||
effects->windowUserMovedResized( this, true, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2268,6 +2283,8 @@ void Client::finishMoveResize( bool cancel )
|
|||
checkMaximizeGeometry();
|
||||
// FRAME update();
|
||||
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
|
||||
if( effects )
|
||||
effects->windowUserMovedResized( this, false, true );
|
||||
}
|
||||
|
||||
void Client::leaveMoveResize()
|
||||
|
@ -2531,7 +2548,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
|||
}
|
||||
if ( isMove() )
|
||||
workspace()->clientMoved(globalPos, xTime());
|
||||
if( effects )
|
||||
effects->windowUserMovedResized( this, false, false );
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -42,7 +42,7 @@ void Scene::windowDeleted( Toplevel* )
|
|||
{
|
||||
}
|
||||
|
||||
void Scene::transformWindowDamage( Toplevel*, XserverRegion ) const
|
||||
void Scene::transformWindowDamage( Toplevel*, QRegion& ) const
|
||||
{
|
||||
}
|
||||
|
||||
|
|
4
scene.h
4
scene.h
|
@ -23,12 +23,12 @@ class Scene
|
|||
public:
|
||||
Scene( Workspace* ws );
|
||||
virtual ~Scene();
|
||||
virtual void paint( XserverRegion damage, ToplevelList windows ) = 0;
|
||||
virtual void paint( QRegion damage, ToplevelList windows ) = 0;
|
||||
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
|
||||
virtual void transformWindowDamage( Toplevel*, QRegion& ) const;
|
||||
virtual void updateTransformation( Toplevel* );
|
||||
protected:
|
||||
Workspace* wspace;
|
||||
|
|
|
@ -29,7 +29,7 @@ SceneBasic::~SceneBasic()
|
|||
{
|
||||
}
|
||||
|
||||
void SceneBasic::paint( XserverRegion, ToplevelList windows )
|
||||
void SceneBasic::paint( QRegion, ToplevelList windows )
|
||||
{
|
||||
Pixmap composite_pixmap = XCreatePixmap( display(), rootWindow(), displayWidth(), displayHeight(), QX11Info::appDepth());
|
||||
XGCValues val;
|
||||
|
|
|
@ -22,7 +22,7 @@ class SceneBasic
|
|||
public:
|
||||
SceneBasic( Workspace* ws );
|
||||
virtual ~SceneBasic();
|
||||
virtual void paint( XserverRegion damage, ToplevelList windows );
|
||||
virtual void paint( QRegion damage, ToplevelList windows );
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -114,7 +114,7 @@ static void quadDraw( int x, int y, int w, int h )
|
|||
glVertex2i( x, y + h );
|
||||
}
|
||||
|
||||
void SceneOpenGL::paint( XserverRegion, ToplevelList windows )
|
||||
void SceneOpenGL::paint( QRegion, ToplevelList windows )
|
||||
{
|
||||
grabXServer();
|
||||
glXWaitX();
|
||||
|
|
|
@ -25,7 +25,7 @@ class SceneOpenGL
|
|||
public:
|
||||
SceneOpenGL( Workspace* ws );
|
||||
virtual ~SceneOpenGL();
|
||||
virtual void paint( XserverRegion damage, ToplevelList windows );
|
||||
virtual void paint( QRegion damage, ToplevelList windows );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
private:
|
||||
|
|
|
@ -22,6 +22,32 @@ namespace KWinInternal
|
|||
// SceneXrender
|
||||
//****************************************
|
||||
|
||||
struct RegionDebug
|
||||
{
|
||||
RegionDebug( XserverRegion r ) : rr( r ) {}
|
||||
XserverRegion rr;
|
||||
};
|
||||
|
||||
#ifdef NDEBUG
|
||||
inline
|
||||
kndbgstream& operator<<( kndbgstream& stream, RegionDebug ) { return stream; }
|
||||
#else
|
||||
kdbgstream& operator<<( kdbgstream& stream, RegionDebug r )
|
||||
{
|
||||
if( r.rr == None )
|
||||
return stream << "EMPTY";
|
||||
int num;
|
||||
XRectangle* rects = XFixesFetchRegion( display(), r.rr, &num );
|
||||
if( rects == NULL || num == 0 )
|
||||
return stream << "EMPTY";
|
||||
for( int i = 0;
|
||||
i < num;
|
||||
++i )
|
||||
stream << "[" << rects[ i ].x << "+" << rects[ i ].y << " " << rects[ i ].width << "x" << rects[ i ].height << "]";
|
||||
return stream;
|
||||
}
|
||||
#endif
|
||||
|
||||
SceneXrender::SceneXrender( Workspace* ws )
|
||||
: Scene( ws )
|
||||
{
|
||||
|
@ -42,16 +68,24 @@ SceneXrender::~SceneXrender()
|
|||
(*it).free();
|
||||
}
|
||||
|
||||
void SceneXrender::paint( XserverRegion damage, ToplevelList windows )
|
||||
void SceneXrender::paint( QRegion dam, ToplevelList windows )
|
||||
{
|
||||
#if 1
|
||||
XRectangle r;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = displayWidth();
|
||||
r.height = displayHeight();
|
||||
XFixesSetRegion( display(), damage, &r, 1 );
|
||||
dam = QRegion( 0, 0, displayWidth(), displayHeight());
|
||||
#endif
|
||||
QVector< QRect > rects = dam.rects();
|
||||
XRectangle* xr = new XRectangle[ rects.count() ];
|
||||
for( int i = 0;
|
||||
i < rects.count();
|
||||
++i )
|
||||
{
|
||||
xr[ i ].x = rects[ i ].x();
|
||||
xr[ i ].y = rects[ i ].y();
|
||||
xr[ i ].width = rects[ i ].width();
|
||||
xr[ i ].height = rects[ i ].height();
|
||||
}
|
||||
XserverRegion damage = XFixesCreateRegion( display(), xr, rects.count());
|
||||
delete[] xr;
|
||||
// Use the damage region as the clip region for the root window
|
||||
XFixesSetPictureClipRegion( display(), front, 0, 0, damage );
|
||||
// Prepare pass for windows
|
||||
|
@ -144,9 +178,10 @@ void SceneXrender::paint( XserverRegion damage, ToplevelList windows )
|
|||
XFixesSetPictureClipRegion( display(), buffer, 0, 0, None );
|
||||
XRenderComposite( display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
|
||||
XFlush( display());
|
||||
XFixesDestroyRegion( display(), damage );
|
||||
}
|
||||
|
||||
void SceneXrender::transformWindowDamage( Toplevel* c, XserverRegion r ) const
|
||||
void SceneXrender::transformWindowDamage( Toplevel* c, QRegion& r ) const
|
||||
{
|
||||
if( !window_data.contains( c ))
|
||||
return;
|
||||
|
@ -154,17 +189,13 @@ void SceneXrender::transformWindowDamage( Toplevel* c, XserverRegion r ) const
|
|||
if( matrix.isIdentity())
|
||||
return;
|
||||
if( matrix.isOnlyTranslate())
|
||||
XFixesTranslateRegion( display(), r, int( matrix.xTranslate()), int( matrix.yTranslate()));
|
||||
r.translate( int( matrix.xTranslate()), int( matrix.yTranslate()));
|
||||
else
|
||||
{
|
||||
// The region here should be translated using the matrix, but that's not possible
|
||||
// (well, maybe fetch the region and transform manually - TODO check). So simply
|
||||
// mark whole screen as damaged.
|
||||
XRectangle s;
|
||||
s.x = s.y = 0;
|
||||
s.width = displayWidth();
|
||||
s.height = displayHeight();
|
||||
XFixesSetRegion( display(), r, &s, 1 );
|
||||
r = QRegion( 0, 0, displayWidth(), displayHeight());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,12 +30,12 @@ class SceneXrender
|
|||
public:
|
||||
SceneXrender( Workspace* ws );
|
||||
virtual ~SceneXrender();
|
||||
virtual void paint( XserverRegion damage, ToplevelList windows );
|
||||
virtual void paint( QRegion damage, ToplevelList windows );
|
||||
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
|
||||
virtual void transformWindowDamage( Toplevel*, QRegion& ) const;
|
||||
virtual void updateTransformation( Toplevel* );
|
||||
private:
|
||||
void createBuffer();
|
||||
|
|
|
@ -18,7 +18,6 @@ Toplevel::Toplevel( Workspace* ws )
|
|||
, id( None )
|
||||
, wspace( ws )
|
||||
, damage_handle( None )
|
||||
, damage_region( None )
|
||||
, window_pixmap( None )
|
||||
{
|
||||
}
|
||||
|
@ -26,7 +25,6 @@ Toplevel::Toplevel( Workspace* ws )
|
|||
Toplevel::~Toplevel()
|
||||
{
|
||||
assert( damage_handle == None );
|
||||
assert( damage_region == None );
|
||||
assert( window_pixmap == None );
|
||||
}
|
||||
|
||||
|
|
|
@ -60,8 +60,7 @@ class Toplevel
|
|||
void finishCompositing();
|
||||
void addDamage( const QRect& r );
|
||||
void addDamage( int x, int y, int w, int h );
|
||||
void addDamage( XserverRegion r, bool destroy );
|
||||
XserverRegion damage() const;
|
||||
QRegion damage() const;
|
||||
void resetDamage();
|
||||
protected:
|
||||
void setHandle( Window id );
|
||||
|
@ -75,7 +74,7 @@ class Toplevel
|
|||
Window id;
|
||||
Workspace* wspace;
|
||||
Damage damage_handle;
|
||||
XserverRegion damage_region;
|
||||
QRegion damage_region;
|
||||
mutable Pixmap window_pixmap;
|
||||
};
|
||||
|
||||
|
@ -185,7 +184,7 @@ inline bool Toplevel::isNormalWindow() const
|
|||
return windowType() == NET::Normal;
|
||||
}
|
||||
|
||||
inline XserverRegion Toplevel::damage() const
|
||||
inline QRegion Toplevel::damage() const
|
||||
{
|
||||
return damage_region;
|
||||
}
|
||||
|
|
81
utils.cpp
81
utils.cpp
|
@ -30,6 +30,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <X11/extensions/shape.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <QX11Info>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "atoms.h"
|
||||
|
@ -42,41 +43,54 @@ namespace KWinInternal
|
|||
|
||||
#ifndef KCMRULES
|
||||
|
||||
// used to store the return values of
|
||||
// XShapeQueryExtension.
|
||||
// Necessary since shaped window are an extension to X
|
||||
int Shape::kwin_shape_version = 0;
|
||||
int Shape::kwin_shape_event = 0;
|
||||
bool Extensions::has_shape = 0;
|
||||
int Extensions::shape_event_base = 0;
|
||||
bool Extensions::has_damage = 0;
|
||||
int Extensions::damage_event_base = 0;
|
||||
bool Extensions::has_composite = 0;
|
||||
bool Extensions::has_fixes = 0;
|
||||
|
||||
// does the window w need a shape combine mask around it?
|
||||
bool Shape::hasShape( WId w)
|
||||
void Extensions::init()
|
||||
{
|
||||
int xws, yws, xbs, ybs;
|
||||
unsigned int wws, hws, wbs, hbs;
|
||||
int boundingShaped = 0, clipShaped = 0;
|
||||
if (!available())
|
||||
return false;
|
||||
XShapeQueryExtents(display(), w,
|
||||
&boundingShaped, &xws, &yws, &wws, &hws,
|
||||
&clipShaped, &xbs, &ybs, &wbs, &hbs);
|
||||
return boundingShaped != 0;
|
||||
}
|
||||
|
||||
int Shape::shapeEvent()
|
||||
{
|
||||
return kwin_shape_event;
|
||||
}
|
||||
|
||||
void Shape::init()
|
||||
{
|
||||
kwin_shape_version = 0;
|
||||
int dummy;
|
||||
if( !XShapeQueryExtension( display(), &kwin_shape_event, &dummy ))
|
||||
return;
|
||||
int major, minor;
|
||||
if( !XShapeQueryVersion( display(), &major, &minor ))
|
||||
return;
|
||||
kwin_shape_version = major * 0x10 + minor;
|
||||
has_shape = XShapeQueryExtension( display(), &shape_event_base, &dummy);
|
||||
#ifdef HAVE_XDAMAGE
|
||||
has_damage = XDamageQueryExtension( display(), &damage_event_base, &dummy );
|
||||
#else
|
||||
has_damage = false;
|
||||
#endif
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
has_composite = XCompositeQueryExtension( display(), &dummy, &dummy );
|
||||
if( has_composite )
|
||||
{
|
||||
int major = 0;
|
||||
int minor = 2;
|
||||
XCompositeQueryVersion( display(), &major, &minor );
|
||||
if( major == 0 && minor < 2 )
|
||||
has_composite = false;
|
||||
}
|
||||
#else
|
||||
has_composite = false;
|
||||
#endif
|
||||
#ifdef HAVE_XFIXES
|
||||
has_fixes = XFixesQueryExtension( display(), &dummy, &dummy );
|
||||
#else
|
||||
has_fixes = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Extensions::shapeNotifyEvent()
|
||||
{
|
||||
return shape_event_base + ShapeNotify;
|
||||
}
|
||||
|
||||
int Extensions::damageNotifyEvent()
|
||||
{
|
||||
#ifdef HAVE_XDAMAGE
|
||||
return damage_event_base + XDamageNotify;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
|
||||
|
@ -300,7 +314,6 @@ bool grabbedXServer()
|
|||
{
|
||||
return server_grab_count > 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool isLocalMachine( const QByteArray& host )
|
||||
|
@ -367,8 +380,6 @@ void ShortcutDialog::accept()
|
|||
KShortcutDialog::accept();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifndef KCMRULES
|
||||
|
|
18
utils.h
18
utils.h
|
@ -44,11 +44,6 @@ struct XDamageNotifyEvent
|
|||
{
|
||||
};
|
||||
#endif
|
||||
#ifndef HAVE_XFIXES
|
||||
struct XserverRegion
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
|
||||
| NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
|
||||
|
@ -122,19 +117,6 @@ enum allowed_t { Allowed };
|
|||
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
|
||||
|
||||
|
||||
struct RegionDebug
|
||||
{
|
||||
RegionDebug( XserverRegion r ) : rr( r ) {}
|
||||
XserverRegion rr;
|
||||
};
|
||||
|
||||
#ifdef NDEBUG
|
||||
inline
|
||||
kndbgstream& operator<<( kndbgstream& stream, RegionDebug ) { return stream; }
|
||||
#else
|
||||
kdbgstream& operator<<( kdbgstream& stream, RegionDebug r );
|
||||
#endif
|
||||
|
||||
// Areas, mostly related to Xinerama
|
||||
enum clientAreaOption
|
||||
{
|
||||
|
|
|
@ -285,10 +285,10 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
|
||||
void addDamage( const QRect& r );
|
||||
void addDamage( int x, int y, int w, int h );
|
||||
void addDamage( XserverRegion r, bool destroy );
|
||||
// these damage the workspace without actually damaging the contents
|
||||
// of the toplevel - e.g. when the toplevel moves away from that area
|
||||
void addDamage( Toplevel* c, const QRect& r );
|
||||
void addDamage( Toplevel* c, int x, int y, int w, int h );
|
||||
void addDamage( Toplevel* c, XserverRegion r, bool destroy );
|
||||
|
||||
public slots:
|
||||
void refresh();
|
||||
|
@ -633,7 +633,7 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
bool forced_global_mouse_grab;
|
||||
friend class StackingUpdatesBlocker;
|
||||
QTimer compositeTimer;
|
||||
XserverRegion damage_region;
|
||||
QRegion damage_region;
|
||||
QSlider *transSlider;
|
||||
QPushButton *transButton;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue