Use signals'n'slots instead of deep function call into Compositor

For most actions where the compositor needs to perform an action
(e.g. scheduling another repaint) signals were already emitted.
So it's easier to just connect the signals to the Compositor
which in turn makes the code much more readable.

All signals are connected from the Workspace when either the
Compositor gets constructed or a Toplevel gets created.
This commit is contained in:
Martin Gräßlin 2012-08-23 13:42:59 +02:00
parent 0f2e5e61a8
commit 62c4d449f5
11 changed files with 53 additions and 39 deletions

View file

@ -41,7 +41,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "rules.h" #include "rules.h"
#include "useractions.h" #include "useractions.h"
#include <QX11Info> #include <QX11Info>
#include "composite.h"
namespace KWin namespace KWin
{ {
@ -874,9 +873,6 @@ void Client::setActive(bool act)
emit activeChanged(); emit activeChanged();
updateMouseGrab(); updateMouseGrab();
updateUrgency(); // demand attention again if it's still urgent updateUrgency(); // demand attention again if it's still urgent
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
} }
void Client::startupIdChanged() void Client::startupIdChanged()

View file

@ -2339,9 +2339,8 @@ void Client::setBlockingCompositing(bool block)
{ {
const bool usedToBlock = blocks_compositing; const bool usedToBlock = blocks_compositing;
blocks_compositing = rules()->checkBlockCompositing(block); blocks_compositing = rules()->checkBlockCompositing(block);
if (usedToBlock != blocks_compositing && workspace()->compositor()) { if (usedToBlock != blocks_compositing) {
workspace()->compositor()->updateCompositeBlocking(blocks_compositing ? this : 0); emit blockingCompositingChanged(blocks_compositing ? this : 0);
emit blockingCompositingChanged();
} }
} }

View file

@ -736,7 +736,7 @@ signals:
/** /**
* Emitted whenever the Client's block compositing state changes. * Emitted whenever the Client's block compositing state changes.
**/ **/
void blockingCompositingChanged(); void blockingCompositingChanged(KWin::Client *client);
private: private:
void exportMappingState(int s); // ICCCM 4.1.3.1, 4.1.4, NETWM 2.5.1 void exportMappingState(int s); // ICCCM 4.1.3.1, 4.1.4, NETWM 2.5.1

View file

