diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b8cdaa191..bfe2acb0ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,9 @@ set(kwin_KDEINIT_SRCS composite.cpp toplevel.cpp unmanaged.cpp + scene.cpp + scene_basic.cpp + scene_xrender.cpp effects.cpp ) kde4_automoc(${kwin_KDEINIT_SRCS}) diff --git a/composite.cpp b/composite.cpp index dc91c2a690..d5e8d869dc 100644 --- a/composite.cpp +++ b/composite.cpp @@ -12,7 +12,8 @@ License. See the file "COPYING" for the exact licensing terms. #include "workspace.h" #include "client.h" #include "unmanaged.h" -#include "effects.h" +#include "scene.h" +#include "scene_basic.h" namespace KWinInternal { @@ -26,22 +27,24 @@ void Workspace::setupCompositing() { if( !Extensions::compositeAvailable() || !Extensions::damageAvailable()) return; - if( composite_pixmap != None ) + if( scene != NULL ) return; + // TODO start tracking unmanaged windows compositeTimer.start( 20 ); XCompositeRedirectSubwindows( display(), rootWindow(), CompositeRedirectManual ); - composite_pixmap = XCreatePixmap( display(), rootWindow(), displayWidth(), displayHeight(), QX11Info::appDepth()); setDamaged(); + scene = new SceneBasic( this ); } void Workspace::finishCompositing() { - if( composite_pixmap == None ) + if( scene == NULL ) return; XCompositeUnredirectSubwindows( display(), rootWindow(), CompositeRedirectManual ); - XFreePixmap( display(), composite_pixmap ); compositeTimer.stop(); - composite_pixmap = None; + // TODO stop tracking unmanaged windows + delete scene; + scene = NULL; } void Workspace::setDamaged() @@ -55,6 +58,7 @@ void Workspace::compositeTimeout() { if( !damaged ) return; + damaged = false; ToplevelList windows; Window* children; unsigned int children_count; @@ -65,44 +69,15 @@ void Workspace::compositeTimeout() ++i ) { if( Client* c = findClient( FrameIdMatchPredicate( children[ i ] ))) - windows.append( c ); + { + if( c->isShown( true ) && c->isOnCurrentDesktop()) + windows.append( c ); + } else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( children[ i ] ))) windows.append( c ); } - XGCValues val; - val.foreground = WhitePixel( display(), DefaultScreen( display())); - val.subwindow_mode = IncludeInferiors; - GC gc = XCreateGC( display(), composite_pixmap, GCForeground | GCSubwindowMode, &val ); - XFillRectangle( display(), composite_pixmap, gc, 0, 0, displayWidth(), displayHeight()); - for( ToplevelList::ConstIterator it = windows.begin(); - it != windows.end(); - ++it ) - { - if( Client* c = dynamic_cast< Client* >( *it )) - { - if( !c->isShown( true ) || !c->isOnCurrentDesktop()) - continue; - } -#if 1 - (*it)->windowPixmap(); // trigger creation - effects->paintWindow( *it ); -#else - QRect r = (*it)->geometry().intersect( QRect( 0, 0, displayWidth(), displayHeight())); - if( !r.isEmpty()) - { - XCopyArea( display(), (*it)->windowPixmap(), composite_pixmap, gc, - qMax( 0, -(*it)->x()), qMax( 0, -(*it)->y()), r.width(), r.height(), r.x(), r.y()); - } -#endif - } -#if 1 - effects->paintWorkspace( this ); -#else - XCopyArea( display(), composite_pixmap, rootWindow(), gc, 0, 0, displayWidth(), displayHeight(), 0, 0 ); -#endif - XFreeGC( display(), gc ); - XFlush( display()); - damaged = false; + scene->setWindows( windows ); + scene->paint(); } //**************************************** @@ -111,7 +86,7 @@ void Workspace::compositeTimeout() void Toplevel::setupCompositing() { - if( !workspace()->compositing()) + if( !compositing()) return; if( damage != None ) return; @@ -134,14 +109,14 @@ void Toplevel::finishCompositing() void Toplevel::setDamaged() { - if( !workspace()->compositing()) + if( !compositing()) return; workspace()->setDamaged(); } void Toplevel::resetWindowPixmap() { - if( !workspace()->compositing()) + if( !compositing()) return; if( window_pixmap != None ) XFreePixmap( display(), window_pixmap ); @@ -150,7 +125,7 @@ void Toplevel::resetWindowPixmap() Pixmap Toplevel::windowPixmap() const { - if( window_pixmap == None && workspace()->compositing()) + if( window_pixmap == None && compositing()) window_pixmap = XCompositeNameWindowPixmap( display(), handle()); return window_pixmap; } diff --git a/scene.cpp b/scene.cpp new file mode 100644 index 0000000000..2b1eb6e8d3 --- /dev/null +++ b/scene.cpp @@ -0,0 +1,36 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#include "scene_basic.h" + +namespace KWinInternal +{ + +//**************************************** +// Scene +//**************************************** + +Scene::Scene( Workspace* ws ) + : wspace( ws ) + { + } + +Scene::~Scene() + { + } + +void Scene::setWindows( const ToplevelList& list ) + { + windows = list; + } + +Scene* scene; + +} // namespace diff --git a/scene.h b/scene.h new file mode 100644 index 0000000000..b9b3d954ba --- /dev/null +++ b/scene.h @@ -0,0 +1,37 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_SCENE_H +#define KWIN_SCENE_H + +#include "utils.h" + +namespace KWinInternal +{ + +class Workspace; + +class Scene + { + public: + Scene( Workspace* ws ); + virtual ~Scene(); + void setWindows( const ToplevelList& list ); + virtual void paint() = 0; + protected: + Workspace* wspace; + ToplevelList windows; + }; + +extern Scene* scene; + +} // namespace + +#endif diff --git a/scene_basic.cpp b/scene_basic.cpp new file mode 100644 index 0000000000..38dff23f9c --- /dev/null +++ b/scene_basic.cpp @@ -0,0 +1,57 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#include "scene_basic.h" + +#include "utils.h" +#include "client.h" + +namespace KWinInternal +{ + +//**************************************** +// SceneBasic +//**************************************** + +SceneBasic::SceneBasic( Workspace* ws ) + : Scene( ws ) + { + } + +SceneBasic::~SceneBasic() + { + } + +void SceneBasic::paint() + { + Pixmap composite_pixmap = XCreatePixmap( display(), rootWindow(), displayWidth(), displayHeight(), QX11Info::appDepth()); + XGCValues val; + val.foreground = WhitePixel( display(), DefaultScreen( display())); + val.subwindow_mode = IncludeInferiors; + GC gc = XCreateGC( display(), composite_pixmap, GCForeground | GCSubwindowMode, &val ); + XFillRectangle( display(), composite_pixmap, gc, 0, 0, displayWidth(), displayHeight()); + for( ToplevelList::ConstIterator it = windows.begin(); + it != windows.end(); + ++it ) + { + QRect r = (*it)->geometry().intersect( QRect( 0, 0, displayWidth(), displayHeight())); + if( !r.isEmpty()) + { + XCopyArea( display(), (*it)->windowPixmap(), composite_pixmap, gc, + qMax( 0, -(*it)->x()), qMax( 0, -(*it)->y()), r.width(), r.height(), r.x(), r.y()); + } + } + XCopyArea( display(), composite_pixmap, rootWindow(), gc, 0, 0, displayWidth(), displayHeight(), 0, 0 ); + XFreeGC( display(), gc ); + XFreePixmap( display(), composite_pixmap ); + XFlush( display()); + } + +} // namespace diff --git a/scene_basic.h b/scene_basic.h new file mode 100644 index 0000000000..ddd2d3dfe2 --- /dev/null +++ b/scene_basic.h @@ -0,0 +1,31 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_SCENE_BASIC_H +#define KWIN_SCENE_BASIC_H + +#include "scene.h" + +namespace KWinInternal +{ + +class SceneBasic + : public Scene + { + public: + SceneBasic( Workspace* ws ); + virtual ~SceneBasic(); + virtual void paint(); + }; + + +} // namespace + +#endif diff --git a/scene_xrender.cpp b/scene_xrender.cpp new file mode 100644 index 0000000000..d420e84393 --- /dev/null +++ b/scene_xrender.cpp @@ -0,0 +1,20 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#include "scene_xrender.h" + +namespace KWinInternal +{ + +//**************************************** +// SceneXrender +//**************************************** + +} // namespace diff --git a/scene_xrender.h b/scene_xrender.h new file mode 100644 index 0000000000..a4bf6a4bf7 --- /dev/null +++ b/scene_xrender.h @@ -0,0 +1,19 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_SCENE_XRENDER_H +#define KWIN_SCENE_XRENDER_H + +namespace KWinInternal +{ + +} // namespace + +#endif diff --git a/utils.h b/utils.h index 0654e959a9..cf16175228 100644 --- a/utils.h +++ b/utils.h @@ -250,6 +250,10 @@ int displayHeight() return XDisplayHeight( display(), DefaultScreen( display())); } +class Scene; +extern Scene* scene; +inline bool compositing() { return scene != NULL; } + // the docs say it's UrgencyHint, but it's often #defined as XUrgencyHint #ifndef UrgencyHint #define UrgencyHint XUrgencyHint diff --git a/workspace.cpp b/workspace.cpp index d3ba7d5b30..08b001f188 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -124,7 +124,6 @@ Workspace::Workspace( bool restore ) set_active_client_recursion( 0 ), block_stacking_updates( 0 ), forced_global_mouse_grab( false ), - composite_pixmap( None ), damaged( false ) { new KWinAdaptor( "org.kde.kwin", "/KWin", QDBus::sessionBus(), this ); diff --git a/workspace.h b/workspace.h index 8b72de8224..f0331b3625 100644 --- a/workspace.h +++ b/workspace.h @@ -78,8 +78,6 @@ class Workspace : public QObject, public KDecorationDefines static Workspace * self() { return _self; } - bool compositing() const { return composite_pixmap != None; } - bool workspaceEvent( XEvent * ); KDecoration* createDecoration( KDecorationBridge* bridge ); @@ -632,7 +630,6 @@ class Workspace : public QObject, public KDecorationDefines bool forced_global_mouse_grab; friend class StackingUpdatesBlocker; - Pixmap composite_pixmap; bool damaged; QTimer compositeTimer;