From 5173fb51afa4a5daf94dac4deac189486c00368f Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Mon, 18 Apr 2022 16:50:33 +0800 Subject: [PATCH] macos: add initial implementation Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- .../Core/framelesshelpercore_global.h | 10 +- include/FramelessHelper/Core/utils.h | 9 +- .../Widgets/framelesswidgetshelper.h | 3 +- src/core/CMakeLists.txt | 9 +- src/core/framelesshelper_qt.cpp | 15 +- src/core/framelesswindowsmanager.cpp | 22 +- src/core/framelesswindowsmanager_p.h | 4 +- src/core/utils_mac.cpp | 31 --- src/core/utils_mac.mm | 250 ++++++++++++++++++ src/quick/framelessquickwindow.cpp | 20 +- src/widgets/framelesswidgetshelper.cpp | 33 +-- 11 files changed, 314 insertions(+), 92 deletions(-) delete mode 100644 src/core/utils_mac.cpp create mode 100644 src/core/utils_mac.mm diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index 7959c5a..ecdae5e 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -311,6 +311,8 @@ using GetWindowDevicePixelRatioCallback = std::function; using SetSystemButtonStateCallback = std::function; +using GetWindowIdCallback = std::function; + struct UserSettings { QPoint startupPosition = {}; @@ -327,8 +329,6 @@ struct UserSettings struct SystemParameters { - WId windowId = 0; - GetWindowFlagsCallback getWindowFlags = nullptr; SetWindowFlagsCallback setWindowFlags = nullptr; @@ -358,15 +358,17 @@ struct SystemParameters SetSystemButtonStateCallback setSystemButtonState = nullptr; + GetWindowIdCallback getWindowId = nullptr; + [[nodiscard]] inline bool isValid() const { - return (windowId && getWindowFlags && setWindowFlags && getWindowSize + return (getWindowFlags && setWindowFlags && getWindowSize && setWindowSize && getWindowPosition && setWindowPosition && getWindowScreen && isWindowFixedSize && setWindowFixedSize && getWindowState && setWindowState && getWindowHandle && windowToScreen && screenToWindow && isInsideSystemButtons && isInsideTitleBarDraggableArea && getWindowDevicePixelRatio - && setSystemButtonState); + && setSystemButtonState && getWindowId); } }; diff --git a/include/FramelessHelper/Core/utils.h b/include/FramelessHelper/Core/utils.h index ffe0d89..00d746b 100644 --- a/include/FramelessHelper/Core/utils.h +++ b/include/FramelessHelper/Core/utils.h @@ -36,8 +36,8 @@ namespace Utils const QPoint &pos); [[nodiscard]] FRAMELESSHELPER_CORE_API Qt::Edges calculateWindowEdges(const QWindow *window, const QPoint &pos); -FRAMELESSHELPER_CORE_API void startSystemMove(QWindow *window); -FRAMELESSHELPER_CORE_API void startSystemResize(QWindow *window, const Qt::Edges edges); +FRAMELESSHELPER_CORE_API void startSystemMove(QWindow *window, const QPoint &globalPos); +FRAMELESSHELPER_CORE_API void startSystemResize(QWindow *window, const Qt::Edges edges, const QPoint &globalPos); [[nodiscard]] FRAMELESSHELPER_CORE_API QVariant getSystemButtonIconResource(const Global::SystemButtonType button, const Global::SystemTheme theme, @@ -113,6 +113,11 @@ FRAMELESSHELPER_CORE_API void tryToEnableHighestDpiAwarenessLevel(); FRAMELESSHELPER_CORE_API void updateGlobalWin32ControlsTheme(const WId windowId, const bool dark); #endif // Q_OS_WINDOWS +#ifdef Q_OS_MACOS +FRAMELESSHELPER_CORE_API void setWindowHook(const WId windowId); +FRAMELESSHELPER_CORE_API void unsetWindowHook(const WId windowId); +FRAMELESSHELPER_CORE_API void removeWindowFrame(const WId windowId); +#endif // Q_OS_MACOS } // namespace Utils FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Widgets/framelesswidgetshelper.h b/include/FramelessHelper/Widgets/framelesswidgetshelper.h index 57d3868..1711ac6 100644 --- a/include/FramelessHelper/Widgets/framelesswidgetshelper.h +++ b/include/FramelessHelper/Widgets/framelesswidgetshelper.h @@ -100,7 +100,7 @@ private Q_SLOTS: void updateSystemMaximizeButton(); private: - QPointer q = nullptr; + QWidget *q = nullptr; bool m_initialized = false; QScopedPointer m_systemTitleBarWidget; QScopedPointer m_systemWindowTitleLabel; @@ -114,7 +114,6 @@ private: QScopedPointer m_userContentContainerWidget; QScopedPointer m_userContentContainerLayout; Qt::WindowState m_savedWindowState = {}; - QPointer m_window = nullptr; Global::UserSettings m_settings = {}; Global::SystemParameters m_params = {}; bool m_windowExposed = false; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 877def2..9522bf2 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -53,7 +53,7 @@ if(WIN32) framelesshelper_win.cpp ) elseif(APPLE) - list(APPEND SOURCES utils_mac.cpp) + list(APPEND SOURCES utils_mac.mm) elseif(UNIX) list(APPEND SOURCES utils_linux.cpp) endif() @@ -121,6 +121,13 @@ if(UNIX AND NOT APPLE) ) endif() +if(APPLE) + target_link_libraries(${SUB_PROJ_NAME} PRIVATE + "-framework Cocoa" + "-framework Carbon" + ) +endif() + target_link_libraries(${SUB_PROJ_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::CorePrivate Qt${QT_VERSION_MAJOR}::GuiPrivate diff --git a/src/core/framelesshelper_qt.cpp b/src/core/framelesshelper_qt.cpp index 7982cb0..6e00756 100644 --- a/src/core/framelesshelper_qt.cpp +++ b/src/core/framelesshelper_qt.cpp @@ -59,8 +59,9 @@ void FramelessHelperQt::addWindow(const UserSettings &settings, const SystemPara if (!params.isValid()) { return; } + const WId windowId = params.getWindowId(); g_qtHelper()->mutex.lock(); - if (g_qtHelper()->data.contains(params.windowId)) { + if (g_qtHelper()->data.contains(windowId)) { g_qtHelper()->mutex.unlock(); return; } @@ -70,10 +71,16 @@ void FramelessHelperQt::addWindow(const UserSettings &settings, const SystemPara QWindow *window = params.getWindowHandle(); // Give it a parent so that it can be deleted even if we forget to do so. data.eventFilter = new FramelessHelperQt(window); - g_qtHelper()->data.insert(params.windowId, data); + g_qtHelper()->data.insert(windowId, data); g_qtHelper()->mutex.unlock(); +#ifndef Q_OS_MACOS params.setWindowFlags(params.getWindowFlags() | Qt::FramelessWindowHint); +#endif window->installEventFilter(data.eventFilter); +#ifdef Q_OS_MACOS + Utils::setWindowHook(windowId); + Utils::removeWindowFrame(windowId); +#endif } bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) @@ -115,8 +122,10 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) const auto mouseEvent = static_cast(event); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) const QPoint scenePos = mouseEvent->scenePosition().toPoint(); + const QPoint globalPos = mouseEvent->globalPosition().toPoint(); #else const QPoint scenePos = mouseEvent->windowPos().toPoint(); + const QPoint globalPos = mouseEvent->globalPos(); #endif switch (type) { case QEvent::MouseMove: { @@ -138,7 +147,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) if (edges == Qt::Edges{}) { return false; } - Utils::startSystemResize(window, edges); + Utils::startSystemResize(window, edges, globalPos); return true; } default: diff --git a/src/core/framelesswindowsmanager.cpp b/src/core/framelesswindowsmanager.cpp index 5c05a67..1cd295f 100644 --- a/src/core/framelesswindowsmanager.cpp +++ b/src/core/framelesswindowsmanager.cpp @@ -50,6 +50,9 @@ Q_GLOBAL_STATIC(FramelessWindowsManagerHelper, g_helper) Q_GLOBAL_STATIC(FramelessWindowsManager, g_manager) +static constexpr const char MAC_LAYER_ENV_VAR[] = "QT_MAC_WANTS_LAYER"; +FRAMELESSHELPER_BYTEARRAY_CONSTANT2(OptionEnabled, "1") + FramelessWindowsManagerPrivate::FramelessWindowsManagerPrivate(FramelessWindowsManager *q) : QObject(q) { Q_ASSERT(q); @@ -80,7 +83,7 @@ const FramelessWindowsManagerPrivate *FramelessWindowsManagerPrivate::get(const return pub->d_func(); } -bool FramelessWindowsManagerPrivate::usePureQtImplementation() const +bool FramelessWindowsManagerPrivate::usePureQtImplementation() { #ifdef Q_OS_WINDOWS static const bool result = []() -> bool { @@ -108,12 +111,13 @@ void FramelessWindowsManagerPrivate::addWindow(const UserSettings &settings, con if (!params.isValid()) { return; } + const WId windowId = params.getWindowId(); g_helper()->mutex.lock(); - if (g_helper()->windowIds.contains(params.windowId)) { + if (g_helper()->windowIds.contains(windowId)) { g_helper()->mutex.unlock(); return; } - g_helper()->windowIds.append(params.windowId); + g_helper()->windowIds.append(windowId); g_helper()->mutex.unlock(); static const bool pureQt = usePureQtImplementation(); #ifdef Q_OS_WINDOWS @@ -121,11 +125,11 @@ void FramelessWindowsManagerPrivate::addWindow(const UserSettings &settings, con // Work-around Win32 multi-monitor artifacts. QWindow * const window = params.getWindowHandle(); Q_ASSERT(window); - connect(window, &QWindow::screenChanged, window, [¶ms, window](QScreen *screen){ + connect(window, &QWindow::screenChanged, window, [windowId, window](QScreen *screen){ Q_UNUSED(screen); // Force a WM_NCCALCSIZE event to inform Windows about our custom window frame, // this is only necessary when the window is being moved cross monitors. - Utils::triggerFrameChange(params.windowId); + Utils::triggerFrameChange(windowId); // For some reason the window is not repainted correctly when moving cross monitors, // we workaround this issue by force a re-paint and re-layout of the window by triggering // a resize event manually. Although the actual size does not change, the issue we @@ -142,8 +146,12 @@ void FramelessWindowsManagerPrivate::addWindow(const UserSettings &settings, con FramelessHelperWin::addWindow(settings, params); } if (!(settings.options & Option::DontInstallSystemMenuHook)) { - Utils::installSystemMenuHook(params.windowId, settings.options, - settings.systemMenuOffset, params.isWindowFixedSize); + Utils::installSystemMenuHook(windowId, settings.options, settings.systemMenuOffset, params.isWindowFixedSize); + } +#endif +#ifdef Q_OS_MACOS + if (qEnvironmentVariableIntValue(MAC_LAYER_ENV_VAR) != 1) { + qputenv(MAC_LAYER_ENV_VAR, kOptionEnabled); } #endif } diff --git a/src/core/framelesswindowsmanager_p.h b/src/core/framelesswindowsmanager_p.h index f79fa21..e003612 100644 --- a/src/core/framelesswindowsmanager_p.h +++ b/src/core/framelesswindowsmanager_p.h @@ -44,11 +44,11 @@ public: Q_NODISCARD static FramelessWindowsManagerPrivate *get(FramelessWindowsManager *pub); Q_NODISCARD static const FramelessWindowsManagerPrivate *get(const FramelessWindowsManager *pub); - Q_NODISCARD bool usePureQtImplementation() const; + Q_NODISCARD static bool usePureQtImplementation(); Q_NODISCARD Global::SystemTheme systemTheme() const; public Q_SLOTS: - void addWindow(const Global::UserSettings &settings, const Global::SystemParameters ¶ms); + static void addWindow(const Global::UserSettings &settings, const Global::SystemParameters ¶ms); void notifySystemThemeHasChangedOrNot(); private: diff --git a/src/core/utils_mac.cpp b/src/core/utils_mac.cpp deleted file mode 100644 index 2908579..0000000 --- a/src/core/utils_mac.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * MIT License - * - * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "utils.h" - -FRAMELESSHELPER_BEGIN_NAMESPACE - - - -FRAMELESSHELPER_END_NAMESPACE diff --git a/src/core/utils_mac.mm b/src/core/utils_mac.mm new file mode 100644 index 0000000..3d6851d --- /dev/null +++ b/src/core/utils_mac.mm @@ -0,0 +1,250 @@ +/* + * MIT License + * + * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "utils.h" +#include +#include +#include +#include +#include + +FRAMELESSHELPER_BEGIN_NAMESPACE + +using namespace Global; + +[[nodiscard]] bool shouldAppsUseDarkMode_macos() +{ +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) + if (__builtin_available(macOS 10.14, *)) { + const auto appearance = [NSApp.effectiveAppearance bestMatchFromAppearancesWithNames: + @[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; + return [appearance isEqualToString:NSAppearanceNameDarkAqua]; + } +#endif + return false; +} + +class NSWindowProxy +{ + Q_DISABLE_COPY_MOVE(NSWindowProxy) + +public: + explicit NSWindowProxy(NSWindow *window) + { + Q_ASSERT(window); + if (!window) { + return; + } + nswindow = window; + saveState(); + } + + ~NSWindowProxy() + { + restoreState(); + nswindow = nullptr; + } + + void saveState() + { + oldStyleMask = nswindow.styleMask; + oldTitlebarAppearsTransparent = nswindow.titlebarAppearsTransparent; + oldTitleVisibility = nswindow.titleVisibility; + oldHasShadow = nswindow.hasShadow; + oldShowsToolbarButton = nswindow.showsToolbarButton; + oldMovableByWindowBackground = nswindow.movableByWindowBackground; + oldMovable = nswindow.movable; + oldCloseButtonVisible = ![nswindow standardWindowButton:NSWindowCloseButton].hidden; + oldMiniaturizeButtonVisible = ![nswindow standardWindowButton:NSWindowMiniaturizeButton].hidden; + oldZoomButtonVisible = ![nswindow standardWindowButton:NSWindowZoomButton].hidden; + } + + void restoreState() + { + nswindow.styleMask = oldStyleMask; + nswindow.titlebarAppearsTransparent = oldTitlebarAppearsTransparent; + nswindow.titleVisibility = oldTitleVisibility; + nswindow.hasShadow = oldHasShadow; + nswindow.showsToolbarButton = oldShowsToolbarButton; + nswindow.movableByWindowBackground = oldMovableByWindowBackground; + nswindow.movable = oldMovable; + [nswindow standardWindowButton:NSWindowCloseButton].hidden = !oldCloseButtonVisible; + [nswindow standardWindowButton:NSWindowMiniaturizeButton].hidden = !oldMiniaturizeButtonVisible; + [nswindow standardWindowButton:NSWindowZoomButton].hidden = !oldZoomButtonVisible; + } + + void removeWindowFrame() + { + NSView *nsview = [nswindow contentView]; + Q_ASSERT(nsview); + if (!nsview) { + return; + } + nsview.wantsLayer = YES; + nswindow.styleMask |= NSWindowStyleMaskFullSizeContentView; + nswindow.titlebarAppearsTransparent = true; + nswindow.titleVisibility = NSWindowTitleHidden; + nswindow.hasShadow = true; + nswindow.showsToolbarButton = false; + nswindow.movableByWindowBackground = false; + nswindow.movable = false; + [nswindow standardWindowButton:NSWindowCloseButton].hidden = true; + [nswindow standardWindowButton:NSWindowMiniaturizeButton].hidden = true; + [nswindow standardWindowButton:NSWindowZoomButton].hidden = true; + } + +private: + NSWindow *nswindow; + + NSWindowStyleMask oldStyleMask; + BOOL oldTitlebarAppearsTransparent; + BOOL oldHasShadow; + BOOL oldShowsToolbarButton; + BOOL oldMovableByWindowBackground; + BOOL oldMovable; + BOOL oldCloseButtonVisible; + BOOL oldMiniaturizeButtonVisible; + BOOL oldZoomButtonVisible; + NSWindowTitleVisibility oldTitleVisibility; +}; + +using NSWindowProxyHash = QHash; +Q_GLOBAL_STATIC(NSWindowProxyHash, g_nswindowOverrideHash); + +[[nodiscard]] static inline NSWindow *mac_getNSWindow(const WId windowId) +{ + Q_ASSERT(windowId); + if (!windowId) { + return nullptr; + } + const auto nsview = reinterpret_cast(windowId); + Q_ASSERT(nsview); + if (!nsview) { + return nullptr; + } + return [nsview window]; +} + +static inline void mac_windowStartNativeDrag(const WId windowId, const QPoint &globalPos) +{ + Q_ASSERT(windowId); + if (!windowId) { + return; + } + const NSWindow * const nswindow = mac_getNSWindow(windowId); + if (!nswindow) { + return; + } + const CGEventRef clickDown = CGEventCreateMouseEvent( + NULL, kCGEventLeftMouseDown, CGPointMake(globalPos.x(), globalPos.y()), kCGMouseButtonLeft); + NSEvent * const nsevent = [NSEvent eventWithCGEvent:clickDown]; + Q_ASSERT(nsevent); + if (!nsevent) { + CFRelease(clickDown); + return; + } + [nswindow performWindowDragWithEvent:nsevent]; + CFRelease(clickDown); +} + +SystemTheme Utils::getSystemTheme() +{ + // ### TODO: how to detect high contrast mode on macOS? + return (shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light); +} + +void Utils::setWindowHook(const WId windowId) +{ + Q_ASSERT(windowId); + if (!windowId) { + return; + } + if (g_nswindowOverrideHash()->contains(windowId)) { + return; + } + NSWindow * const nswindow = mac_getNSWindow(windowId); + if (!nswindow) { + return; + } + const auto proxy = new NSWindowProxy(nswindow); + g_nswindowOverrideHash()->insert(windowId, proxy); +} + +void Utils::unsetWindowHook(const WId windowId) +{ + Q_ASSERT(windowId); + if (!windowId) { + return; + } + if (!g_nswindowOverrideHash()->contains(windowId)) { + return; + } + const NSWindowProxy * const proxy = g_nswindowOverrideHash()->value(windowId); + g_nswindowOverrideHash()->remove(windowId); + Q_ASSERT(proxy); + if (!proxy) { + return; + } + delete proxy; +} + +void Utils::removeWindowFrame(const WId windowId) +{ + Q_ASSERT(windowId); + if (!windowId) { + return; + } + if (!g_nswindowOverrideHash()->contains(windowId)) { + return; + } + NSWindowProxy * const proxy = g_nswindowOverrideHash()->value(windowId); + Q_ASSERT(proxy); + if (!proxy) { + return; + } + proxy->removeWindowFrame(); +} + +void Utils::startSystemMove(QWindow *window, const QPoint &globalPos) +{ + Q_ASSERT(window); + if (!window) { + return; + } + mac_windowStartNativeDrag(window->winId(), globalPos); +} + +void Utils::startSystemResize(QWindow *window, const Qt::Edges edges, const QPoint &globalPos) +{ + Q_ASSERT(window); + if (!window) { + return; + } + if (edges == Qt::Edges{}) { + return; + } + mac_windowStartNativeDrag(window->winId(), globalPos); +} + +FRAMELESSHELPER_END_NAMESPACE diff --git a/src/quick/framelessquickwindow.cpp b/src/quick/framelessquickwindow.cpp index a629143..3de9337 100644 --- a/src/quick/framelessquickwindow.cpp +++ b/src/quick/framelessquickwindow.cpp @@ -24,6 +24,7 @@ #include "framelessquickwindow.h" #include "framelessquickwindow_p.h" +#include #include #include #include @@ -373,11 +374,7 @@ void FramelessQuickWindowPrivate::showSystemMenu(const QPoint &pos) void FramelessQuickWindowPrivate::startSystemMove2() { Q_Q(FramelessQuickWindow); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - q->startSystemMove(); -#else - Utils::startSystemMove(q); -#endif + Utils::startSystemMove(q, QCursor::pos(q->screen())); } void FramelessQuickWindowPrivate::startSystemResize2(const Qt::Edges edges) @@ -389,11 +386,7 @@ void FramelessQuickWindowPrivate::startSystemResize2(const Qt::Edges edges) return; } Q_Q(FramelessQuickWindow); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - q->startSystemResize(edges); -#else - Utils::startSystemResize(q, edges); -#endif + Utils::startSystemResize(q, edges, QCursor::pos(q->screen())); } void FramelessQuickWindowPrivate::initialize() @@ -403,12 +396,7 @@ void FramelessQuickWindowPrivate::initialize() } m_initialized = true; Q_Q(FramelessQuickWindow); - const WId windowId = q->winId(); - Q_ASSERT(windowId); - if (!windowId) { - return; - } - m_params.windowId = windowId; + m_params.getWindowId = [q]() -> WId { return q->winId(); }; m_params.getWindowFlags = [q]() -> Qt::WindowFlags { return q->flags(); }; m_params.setWindowFlags = [q](const Qt::WindowFlags flags) -> void { q->setFlags(flags); }; m_params.getWindowSize = [q]() -> QSize { return q->size(); }; diff --git a/src/widgets/framelesswidgetshelper.cpp b/src/widgets/framelesswidgetshelper.cpp index ac59244..db286c1 100644 --- a/src/widgets/framelesswidgetshelper.cpp +++ b/src/widgets/framelesswidgetshelper.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -356,17 +357,7 @@ void FramelessWidgetsHelper::initialize() // Force the widget become a native window now so that we can deal with its // win32 events as soon as possible. q->setAttribute(Qt::WA_NativeWindow); - const WId windowId = q->winId(); - Q_ASSERT(windowId); - if (!windowId) { - return; - } - m_window = q->windowHandle(); - Q_ASSERT(m_window); - if (!m_window) { - return; - } - m_params.windowId = windowId; + m_params.getWindowId = [this]() -> WId { return q->winId(); }; m_params.getWindowFlags = [this]() -> Qt::WindowFlags { return q->windowFlags(); }; m_params.setWindowFlags = [this](const Qt::WindowFlags flags) -> void { q->setWindowFlags(flags); }; m_params.getWindowSize = [this]() -> QSize { return q->size(); }; @@ -377,14 +368,14 @@ void FramelessWidgetsHelper::initialize() #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) return q->screen(); #else - return m_window->screen(); + return q->windowHandle()->screen(); #endif }; m_params.isWindowFixedSize = [this]() -> bool { return isFixedSize(); }; m_params.setWindowFixedSize = [this](const bool value) -> void { setFixedSize(value); }; m_params.getWindowState = [this]() -> Qt::WindowState { return Utils::windowStatesToWindowState(q->windowState()); }; m_params.setWindowState = [this](const Qt::WindowState state) -> void { q->setWindowState(state); }; - m_params.getWindowHandle = [this]() -> QWindow * { return m_window; }; + m_params.getWindowHandle = [this]() -> QWindow * { return q->windowHandle(); }; m_params.windowToScreen = [this](const QPoint &pos) -> QPoint { return q->mapToGlobal(pos); }; m_params.screenToWindow = [this](const QPoint &pos) -> QPoint { return q->mapFromGlobal(pos); }; m_params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool { return isInSystemButtons(pos, button); }; @@ -474,7 +465,7 @@ void FramelessWidgetsHelper::initialize() } QMetaObject::invokeMethod(q, "systemThemeChanged"); }); - connect(m_window, &QWindow::visibilityChanged, this, [this](){ + connect(q->windowHandle(), &QWindow::visibilityChanged, this, [this](){ QMetaObject::invokeMethod(q, "hiddenChanged"); QMetaObject::invokeMethod(q, "normalChanged"); QMetaObject::invokeMethod(q, "zoomedChanged"); @@ -787,20 +778,14 @@ void FramelessWidgetsHelper::showSystemMenu(const QPoint &pos) void FramelessWidgetsHelper::startSystemMove2() { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - m_window->startSystemMove(); -#else - Utils::startSystemMove(m_window); -#endif + QWindow * const window = q->windowHandle(); + Utils::startSystemMove(window, QCursor::pos(window->screen())); } void FramelessWidgetsHelper::startSystemResize2(const Qt::Edges edges) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - m_window->startSystemResize(edges); -#else - Utils::startSystemResize(m_window, edges); -#endif + QWindow * const window = q->windowHandle(); + Utils::startSystemResize(window, edges, QCursor::pos(window->screen())); } bool FramelessWidgetsHelper::eventFilter(QObject *object, QEvent *event)