@ -212,9 +212,10 @@ void Compositor::slotCompositingOptionsInitialized()
} else } else
vBlankInterval = 1 << 10; // no sync - DO NOT set "0", would cause div-by-zero segfaults. 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 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); XCompositeRedirectSubwindows(display(), rootWindow(), CompositeRedirectManual);
new EffectsHandlerImpl(m_scene); // sets also the 'effects' pointer new EffectsHandlerImpl(m_scene); // sets also the 'effects' pointer
connect(effects, SIGNAL(screenGeometryChanged(QSize)), SLOT(addRepaintFull()));
addRepaintFull(); addRepaintFull();
foreach (Client * c, Workspace::self()->clientList()) foreach (Client * c, Workspace::self()->clientList())
c->setupCompositing(); c->setupCompositing();
@ -228,7 +229,7 @@ void Compositor::slotCompositingOptionsInitialized()
performCompositing(); performCompositing();
} }
void Compositor::checkCompositeTimer() void Compositor::scheduleRepaint()
{ {
if (!compositeTimer.isActive()) if (!compositeTimer.isActive())
setCompositeTimer(); setCompositeTimer();
@ -366,6 +367,11 @@ QStringList Workspace::activeEffects() const
return QStringList(); return QStringList();
} }
void Compositor::updateCompositeBlocking()
{
updateCompositeBlocking(NULL);
}
void Compositor::updateCompositeBlocking(Client *c) void Compositor::updateCompositeBlocking(Client *c)
{ {
if (c) { // if c == 0 we just check if we can resume 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()) if (!hasScene())
return; return;
repaints_region += QRegion(x, y, w, h); repaints_region += QRegion(x, y, w, h);
checkCompositeTimer(); scheduleRepaint();
} }
void Compositor::addRepaint(const QRect& r) void Compositor::addRepaint(const QRect& r)
@ -422,7 +428,7 @@ void Compositor::addRepaint(const QRect& r)
if (!hasScene()) if (!hasScene())
return; return;
repaints_region += r; repaints_region += r;
checkCompositeTimer(); scheduleRepaint();
} }
void Compositor::addRepaint(const QRegion& r) void Compositor::addRepaint(const QRegion& r)
@ -430,7 +436,7 @@ void Compositor::addRepaint(const QRegion& r)
if (!hasScene()) if (!hasScene())
return; return;
repaints_region += r; repaints_region += r;
checkCompositeTimer(); scheduleRepaint();
} }
void Compositor::addRepaintFull() void Compositor::addRepaintFull()
@ -438,7 +444,7 @@ void Compositor::addRepaintFull()
if (!hasScene()) if (!hasScene())
return; return;
repaints_region = QRegion(0, 0, displayWidth(), displayHeight()); repaints_region = QRegion(0, 0, displayWidth(), displayHeight());
checkCompositeTimer(); scheduleRepaint();
} }
void Compositor::timerEvent(QTimerEvent *te) 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 // 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 // checkCompositeTime() would restart it again somewhen later, called from functions that
// would again add something pending. // would again add something pending.
checkCompositeTimer(); scheduleRepaint();
} }
void Compositor::performMousePoll() void Compositor::performMousePoll()
@ -575,6 +581,11 @@ bool Compositor::isActive()
return !m_finishing && hasScene(); return !m_finishing && hasScene();
} }
void Compositor::checkUnredirect()
{
checkUnredirect(false);
}
// force is needed when the list of windows changes (e.g. a window goes away) // force is needed when the list of windows changes (e.g. a window goes away)
void Compositor::checkUnredirect(bool force) 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()); effect_window->setData(LanczosCacheRole, QVariant());
} }
} }
workspace()->compositor()->checkCompositeTimer();
} }
void Toplevel::addDamageFull() void Toplevel::addDamageFull()
@ -922,7 +932,6 @@ void Toplevel::addDamageFull()
effect_window->setData(LanczosCacheRole, QVariant()); effect_window->setData(LanczosCacheRole, QVariant());
} }
} }
workspace()->compositor()->checkCompositeTimer();
} }
void Toplevel::resetDamage(const QRect& r) void Toplevel::resetDamage(const QRect& r)
@ -940,7 +949,7 @@ void Toplevel::addRepaint(const QRect& r)
return; return;
} }
repaints_region += r; repaints_region += r;
workspace()->compositor()->checkCompositeTimer(); emit needsRepaint();
} }
void Toplevel::addRepaint(int x, int y, int w, int h) void Toplevel::addRepaint(int x, int y, int w, int h)
@ -955,7 +964,7 @@ void Toplevel::addRepaint(const QRegion& r)
return; return;
} }
repaints_region += r; repaints_region += r;
workspace()->compositor()->checkCompositeTimer(); emit needsRepaint();
} }
void Toplevel::addLayerRepaint(const QRect& r) void Toplevel::addLayerRepaint(const QRect& r)
@ -964,7 +973,7 @@ void Toplevel::addLayerRepaint(const QRect& r)
return; return;
} }
layer_repaints_region += r; layer_repaints_region += r;
workspace()->compositor()->checkCompositeTimer(); emit needsRepaint();
} }
void Toplevel::addLayerRepaint(int x, int y, int w, int h) void Toplevel::addLayerRepaint(int x, int y, int w, int h)
@ -978,13 +987,13 @@ void Toplevel::addLayerRepaint(const QRegion& r)
if (!compositing()) if (!compositing())
return; return;
layer_repaints_region += r; layer_repaints_region += r;
workspace()->compositor()->checkCompositeTimer(); emit needsRepaint();
} }
void Toplevel::addRepaintFull() void Toplevel::addRepaintFull()
{ {
repaints_region = visibleRect().translated(-pos()); repaints_region = visibleRect().translated(-pos());
workspace()->compositor()->checkCompositeTimer(); emit needsRepaint();
} }
void Toplevel::resetRepaints() void Toplevel::resetRepaints()

