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