Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fullscreen toggle rework #11566

Merged
merged 5 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 78 additions & 26 deletions src/mixxxmainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ MixxxMainWindow::MixxxMainWindow(std::shared_ptr<mixxx::CoreServices> 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()),
Expand Down Expand Up @@ -161,6 +164,7 @@ void MixxxMainWindow::initializeQOpenGL() {
#endif

void MixxxMainWindow::initialize() {
qWarning() << " $ initialize";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug leftover? There are more warning that should be removed or become debug messages if it adds any value to the mixxx.log.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the last commit with debug output which should help debugging in case something doesn't work as expected.
I'll remove that in case the other commits are considered okay.

m_pCoreServices->getControlIndicatorTimer()->setLegacyVsyncEnabled(true);

UserSettingsPointer pConfig = m_pCoreServices->getSettings();
Expand Down Expand Up @@ -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<bool>(
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();
}

Expand Down Expand Up @@ -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"),
Expand Down Expand Up @@ -485,6 +497,7 @@ MixxxMainWindow::~MixxxMainWindow() {
}

void MixxxMainWindow::initializeWindow() {
qWarning() << " $ initializeWindow";
// be sure createMenuBar() is called first
DEBUG_ASSERT(m_pMenuBar);

Expand All @@ -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"))
Expand Down Expand Up @@ -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<WMainMenuBar>(
Expand All @@ -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,
Expand Down Expand Up @@ -728,7 +747,8 @@ void MixxxMainWindow::connectMenuBar() {
connect(m_pMenuBar,
&WMainMenuBar::showKeywheel,
this,
&MixxxMainWindow::slotShowKeywheel);
&MixxxMainWindow::slotShowKeywheel,
Qt::UniqueConnection);

// Fullscreen
connect(m_pMenuBar,
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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<QWindowStateChangeEvent*>(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);
Expand Down
3 changes: 3 additions & 0 deletions src/mixxxmainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ class MixxxMainWindow : public QMainWindow {

QWidget* m_pCentralWidget;
LaunchImage* m_pLaunchImage;
#ifndef __APPLE__
Qt::WindowStates m_prevState;
#endif

std::shared_ptr<mixxx::skin::SkinLoader> m_pSkinLoader;
GuiTick* m_pGuiTick;
Expand Down