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.
icc-effect-5.14.5
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 "useractions.h"
#include <QX11Info>
#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()

View File

@ -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);
}
}

View File

@ -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

View File

@ -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()

View File

@ -3,6 +3,7 @@
This file is part of the KDE project.
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
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);

View File

@ -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)

View File

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

View File

@ -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);

View File

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

View File

@ -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();

View File

@ -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;
}