diff --git a/activation.cpp b/activation.cpp
index 0562e317ea..836e9983ba 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -41,7 +41,6 @@ along with this program. If not, see .
#include "rules.h"
#include "useractions.h"
#include
-#include "composite.h"
namespace KWin
{
@@ -874,9 +873,6 @@ void Client::setActive(bool act)
emit activeChanged();
updateMouseGrab();
updateUrgency(); // demand attention again if it's still urgent
- if (workspace()->compositor()) {
- workspace()->compositor()->checkUnredirect();
- }
}
void Client::startupIdChanged()
diff --git a/client.cpp b/client.cpp
index e6347d04c7..5694944181 100644
--- a/client.cpp
+++ b/client.cpp
@@ -2339,9 +2339,8 @@ void Client::setBlockingCompositing(bool block)
{
const bool usedToBlock = blocks_compositing;
blocks_compositing = rules()->checkBlockCompositing(block);
- if (usedToBlock != blocks_compositing && workspace()->compositor()) {
- workspace()->compositor()->updateCompositeBlocking(blocks_compositing ? this : 0);
- emit blockingCompositingChanged();
+ if (usedToBlock != blocks_compositing) {
+ emit blockingCompositingChanged(blocks_compositing ? this : 0);
}
}
diff --git a/client.h b/client.h
index f31707b3d3..4c33ab4fdb 100644
--- a/client.h
+++ b/client.h
@@ -736,7 +736,7 @@ signals:
/**
* Emitted whenever the Client's block compositing state changes.
**/
- void blockingCompositingChanged();
+ void blockingCompositingChanged(KWin::Client *client);
private:
void exportMappingState(int s); // ICCCM 4.1.3.1, 4.1.4, NETWM 2.5.1
diff --git a/composite.cpp b/composite.cpp
index 55b5d2b2ff..3fe4213fc9 100644
--- a/composite.cpp
+++ b/composite.cpp
@@ -212,9 +212,10 @@ void Compositor::slotCompositingOptionsInitialized()
} else
vBlankInterval = 1 << 10; // no sync - DO NOT set "0", would cause div-by-zero segfaults.
m_timeSinceLastVBlank = fpsInterval - 1; // means "start now" - we don't have even a slight idea when the first vsync will occur
- checkCompositeTimer();
+ scheduleRepaint();
XCompositeRedirectSubwindows(display(), rootWindow(), CompositeRedirectManual);
new EffectsHandlerImpl(m_scene); // sets also the 'effects' pointer
+ connect(effects, SIGNAL(screenGeometryChanged(QSize)), SLOT(addRepaintFull()));
addRepaintFull();
foreach (Client * c, Workspace::self()->clientList())
c->setupCompositing();
@@ -228,7 +229,7 @@ void Compositor::slotCompositingOptionsInitialized()
performCompositing();
}
-void Compositor::checkCompositeTimer()
+void Compositor::scheduleRepaint()
{
if (!compositeTimer.isActive())
setCompositeTimer();
@@ -366,6 +367,11 @@ QStringList Workspace::activeEffects() const
return QStringList();
}
+void Compositor::updateCompositeBlocking()
+{
+ updateCompositeBlocking(NULL);
+}
+
void Compositor::updateCompositeBlocking(Client *c)
{
if (c) { // if c == 0 we just check if we can resume
@@ -414,7 +420,7 @@ void Compositor::addRepaint(int x, int y, int w, int h)
if (!hasScene())
return;
repaints_region += QRegion(x, y, w, h);
- checkCompositeTimer();
+ scheduleRepaint();
}
void Compositor::addRepaint(const QRect& r)
@@ -422,7 +428,7 @@ void Compositor::addRepaint(const QRect& r)
if (!hasScene())
return;
repaints_region += r;
- checkCompositeTimer();
+ scheduleRepaint();
}
void Compositor::addRepaint(const QRegion& r)
@@ -430,7 +436,7 @@ void Compositor::addRepaint(const QRegion& r)
if (!hasScene())
return;
repaints_region += r;
- checkCompositeTimer();
+ scheduleRepaint();
}
void Compositor::addRepaintFull()
@@ -438,7 +444,7 @@ void Compositor::addRepaintFull()
if (!hasScene())
return;
repaints_region = QRegion(0, 0, displayWidth(), displayHeight());
- checkCompositeTimer();
+ scheduleRepaint();
}
void Compositor::timerEvent(QTimerEvent *te)
@@ -491,7 +497,7 @@ void Compositor::performCompositing()
// is called the next time. If there would be nothing pending, it will not restart the timer and
// checkCompositeTime() would restart it again somewhen later, called from functions that
// would again add something pending.
- checkCompositeTimer();
+ scheduleRepaint();
}
void Compositor::performMousePoll()
@@ -575,6 +581,11 @@ bool Compositor::isActive()
return !m_finishing && hasScene();
}
+void Compositor::checkUnredirect()
+{
+ checkUnredirect(false);
+}
+
// force is needed when the list of windows changes (e.g. a window goes away)
void Compositor::checkUnredirect(bool force)
{
@@ -901,7 +912,6 @@ void Toplevel::addDamage(int x, int y, int w, int h)
effect_window->setData(LanczosCacheRole, QVariant());
}
}
- workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::addDamageFull()
@@ -922,7 +932,6 @@ void Toplevel::addDamageFull()
effect_window->setData(LanczosCacheRole, QVariant());
}
}
- workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::resetDamage(const QRect& r)
@@ -940,7 +949,7 @@ void Toplevel::addRepaint(const QRect& r)
return;
}
repaints_region += r;
- workspace()->compositor()->checkCompositeTimer();
+ emit needsRepaint();
}
void Toplevel::addRepaint(int x, int y, int w, int h)
@@ -955,7 +964,7 @@ void Toplevel::addRepaint(const QRegion& r)
return;
}
repaints_region += r;
- workspace()->compositor()->checkCompositeTimer();
+ emit needsRepaint();
}
void Toplevel::addLayerRepaint(const QRect& r)
@@ -964,7 +973,7 @@ void Toplevel::addLayerRepaint(const QRect& r)
return;
}
layer_repaints_region += r;
- workspace()->compositor()->checkCompositeTimer();
+ emit needsRepaint();
}
void Toplevel::addLayerRepaint(int x, int y, int w, int h)
@@ -978,13 +987,13 @@ void Toplevel::addLayerRepaint(const QRegion& r)
if (!compositing())
return;
layer_repaints_region += r;
- workspace()->compositor()->checkCompositeTimer();
+ emit needsRepaint();
}
void Toplevel::addRepaintFull()
{
repaints_region = visibleRect().translated(-pos());
- workspace()->compositor()->checkCompositeTimer();
+ emit needsRepaint();
}
void Toplevel::resetRepaints()
diff --git a/composite.h b/composite.h
index 5e65371f0b..a4a37107ff 100644
--- a/composite.h
+++ b/composite.h
@@ -3,6 +3,7 @@
This file is part of the KDE project.
Copyright (C) 2011 Arthur Arlt
+Copyright (C) 2012 Martin Gräßlin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +30,7 @@ class KSelectionOwner;
namespace KWin {
+class Client;
class Scene;
class Compositor : public QObject {
@@ -36,19 +38,16 @@ class Compositor : public QObject {
public:
Compositor(QObject *workspace);
~Compositor();
- void checkCompositeTimer();
// when adding repaints caused by a window, you probably want to use
// either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint()
void addRepaint(const QRect& r);
void addRepaint(const QRegion& r);
void addRepaint(int x, int y, int w, int h);
- void checkUnredirect(bool force = false);
/**
* Called from the D-Bus interface. Does the same as slotToggleCompositing with the
* addition to show a notification on how to revert the compositing state.
**/
void toggleCompositing();
- void updateCompositeBlocking(Client* c = NULL);
// Mouse polling
void startMousePolling();
void stopMousePolling();
@@ -107,6 +106,14 @@ public Q_SLOTS:
* Connected to the D-Bus signal org.kde.KWin /KWin reinitCompositing
**/
void slotReinitialize();
+ /**
+ * Schedules a new repaint if no repaint is currently scheduled.
+ **/
+ void scheduleRepaint();
+ void checkUnredirect();
+ void checkUnredirect(bool force);
+ void updateCompositeBlocking();
+ void updateCompositeBlocking(KWin::Client* c);
Q_SIGNALS:
void compositingToggled(bool active);
diff --git a/effects.cpp b/effects.cpp
index 5bd15201ce..b90030ce55 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -588,7 +588,6 @@ void EffectsHandlerImpl::desktopResized(const QSize &size)
{
m_scene->screenGeometryChanged(size);
emit screenGeometryChanged(size);
- Workspace::self()->compositor()->addRepaintFull();
}
void EffectsHandlerImpl::slotPropertyNotify(Toplevel* t, long int atom)
diff --git a/events.cpp b/events.cpp
index 074a8d67fa..23e1921bfa 100644
--- a/events.cpp
+++ b/events.cpp
@@ -461,7 +461,7 @@ bool Workspace::workspaceEvent(XEvent * e)
}
}
if (m_compositor) {
- m_compositor->checkCompositeTimer();
+ m_compositor->scheduleRepaint();
}
}
break;
diff --git a/geometry.cpp b/geometry.cpp
index 485ad9c022..19a911d097 100644
--- a/geometry.cpp
+++ b/geometry.cpp
@@ -1910,9 +1910,6 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force)
// to detect changes
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
- if (workspace()->compositor()) {
- workspace()->compositor()->checkUnredirect();
- }
// need to regenerate decoration pixmaps when either
// - size is changed
@@ -1986,9 +1983,6 @@ void Client::plainResize(int w, int h, ForceGeometry_t force)
updateWindowRules(Rules::Position|Rules::Size);
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
- if (workspace()->compositor()) {
- workspace()->compositor()->checkUnredirect();
- }
discardWindowPixmap();
emit geometryShapeChanged(this, geom_before_block);
const QRect deco_rect = visibleRect();
@@ -2034,6 +2028,7 @@ void Client::move(int x, int y, ForceGeometry_t force)
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
if (workspace()->compositor()) {
+ // TODO: move out of geometry.cpp, is this really needed here?
workspace()->compositor()->checkUnredirect();
}
// client itself is not damaged
@@ -2381,9 +2376,6 @@ void Client::setFullScreen(bool set, bool user)
}
}
updateWindowRules(Rules::Fullscreen|Rules::Position|Rules::Size);
- if (workspace()->compositor()) {
- workspace()->compositor()->checkUnredirect();
- }
if (was_fs != isFullScreen()) {
emit clientFullScreenSet(this, set, user);
diff --git a/toplevel.cpp b/toplevel.cpp
index 94178130e3..69fb7d77cd 100644
--- a/toplevel.cpp
+++ b/toplevel.cpp
@@ -45,6 +45,7 @@ Toplevel::Toplevel(Workspace* ws)
, unredirect(false)
, unredirectSuspend(false)
{
+ connect(this, SIGNAL(damaged(KWin::Toplevel*,QRect)), SIGNAL(needsRepaint()));
}
Toplevel::~Toplevel()
diff --git a/toplevel.h b/toplevel.h
index 777056904a..4fc15429fb 100644
--- a/toplevel.h
+++ b/toplevel.h
@@ -299,6 +299,11 @@ signals:
* decoration.
**/
void shapedChanged();
+ /**
+ * Emitted whenever the state changes in a way, that the Compositor should
+ * schedule a repaint of the scene.
+ **/
+ void needsRepaint();
protected:
virtual ~Toplevel();
diff --git a/workspace.cpp b/workspace.cpp
index d5956297a6..c6afa93bc4 100644
--- a/workspace.cpp
+++ b/workspace.cpp
@@ -205,6 +205,7 @@ Workspace::Workspace(bool restore)
#endif
m_compositor = new Compositor(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()));
dbus.connect(QString(), "/KWin", "org.kde.KWin", "reinitCompositing",
@@ -536,6 +537,12 @@ Client* Workspace::createClient(Window w, bool is_mapped)
Client::deleteClient(c, Allowed);
return NULL;
}
+ connect(c, SIGNAL(needsRepaint()), m_compositor, SLOT(scheduleRepaint()));
+ connect(c, SIGNAL(activeChanged()), m_compositor, SLOT(checkUnredirect()));
+ connect(c, SIGNAL(fullScreenChanged()), m_compositor, SLOT(checkUnredirect()));
+ connect(c, SIGNAL(geometryChanged()), m_compositor, SLOT(checkUnredirect()));
+ connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), m_compositor, SLOT(checkUnredirect()));
+ connect(c, SIGNAL(blockingCompositingChanged(KWin::Client*)), m_compositor, SLOT(updateCompositeBlocking(KWin::Client*)));
addClient(c, Allowed);
return c;
}
@@ -549,6 +556,7 @@ Unmanaged* Workspace::createUnmanaged(Window w)
Unmanaged::deleteUnmanaged(c, Allowed);
return NULL;
}
+ connect(c, SIGNAL(needsRepaint()), m_compositor, SLOT(scheduleRepaint()));
addUnmanaged(c, Allowed);
emit unmanagedAdded(c);
return c;
@@ -699,6 +707,7 @@ void Workspace::addDeleted(Deleted* c, Toplevel *orig, allowed_t)
stacking_order.append(c);
}
x_stacking_dirty = true;
+ connect(c, SIGNAL(needsRepaint()), m_compositor, SLOT(scheduleRepaint()));
}
void Workspace::removeDeleted(Deleted* c, allowed_t)
@@ -1301,9 +1310,6 @@ bool Workspace::setCurrentDesktop(int new_desktop)
// s += QString::number( desktop_focus_chain[i] ) + ", ";
//kDebug( 1212 ) << s << "}\n";
- if (compositing() && m_compositor)
- m_compositor->addRepaintFull();
-
emit currentDesktopChanged(old_desktop, movingClient);
return true;
}