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
This commit is contained in:
David Edmundson 2019-09-26 16:09:16 +01:00
parent 086428754e
commit 3ba33e4b58
3 changed files with 17 additions and 12 deletions

View file

@ -885,7 +885,6 @@ X11Compositor::X11Compositor(QObject *parent)
, m_suspended(options->isUseCompositing() ? NoReasonSuspend : UserSuspend)
, m_xrrRefreshRate(0)
{
qRegisterMetaType<X11Compositor::SuspendReason>("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);
}
}
}

View file

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

View file

@ -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<X11Compositor*>(Compositor::self()), "suspend",
Qt::QueuedConnection, Q_ARG(X11Compositor::SuspendReason, X11Compositor::AllReasonSuspend));
auto compositor = static_cast<X11Compositor*>(Compositor::self());
QMetaObject::invokeMethod(compositor, [compositor]() {
compositor->suspend(X11Compositor::AllReasonSuspend);
}, Qt::QueuedConnection);
return false;
}
return true;