Skip to content

Commit 67f8616

Browse files
committed
fixed app quit
1 parent 0d8cb45 commit 67f8616

File tree

4 files changed

+117
-96
lines changed

4 files changed

+117
-96
lines changed

src/app/internal/guiapp.cpp

Lines changed: 101 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void GuiApp::setup()
8686
#ifndef MUSE_MULTICONTEXT_WIP
8787
modularity::ContextPtr ctx = std::make_shared<modularity::Context>();
8888
ctx->id = 0;
89-
std::vector<muse::modularity::IContextSetup*>& csetups = contextSetups(ctx);
89+
std::vector<muse::modularity::IContextSetup*>& csetups = context(ctx).setups;
9090
for (modularity::IContextSetup* s : csetups) {
9191
s->registerExports();
9292
}
@@ -248,11 +248,11 @@ void GuiApp::setup()
248248
}
249249
}
250250

251-
std::vector<muse::modularity::IContextSetup*>& GuiApp::contextSetups(const muse::modularity::ContextPtr& ctx)
251+
GuiApp::Context& GuiApp::context(const muse::modularity::ContextPtr& ctx)
252252
{
253253
for (Context& c : m_contexts) {
254254
if (c.ctx->id == ctx->id) {
255-
return c.setups;
255+
return c;
256256
}
257257
}
258258

@@ -273,40 +273,7 @@ std::vector<muse::modularity::IContextSetup*>& GuiApp::contextSetups(const muse:
273273
}
274274
}
275275

276-
return ref.setups;
277-
}
278-
279-
void GuiApp::destroyContext(const modularity::ContextPtr& ctx)
280-
{
281-
if (!ctx) {
282-
return;
283-
}
284-
285-
LOGI() << "Destroying context with id: " << ctx->id;
286-
287-
auto it = std::find_if(m_contexts.begin(), m_contexts.end(),
288-
[&ctx](const Context& c) { return c.ctx->id == ctx->id; });
289-
if (it == m_contexts.end()) {
290-
LOGW() << "Context not found: " << ctx->id;
291-
return;
292-
}
293-
294-
// Engine quit
295-
muse::modularity::ioc(ctx)->resolve<muse::ui::IUiEngine>("app")->quit();
296-
297-
for (modularity::IContextSetup* s : it->setups) {
298-
s->onDeinit();
299-
}
300-
301-
qDeleteAll(it->setups);
302-
m_contexts.erase(it);
303-
304-
modularity::removeIoC(ctx);
305-
}
306-
307-
size_t GuiApp::contextCount() const
308-
{
309-
return m_contexts.size();
276+
return ref;
310277
}
311278

312279
std::vector<muse::modularity::ContextPtr> GuiApp::contexts() const
@@ -319,6 +286,11 @@ std::vector<muse::modularity::ContextPtr> GuiApp::contexts() const
319286
return ctxs;
320287
}
321288

289+
size_t GuiApp::contextCount() const
290+
{
291+
return m_contexts.size();
292+
}
293+
322294
muse::modularity::ContextPtr GuiApp::setupNewContext(const StringList& args)
323295
{
324296
//! NOTE
@@ -335,13 +307,13 @@ muse::modularity::ContextPtr GuiApp::setupNewContext(const StringList& args)
335307
once = true;
336308
#endif
337309

338-
modularity::ContextPtr ctx = std::make_shared<modularity::Context>();
310+
modularity::ContextPtr ctxId = std::make_shared<modularity::Context>();
339311
++m_lastId;
340312
#ifdef MUSE_MULTICONTEXT_WIP
341313
ctx->id = m_lastId;
342314
#else
343315
// only global
344-
ctx->id = 0;
316+
ctxId->id = 0;
345317
#endif
346318

347319
const CmdOptions& options = m_options;
@@ -350,11 +322,11 @@ muse::modularity::ContextPtr GuiApp::setupNewContext(const StringList& args)
350322
return nullptr;
351323
}
352324

353-
LOGI() << "New context created with id: " << ctx->id;
325+
LOGI() << "New context created with id: " << ctxId->id;
354326

355327
// Setup
356328
#ifdef MUSE_MULTICONTEXT_WIP
357-
std::vector<muse::modularity::IContextSetup*>& csetups = contextSetups(ctx);
329+
std::vector<muse::modularity::IContextSetup*>& csetups = context(ctxId).setups;
358330

