diff --git a/core/framelesshelper_win.cpp b/core/framelesshelper_win.cpp index 02e21b4..0214133 100644 --- a/core/framelesshelper_win.cpp +++ b/core/framelesshelper_win.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include "framelesswindowsmanager.h" @@ -41,7 +40,6 @@ struct Win32Helper QScopedPointer nativeEventFilter; QWindowList framelessWindows = {}; QHash windowMapping = {}; - QHash qtWindowProcs = {}; explicit Win32Helper() = default; ~Win32Helper() = default; @@ -52,127 +50,6 @@ private: Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) -[[nodiscard]] static inline LRESULT CALLBACK HookWindowProc - (const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam) -{ - g_win32Helper()->mutex.lock(); - if (!g_win32Helper()->qtWindowProcs.contains(hWnd)) { - g_win32Helper()->mutex.unlock(); - return DefWindowProcW(hWnd, uMsg, wParam, lParam); - } - g_win32Helper()->mutex.unlock(); - const auto winId = reinterpret_cast(hWnd); - const auto getGlobalPosFromMouse = [lParam]() -> QPointF { - return {qreal(GET_X_LPARAM(lParam)), qreal(GET_Y_LPARAM(lParam))}; - }; - const auto getGlobalPosFromKeyboard = [hWnd, winId]() -> QPointF { - RECT windowPos = {}; - if (GetWindowRect(hWnd, &windowPos) == FALSE) { - qWarning() << Utils::getSystemErrorMessage(QStringLiteral("GetWindowRect")); - return {}; - } - const bool maxOrFull = (IsMaximized(hWnd) || Utils::isFullScreen(winId)); - const int frameSizeX = Utils::getResizeBorderThickness(winId, true, true); - const int frameSizeY = Utils::getResizeBorderThickness(winId, false, true); - const int titleBarHeight = Utils::getTitleBarHeight(winId, true); - const int horizontalOffset = ((maxOrFull || !Utils::isWindowFrameBorderVisible()) ? 0 : frameSizeX); - const int verticalOffset = (maxOrFull ? titleBarHeight : (titleBarHeight - frameSizeY)); - return {qreal(windowPos.left + horizontalOffset), qreal(windowPos.top + verticalOffset)}; - }; - bool shouldShowSystemMenu = false; - QPointF globalPos = {}; - if (uMsg == WM_NCRBUTTONUP) { - if (wParam == HTCAPTION) { - shouldShowSystemMenu = true; - globalPos = getGlobalPosFromMouse(); - } - } else if (uMsg == WM_SYSCOMMAND) { - const WPARAM filteredWParam = (wParam & 0xFFF0); - if ((filteredWParam == SC_KEYMENU) && (lParam == VK_SPACE)) { - shouldShowSystemMenu = true; - globalPos = getGlobalPosFromKeyboard(); - } - } else if ((uMsg == WM_KEYDOWN) || (uMsg == WM_SYSKEYDOWN)) { - const bool altPressed = ((wParam == VK_MENU) || (GetKeyState(VK_MENU) < 0)); - const bool spacePressed = ((wParam == VK_SPACE) || (GetKeyState(VK_SPACE) < 0)); - if (altPressed && spacePressed) { - shouldShowSystemMenu = true; - globalPos = getGlobalPosFromKeyboard(); - } - } - if (shouldShowSystemMenu) { - Utils::showSystemMenu(winId, globalPos); - // QPA's internal code will handle system menu events separately, and its - // behavior is not what we would want to see because it doesn't know our - // window doesn't have any window frame now, so return early here to avoid - // entering Qt's own handling logic. - return 0; // Return 0 means we have handled this event. - } - g_win32Helper()->mutex.lock(); - const WNDPROC originalWindowProc = g_win32Helper()->qtWindowProcs.value(hWnd); - g_win32Helper()->mutex.unlock(); - Q_ASSERT(originalWindowProc); - if (originalWindowProc) { - // Hand over to Qt's original window proc function for events we are not - // interested in. - return CallWindowProcW(originalWindowProc, hWnd, uMsg, wParam, lParam); - } else { - return DefWindowProcW(hWnd, uMsg, wParam, lParam); - } -} - -[[nodiscard]] static inline bool installWindowHook(const WId winId) -{ - Q_ASSERT(winId); - if (!winId) { - return false; - } - const auto hwnd = reinterpret_cast(winId); - QMutexLocker locker(&g_win32Helper()->mutex); - if (g_win32Helper()->qtWindowProcs.contains(hwnd)) { - return false; - } - SetLastError(ERROR_SUCCESS); - const auto originalWindowProc = reinterpret_cast(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)); - Q_ASSERT(originalWindowProc); - if (!originalWindowProc) { - qWarning() << Utils::getSystemErrorMessage(QStringLiteral("GetWindowLongPtrW")); - return false; - } - SetLastError(ERROR_SUCCESS); - if (SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast(HookWindowProc)) == 0) { - qWarning() << Utils::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW")); - return false; - } - g_win32Helper()->qtWindowProcs.insert(hwnd, originalWindowProc); - return true; -} - -[[nodiscard]] static inline bool uninstallWindowHook(const WId winId) -{ - Q_ASSERT(winId); - if (!winId) { - return false; - } - const auto hwnd = reinterpret_cast(winId); - QMutexLocker locker(&g_win32Helper()->mutex); - if (!g_win32Helper()->qtWindowProcs.contains(hwnd)) { - return false; - } - const WNDPROC originalWindowProc = g_win32Helper()->qtWindowProcs.value(hwnd); - Q_ASSERT(originalWindowProc); - if (!originalWindowProc) { - return false; - } - SetLastError(ERROR_SUCCESS); - if (SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast(originalWindowProc)) == 0) { - qWarning() << Utils::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW")); - return false; - } - g_win32Helper()->qtWindowProcs.remove(hwnd); - return true; -} - FramelessHelperWin::FramelessHelperWin() : QAbstractNativeEventFilter() {} FramelessHelperWin::~FramelessHelperWin() @@ -204,9 +81,6 @@ void FramelessHelperWin::addWindow(QWindow *window) Utils::updateWindowFrameMargins(winId, false); const bool dark = Utils::shouldAppsUseDarkMode(); Utils::updateWindowFrameBorderColor(winId, dark); - if (!installWindowHook(winId)) { - qWarning() << "Failed to hook the window proc function."; - } } void FramelessHelperWin::removeWindow(QWindow *window) @@ -224,9 +98,6 @@ void FramelessHelperWin::removeWindow(QWindow *window) const WId winId = window->winId(); g_win32Helper()->windowMapping.remove(winId); g_win32Helper()->mutex.unlock(); - if (!uninstallWindowHook(winId)) { - qWarning() << "Failed to un-hook the window proc function."; - } Utils::updateInternalWindowFrameMargins(window, false); Utils::updateWindowFrameMargins(winId, true); } diff --git a/core/framelesswindowsmanager.cpp b/core/framelesswindowsmanager.cpp index 04402ef..6f15c27 100644 --- a/core/framelesswindowsmanager.cpp +++ b/core/framelesswindowsmanager.cpp @@ -34,12 +34,6 @@ FRAMELESSHELPER_BEGIN_NAMESPACE -#ifdef Q_OS_WINDOWS -static const bool g_usePureQtImplementation = (qEnvironmentVariableIntValue("FRAMELESSHELPER_PURE_QT_IMPL") != 0); -#else -static constexpr const bool g_usePureQtImplementation = true; -#endif - Q_GLOBAL_STATIC(FramelessWindowsManager, g_manager) FramelessWindowsManagerPrivate::FramelessWindowsManagerPrivate(FramelessWindowsManager *q) @@ -52,6 +46,25 @@ FramelessWindowsManagerPrivate::FramelessWindowsManagerPrivate(FramelessWindowsM FramelessWindowsManagerPrivate::~FramelessWindowsManagerPrivate() = default; +FramelessWindowsManagerPrivate *FramelessWindowsManagerPrivate::get(FramelessWindowsManager *manager) +{ + Q_ASSERT(manager); + if (!manager) { + return nullptr; + } + return manager->d_func(); +} + +bool FramelessWindowsManagerPrivate::usePureQtImplementation() const +{ +#ifdef Q_OS_WINDOWS + static const bool result = (qEnvironmentVariableIntValue("FRAMELESSHELPER_PURE_QT_IMPL") != 0); +#else + static constexpr const bool result = true; +#endif + return result; +} + QUuid FramelessWindowsManagerPrivate::findIdByWindow(QWindow *value) const { Q_ASSERT(value); @@ -140,16 +153,18 @@ void FramelessWindowsManager::addWindow(QWindow *window) } const QUuid uuid = QUuid::createUuid(); d->windowMapping.insert(window, uuid); - d->winIdMapping.insert(window->winId(), uuid); + const WId winId = window->winId(); + d->winIdMapping.insert(winId, uuid); + static const bool pureQt = d->usePureQtImplementation(); #ifdef Q_OS_WINDOWS - if (!g_usePureQtImplementation) { + if (!pureQt) { // Work-around Win32 multi-monitor artifacts. const QMetaObject::Connection workaroundConnection = - connect(window, &QWindow::screenChanged, window, [window](QScreen *screen){ + connect(window, &QWindow::screenChanged, window, [winId, 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(window->winId()); + Utils::triggerFrameChange(winId); // 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 @@ -160,13 +175,14 @@ void FramelessWindowsManager::addWindow(QWindow *window) } #endif d->mutex.unlock(); - if (g_usePureQtImplementation) { + if (pureQt) { FramelessHelperQt::addWindow(window); } #ifdef Q_OS_WINDOWS - if (!g_usePureQtImplementation) { + if (!pureQt) { FramelessHelperWin::addWindow(window); } + Utils::installSystemMenuHook(winId); #endif } @@ -186,20 +202,25 @@ void FramelessWindowsManager::removeWindow(QWindow *window) if (uuid.isNull()) { return; } - if (g_usePureQtImplementation) { - FramelessHelperQt::removeWindow(window); - } + const WId winId = window->winId(); #ifdef Q_OS_WINDOWS - if (!g_usePureQtImplementation) { - FramelessHelperWin::removeWindow(window); - } if (d->win32WorkaroundConnections.contains(uuid)) { disconnect(d->win32WorkaroundConnections.value(uuid)); d->win32WorkaroundConnections.remove(uuid); } + Utils::uninstallSystemMenuHook(winId); +#endif + static const bool pureQt = d->usePureQtImplementation(); + if (pureQt) { + FramelessHelperQt::removeWindow(window); + } +#ifdef Q_OS_WINDOWS + if (!pureQt) { + FramelessHelperWin::removeWindow(window); + } #endif d->windowMapping.remove(window); - d->winIdMapping.remove(window->winId()); + d->winIdMapping.remove(winId); } FRAMELESSHELPER_END_NAMESPACE diff --git a/core/framelesswindowsmanager_p.h b/core/framelesswindowsmanager_p.h index b243c62..6171c3f 100644 --- a/core/framelesswindowsmanager_p.h +++ b/core/framelesswindowsmanager_p.h @@ -43,6 +43,10 @@ public: explicit FramelessWindowsManagerPrivate(FramelessWindowsManager *q); ~FramelessWindowsManagerPrivate(); + [[nodiscard]] static FramelessWindowsManagerPrivate *get(FramelessWindowsManager *manager); + + [[nodiscard]] bool usePureQtImplementation() const; + [[nodiscard]] QUuid findIdByWindow(QWindow *value) const; [[nodiscard]] QUuid findIdByWinId(const WId value) const; diff --git a/core/utils.h b/core/utils.h index 24a5a81..74a2038 100644 --- a/core/utils.h +++ b/core/utils.h @@ -109,6 +109,8 @@ FRAMELESSHELPER_CORE_API void fixupQtInternals(const WId winId); [[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowFrameBorderVisible(); [[nodiscard]] FRAMELESSHELPER_CORE_API bool isTitleBarColorized(); [[nodiscard]] FRAMELESSHELPER_CORE_API bool isFrameBorderColorized(); +FRAMELESSHELPER_CORE_API void installSystemMenuHook(const WId winId); +FRAMELESSHELPER_CORE_API void uninstallSystemMenuHook(const WId winId); #endif // Q_OS_WINDOWS } // namespace Utils diff --git a/core/utils_win.cpp b/core/utils_win.cpp index d17a81c..ed95b3d 100644 --- a/core/utils_win.cpp +++ b/core/utils_win.cpp @@ -24,6 +24,8 @@ #include "utils.h" #include +#include +#include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) @@ -39,6 +41,8 @@ #endif #include "qwinregistry_p.h" #include "framelesshelper_windows.h" +#include "framelesswindowsmanager.h" +#include "framelesswindowsmanager_p.h" #if 0 #include #include @@ -48,6 +52,20 @@ Q_DECLARE_METATYPE(QMargins) FRAMELESSHELPER_BEGIN_NAMESPACE +struct Win32UtilsHelper +{ + QMutex mutex = {}; + QHash qtWindowProcs = {}; + + explicit Win32UtilsHelper() = default; + ~Win32UtilsHelper() = default; + +private: + Q_DISABLE_COPY_MOVE(Win32UtilsHelper) +}; + +Q_GLOBAL_STATIC(Win32UtilsHelper, g_utilsHelper) + static const QString successErrorText = QStringLiteral("The operation completed successfully."); #if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0)) @@ -154,6 +172,90 @@ static const QString successErrorText = QStringLiteral("The operation completed } #endif +[[nodiscard]] static inline LRESULT CALLBACK SystemMenuHookWindowProc + (const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam) +{ + g_utilsHelper()->mutex.lock(); + if (!g_utilsHelper()->qtWindowProcs.contains(hWnd)) { + g_utilsHelper()->mutex.unlock(); + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + g_utilsHelper()->mutex.unlock(); + const auto winId = reinterpret_cast(hWnd); + const auto getGlobalPosFromMouse = [lParam]() -> QPointF { + return {qreal(GET_X_LPARAM(lParam)), qreal(GET_Y_LPARAM(lParam))}; + }; + const auto getGlobalPosFromKeyboard = [hWnd, winId]() -> QPointF { + RECT windowPos = {}; + if (GetWindowRect(hWnd, &windowPos) == FALSE) { + qWarning() << Utils::getSystemErrorMessage(QStringLiteral("GetWindowRect")); + return {}; + } + const bool maxOrFull = (IsMaximized(hWnd) || Utils::isFullScreen(winId)); + const int frameSizeX = Utils::getResizeBorderThickness(winId, true, true); + const bool frameBorderVisible = Utils::isWindowFrameBorderVisible(); + const int horizontalOffset = ((maxOrFull || !frameBorderVisible) ? 0 : frameSizeX); + const int verticalOffset = [winId, frameBorderVisible, maxOrFull]() -> int { + const int titleBarHeight = Utils::getTitleBarHeight(winId, true); + if (!frameBorderVisible) { + return titleBarHeight; + } + const int frameSizeY = Utils::getResizeBorderThickness(winId, false, true); + if (Utils::isWin11OrGreater()) { + if (maxOrFull) { + return (titleBarHeight + frameSizeY); + } + return titleBarHeight; + } + if (maxOrFull) { + return titleBarHeight; + } + return (titleBarHeight - frameSizeY); + }(); + return {qreal(windowPos.left + horizontalOffset), qreal(windowPos.top + verticalOffset)}; + }; + bool shouldShowSystemMenu = false; + QPointF globalPos = {}; + if (uMsg == WM_NCRBUTTONUP) { + if (wParam == HTCAPTION) { + shouldShowSystemMenu = true; + globalPos = getGlobalPosFromMouse(); + } + } else if (uMsg == WM_SYSCOMMAND) { + const WPARAM filteredWParam = (wParam & 0xFFF0); + if ((filteredWParam == SC_KEYMENU) && (lParam == VK_SPACE)) { + shouldShowSystemMenu = true; + globalPos = getGlobalPosFromKeyboard(); + } + } else if ((uMsg == WM_KEYDOWN) || (uMsg == WM_SYSKEYDOWN)) { + const bool altPressed = ((wParam == VK_MENU) || (GetKeyState(VK_MENU) < 0)); + const bool spacePressed = ((wParam == VK_SPACE) || (GetKeyState(VK_SPACE) < 0)); + if (altPressed && spacePressed) { + shouldShowSystemMenu = true; + globalPos = getGlobalPosFromKeyboard(); + } + } + if (shouldShowSystemMenu) { + Utils::showSystemMenu(winId, globalPos); + // QPA's internal code will handle system menu events separately, and its + // behavior is not what we would want to see because it doesn't know our + // window doesn't have any window frame now, so return early here to avoid + // entering Qt's own handling logic. + return 0; // Return 0 means we have handled this event. + } + g_utilsHelper()->mutex.lock(); + const WNDPROC originalWindowProc = g_utilsHelper()->qtWindowProcs.value(hWnd); + g_utilsHelper()->mutex.unlock(); + Q_ASSERT(originalWindowProc); + if (originalWindowProc) { + // Hand over to Qt's original window proc function for events we are not + // interested in. + return CallWindowProcW(originalWindowProc, hWnd, uMsg, wParam, lParam); + } else { + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } +} + bool Utils::isWin8OrGreater() { #if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) @@ -860,12 +962,24 @@ void Utils::startSystemResize(QWindow *window, const Qt::Edges edges) bool Utils::isWindowFrameBorderVisible() { static const bool result = []() -> bool { - if (qEnvironmentVariableIntValue("FRAMELESSHELPER_FORCE_SHOW_FRAME_BORDER") != 0) { - return true; + FramelessWindowsManager *manager = FramelessWindowsManager::instance(); + Q_ASSERT(manager); + if (manager) { + FramelessWindowsManagerPrivate *internal = FramelessWindowsManagerPrivate::get(manager); + Q_ASSERT(internal); + if (internal) { + if (internal->usePureQtImplementation()) { + return false; + } + } } // If we preserve the window frame border on systems prior to Windows 10, // the window will look rather ugly and I guess no one would like to see - // such weired windows. + // such weired windows. But for the ones who really want to see what the + // window look like, I still provide a way to enter such scenarios. + if (qEnvironmentVariableIntValue("FRAMELESSHELPER_FORCE_SHOW_FRAME_BORDER") != 0) { + return true; + } return (isWin10OrGreater() && !qEnvironmentVariableIsSet("FRAMELESSHELPER_HIDE_FRAME_BORDER")); }(); return result; @@ -886,4 +1000,54 @@ bool Utils::isFrameBorderColorized() return isTitleBarColorized(); } +void Utils::installSystemMenuHook(const WId winId) +{ + Q_ASSERT(winId); + if (!winId) { + return; + } + const auto hwnd = reinterpret_cast(winId); + QMutexLocker locker(&g_utilsHelper()->mutex); + if (g_utilsHelper()->qtWindowProcs.contains(hwnd)) { + return; + } + SetLastError(ERROR_SUCCESS); + const auto originalWindowProc = reinterpret_cast(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)); + Q_ASSERT(originalWindowProc); + if (!originalWindowProc) { + qWarning() << getSystemErrorMessage(QStringLiteral("GetWindowLongPtrW")); + return; + } + SetLastError(ERROR_SUCCESS); + if (SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast(SystemMenuHookWindowProc)) == 0) { + qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW")); + return; + } + g_utilsHelper()->qtWindowProcs.insert(hwnd, originalWindowProc); +} + +void Utils::uninstallSystemMenuHook(const WId winId) +{ + Q_ASSERT(winId); + if (!winId) { + return; + } + const auto hwnd = reinterpret_cast(winId); + QMutexLocker locker(&g_utilsHelper()->mutex); + if (!g_utilsHelper()->qtWindowProcs.contains(hwnd)) { + return; + } + const WNDPROC originalWindowProc = g_utilsHelper()->qtWindowProcs.value(hwnd); + Q_ASSERT(originalWindowProc); + if (!originalWindowProc) { + return; + } + SetLastError(ERROR_SUCCESS); + if (SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast(originalWindowProc)) == 0) { + qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW")); + return; + } + g_utilsHelper()->qtWindowProcs.remove(hwnd); +} + FRAMELESSHELPER_END_NAMESPACE diff --git a/quick/framelessquickeventfilter.cpp b/quick/framelessquickeventfilter.cpp index 7a5ef0e..d097483 100644 --- a/quick/framelessquickeventfilter.cpp +++ b/quick/framelessquickeventfilter.cpp @@ -200,9 +200,11 @@ bool FramelessQuickEventFilter::eventFilter(QObject *object, QEvent *event) #else const QPointF scenePos = mouseEvent->windowPos(); #endif - if ((scenePos.x() < kDefaultResizeBorderThickness) - || (scenePos.x() >= (window->width() - kDefaultResizeBorderThickness)) - || (scenePos.y() < kDefaultResizeBorderThickness)) { + const QQuickWindow::Visibility visibility = window->visibility(); + if ((visibility == QQuickWindow::Windowed) + && ((scenePos.x() < kDefaultResizeBorderThickness) + || (scenePos.x() >= (window->width() - kDefaultResizeBorderThickness)) + || (scenePos.y() < kDefaultResizeBorderThickness))) { return false; } const bool titleBar = isInTitleBarDraggableArea(window, scenePos); @@ -240,7 +242,6 @@ bool FramelessQuickEventFilter::eventFilter(QObject *object, QEvent *event) if (!titleBar) { return false; } - const QQuickWindow::Visibility visibility = window->visibility(); if ((visibility == QQuickWindow::Maximized) || (visibility == QQuickWindow::FullScreen)) { window->showNormal(); } else { diff --git a/widgets/framelesswidgetshelper.cpp b/widgets/framelesswidgetshelper.cpp index 9c47fdf..c8467cc 100644 --- a/widgets/framelesswidgetshelper.cpp +++ b/widgets/framelesswidgetshelper.cpp @@ -212,9 +212,7 @@ void FramelessWidgetsHelper::mousePressEventHandler(QMouseEvent *event) #else const QPoint scenePos = event->windowPos(); #endif - if ((scenePos.x() < kDefaultResizeBorderThickness) - || (scenePos.x() >= (q->width() - kDefaultResizeBorderThickness)) - || (scenePos.y() < kDefaultResizeBorderThickness)) { + if (shouldIgnoreMouseEvents(scenePos)) { return; } if (!isInTitleBarDraggableArea(scenePos)) { @@ -237,9 +235,7 @@ void FramelessWidgetsHelper::mouseReleaseEventHandler(QMouseEvent *event) #else const QPoint scenePos = event->windowPos(); #endif - if ((scenePos.x() < kDefaultResizeBorderThickness) - || (scenePos.x() >= (q->width() - kDefaultResizeBorderThickness)) - || (scenePos.y() < kDefaultResizeBorderThickness)) { + if (shouldIgnoreMouseEvents(scenePos)) { return; } if (!isInTitleBarDraggableArea(scenePos)) { @@ -270,9 +266,7 @@ void FramelessWidgetsHelper::mouseDoubleClickEventHandler(QMouseEvent *event) #else const QPoint scenePos = event->windowPos(); #endif - if ((scenePos.x() < kDefaultResizeBorderThickness) - || (scenePos.x() >= (q->width() - kDefaultResizeBorderThickness)) - || (scenePos.y() < kDefaultResizeBorderThickness)) { + if (shouldIgnoreMouseEvents(scenePos)) { return; } if (!isInTitleBarDraggableArea(scenePos)) { @@ -439,6 +433,13 @@ bool FramelessWidgetsHelper::isCustomLayout() const return (m_windowLayout == WindowLayout::Custom); } +bool FramelessWidgetsHelper::shouldIgnoreMouseEvents(const QPoint &pos) const +{ + return (isNormal() && ((pos.x() < kDefaultResizeBorderThickness) + || (pos.x() >= (q->width() - kDefaultResizeBorderThickness)) + || (pos.y() < kDefaultResizeBorderThickness))); +} + void FramelessWidgetsHelper::updateContentsMargins() { #ifdef Q_OS_WINDOWS diff --git a/widgets/framelesswidgetshelper.h b/widgets/framelesswidgetshelper.h index dd79dcc..402b49a 100644 --- a/widgets/framelesswidgetshelper.h +++ b/widgets/framelesswidgetshelper.h @@ -78,6 +78,7 @@ private: Q_NODISCARD bool shouldDrawFrameBorder() const; Q_NODISCARD bool isStandardLayout() const; Q_NODISCARD bool isCustomLayout() const; + Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const; private Q_SLOTS: void updateContentsMargins();