From 3ba33e4b581f7d95effc481d47e553c392404e11 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Thu, 26 Sep 2019 16:09:16 +0100 Subject: [PATCH] Use lambdas for queued invocation of composition suspending Summary: Qt's metaobject is rather sensitive with scope resolution. Foo::Bar and Bar don't always match to a Qt metaobject, even if they refer to the same thing to a compiler. Here we register X11Compositor::SuspendReason but Q_ARG uses SuspendReason and they don't match. This leads to a runtime failure where the method isn't invoked. Rather than fixing metaobject usage, port the whole thing to lambdas which does better compile time checking and is generally nicer to read. BUG: 412353 Test Plan: Ran xprop to block compositing. Compositing was blocked. Grepped source code for Q_ARG use Reviewers: #kwin, zzag Reviewed By: #kwin, zzag Subscribers: zzag, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D24244 --- composite.cpp | 17 +++++++++-------- composite.h | 6 ++++-- plugins/scenes/opengl/scene_opengl.cpp | 6 ++++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/composite.cpp b/composite.cpp index 3bc79a28c4..779e419c4d 100644 --- a/composite.cpp +++ b/composite.cpp @@ -885,7 +885,6 @@ X11Compositor::X11Compositor(QObject *parent) , m_suspended(options->isUseCompositing() ? NoReasonSuspend : UserSuspend) , m_xrrRefreshRate(0) { - qRegisterMetaType("X11Compositor::SuspendReason"); } void X11Compositor::toggleCompositing() @@ -1014,25 +1013,27 @@ void X11Compositor::updateClientCompositeBlocking(Client *c) if (c->isBlockingCompositing()) { // Do NOT attempt to call suspend(true) from within the eventchain! if (!(m_suspended & BlockRuleSuspend)) - QMetaObject::invokeMethod(this, "suspend", Qt::QueuedConnection, - Q_ARG(SuspendReason, BlockRuleSuspend)); + QMetaObject::invokeMethod(this, [this]() { + suspend(BlockRuleSuspend); + }, Qt::QueuedConnection); } } else if (m_suspended & BlockRuleSuspend) { // If !c we just check if we can resume in case a blocking client was lost. - bool resume = true; + bool shouldResume = true; for (ClientList::ConstIterator it = Workspace::self()->clientList().constBegin(); it != Workspace::self()->clientList().constEnd(); ++it) { if ((*it)->isBlockingCompositing()) { - resume = false; + shouldResume = false; break; } } - if (resume) { + if (shouldResume) { // Do NOT attempt to call suspend(false) from within the eventchain! - QMetaObject::invokeMethod(this, "resume", Qt::QueuedConnection, - Q_ARG(SuspendReason, BlockRuleSuspend)); + QMetaObject::invokeMethod(this, [this]() { + resume(BlockRuleSuspend); + }, Qt::QueuedConnection); } } } diff --git a/composite.h b/composite.h index 0dc0d8d0dc..1d7b2204e5 100644 --- a/composite.h +++ b/composite.h @@ -201,6 +201,8 @@ public: AllReasonSuspend = 0xff }; Q_DECLARE_FLAGS(SuspendReasons, SuspendReason) + Q_ENUM(SuspendReason) + Q_FLAG(SuspendReasons) static X11Compositor *create(QObject *parent = nullptr); @@ -214,7 +216,7 @@ public: * @see resume * @see isActive */ - Q_INVOKABLE void suspend(SuspendReason reason); + void suspend(SuspendReason reason); /** * @brief Resumes the Compositor if it is currently suspended. @@ -233,7 +235,7 @@ public: * @see isCompositingPossible * @see isOpenGLBroken */ - Q_INVOKABLE void resume(SuspendReason reason); + void resume(SuspendReason reason); void toggleCompositing() override; void reinitialize() override; diff --git a/plugins/scenes/opengl/scene_opengl.cpp b/plugins/scenes/opengl/scene_opengl.cpp index b253ee9c9d..319252b6ec 100644 --- a/plugins/scenes/opengl/scene_opengl.cpp +++ b/plugins/scenes/opengl/scene_opengl.cpp @@ -830,8 +830,10 @@ bool SceneOpenGL::viewportLimitsMatched(const QSize &size) const { GLint limit[2]; glGetIntegerv(GL_MAX_VIEWPORT_DIMS, limit); if (limit[0] < size.width() || limit[1] < size.height()) { - QMetaObject::invokeMethod(static_cast(Compositor::self()), "suspend", - Qt::QueuedConnection, Q_ARG(X11Compositor::SuspendReason, X11Compositor::AllReasonSuspend)); + auto compositor = static_cast(Compositor::self()); + QMetaObject::invokeMethod(compositor, [compositor]() { + compositor->suspend(X11Compositor::AllReasonSuspend); + }, Qt::QueuedConnection); return false; } return true;