diff --git a/framelesswindowsmanager.cpp b/framelesswindowsmanager.cpp index 76fbf90..80ef70a 100644 --- a/framelesswindowsmanager.cpp +++ b/framelesswindowsmanager.cpp @@ -44,10 +44,6 @@ namespace { -#ifndef Q_OS_WINDOWS -FramelessHelper framelessHelper; -#endif - void reportError() { qFatal("Only top level QWidgets and QWindows are accepted."); @@ -89,8 +85,19 @@ void *getRawHandleFromWindow(QObject *window) } #endif +#ifndef Q_OS_WINDOWS +using FLWM_CORE_DATA = struct _FLWM_CORE_DATA +{ + FramelessHelper framelessHelper; +}; +#endif + } // namespace +#ifndef Q_OS_WINDOWS +Q_GLOBAL_STATIC(FLWM_CORE_DATA, coreData) +#endif + FramelessWindowsManager::FramelessWindowsManager() {} void FramelessWindowsManager::addWindow(QObject *window, const bool center) @@ -99,7 +106,7 @@ void FramelessWindowsManager::addWindow(QObject *window, const bool center) #ifdef Q_OS_WINDOWS WinNativeEventFilter::addFramelessWindow(window); #else - framelessHelper.removeWindowFrame(window); + coreData()->framelessHelper.removeWindowFrame(window); #endif if (center) { moveWindowToDesktopCenter(window); @@ -194,7 +201,7 @@ void FramelessWindowsManager::addIgnoreArea(QObject *window, const QRect &area) data->ignoreAreas.append(area); } #else - framelessHelper.addIgnoreArea(window, area); + coreData()->framelessHelper.addIgnoreArea(window, area); #endif } @@ -207,7 +214,7 @@ void FramelessWindowsManager::addDraggableArea(QObject *window, const QRect &are data->draggableAreas.append(area); } #else - framelessHelper.addDraggableArea(window, area); + coreData()->framelessHelper.addDraggableArea(window, area); #endif } @@ -220,7 +227,7 @@ void FramelessWindowsManager::addIgnoreObject(QObject *window, QObject *object) data->ignoreObjects.append(object); } #else - framelessHelper.addIgnoreObject(window, object); + coreData()->framelessHelper.addIgnoreObject(window, object); #endif } @@ -233,7 +240,7 @@ void FramelessWindowsManager::addDraggableObject(QObject *window, QObject *objec data->draggableObjects.append(object); } #else - framelessHelper.addDraggableObject(window, object); + coreData()->framelessHelper.addDraggableObject(window, object); #endif } @@ -245,7 +252,7 @@ int FramelessWindowsManager::getBorderWidth(QObject *window) WinNativeEventFilter::SystemMetric::BorderWidth); #else Q_UNUSED(window) - return framelessHelper.getBorderWidth(); + return coreData()->framelessHelper.getBorderWidth(); #endif } @@ -259,7 +266,7 @@ void FramelessWindowsManager::setBorderWidth(QObject *window, const int value) } #else Q_UNUSED(window) - framelessHelper.setBorderWidth(value); + coreData()->framelessHelper.setBorderWidth(value); #endif } @@ -271,7 +278,7 @@ int FramelessWindowsManager::getBorderHeight(QObject *window) WinNativeEventFilter::SystemMetric::BorderHeight); #else Q_UNUSED(window) - return framelessHelper.getBorderHeight(); + return coreData()->framelessHelper.getBorderHeight(); #endif } @@ -285,7 +292,7 @@ void FramelessWindowsManager::setBorderHeight(QObject *window, const int value) } #else Q_UNUSED(window) - framelessHelper.setBorderHeight(value); + coreData()->framelessHelper.setBorderHeight(value); #endif } @@ -297,7 +304,7 @@ int FramelessWindowsManager::getTitleBarHeight(QObject *window) WinNativeEventFilter::SystemMetric::TitleBarHeight); #else Q_UNUSED(window) - return framelessHelper.getTitleBarHeight(); + return coreData()->framelessHelper.getTitleBarHeight(); #endif } @@ -311,7 +318,7 @@ void FramelessWindowsManager::setTitleBarHeight(QObject *window, const int value } #else Q_UNUSED(window) - framelessHelper.setTitleBarHeight(value); + coreData()->framelessHelper.setTitleBarHeight(value); #endif } @@ -322,7 +329,7 @@ bool FramelessWindowsManager::getResizable(QObject *window) const auto data = WinNativeEventFilter::windowData(window); return data ? !data->fixedSize : false; #else - return framelessHelper.getResizable(window); + return coreData()->framelessHelper.getResizable(window); #endif } @@ -335,7 +342,7 @@ void FramelessWindowsManager::setResizable(QObject *window, const bool value) data->fixedSize = !value; } #else - framelessHelper.setResizable(window, value); + coreData()->framelessHelper.setResizable(window, value); #endif } @@ -436,7 +443,7 @@ bool FramelessWindowsManager::getTitleBarEnabled(QObject *window) const auto data = WinNativeEventFilter::windowData(window); return data ? !data->disableTitleBar : false; #else - return framelessHelper.getTitleBarEnabled(window); + return coreData()->framelessHelper.getTitleBarEnabled(window); #endif } @@ -449,6 +456,6 @@ void FramelessWindowsManager::setTitleBarEnabled(QObject *window, const bool val data->disableTitleBar = !value; } #else - framelessHelper.setTitleBarEnabled(window, value); + coreData()->framelessHelper.setTitleBarEnabled(window, value); #endif } diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp index e161ce3..8d3dd88 100644 --- a/winnativeeventfilter.cpp +++ b/winnativeeventfilter.cpp @@ -1037,40 +1037,6 @@ HWND getHWNDFromQObject(QObject *object) return reinterpret_cast(wid); } -// The standard values of border width, border height and title bar height -// when DPI is 96. -const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBarHeight = 30; - -int m_borderWidth = -1, m_borderHeight = -1, m_titleBarHeight = -1; - -// The thickness of an auto-hide taskbar in pixels. -const int kAutoHideTaskbarThicknessPx = 2; -const int kAutoHideTaskbarThicknessPy = kAutoHideTaskbarThicknessPx; - -QScopedPointer m_instance; - -QList m_framelessWindows = {}; - -void install() -{ - qCoreAppFixup(); - if (m_instance.isNull()) { - m_instance.reset(new WinNativeEventFilter); - qApp->installNativeEventFilter(m_instance.data()); - } -} - -void uninstall() -{ - if (!m_instance.isNull()) { - qApp->removeNativeEventFilter(m_instance.data()); - m_instance.reset(); - } - if (!m_framelessWindows.isEmpty()) { - m_framelessWindows.clear(); - } -} - void updateQtFrame_internal(const HWND handle) { Q_ASSERT(handle); @@ -1138,13 +1104,54 @@ QString getCurrentScreenSerialNumber(const HWND handle) currentScreen = window->screen(); } } - return currentScreen ? currentScreen->serialNumber().toUpper() : QString(); + if (currentScreen) { + const QString sn = currentScreen->serialNumber().toUpper(); + return sn.isEmpty() ? currentScreen->name().toUpper() : sn; + } } return {}; } +// The standard values of border width, border height and title bar height +// when DPI is 96. +const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBarHeight = 30; + +// The thickness of an auto-hide taskbar in pixels. +const int kAutoHideTaskbarThicknessPx = 2; +const int kAutoHideTaskbarThicknessPy = kAutoHideTaskbarThicknessPx; + +// Internal data structure. +using WNEF_CORE_DATA = struct _WNEF_CORE_DATA +{ + int m_borderWidth = -1, m_borderHeight = -1, m_titleBarHeight = -1; + QScopedPointer m_instance; + QList m_framelessWindows = {}; +}; + } // namespace +Q_GLOBAL_STATIC(WNEF_CORE_DATA, coreData) + +static void install() +{ + qCoreAppFixup(); + if (coreData()->m_instance.isNull()) { + coreData()->m_instance.reset(new WinNativeEventFilter); + qApp->installNativeEventFilter(coreData()->m_instance.data()); + } +} + +static void uninstall() +{ + if (!coreData()->m_instance.isNull()) { + qApp->removeNativeEventFilter(coreData()->m_instance.data()); + coreData()->m_instance.reset(); + } + if (!coreData()->m_framelessWindows.isEmpty()) { + coreData()->m_framelessWindows.clear(); + } +} + WinNativeEventFilter::WinNativeEventFilter() { ResolveWin32APIs(); @@ -1165,8 +1172,9 @@ void WinNativeEventFilter::addFramelessWindow(void *window, ResolveWin32APIs(); qCoreAppFixup(); const auto hwnd = reinterpret_cast(window); - if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd) && !m_framelessWindows.contains(hwnd)) { - m_framelessWindows.append(hwnd); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd) + && !coreData()->m_framelessWindows.contains(hwnd)) { + coreData()->m_framelessWindows.append(hwnd); createUserData(hwnd, data); install(); updateQtFrame_internal(hwnd); @@ -1195,8 +1203,8 @@ void WinNativeEventFilter::removeFramelessWindow(void *window) { Q_ASSERT(window); const auto hwnd = reinterpret_cast(window); - if (m_framelessWindows.contains(hwnd)) { - m_framelessWindows.removeAll(hwnd); + if (coreData()->m_framelessWindows.contains(hwnd)) { + coreData()->m_framelessWindows.removeAll(hwnd); } } @@ -1208,8 +1216,8 @@ void WinNativeEventFilter::removeFramelessWindow(QObject *window) void WinNativeEventFilter::clearFramelessWindows() { - if (!m_framelessWindows.isEmpty()) { - m_framelessWindows.clear(); + if (!coreData()->m_framelessWindows.isEmpty()) { + coreData()->m_framelessWindows.clear(); } } @@ -1246,12 +1254,12 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, // Anyway, we should skip it in this case. return false; } - if (m_framelessWindows.isEmpty()) { + if (coreData()->m_framelessWindows.isEmpty()) { // Only top level windows can be frameless. if (!IsTopLevel(msg->hwnd)) { return false; } - } else if (!m_framelessWindows.contains(msg->hwnd)) { + } else if (!coreData()->m_framelessWindows.contains(msg->hwnd)) { return false; } const auto data = reinterpret_cast( @@ -1287,6 +1295,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, data->initialized = true; // Record the current screen. data->currentScreen = getCurrentScreenSerialNumber(msg->hwnd); + Q_ASSERT(!data->currentScreen.isEmpty()); // Don't restore the window styles to default when you are // developing Qt Quick applications because the QWindow // will disappear once you do it. However, Qt Widgets applications @@ -2045,17 +2054,17 @@ WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::windowData(QObject *wind void WinNativeEventFilter::setBorderWidth(const int bw) { - m_borderWidth = bw; + coreData()->m_borderWidth = bw; } void WinNativeEventFilter::setBorderHeight(const int bh) { - m_borderHeight = bh; + coreData()->m_borderHeight = bh; } void WinNativeEventFilter::setTitleBarHeight(const int tbh) { - m_titleBarHeight = tbh; + coreData()->m_titleBarHeight = tbh; } void WinNativeEventFilter::updateWindow(void *handle, @@ -2145,20 +2154,20 @@ int WinNativeEventFilter::getSystemMetric(void *handle, } switch (metric) { case SystemMetric::BorderWidth: - if (m_borderWidth > 0) { - return qRound(m_borderWidth * dpr); + if (coreData()->m_borderWidth > 0) { + return qRound(coreData()->m_borderWidth * dpr); } else { return qRound(m_defaultBorderWidth * dpr); } case SystemMetric::BorderHeight: - if (m_borderHeight > 0) { - return qRound(m_borderHeight * dpr); + if (coreData()->m_borderHeight > 0) { + return qRound(coreData()->m_borderHeight * dpr); } else { return qRound(m_defaultBorderHeight * dpr); } case SystemMetric::TitleBarHeight: - if (m_titleBarHeight > 0) { - return qRound(m_titleBarHeight * dpr); + if (coreData()->m_titleBarHeight > 0) { + return qRound(coreData()->m_titleBarHeight * dpr); } else { return qRound(m_defaultTitleBarHeight * dpr); }