From 17dd341292c20d0a371e3802a3a69c87229314e9 Mon Sep 17 00:00:00 2001 From: Eism Date: Mon, 24 Aug 2026 14:56:20 +0300 Subject: [PATCH 1/3] show window if page is loaded --- src/app/internal/guiapp.cpp | 29 +++++++++++++++---- src/app/internal/guiapp.h | 4 ++- .../qml/MuseScore/AppShell/AppWindow.qml | 5 ++++ .../qml/MuseScore/AppShell/WindowContent.qml | 4 +++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/app/internal/guiapp.cpp b/src/app/internal/guiapp.cpp index a3cb94a4321a6..6106ad176e4df 100644 --- a/src/app/internal/guiapp.cpp +++ b/src/app/internal/guiapp.cpp @@ -2,6 +2,8 @@ #include "modularity/ioc.h" #include "appshell/internal/istartupscenario.h" +#include "dockwindow/idockwindowprovider.h" +#include "dockwindow/idockwindow.h" #include "commandlineparser.h" @@ -125,18 +127,33 @@ void MuseScoreGuiApp::doStartupScenario(const muse::modularity::ContextPtr& ctxI startupScenario->runOnSplashScreen(); QMetaObject::invokeMethod(qApp, [this, ctxId, startupScenario]() { -#ifdef MUE_ENABLE_SPLASHSCREEN - if (m_splashScreen) { - m_splashScreen->close(); - delete m_splashScreen; - m_splashScreen = nullptr; + auto dockWindowProvider = muse::modularity::ioc(ctxId)->resolve("app"); + muse::dock::IDockWindow* dockWindow = dockWindowProvider ? dockWindowProvider->window() : nullptr; + if (dockWindow) { + dockWindow->currentPageChanged().onNotify(this, [this, dockWindow]() { + dockWindow->currentPageChanged().disconnect(this); + + QMetaObject::invokeMethod(qApp, [this]() { + closeSplash(); + }, Qt::QueuedConnection); + }); } -#endif startupScenario->runAfterSplashScreen(); }, Qt::QueuedConnection); } +void MuseScoreGuiApp::closeSplash() +{ +#ifdef MUE_ENABLE_SPLASHSCREEN + if (m_splashScreen) { + m_splashScreen->close(); + delete m_splashScreen; + m_splashScreen = nullptr; + } +#endif +} + void MuseScoreGuiApp::applyCommandLineOptions(const std::shared_ptr& opt) { GuiApplication::applyCommandLineOptions(opt); diff --git a/src/app/internal/guiapp.h b/src/app/internal/guiapp.h index 7a4381131ec1c..249902fefc819 100644 --- a/src/app/internal/guiapp.h +++ b/src/app/internal/guiapp.h @@ -6,6 +6,7 @@ #include "ui/internal/guiapplication.h" #include "../cmdoptions.h" +#include "async/asyncable.h" #include "modularity/ioc.h" #include "multiwindows/imultiwindowsprovider.h" #include "appshell/iappshellconfiguration.h" @@ -16,7 +17,7 @@ class QQuickWindow; namespace mu::app { -class MuseScoreGuiApp : public muse::ui::GuiApplication +class MuseScoreGuiApp : public muse::ui::GuiApplication, public muse::async::Asyncable { muse::GlobalInject multiwindowsProvider; muse::GlobalInject appshellConfiguration; @@ -26,6 +27,7 @@ class MuseScoreGuiApp : public muse::ui::GuiApplication MuseScoreGuiApp(const std::shared_ptr& options); void showSplash() override; + void closeSplash() override; private: diff --git a/src/appshell/qml/MuseScore/AppShell/AppWindow.qml b/src/appshell/qml/MuseScore/AppShell/AppWindow.qml index 2195d4b7bf3d5..c76c2355bb1bb 100644 --- a/src/appshell/qml/MuseScore/AppShell/AppWindow.qml +++ b/src/appshell/qml/MuseScore/AppShell/AppWindow.qml @@ -47,6 +47,11 @@ ApplicationWindow { visible: false + //! NOTE The window must be shown early, + //! but should not be visible until the first page has loaded, + //! so it starts fully transparent; WindowContent restores the opacity. + opacity: 0 + color: ui.theme.backgroundPrimaryColor Component.onCompleted: { diff --git a/src/appshell/qml/MuseScore/AppShell/WindowContent.qml b/src/appshell/qml/MuseScore/AppShell/WindowContent.qml index f64e1e95b1754..a87300877e679 100644 --- a/src/appshell/qml/MuseScore/AppShell/WindowContent.qml +++ b/src/appshell/qml/MuseScore/AppShell/WindowContent.qml @@ -42,6 +42,10 @@ DockWindow { onPageLoaded: { console.log("WindowContent::onPageLoaded") + + //! NOTE The window content is ready now, remove the startup transparency (see AppWindow) + root.window.opacity = 1.0 + interactiveProvider.onPageOpened() } From 42e5bbf67638728b90000807d0f745cdde3dfcfb Mon Sep 17 00:00:00 2001 From: Eism Date: Mon, 31 Aug 2026 17:11:53 +0300 Subject: [PATCH 2/3] removed tweaks with opacity when the program starts --- src/app/internal/guiapp.cpp | 42 +++++++++++++++++-- src/app/internal/guiapp.h | 1 + .../qml/MuseScore/AppShell/AppWindow.qml | 5 --- .../qml/MuseScore/AppShell/WindowContent.qml | 3 -- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/app/internal/guiapp.cpp b/src/app/internal/guiapp.cpp index 6106ad176e4df..24db5c69aa42b 100644 --- a/src/app/internal/guiapp.cpp +++ b/src/app/internal/guiapp.cpp @@ -1,5 +1,8 @@ #include "guiapp.h" +#include +#include + #include "modularity/ioc.h" #include "appshell/internal/istartupscenario.h" #include "dockwindow/idockwindowprovider.h" @@ -130,19 +133,52 @@ void MuseScoreGuiApp::doStartupScenario(const muse::modularity::ContextPtr& ctxI auto dockWindowProvider = muse::modularity::ioc(ctxId)->resolve("app"); muse::dock::IDockWindow* dockWindow = dockWindowProvider ? dockWindowProvider->window() : nullptr; if (dockWindow) { - dockWindow->currentPageChanged().onNotify(this, [this, dockWindow]() { + dockWindow->currentPageChanged().onNotify(this, [this, ctxId, dockWindow]() { dockWindow->currentPageChanged().disconnect(this); - QMetaObject::invokeMethod(qApp, [this]() { - closeSplash(); + QMetaObject::invokeMethod(qApp, [this, ctxId]() { + showMainWindowAndCloseSplash(ctxId); }, Qt::QueuedConnection); }); + } else { + //! NOTE No dock window - no page loading to wait for + showMainWindowAndCloseSplash(ctxId); } startupScenario->runAfterSplashScreen(); }, Qt::QueuedConnection); } +void MuseScoreGuiApp::showMainWindowAndCloseSplash(const muse::modularity::ContextPtr& ctxId) +{ + auto it = m_windows.find(ctxId->id); + QQuickWindow* window = it != m_windows.end() ? it->second : nullptr; + if (!window) { + closeSplash(); + return; + } + + //! NOTE Close the splash only after the window has rendered its first frame, + //! so that the empty window is never visible + auto conn = std::make_shared(); + *conn = QObject::connect(window, &QQuickWindow::frameSwapped, qApp, [this, conn]() { + QObject::disconnect(*conn); + closeSplash(); + }, Qt::QueuedConnection); + + //! NOTE Safety net for the case when the window never renders a frame; + //! long enough so that it cannot fire before the first frame of a healthy startup + static constexpr int SPLASH_CLOSE_TIMEOUT_MS = 10000; + QTimer::singleShot(SPLASH_CLOSE_TIMEOUT_MS, qApp, [this]() { + if (m_splashScreen) { + LOGW() << "the main window has not rendered any frame, closing the splash screen forcibly"; + closeSplash(); + } + }); + + window->setVisible(true); +} + void MuseScoreGuiApp::closeSplash() { #ifdef MUE_ENABLE_SPLASHSCREEN diff --git a/src/app/internal/guiapp.h b/src/app/internal/guiapp.h index 249902fefc819..9c0a1598c8278 100644 --- a/src/app/internal/guiapp.h +++ b/src/app/internal/guiapp.h @@ -45,6 +45,7 @@ class MuseScoreGuiApp : public muse::ui::GuiApplication, public muse::async::Asy void showContextSplash(const muse::modularity::ContextPtr& ctxId) override; QString mainWindowQmlPath(const QString& platform) const override; void doStartupScenario(const muse::modularity::ContextPtr& ctxId) override; + void showMainWindowAndCloseSplash(const muse::modularity::ContextPtr& ctxId); appshell::SplashScreen* m_splashScreen = nullptr; }; diff --git a/src/appshell/qml/MuseScore/AppShell/AppWindow.qml b/src/appshell/qml/MuseScore/AppShell/AppWindow.qml index c76c2355bb1bb..2195d4b7bf3d5 100644 --- a/src/appshell/qml/MuseScore/AppShell/AppWindow.qml +++ b/src/appshell/qml/MuseScore/AppShell/AppWindow.qml @@ -47,11 +47,6 @@ ApplicationWindow { visible: false - //! NOTE The window must be shown early, - //! but should not be visible until the first page has loaded, - //! so it starts fully transparent; WindowContent restores the opacity. - opacity: 0 - color: ui.theme.backgroundPrimaryColor Component.onCompleted: { diff --git a/src/appshell/qml/MuseScore/AppShell/WindowContent.qml b/src/appshell/qml/MuseScore/AppShell/WindowContent.qml index a87300877e679..7412b0ea54ecd 100644 --- a/src/appshell/qml/MuseScore/AppShell/WindowContent.qml +++ b/src/appshell/qml/MuseScore/AppShell/WindowContent.qml @@ -43,9 +43,6 @@ DockWindow { onPageLoaded: { console.log("WindowContent::onPageLoaded") - //! NOTE The window content is ready now, remove the startup transparency (see AppWindow) - root.window.opacity = 1.0 - interactiveProvider.onPageOpened() } From 2435390f4bb4e1c9d3741ddfa215928fd25ccbf5 Mon Sep 17 00:00:00 2001 From: Eism Date: Mon, 31 Aug 2026 17:13:06 +0300 Subject: [PATCH 3/3] updated framework and deps --- muse | 2 +- muse_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/muse b/muse index ee2c97edf5fff..ec022e43394b0 160000 --- a/muse +++ b/muse @@ -1 +1 @@ -Subproject commit ee2c97edf5fff6ae46289851ec8e2968a5deb045 +Subproject commit ec022e43394b0e1c1213e4aa857fbe3388a6236f diff --git a/muse_deps b/muse_deps index 31ad619b85f58..621f8a4b61484 160000 --- a/muse_deps +++ b/muse_deps @@ -1 +1 @@ -Subproject commit 31ad619b85f58e10c75bb633ccdbb64137b2b314 +Subproject commit 621f8a4b61484c7adade3f3210070e6fd368610b