diff --git a/src/mixxxmainwindow.cpp b/src/mixxxmainwindow.cpp index 682c3eeaefb..fe6584b3698 100644 --- a/src/mixxxmainwindow.cpp +++ b/src/mixxxmainwindow.cpp @@ -87,6 +87,9 @@ MixxxMainWindow::MixxxMainWindow(std::shared_ptr pCoreServi : m_pCoreServices(pCoreServices), m_pCentralWidget(nullptr), m_pLaunchImage(nullptr), +#ifndef __APPLE__ + m_prevState(Qt::WindowNoState), +#endif m_pGuiTick(nullptr), #ifdef __LINUX__ m_supportsGlobalMenuBar(supportsGlobalMenu()), @@ -161,6 +164,7 @@ void MixxxMainWindow::initializeQOpenGL() { #endif void MixxxMainWindow::initialize() { + qWarning() << " $ initialize"; m_pCoreServices->getControlIndicatorTimer()->setLegacyVsyncEnabled(true); UserSettingsPointer pConfig = m_pCoreServices->getSettings(); @@ -190,10 +194,13 @@ void MixxxMainWindow::initialize() { // Turn on fullscreen mode // if we were told to start in fullscreen mode on the command-line // or if the user chose to always start in fullscreen mode. - // Remember to refresh the Fullscreen menu item after connectMenuBar() + // The Fullscreen menu item is refreshed in connectMenuBar() bool fullscreenPref = m_pCoreServices->getSettings()->getValue( ConfigKey("[Config]", "StartInFullscreen")); - if (CmdlineArgs::Instance().getStartInFullscreen() || fullscreenPref) { + if ((CmdlineArgs::Instance().getStartInFullscreen() || fullscreenPref) && + // could be we're fullscreen already after setGeomtery(previousGeometry) + !isFullScreen()) { + qWarning() << " init: go fullscreen"; showFullScreen(); } @@ -418,6 +425,11 @@ MixxxMainWindow::~MixxxMainWindow() { // Simply maximize the window so we can store a geometry that fits the screen. // Don't call slotViewFullScreen(false) (calls showNormal()) because that // can make the main window incl. window decoration too large for the screen. +#ifndef __APPLE__ + // Before, store the expected window state so eventFilter() will ignore + // the following QWindowChangeEvent and not recreate & re-sync the menu bar. + m_prevState = Qt::WindowMaximized; +#endif showMaximized(); } m_pCoreServices->getSettings()->set(ConfigKey("[MainWindow]", "geometry"), @@ -485,6 +497,7 @@ MixxxMainWindow::~MixxxMainWindow() { } void MixxxMainWindow::initializeWindow() { + qWarning() << " $ initializeWindow"; // be sure createMenuBar() is called first DEBUG_ASSERT(m_pMenuBar); @@ -498,7 +511,11 @@ void MixxxMainWindow::initializeWindow() { Pal.setColor(QPalette::Window, MenuBarBackground); m_pMenuBar->setPalette(Pal); - // Restore the current window state (position, maximized, etc) + // Restore the current window state (position, maximized, etc). + // This will also restore fullscreen and thereby create a seamless + // start if we did shut down while in fullscreen mode and with + // [Config],StartInFullscreen = 1 + // (slotViewFullScreen(true) in initialize() is a no-op then) restoreGeometry(QByteArray::fromBase64( m_pCoreServices->getSettings() ->getValueString(ConfigKey("[MainWindow]", "geometry")) @@ -687,6 +704,7 @@ void MixxxMainWindow::slotUpdateWindowTitle(TrackPointer pTrack) { } void MixxxMainWindow::createMenuBar() { + qWarning() << " $ createMenuBar"; ScopedTimer t(u"MixxxMainWindow::createMenuBar"); DEBUG_ASSERT(m_pCoreServices->getKeyboardConfig()); m_pMenuBar = make_parented( @@ -700,6 +718,7 @@ void MixxxMainWindow::createMenuBar() { void MixxxMainWindow::connectMenuBar() { // This function might be invoked multiple times on startup // so all connections must be unique! + qWarning() << " $ connectMenuBar"; ScopedTimer t(u"MixxxMainWindow::connectMenuBar"); connect(this, @@ -728,7 +747,8 @@ void MixxxMainWindow::connectMenuBar() { connect(m_pMenuBar, &WMainMenuBar::showKeywheel, this, - &MixxxMainWindow::slotShowKeywheel); + &MixxxMainWindow::slotShowKeywheel, + Qt::UniqueConnection); // Fullscreen connect(m_pMenuBar, @@ -940,35 +960,21 @@ void MixxxMainWindow::slotDeveloperToolsClosed() { } void MixxxMainWindow::slotViewFullScreen(bool toggle) { + qWarning() << " $ slotViewFullScreen" << toggle; if (isFullScreen() == toggle) { + qWarning() << " (no-op)"; return; } + // Just switch the window state here. eventFilter() will catch the + // QWindowStateChangeEvent and inform the menu bar that fullscreen changed. if (toggle) { + qWarning() << " > showFullScreen()"; showFullScreen(); -#ifdef __LINUX__ - // Fix for "No menu bar with ubuntu unity in full screen mode" (issues - // #6072 and #6689. Before touching anything here, please read - // those bugs. - // Set this attribute instead of calling setNativeMenuBar(false), see - // https://github.com/mixxxdj/mixxx/issues/11320 - if (m_supportsGlobalMenuBar) { - QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true); - createMenuBar(); - connectMenuBar(); - } -#endif } else { -#ifdef __LINUX__ - if (m_supportsGlobalMenuBar) { - QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, false); - createMenuBar(); - connectMenuBar(); - } -#endif + qWarning() << " > showNormal()"; showNormal(); } - emit fullScreenChanged(toggle); } void MixxxMainWindow::slotOptionsPreferences() { @@ -1086,7 +1092,9 @@ void MixxxMainWindow::rebootMixxxView() { // window returns to 0,0 but and the backdrop disappears so it looks as if // it is not fullscreen, but acts as if it is. bool wasFullScreen = isFullScreen(); - slotViewFullScreen(false); + if (wasFullScreen) { + showMaximized(); + } if (!loadConfiguredSkin()) { QMessageBox::critical(this, @@ -1107,7 +1115,7 @@ void MixxxMainWindow::rebootMixxxView() { #endif if (wasFullScreen) { - slotViewFullScreen(true); + showFullScreen(); } else { // Programmatic placement at this point is very problematic. // The screen() method returns stale data (primary screen) @@ -1158,6 +1166,50 @@ bool MixxxMainWindow::eventFilter(QObject* obj, QEvent* event) { return true; } } + } else if (event->type() == QEvent::WindowStateChange) { +#ifndef __APPLE__ + qWarning() << "$ WindowStateChange:" << windowState(); + if (windowState() == m_prevState) { + // Ignore no-op. This happens if another window is raised above + // MixxxMianWindow, e.g. DlgPeferences. In such a case event->oldState() + // will be Qt::WindowNoState which is wrong anyway, so there is nothing + // to do internally. + qWarning() << "$ WindowStateChange IGNORE"; + return QMainWindow::eventFilter(obj, event); + } + m_prevState = windowState(); +#endif + // Detect if we entered or quit fullscreen mode. + QWindowStateChangeEvent* changeEvent = + static_cast(event); + const bool wasFullScreen = changeEvent->oldState() & Qt::WindowFullScreen; + const bool isFullScreenNow = windowState() & Qt::WindowFullScreen; + if ((isFullScreenNow && !wasFullScreen) || + (!isFullScreenNow && wasFullScreen)) { + qWarning() << "$ fullscreen changed, now" + << (isFullScreenNow ? "fullscreen" : "window"); +#ifdef __LINUX__ + // Fix for "No menu bar with ubuntu unity in full screen mode" + // (issues #6072 and #6689). Before touching anything here, please + // read those bugs. + // Set this attribute instead of calling setNativeMenuBar(false), + // see https://github.com/mixxxdj/mixxx/issues/11320 + if (m_supportsGlobalMenuBar) { + qWarning() << "$ global menu > rebuild"; + QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, isFullScreenNow); + createMenuBar(); + connectMenuBar(); + } +#endif + // This will toggle the Fullscreen checkbox and hide the menubar if + // we go fullscreen. + // Skip this during startup or the launchimage will be shifted + // up & down when the menu is shown menu and 'hidden'. The menu + // will be updated when the skin finished loading. + if (centralWidget() != m_pLaunchImage) { + emit fullScreenChanged(isFullScreen()); + } + } } // standard event processing return QMainWindow::eventFilter(obj, event); diff --git a/src/mixxxmainwindow.h b/src/mixxxmainwindow.h index fae4ce61697..98cea999928 100644 --- a/src/mixxxmainwindow.h +++ b/src/mixxxmainwindow.h @@ -115,6 +115,9 @@ class MixxxMainWindow : public QMainWindow { QWidget* m_pCentralWidget; LaunchImage* m_pLaunchImage; +#ifndef __APPLE__ + Qt::WindowStates m_prevState; +#endif std::shared_ptr m_pSkinLoader; GuiTick* m_pGuiTick;