Verified Commit a917bf19 authored by ivan tkachenko's avatar ivan tkachenko
Browse files

osd: Fix a crash when quitting from QML signal handler

kscreen_osd_service[9979]:
    Object 0x55a9840ff5c0 destroyed while one of its QML signal handlers is in progress.
    Most likely the object was deleted synchronously (use QObject::deleteLater() instead), or the application is running a nested event loop.
    This behavior is NOT supported!
    qrc:/qml/OsdSelector.qml:102: function() { [native code] }

Call to quit() should be posted to an event loop to avoid destroying Osd
objects with their engines while a key press signal handler is still
running. Additional clean up must be performed to ensure that a map
does not contain dangling references, ans thus double call to hideOsd()
won't cause another crash either.

Also, don't bother hiding individual OSD instances if we are about to
quit anyway. That's what other code path with timer is [not] doing
already.

CCBUG: 459368
(cherry picked from commit 6ba04351)
parent a54994c7
Pipeline #247167 passed with stage
in 1 minute and 2 seconds
......@@ -40,12 +40,14 @@ OsdManager::OsdManager(QObject *parent)
void OsdManager::hideOsd()
{
quit();
// Let QML engine finish execution of signal handlers, if any.
QTimer::singleShot(0, this, &OsdManager::quit);
}
void OsdManager::quit()
{
qDeleteAll(m_osds);
m_osds.clear();
qApp->quit();
}
......@@ -108,12 +110,10 @@ OsdAction::Action OsdManager::showActionSelector()
osd = new KScreen::Osd(osdOutput, this);
m_osds.insert(osdOutput->name(), osd);
connect(osd, &Osd::osdActionSelected, this, [this, message](OsdAction::Action action) {
for (auto osd : qAsConst(m_osds)) {
osd->hideOsd();
}
auto reply = message.createReply(action);
QDBusConnection::sessionBus().send(reply);
quit();
hideOsd();
});
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment