Make the Compositor a proper Singleton

The Compositor class actually behaves like a Singleton so it should be
one. Therefore four static methods are added:
* self() to access the Singleton
* createCompositor() to be used by Workspace to create the instance
* isCreated() to have a simple check whether the Singleton is already
  created
* compositing() as a shortcut to test whether the compositor has been
  created and is active

The isCreated() check is actually required as especially Clients might
be created and trying to access the Compositor before it is setup.
This commit is contained in:
Martin Gräßlin 2012-08-28 19:31:17 +02:00
parent 93564b7004
commit 7497ef9148
8 changed files with 80 additions and 30 deletions

View file

@ -216,10 +216,7 @@ void Bridge::grabXServer(bool grab)
bool Bridge::compositingActive() const
{
if (c->workspace()->compositor()) {
return c->workspace()->compositor()->isActive();
}
return false;
return Compositor::compositing();
}
QRect Bridge::transparentRect() const

View file

@ -617,7 +617,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapTop.handle());
}
if (workspace()->compositor() && workspace()->compositor()->isActive() && effects->compositingType() == OpenGLCompositing) {
if (effects->compositingType() == OpenGLCompositing) {
decorationPixmapTop = QPixmap(tr.size());
m_responsibleForDecoPixmap = false;
} else {
@ -636,7 +636,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapBottom.handle());
}
if (workspace()->compositor() && workspace()->compositor()->isActive() && effects->compositingType() == OpenGLCompositing) {
if (effects->compositingType() == OpenGLCompositing) {
decorationPixmapBottom = QPixmap(br.size());
m_responsibleForDecoPixmap = false;
} else {
@ -655,7 +655,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapLeft.handle());
}
if (workspace()->compositor() && workspace()->compositor()->isActive() && effects->compositingType() == OpenGLCompositing) {
if (effects->compositingType() == OpenGLCompositing) {
decorationPixmapLeft = QPixmap(lr.size());
m_responsibleForDecoPixmap = false;
} else {
@ -674,7 +674,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapRight.handle());
}
if (workspace()->compositor() && workspace()->compositor()->isActive() && effects->compositingType() == OpenGLCompositing) {
if (effects->compositingType() == OpenGLCompositing) {
decorationPixmapRight = QPixmap(rr.size());
m_responsibleForDecoPixmap = false;
} else {
@ -1269,8 +1269,8 @@ void Client::internalShow(allowed_t)
XMapWindow(display(), inputId());
updateHiddenPreview();
}
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
if (Compositor::isCreated()) {
Compositor::self()->checkUnredirect();
}
}
@ -1286,8 +1286,8 @@ void Client::internalHide(allowed_t)
updateHiddenPreview();
addWorkspaceRepaint(visibleRect());
workspace()->clientHidden(this);
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
if (Compositor::isCreated()) {
Compositor::self()->checkUnredirect();
}
}
@ -1305,8 +1305,8 @@ void Client::internalKeep(allowed_t)
updateHiddenPreview();
addWorkspaceRepaint(visibleRect());
workspace()->clientHidden(this);
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
if (Compositor::isCreated()) {
Compositor::self()->checkUnredirect();
}
}

View file

@ -77,12 +77,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin
{
Compositor *Compositor::s_compositor = NULL;
extern int currentRefreshRate();
//****************************************
// Workspace
//****************************************
Compositor *Compositor::createCompositor(QObject *parent)
{
Q_ASSERT(!s_compositor);
s_compositor = new Compositor(parent);
return s_compositor;
}
Compositor::Compositor(QObject* workspace)
: QObject(workspace)
, m_suspended(!options->isUseCompositing())
@ -750,8 +758,8 @@ bool Toplevel::setupCompositing()
damage_region = QRegion(0, 0, width(), height());
effect_window = new EffectWindowImpl(this);
unredirect = false;
workspace()->compositor()->checkUnredirect(true);
workspace()->compositor()->scene()->windowAdded(this);
Compositor::self()->checkUnredirect(true);
Compositor::self()->scene()->windowAdded(this);
return true;
}
@ -760,7 +768,7 @@ void Toplevel::finishCompositing()
damageRatio = 0.0;
if (damage_handle == None)
return;
workspace()->compositor()->checkUnredirect(true);
Compositor::self()->checkUnredirect(true);
if (effect_window->window() == this) { // otherwise it's already passed to Deleted, don't free data
discardWindowPixmap();
delete effect_window;
@ -874,7 +882,7 @@ void Toplevel::damageNotifyEvent(XDamageNotifyEvent* e)
bool Toplevel::compositing() const
{
Compositor *c = workspace()->compositor();
Compositor *c = Compositor::self();
return c && c->hasScene();
}
@ -1035,7 +1043,7 @@ void Toplevel::addWorkspaceRepaint(const QRect& r2)
{
if (!compositing())
return;
workspace()->compositor()->addRepaint(r2);
Compositor::self()->addRepaint(r2);
}
bool Toplevel::updateUnredirectedState()
@ -1063,7 +1071,7 @@ void Toplevel::suspendUnredirect(bool suspend)
if (unredirectSuspend == suspend)
return;
unredirectSuspend = suspend;
workspace()->compositor()->checkUnredirect();
Compositor::self()->checkUnredirect();
}
//****************************************