View file

@ -3,6 +3,7 @@
This file is part of the KDE project. This file is part of the KDE project.
Copyright (C) 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de> Copyright (C) 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -29,6 +30,7 @@ class KSelectionOwner;
namespace KWin { namespace KWin {
class Client;
class Scene; class Scene;
class Compositor : public QObject { class Compositor : public QObject {
@ -36,19 +38,16 @@ class Compositor : public QObject {
public: public:
Compositor(QObject *workspace); Compositor(QObject *workspace);
~Compositor(); ~Compositor();
void checkCompositeTimer();
// when adding repaints caused by a window, you probably want to use // when adding repaints caused by a window, you probably want to use
// either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint() // either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint()
void addRepaint(const QRect& r); void addRepaint(const QRect& r);
void addRepaint(const QRegion& r); void addRepaint(const QRegion& r);
void addRepaint(int x, int y, int w, int h); 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 * 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. * addition to show a notification on how to revert the compositing state.
**/ **/
void toggleCompositing(); void toggleCompositing();
void updateCompositeBlocking(Client* c = NULL);
// Mouse polling // Mouse polling
void startMousePolling(); void startMousePolling();
void stopMousePolling(); void stopMousePolling();
@ -107,6 +106,14 @@ public Q_SLOTS:
* Connected to the D-Bus signal org.kde.KWin /KWin reinitCompositing * Connected to the D-Bus signal org.kde.KWin /KWin reinitCompositing
**/ **/
void slotReinitialize(); 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: Q_SIGNALS:
void compositingToggled(bool active); void compositingToggled(bool active);

View file

@ -588,7 +588,6 @@ void EffectsHandlerImpl::desktopResized(const QSize &size)
{ {
m_scene->screenGeometryChanged(size); m_scene->screenGeometryChanged(size);
emit screenGeometryChanged(size); emit screenGeometryChanged(size);
Workspace::self()->compositor()->addRepaintFull();
} }
void EffectsHandlerImpl::slotPropertyNotify(Toplevel* t, long int atom) void EffectsHandlerImpl::slotPropertyNotify(Toplevel* t, long int atom)

View file

@ -461,7 +461,7 @@ bool Workspace::workspaceEvent(XEvent * e)
} }
} }
if (m_compositor) { if (m_compositor) {
m_compositor->checkCompositeTimer(); m_compositor->scheduleRepaint();
} }
} }
break; break;

View file

