From c8e2b61f48564f4361a29d5e2ab3b8dced633992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 9 Jan 2013 16:03:54 +0100 Subject: [PATCH] 32 bit compositing suspension REVIEW: 108304 BUG: 308438 --- composite.cpp | 54 ++++++++++++++++++++++++--------------------------- composite.h | 23 ++++++++++++++-------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/composite.cpp b/composite.cpp index af3cb37e39..1d1d44454b 100644 --- a/composite.cpp +++ b/composite.cpp @@ -53,6 +53,8 @@ along with this program. If not, see . #include #include +Q_DECLARE_METATYPE(KWin::Compositor::SuspendReason) + namespace KWin { @@ -68,8 +70,7 @@ Compositor *Compositor::createCompositor(QObject *parent) Compositor::Compositor(QObject* workspace) : QObject(workspace) - , m_suspended(!options->isUseCompositing()) - , m_blocked(false) + , m_suspended(options->isUseCompositing() ? NoReasonSuspend : UserSuspend) , cm_selection(NULL) , vBlankInterval(0) , fpsInterval(0) @@ -80,6 +81,7 @@ Compositor::Compositor(QObject* workspace) , m_nextFrameDelay(0) , m_scene(NULL) { + qRegisterMetaType("Compositor::SuspendReason"); new CompositingAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject("/Compositor", this); @@ -116,7 +118,7 @@ void Compositor::setup() if (hasScene()) return; if (m_suspended) { - kDebug(1212) << "Compositing is suspended"; + kDebug(1212) << "Compositing is suspended, reason:" << m_suspended; return; } else if (!CompositingPrefs::compositingPossible()) { kError(1212) << "Compositing is not possible"; @@ -365,7 +367,7 @@ void Compositor::slotReinitialize() // Restart compositing finish(); // resume compositing if suspended - m_suspended = false; + m_suspended = NoReasonSuspend; options->setCompositingInitialized(false); setup(); @@ -377,13 +379,17 @@ void Compositor::slotReinitialize() // for the shortcut void Compositor::slotToggleCompositing() { - setCompositing(m_suspended); + if (m_suspended) { // direct user call; clear all bits + resume(AllReasonSuspend); + } else { // but only set the user one (sufficient to suspend) + suspend(UserSuspend); + } } // for the dbus call void Compositor::toggleCompositing() { - slotToggleCompositing(); + slotToggleCompositing(); // TODO only operate on script level here? if (m_suspended) { // when disabled show a shortcut how the user can get back compositing QString shortcut, message; @@ -407,14 +413,11 @@ void Compositor::updateCompositeBlocking(Client *c) { if (c) { // if c == 0 we just check if we can resume if (c->isBlockingCompositing()) { - if (!m_blocked) // do NOT attempt to call suspend(true); from within the eventchain! - QMetaObject::invokeMethod(this, "suspend", Qt::QueuedConnection); - m_blocked = true; + if (!(m_suspended & BlockRuleSuspend)) // do NOT attempt to call suspend(true); from within the eventchain! + QMetaObject::invokeMethod(this, "suspend", Qt::QueuedConnection, Q_ARG(Compositor::SuspendReason, BlockRuleSuspend)); } } - else if (m_blocked) { // lost a client and we're blocked - can we resume? - // NOTICE do NOT check for "m_Suspended" or "!compositing()" - // only "resume" if it was really disabled for a block + else if (m_suspended & BlockRuleSuspend) { // lost a client and we're blocked - can we resume? bool resume = true; for (ClientList::ConstIterator it = Workspace::self()->clientList().constBegin(); it != Workspace::self()->clientList().constEnd(); ++it) { if ((*it)->isBlockingCompositing()) { @@ -423,38 +426,31 @@ void Compositor::updateCompositeBlocking(Client *c) } } if (resume) { // do NOT attempt to call suspend(false); from within the eventchain! - m_blocked = false; - if (m_suspended) - QMetaObject::invokeMethod(this, "resume", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "resume", Qt::QueuedConnection, Q_ARG(Compositor::SuspendReason, BlockRuleSuspend)); } } } -void Compositor::suspend() +void Compositor::suspend(Compositor::SuspendReason reason) { - if (m_suspended) { - return; - } - m_suspended = true; + Q_ASSERT(reason != NoReasonSuspend); + m_suspended |= reason; finish(); } -void Compositor::resume() +void Compositor::resume(Compositor::SuspendReason reason) { - if (!m_suspended && hasScene()) { - return; - } - m_suspended = false; - // signal toggled is eventually emitted from within setup - setup(); + Q_ASSERT(reason != NoReasonSuspend); + m_suspended &= ~reason; + setup(); // signal "toggled" is eventually emitted from within setup } void Compositor::setCompositing(bool active) { if (active) { - resume(); + resume(ScriptSuspend); } else { - suspend(); + suspend(ScriptSuspend); } } diff --git a/composite.h b/composite.h index 04ac4d56cf..963e63a3d3 100644 --- a/composite.h +++ b/composite.h @@ -66,6 +66,8 @@ class Compositor : public QObject { **/ Q_PROPERTY(QString compositingType READ compositingType) public: + enum SuspendReason { NoReasonSuspend = 0, UserSuspend = 1<<0, BlockRuleSuspend = 1<<1, ScriptSuspend = 1<<2, AllReasonSuspend = 0xff }; + Q_DECLARE_FLAGS(SuspendReasons, SuspendReason) ~Compositor(); // when adding repaints caused by a window, you probably want to use // either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint() @@ -186,7 +188,8 @@ public Q_SLOTS: * @see resume * @see isActive **/ - Q_SCRIPTABLE void suspend(); + Q_SCRIPTABLE inline void suspend() { suspend(ScriptSuspend); } + void suspend(Compositor::SuspendReason reason); /** * @brief Resumes the Compositor if it is currently suspended. * @@ -204,7 +207,8 @@ public Q_SLOTS: * @see isCompositingPossible * @see isOpenGLBroken **/ - Q_SCRIPTABLE void resume(); + Q_SCRIPTABLE inline void resume() { resume(ScriptSuspend); } + void resume(Compositor::SuspendReason reason); /** * @brief Tries to suspend or resume the Compositor based on @p active. * @@ -218,6 +222,10 @@ public Q_SLOTS: * Note: The starting of the Compositor can require some time and is partially done threaded. * After this method returns the setup may not have been completed. * + * Note: This function only impacts whether compositing is suspended or resumed by scripts + * or dbus calls. Compositing may be suspended for user will or a window rule - no matter how + * often you call this function! + * * @param active Whether the Compositor should be resumed (@c true) or suspended (@c false) * @return void * @see suspend @@ -226,6 +234,8 @@ public Q_SLOTS: * @see isCompositingPossible * @see isOpenGLBroken **/ + // NOTICE this is atm. for script usage *ONLY* and needs to be extended like resume / suspend are + // if intended to be used from within KWin code! Q_SCRIPTABLE void setCompositing(bool active); /** * Actual slot to perform the toggling compositing. @@ -289,13 +299,10 @@ private: void restartKWin(const QString &reason); /** - * Whether the Compositor is currently suspended. + * Whether the Compositor is currently suspended, 8 bits encoding the reason **/ - bool m_suspended; - /** - * Whether the Compositor is currently blocked by at least one Client requesting full resources. - **/ - bool m_blocked; + SuspendReasons m_suspended; + QBasicTimer compositeTimer; KSelectionOwner* cm_selection; QTimer m_releaseSelectionTimer;