diff --git a/framework/dockwindow/idockwindow.h b/framework/dockwindow/idockwindow.h index a34657bd14..1fe6876f0e 100644 --- a/framework/dockwindow/idockwindow.h +++ b/framework/dockwindow/idockwindow.h @@ -26,6 +26,7 @@ #include #include "async/channel.h" +#include "async/notification.h" class QPoint; @@ -46,6 +47,8 @@ class IDockWindow virtual void toggleDockFloating(const QString& dockName) = 0; virtual DockPageView* currentPage() const = 0; + virtual async::Notification currentPageChanged() const = 0; + virtual QQuickItem& asItem() const = 0; virtual void restoreDefaultLayout() = 0; diff --git a/framework/dockwindow/qml/Muse/Dock/dockwindow.cpp b/framework/dockwindow/qml/Muse/Dock/dockwindow.cpp index a4678bc761..263d77c02c 100644 --- a/framework/dockwindow/qml/Muse/Dock/dockwindow.cpp +++ b/framework/dockwindow/qml/Muse/Dock/dockwindow.cpp @@ -265,7 +265,7 @@ void DockWindow::loadPage(const QString& uri, const QVariantMap& params) || (m_mainWindow->windowHandle()->windowStates() & Qt::WindowFullScreen)) { //! NOTE: show window as maximized if no geometry has been restored //! or if the user had closed app in FullScreen mode - m_mainWindow->windowHandle()->showMaximized(); + m_mainWindow->windowHandle()->setWindowStates(Qt::WindowMaximized); } notifyAboutPageLoaded(); @@ -323,6 +323,11 @@ DockPageView* DockWindow::currentPage() const return m_currentPage; } +Notification DockWindow::currentPageChanged() const +{ + return m_currentPageChanged; +} + QQuickItem& DockWindow::asItem() const { return *m_mainWindow; @@ -580,6 +585,8 @@ bool DockWindow::doLoadPage(const QString& uri, const QVariantMap& params) m_currentPage = newPage; + m_currentPageChanged.notify(); + connect(m_currentPage, &DockPageView::layoutRequested, this, &DockWindow::forceLayout, Qt::UniqueConnection); @@ -676,10 +683,10 @@ bool DockWindow::restoreLayout(const QByteArray& layout, bool restoreRelativeToM TRACEFUNC; - auto option = restoreRelativeToMainWindow ? KDDockWidgets::RestoreOption_RelativeToMainWindow - : KDDockWidgets::RestoreOption_None; + auto options = restoreRelativeToMainWindow ? KDDockWidgets::RestoreOptions(KDDockWidgets::RestoreOption_RelativeToMainWindow) + : KDDockWidgets::RestoreOptions(KDDockWidgets::RestoreOption_SkipMainWindowVisibility); - KDDockWidgets::LayoutSaver layoutSaver(m_ctx, option); + KDDockWidgets::LayoutSaver layoutSaver(m_ctx, options); return layoutSaver.restoreLayout(layout); } diff --git a/framework/dockwindow/qml/Muse/Dock/dockwindow.h b/framework/dockwindow/qml/Muse/Dock/dockwindow.h index 8c112d2ac5..3667f9f523 100644 --- a/framework/dockwindow/qml/Muse/Dock/dockwindow.h +++ b/framework/dockwindow/qml/Muse/Dock/dockwindow.h @@ -97,6 +97,8 @@ class DockWindow : public QQuickItem, public IDockWindow, public muse::Contextab void toggleDockFloating(const QString& dockName) override; DockPageView* currentPage() const override; + async::Notification currentPageChanged() const override; + QQuickItem& asItem() const override; void restoreDefaultLayout() override; @@ -150,7 +152,10 @@ private slots: int m_ctx = 0; KDDockWidgets::MainWindowBase* m_mainWindow = nullptr; + DockPageView* m_currentPage = nullptr; + async::Notification m_currentPageChanged; + uicomponents::QmlListProperty m_toolBars; uicomponents::QmlListProperty m_pages; async::Channel m_docksOpenStatusChanged; diff --git a/framework/dockwindow/thirdparty/KDDockWidgets/src/KDDockWidgets.h b/framework/dockwindow/thirdparty/KDDockWidgets/src/KDDockWidgets.h index 65261953a8..6141bb5978 100644 --- a/framework/dockwindow/thirdparty/KDDockWidgets/src/KDDockWidgets.h +++ b/framework/dockwindow/thirdparty/KDDockWidgets/src/KDDockWidgets.h @@ -183,6 +183,7 @@ enum RestoreOption { RestoreOption_None = 0, RestoreOption_RelativeToMainWindow = 1, ///< Skips restoring the main window geometry and the restored dock widgets will use relative sizing. + RestoreOption_SkipMainWindowVisibility = 2, ///< Don't show/hide the main window according to the saved layout when restoring. ///< Loading layouts won't change the main window geometry and just use whatever the user has at the moment. }; Q_DECLARE_FLAGS(RestoreOptions, RestoreOption) diff --git a/framework/dockwindow/thirdparty/KDDockWidgets/src/LayoutSaver.cpp b/framework/dockwindow/thirdparty/KDDockWidgets/src/LayoutSaver.cpp index ab7bfe9822..6789ead249 100644 --- a/framework/dockwindow/thirdparty/KDDockWidgets/src/LayoutSaver.cpp +++ b/framework/dockwindow/thirdparty/KDDockWidgets/src/LayoutSaver.cpp @@ -64,15 +64,20 @@ LayoutSaver::Layout *LayoutSaver::Layout::s_currentLayoutBeingRestored = nullptr inline InternalRestoreOptions internalRestoreOptions(RestoreOptions options) { - if (options == RestoreOption_None) { - return InternalRestoreOption::None; - } else if (options == RestoreOption_RelativeToMainWindow) { - return InternalRestoreOptions(InternalRestoreOption::SkipMainWindowGeometry) - | InternalRestoreOption::RelativeFloatingWindowGeometry; - } else { + InternalRestoreOptions ret = {}; + if (options.testFlag(RestoreOption_RelativeToMainWindow)) { + ret.setFlag(InternalRestoreOption::SkipMainWindowGeometry); + ret.setFlag(InternalRestoreOption::RelativeFloatingWindowGeometry); + options.setFlag(RestoreOption_RelativeToMainWindow, false); + } + if (options.testFlag(RestoreOption_SkipMainWindowVisibility)) { + ret.setFlag(InternalRestoreOption::SkipMainWindowVisibility); + options.setFlag(RestoreOption_SkipMainWindowVisibility, false); + } + if (options != RestoreOption_None) { qWarning() << Q_FUNC_INFO << "Unknown options" << options; - return {}; } + return ret; } bool LayoutSaver::Private::s_restoreInProgress = false; @@ -247,7 +252,8 @@ bool LayoutSaver::restoreLayout(const QByteArray &data) continue; if (!(d->m_restoreOptions & InternalRestoreOption::SkipMainWindowGeometry)) { - d->deserializeWindowGeometry(mw, mainWindow->window()); // window(), as the MainWindow can be embedded + const bool applyVisibility = !(d->m_restoreOptions & InternalRestoreOption::SkipMainWindowVisibility); + d->deserializeWindowGeometry(mw, mainWindow->window(), applyVisibility); // window(), as the MainWindow can be embedded if (mw.windowState != Qt::WindowNoState && mw.windowState != Qt::WindowMinimized) { if (auto w = mainWindow->windowHandle()) { w->setWindowState(mw.windowState); @@ -335,7 +341,7 @@ void LayoutSaver::Private::clearRestoredProperty() } template -void LayoutSaver::Private::deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel) +void LayoutSaver::Private::deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel, bool applyVisibility) { // Not simply calling QWidget::setGeometry() here. // For QtQuick we need to modify the QWindow's geometry. @@ -355,7 +361,9 @@ void LayoutSaver::Private::deserializeWindowGeometry(const T &saved, QWidgetOrQu KDDockWidgets::Private::setTopLevelGeometry(geometry, topLevel); } - topLevel->setVisible(saved.isVisible); + if (applyVisibility) { + topLevel->setVisible(saved.isVisible); + } } LayoutSaver::Private::Private(int ctx, RestoreOptions options) diff --git a/framework/dockwindow/thirdparty/KDDockWidgets/src/private/LayoutSaver_p.h b/framework/dockwindow/thirdparty/KDDockWidgets/src/private/LayoutSaver_p.h index 6eaacea1ff..727fd0fdc1 100644 --- a/framework/dockwindow/thirdparty/KDDockWidgets/src/private/LayoutSaver_p.h +++ b/framework/dockwindow/thirdparty/KDDockWidgets/src/private/LayoutSaver_p.h @@ -48,7 +48,8 @@ enum class InternalRestoreOption None = 0, SkipMainWindowGeometry = 1, ///< Don't reposition the main window's geometry when restoring. RelativeFloatingWindowGeometry = - 2 ///< FloatingWindow's are repositioned relatively to the new MainWindow's size + 2, ///< FloatingWindow's are repositioned relatively to the new MainWindow's size + SkipMainWindowVisibility = 4 ///< Don't show/hide the main window according to the saved layout. }; Q_DECLARE_FLAGS(InternalRestoreOptions, InternalRestoreOption) @@ -416,7 +417,7 @@ class LayoutSaver::Private void floatUnknownWidgets(const LayoutSaver::Layout &layout); template - void deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel); + void deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel, bool applyVisibility = true); void deleteEmptyFrames(); void clearRestoredProperty(); diff --git a/framework/dockwindow_v2/idockwindow.h b/framework/dockwindow_v2/idockwindow.h index a34657bd14..1fe6876f0e 100644 --- a/framework/dockwindow_v2/idockwindow.h +++ b/framework/dockwindow_v2/idockwindow.h @@ -26,6 +26,7 @@ #include #include "async/channel.h" +#include "async/notification.h" class QPoint; @@ -46,6 +47,8 @@ class IDockWindow virtual void toggleDockFloating(const QString& dockName) = 0; virtual DockPageView* currentPage() const = 0; + virtual async::Notification currentPageChanged() const = 0; + virtual QQuickItem& asItem() const = 0; virtual void restoreDefaultLayout() = 0; diff --git a/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.cpp b/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.cpp index bf443d3433..637ed50053 100644 --- a/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.cpp +++ b/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.cpp @@ -244,7 +244,7 @@ void DockWindow::loadPage(const QString& uri, const QVariantMap& params) || (m_mainWindow->window()->isFullScreen())) { //! NOTE: show window as maximized if no geometry has been restored //! or if the user had closed app in FullScreen mode - // m_mainWindow->window()->->showMaximized(); // todo kddock + m_mainWindow->window()->setWindowState(KDDockWidgets::WindowState::Maximized); } notifyAboutPageLoaded(); @@ -302,6 +302,11 @@ DockPageView* DockWindow::currentPage() const return m_currentPage; } +Notification DockWindow::currentPageChanged() const +{ + return m_currentPageChanged; +} + QQuickItem& DockWindow::asItem() const { return *m_mainWindow; @@ -518,6 +523,8 @@ bool DockWindow::doLoadPage(const QString& uri, const QVariantMap& params) m_currentPage = newPage; + m_currentPageChanged.notify(); + connect(m_currentPage, &DockPageView::layoutRequested, this, &DockWindow::forceLayout, Qt::UniqueConnection); @@ -605,10 +612,10 @@ bool DockWindow::restoreLayout(const QByteArray& layout, bool restoreRelativeToM TRACEFUNC; - auto option = restoreRelativeToMainWindow ? KDDockWidgets::RestoreOption_RelativeToMainWindow - : KDDockWidgets::RestoreOption_None; + auto options = restoreRelativeToMainWindow ? KDDockWidgets::RestoreOptions(KDDockWidgets::RestoreOption_RelativeToMainWindow) + : KDDockWidgets::RestoreOptions(KDDockWidgets::RestoreOption_SkipMainWindowVisibility); - KDDockWidgets::LayoutSaver layoutSaver(iocContext()->id, option); + KDDockWidgets::LayoutSaver layoutSaver(iocContext()->id, options); return layoutSaver.restoreLayout(layout); } diff --git a/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.h b/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.h index 09ebddff56..8fd9394d1c 100644 --- a/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.h +++ b/framework/dockwindow_v2/qml/Muse/Dock/dockwindow.h @@ -97,6 +97,8 @@ class DockWindow : public QQuickItem, public IDockWindow, public muse::Contextab void toggleDockFloating(const QString& dockName) override; DockPageView* currentPage() const override; + async::Notification currentPageChanged() const override; + QQuickItem& asItem() const override; void restoreDefaultLayout() override; @@ -147,7 +149,10 @@ private slots: void notifyAboutDocksOpenStatus(); KDDockWidgets::QtQuick::MainWindow* m_mainWindow = nullptr; + DockPageView* m_currentPage = nullptr; + async::Notification m_currentPageChanged; + uicomponents::QmlListProperty m_toolBars; uicomponents::QmlListProperty m_pages; async::Channel m_docksOpenStatusChanged; diff --git a/framework/global/iapplication.h b/framework/global/iapplication.h index f279f0b1f4..1e1dd5e11c 100644 --- a/framework/global/iapplication.h +++ b/framework/global/iapplication.h @@ -65,6 +65,7 @@ class IApplication : MODULE_GLOBAL_INTERFACE virtual bool noGui() const = 0; virtual void showSplash() {} + virtual void closeSplash() {} virtual void setup() = 0; virtual void finish() = 0; virtual void restart() = 0; diff --git a/framework/ui/internal/guiapplication.cpp b/framework/ui/internal/guiapplication.cpp index c5cbb79451..3ea31c4a6a 100644 --- a/framework/ui/internal/guiapplication.cpp +++ b/framework/ui/internal/guiapplication.cpp @@ -124,6 +124,8 @@ void GuiApplication::startupScenario(const muse::modularity::ContextPtr& ctxId) QMetaObject::invokeMethod(qApp, [this, ctxId]() { doStartupScenario(ctxId); }, Qt::QueuedConnection); + } else { + closeSplash(); } }, Qt::QueuedConnection); } @@ -174,11 +176,7 @@ bool GuiApplication::loadMainWindow(const muse::modularity::ContextPtr& ctxId) return false; } - // The main window must be shown at this point so KDDockWidgets can read its size correctly - // and scale all sizes properly. https://github.com/musescore/MuseScore/issues/21148 QQuickWindow* window = dynamic_cast(obj); - window->setVisible(true); - m_windows[ctxId->id] = window; return true;