359331
for (modularity::IContextSetup* s : csetups) {
360332
s->registerExports();
@@ -386,7 +358,7 @@ muse::modularity::ContextPtr GuiApp::setupNewContext(const StringList& args)
386358
QString platform = "linux";
387359
#endif
388360

389-
QQmlApplicationEngine* engine = muse::modularity::ioc(ctx)->resolve<muse::ui::IUiEngine>("app")->qmlAppEngine();
361+
QQmlApplicationEngine* engine = muse::modularity::ioc(ctxId)->resolve<muse::ui::IUiEngine>("app")->qmlAppEngine();
390362

391363
QObject::connect(engine, &QQmlApplicationEngine::objectCreated, qApp, [](QObject* obj, const QUrl&) {
392364
QQuickWindow* w = dynamic_cast<QQuickWindow*>(obj);
@@ -406,9 +378,9 @@ muse::modularity::ContextPtr GuiApp::setupNewContext(const StringList& args)
406378
}
407379

408380
QQmlContext* qmlCtx = new QQmlContext(engine);
409-
qmlCtx->setObjectName(QString("QQmlContext: %1").arg(ctx ? ctx->id : 0));
381+
qmlCtx->setObjectName(QString("QQmlContext: %1").arg(ctxId ? ctxId->id : 0));
410382
QmlIoCContext* iocCtx = new QmlIoCContext(qmlCtx);
411-
iocCtx->ctx = ctx;
383+
iocCtx->ctx = ctxId;
412384
qmlCtx->setContextProperty("ioc_context", QVariant::fromValue(iocCtx));
413385

414386
QObject* obj = component.create(qmlCtx);
@@ -418,7 +390,7 @@ muse::modularity::ContextPtr GuiApp::setupNewContext(const StringList& args)
418390
return nullptr;
419391
}
420392

421-
auto startupScenario = muse::modularity::ioc(ctx)->resolve<IStartupScenario>("app");
393+
auto startupScenario = muse::modularity::ioc(ctxId)->resolve<IStartupScenario>("app");
422394

423395
//! NOTE Apply startup options from either:
424396
//! 1. Direct args (single-process mode: openNewWindow passes args)
@@ -462,71 +434,112 @@ muse::modularity::ContextPtr GuiApp::setupNewContext(const StringList& args)
462434
startupScenario->setStartupScoreFile(file);
463435
startupScenario->runOnSplashScreen();
464436

465-
if (m_splashScreen) {
466-
m_splashScreen->close();
467-
delete m_splashScreen;
468-
m_splashScreen = nullptr;
437+
QMetaObject::invokeMethod(qApp, [this, ctxId, obj, startupScenario]() {
438+
if (m_splashScreen) {
439+
m_splashScreen->close();
440+
delete m_splashScreen;
441+
m_splashScreen = nullptr;
442+
}
443+
444+
// The main window must be shown at this point so KDDockWidgets can read its size correctly
445+
// and scale all sizes properly. https://github.com/musescore/MuseScore/issues/21148
446+
// but before that, let's make the window transparent,
447+
// otherwise the empty window frame will be visible
448+
// https://github.com/musescore/MuseScore/issues/29630
449+
// Transparency will be removed after the page loads.
450+
Context& ctx = context(ctxId);
451+
ctx.window = dynamic_cast<QQuickWindow*>(obj);
452+
ctx.window->setOpacity(0.01);
453+
ctx.window->setVisible(true);
454+
455+
startupScenario->runAfterSplashScreen();
456+
}, Qt::QueuedConnection);
457+
458+
return ctxId;
459+
}
460+
461+
void GuiApp::destroyContext(const modularity::ContextPtr& ctx)
462+
{
463+
TRACEFUNC;
464+
465+
if (!ctx) {
466+
return;
467+
}
468+
469+
LOGI() << "Destroying context with id: " << ctx->id;
470+
471+
auto it = std::find_if(m_contexts.begin(), m_contexts.end(),
472+
[&ctx](const Context& c) { return c.ctx->id == ctx->id; });
473+
if (it == m_contexts.end()) {
474+
LOGW() << "Context not found: " << ctx->id;
475+
return;
469476
}
470477

471-
// The main window must be shown at this point so KDDockWidgets can read its size correctly
472-
// and scale all sizes properly. https://github.com/musescore/MuseScore/issues/21148
473-
// but before that, let's make the window transparent,
474-
// otherwise the empty window frame will be visible
475-
// https://github.com/musescore/MuseScore/issues/29630
476-
// Transparency will be removed after the page loads.
477-
QQuickWindow* w = dynamic_cast<QQuickWindow*>(obj);
478-
w->setOpacity(0.01);
479-
w->setVisible(true);
478+
if (it->window) {
479+
it->window->setVisible(false);
480+
}
481+
482+
// Engine quit
483+
muse::modularity::ioc(ctx)->resolve<muse::ui::IUiEngine>("app")->quit();
484+
485+
for (modularity::IContextSetup* s : it->setups) {
486+
s->onDeinit();
487+
}
480488

481-
startupScenario->runAfterSplashScreen();
489+
qDeleteAll(it->setups);
490+
m_contexts.erase(it);
482491

483-
return ctx;
492+
modularity::removeIoC(ctx);
484493
}
485494

486495
void GuiApp::finish()
487496
{
488-
PROFILER_PRINT;
497+
{
498+
TRACEFUNC
489499

490500
// Wait Thread Poll
491501
#ifdef QT_CONCURRENT_SUPPORTED
492-
QThreadPool* globalThreadPool = QThreadPool::globalInstance();
493-
if (globalThreadPool) {
494-
LOGI() << "activeThreadCount: " << globalThreadPool->activeThreadCount();
495-
globalThreadPool->waitForDone();
496-
}
502+
QThreadPool* globalThreadPool = QThreadPool::globalInstance();
503+
if (globalThreadPool) {
504+
LOGI() << "activeThreadCount: " << globalThreadPool->activeThreadCount();
505+
globalThreadPool->waitForDone();
506+
}
497507
#endif
498508

499-
// Deinit
500-
async::processMessages();
509+
// Deinit
510+
async::processMessages();
501511

502-
// Deinit and delete contexts
503-
std::vector<muse::modularity::ContextPtr> ctxs = contexts();
504-
for (auto& c : ctxs) {
505-
destroyContext(c);
506-
}
512+
// Deinit and delete contexts
513+
std::vector<muse::modularity::ContextPtr> ctxs = contexts();
514+
for (auto& c : ctxs) {
515+
destroyContext(c);
516+
}
507517

508-
for (modularity::IModuleSetup* m : m_modules) {
509-
m->onDeinit();
510-
}
518+
for (modularity::IModuleSetup* m : m_modules) {
519+
m->onDeinit();
520+
}
511521

512-
m_globalModule->onDeinit();
522+
m_globalModule->onDeinit();
513523

514-
for (modularity::IModuleSetup* m : m_modules) {
515-
m->onDestroy();
516-
}
524+
for (modularity::IModuleSetup* m : m_modules) {
525+
m->onDestroy();
526+
}
517527

518-
m_globalModule->onDestroy();
528+
m_globalModule->onDestroy();
519529

520-
// Delete modules
521-
qDeleteAll(m_modules);
522-
m_modules.clear();
530+
// Delete modules
531+
qDeleteAll(m_modules);
532+
m_modules.clear();
523533

524-
delete m_globalModule;
525-
m_globalModule = nullptr;
534+
delete m_globalModule;
535+
m_globalModule = nullptr;
526536

527-
muse::modularity::resetAll();
537+
muse::modularity::resetAll();
528538

529-
BaseApplication::finish();
539+
BaseApplication::finish();
540+
}
541+
542+
PROFILER_PRINT;
530543
}
531544

532545
void GuiApp::applyCommandLineOptions(const CmdOptions& options)

src/app/internal/guiapp.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "appshell/internal/istartupscenario.h"
1717
#include "importexport/guitarpro/iguitarproconfiguration.h"
1818

19+
class QQuickWindow;
20+
1921
namespace mu::appshell {
2022
class SplashScreen;
2123
}
@@ -43,7 +45,15 @@ class GuiApp : public muse::BaseApplication, public std::enable_shared_from_this
4345
private:
4446
void applyCommandLineOptions(const CmdOptions& options);
4547

46-
std::vector<muse::modularity::IContextSetup*>& contextSetups(const muse::modularity::ContextPtr& ctx);
48+
struct Context {
49+
muse::modularity::ContextPtr ctx;
50+
std::vector<muse::modularity::IContextSetup*> setups;
51+
QQuickWindow* window = nullptr;
52+
53+
bool isValid() const { return ctx != nullptr && !setups.empty(); }
54+
};
55+
56+
Context& context(const muse::modularity::ContextPtr& ctx);
4757

4858
CmdOptions m_options;
4959

@@ -53,11 +63,6 @@ class GuiApp : public muse::BaseApplication, public std::enable_shared_from_this
5363
muse::GlobalModule* m_globalModule = nullptr;
5464
std::vector<muse::modularity::IModuleSetup*> m_modules;
5565

56-
struct Context {
57-
muse::modularity::ContextPtr ctx;
58-
std::vector<muse::modularity::IContextSetup*> setups;
59-
};
60-
6166
std::vector<Context> m_contexts;
6267
};
6368
}

src/framework/audio/engine/internal/audioengine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ void AudioEngine::deinit()
9090
{
9191
ONLY_AUDIO_ENGINE_THREAD;
9292
if (m_inited) {
93+
m_inited = false;
9394
m_buffer->setSource(nullptr);
9495
m_buffer = nullptr;
9596
m_mixer = nullptr;
96-
m_inited = false;
9797
}
9898
}
9999

src/framework/ui/internal/uiengine.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,14 @@ void UiEngine::init()
8282

8383
void UiEngine::quit()
8484
{
85+
TRACEFUNC;
86+
8587
if (!m_engine) {
8688
return;
8789
}
8890

89-
emit m_engine->quit();
91+
m_engine->exit(0);
92+
9093
delete m_engine;
9194
m_engine = nullptr;
9295
}

0 commit comments

Comments
 (0)