View file

@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KWIN_COMPOSITE_H
#include <QtCore/QObject>
#include <QtCore/QElapsedTimer>
#include <QtCore/QTimer>
#include <QtCore/QElapsedTimer>
#include <QtCore/QBasicTimer>
@ -38,7 +39,6 @@ class Scene;
class Compositor : public QObject {
Q_OBJECT
public:
Compositor(QObject *workspace);
~Compositor();
// when adding repaints caused by a window, you probably want to use
// either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint()
@ -93,6 +93,52 @@ public:
return m_scene;
}
/**
* @brief Factory Method to create the Compositor singleton.
*
* This method is mainly used by Workspace to create the Compositor Singleton as a child
* of the Workspace.
*
* To actually access the Compositor instance use @link self.
*
* @param parent The parent object
* @return :Compositor* Created Compositor if not already created
* @warning This method is not Thread safe.
* @see self
**/
static Compositor *createCompositor(QObject *parent);
/**
* @brief Singleton getter for the Compositor object.
*
* Ensure that the Compositor has been created through createCompositor prior to access
* this method.
*
* @return :Compositor* The Compositor instance
* @see createCompositor
**/
static Compositor *self() {
Q_ASSERT(s_compositor);
return s_compositor;
}
/**
* @brief Checks whether the Compositor has already been created by the Workspace.
*
* This method can be used to check whether self will return the Compositor instance or @c null.
*
* @return bool @c true if the Compositor has been created, @c false otherwise
**/
static bool isCreated() {
return s_compositor != NULL;
}
/**
* @brief Static check to test whether the Compositor is available and active.
*
* @return bool @c true if there is a Compositor and it is active, @c false otherwise
**/
static bool compositing() {
return s_compositor != NULL && s_compositor->isActive();
}
public Q_SLOTS:
void addRepaintFull();
/**
@ -142,6 +188,7 @@ private Q_SLOTS:
void slotConfigChanged();
private:
Compositor(QObject *workspace);
/**
* Suspends or Resumes the Compositor.
* That is stops the Scene in case of @p suspend and restores otherwise.
@ -181,6 +228,8 @@ private:
bool m_finishing; // finish() sets this variable while shutting down
int m_timeSinceLastVBlank, m_nextFrameDelay;
Scene *m_scene;
static Compositor *s_compositor;
};
}

View file

@ -2027,9 +2027,9 @@ void Client::move(int x, int y, ForceGeometry_t force)
updateWindowRules(Rules::Position);
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
if (workspace()->compositor()) {
if (Compositor::isCreated()) {
// TODO: move out of geometry.cpp, is this really needed here?
workspace()->compositor()->checkUnredirect();
Compositor::self()->checkUnredirect();
}
// client itself is not damaged
const QRect deco_rect = visibleRect();

View file

@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE.
#include "paintredirector.h"
#include "workspace.h"
#include "composite.h"
#include <kdebug.h>
#include <qevent.h>
#include <qpainter.h>
@ -82,7 +82,7 @@ bool PaintRedirector::eventFilter(QObject* o, QEvent* e)
break;
}
case QEvent::Paint: {
if (!Workspace::self()->compositingActive()) {
if (!Compositor::compositing()) {
return false;
}
if (!recursionCheck) {

View file

@ -205,7 +205,7 @@ Workspace::Workspace(bool restore)
tab_box = new TabBox::TabBox(this);
#endif
m_compositor = new Compositor(this);
m_compositor = Compositor::createCompositor(this);
connect(this, SIGNAL(currentDesktopChanged(int,KWin::Client*)), m_compositor, SLOT(addRepaintFull()));
connect(m_compositor, SIGNAL(compositingToggled(bool)), SIGNAL(compositingToggled(bool)));
connect(m_compositor, SIGNAL(compositingToggled(bool)), SLOT(slotCompositingToggled()));

View file

@ -537,10 +537,6 @@ public:
return movingClient;
}
Compositor* compositor() const {
return m_compositor;
}
public slots:
// Keybindings
void slotSwitchDesktopNext();