@ -1910,9 +1910,6 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force)
// to detect changes // to detect changes
workspace()->checkActiveScreen(this); workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder(); workspace()->updateStackingOrder();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
// need to regenerate decoration pixmaps when either // need to regenerate decoration pixmaps when either
// - size is changed // - size is changed
@ -1986,9 +1983,6 @@ void Client::plainResize(int w, int h, ForceGeometry_t force)
updateWindowRules(Rules::Position|Rules::Size); updateWindowRules(Rules::Position|Rules::Size);
workspace()->checkActiveScreen(this); workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder(); workspace()->updateStackingOrder();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
discardWindowPixmap(); discardWindowPixmap();
emit geometryShapeChanged(this, geom_before_block); emit geometryShapeChanged(this, geom_before_block);
const QRect deco_rect = visibleRect(); const QRect deco_rect = visibleRect();
@ -2034,6 +2028,7 @@ void Client::move(int x, int y, ForceGeometry_t force)
workspace()->checkActiveScreen(this); workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder(); workspace()->updateStackingOrder();
if (workspace()->compositor()) { if (workspace()->compositor()) {
// TODO: move out of geometry.cpp, is this really needed here?
workspace()->compositor()->checkUnredirect(); workspace()->compositor()->checkUnredirect();
} }
// client itself is not damaged // client itself is not damaged
@ -2381,9 +2376,6 @@ void Client::setFullScreen(bool set, bool user)
} }
} }
updateWindowRules(Rules::Fullscreen|Rules::Position|Rules::Size); updateWindowRules(Rules::Fullscreen|Rules::Position|Rules::Size);
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
if (was_fs != isFullScreen()) { if (was_fs != isFullScreen()) {
emit clientFullScreenSet(this, set, user); emit clientFullScreenSet(this, set, user);

View file

@ -45,6 +45,7 @@ Toplevel::Toplevel(Workspace* ws)
, unredirect(false) , unredirect(false)
, unredirectSuspend(false) , unredirectSuspend(false)
{ {
connect(this, SIGNAL(damaged(KWin::Toplevel*,QRect)), SIGNAL(needsRepaint()));
} }
Toplevel::~Toplevel() Toplevel::~Toplevel()

View file

@ -299,6 +299,11 @@ signals:
* decoration. * decoration.
**/ **/
void shapedChanged(); void shapedChanged();
/**
* Emitted whenever the state changes in a way, that the Compositor should
* schedule a repaint of the scene.
**/
void needsRepaint();
protected: protected:
virtual ~Toplevel(); virtual ~Toplevel();

View file

@ -205,6 +205,7 @@ Workspace::Workspace(bool restore)
#endif #endif
m_compositor = new Compositor(this); 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)), SIGNAL(compositingToggled(bool)));
connect(m_compositor, SIGNAL(compositingToggled(bool)), SLOT(slotCompositingToggled())); connect(m_compositor, SIGNAL(compositingToggled(bool)), SLOT(slotCompositingToggled()));
dbus.connect(QString(), "/KWin", "org.kde.KWin", "reinitCompositing", dbus.connect(QString(), "/KWin", "org.kde.KWin", "reinitCompositing",
@ -536,6 +537,12 @@ Client* Workspace::createClient(Window w, bool is_mapped)
Client::deleteClient(c, Allowed); Client::deleteClient(c, Allowed);
return NULL; 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); addClient(c, Allowed);
return c; return c;
} }
@ -549,6 +556,7 @@ Unmanaged* Workspace::createUnmanaged(Window w)
Unmanaged::deleteUnmanaged(c, Allowed); Unmanaged::deleteUnmanaged(c, Allowed);
return NULL; return NULL;
} }
connect(c, SIGNAL(needsRepaint()), m_compositor, SLOT(scheduleRepaint()));
addUnmanaged(c, Allowed); addUnmanaged(c, Allowed);
emit unmanagedAdded(c); emit unmanagedAdded(c);
return c; return c;
@ -699,6 +707,7 @@ void Workspace::addDeleted(Deleted* c, Toplevel *orig, allowed_t)
stacking_order.append(c); stacking_order.append(c);
} }
x_stacking_dirty = true; x_stacking_dirty = true;
connect(c, SIGNAL(needsRepaint()), m_compositor, SLOT(scheduleRepaint()));
} }
void Workspace::removeDeleted(Deleted* c, allowed_t) void Workspace::removeDeleted(Deleted* c, allowed_t)
@ -1301,9 +1310,6 @@ bool Workspace::setCurrentDesktop(int new_desktop)
// s += QString::number( desktop_focus_chain[i] ) + ", "; // s += QString::number( desktop_focus_chain[i] ) + ", ";
//kDebug( 1212 ) << s << "}\n"; //kDebug( 1212 ) << s << "}\n";
if (compositing() && m_compositor)
m_compositor->addRepaintFull();
emit currentDesktopChanged(old_desktop, movingClient); emit currentDesktopChanged(old_desktop, movingClient);
return true; return true;
} }