From 4664935a66b676aab27601dbdffb7b0f22140903 Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Thu, 2 Jan 2025 21:03:17 -0500 Subject: [PATCH] Qt 6.9 compatibility --- src/mainwindow.cpp | 15 +++++------- src/qvcocoafunctions.h | 6 ++--- src/qvcocoafunctions.mm | 52 +++++++++++++++++++++++++++-------------- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 31704c9c..573903a7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -213,7 +213,7 @@ void MainWindow::showEvent(QShowEvent *event) { #ifdef COCOA_LOADED QTimer::singleShot(0, this, [this]() { - QVCocoaFunctions::setFullSizeContentView(windowHandle(), true); + QVCocoaFunctions::setFullSizeContentView(this, true); }); #endif @@ -244,7 +244,7 @@ void MainWindow::closeEvent(QCloseEvent *event) isClosing = true; #ifdef COCOA_LOADED - QVCocoaFunctions::setFullSizeContentView(windowHandle(), false); + QVCocoaFunctions::setFullSizeContentView(this, false); #endif #if defined COCOA_LOADED && QT_VERSION == QT_VERSION_CHECK(6, 8, 1) @@ -659,7 +659,7 @@ bool MainWindow::getTitlebarHidden() const return false; #if defined COCOA_LOADED && QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - return QVCocoaFunctions::getTitlebarHidden(windowHandle()); + return QVCocoaFunctions::getTitlebarHidden(this); #else return !windowFlags().testFlag(Qt::WindowTitleHint); #endif @@ -670,18 +670,15 @@ void MainWindow::setTitlebarHidden(const bool shouldHide) if (!windowHandle()) return; - auto customizeWindowFlags = [this](const Qt::WindowFlags flagsToChange, const bool on) { + const auto customizeWindowFlags = [this](const Qt::WindowFlags flagsToChange, const bool on) { Qt::WindowFlags newFlags = windowFlags() | Qt::CustomizeWindowHint; - if (on) - newFlags |= flagsToChange; - else - newFlags &= ~flagsToChange; + newFlags = on ? (newFlags | flagsToChange) : (newFlags & ~flagsToChange); overrideWindowFlags(newFlags); windowHandle()->setFlags(newFlags); }; #if defined COCOA_LOADED && QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - QVCocoaFunctions::setTitlebarHidden(windowHandle(), shouldHide); + QVCocoaFunctions::setTitlebarHidden(this, shouldHide); customizeWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowMinMaxButtonsHint | Qt::WindowFullscreenButtonHint, !shouldHide); #elif defined WIN32_LOADED customizeWindowFlags(Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint, !shouldHide); diff --git a/src/qvcocoafunctions.h b/src/qvcocoafunctions.h index 2d39b9a2..18cff527 100644 --- a/src/qvcocoafunctions.h +++ b/src/qvcocoafunctions.h @@ -13,11 +13,11 @@ class QVCocoaFunctions static void setUserDefaults(); - static void setFullSizeContentView(QWindow *window, const bool shouldEnable); + static void setFullSizeContentView(QWidget *window, const bool enable); - static bool getTitlebarHidden(QWindow *window); + static bool getTitlebarHidden(const QWidget *window); - static void setTitlebarHidden(QWindow *window, const bool shouldHide); + static void setTitlebarHidden(QWidget *window, const bool hide); static void setVibrancy(bool alwaysDark, QWindow *window); diff --git a/src/qvcocoafunctions.mm b/src/qvcocoafunctions.mm index 5754e501..56ed7637 100644 --- a/src/qvcocoafunctions.mm +++ b/src/qvcocoafunctions.mm @@ -64,33 +64,39 @@ static void fixNativeMenuEccentricities(QMenu *menu, NSMenu *nativeMenu) [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"]; } -// This function should only be called once because it sets observers -void QVCocoaFunctions::setFullSizeContentView(QWindow *window, const bool shouldEnable) +// This function should only be enabled once because it sets observers +void QVCocoaFunctions::setFullSizeContentView(QWidget *window, const bool enable) { auto *view = reinterpret_cast(window->winId()); - const bool isAlreadyEnabled = view.window.styleMask & NSWindowStyleMaskFullSizeContentView; - if (shouldEnable == isAlreadyEnabled || (shouldEnable && !view.wantsLayer)) + // Make sure the requested state isn't already in effect + if (enable == (view.window.styleMask & NSWindowStyleMaskFullSizeContentView)) return; + // Enable only if this Qt and macOS version combination is already using layer-backed view + if (enable && !view.wantsLayer) + return; + + // Changing the style mask causes the window to resize, so snapshot the original size NSRect originalFrame = view.window.frame; - if (shouldEnable) - { + +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + Qt::WindowFlags newFlags = window->windowFlags().setFlag(Qt::ExpandedClientAreaHint, enable); + window->windowHandle()->setFlags(newFlags); + window->overrideWindowFlags(newFlags); +#else + if (enable) view.window.styleMask |= NSWindowStyleMaskFullSizeContentView; - } else - { - int titlebarOverlap = view.window.contentView.frame.size.height - view.window.contentLayoutRect.size.height; - NSRect adjustedFrame = originalFrame; - adjustedFrame.size.height -= titlebarOverlap; - [view.window setFrame:adjustedFrame display:NO]; view.window.styleMask &= ~NSWindowStyleMaskFullSizeContentView; - } +#endif + + // Restore original size after style mask change [view.window setFrame:originalFrame display:YES]; #if QT_VERSION < QT_VERSION_CHECK(6, 2, 0) // workaround for QTBUG-69975 - if (shouldEnable) + if (enable) { [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowDidExitFullScreenNotification object:view.window queue:nil usingBlock:^(NSNotification *notification){ auto *window = reinterpret_cast(notification.object); @@ -105,17 +111,27 @@ static void fixNativeMenuEccentricities(QMenu *menu, NSMenu *nativeMenu) #endif } -bool QVCocoaFunctions::getTitlebarHidden(QWindow *window) +bool QVCocoaFunctions::getTitlebarHidden(const QWidget *window) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + return window->windowFlags().testFlags(Qt::NoTitleBarBackgroundHint); +#else auto *view = reinterpret_cast(window->winId()); return view.window.titleVisibility == NSWindowTitleHidden; +#endif } -void QVCocoaFunctions::setTitlebarHidden(QWindow *window, const bool shouldHide) +void QVCocoaFunctions::setTitlebarHidden(QWidget *window, const bool hide) { auto *view = reinterpret_cast(window->winId()); - view.window.titleVisibility = shouldHide ? NSWindowTitleHidden : NSWindowTitleVisible; - view.window.titlebarAppearsTransparent = shouldHide; +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + Qt::WindowFlags newFlags = window->windowFlags().setFlag(Qt::NoTitleBarBackgroundHint, hide); + window->windowHandle()->setFlags(newFlags); + window->overrideWindowFlags(newFlags); +#else + view.window.titlebarAppearsTransparent = hide; +#endif + view.window.titleVisibility = hide ? NSWindowTitleHidden : NSWindowTitleVisible; } void QVCocoaFunctions::setVibrancy(bool alwaysDark, QWindow *window)