diff options
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.cpp | 43 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.h | 14 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsdrag.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsdrag.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsmousehandler.cpp | 16 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowspointerhandler.cpp | 175 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowstheme.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 24 |
8 files changed, 232 insertions, 50 deletions
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 253aeb9d76..1f80ac5872 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -148,7 +148,7 @@ static inline bool sessionManagerInteractionBlocked() { return false; } static inline int windowDpiAwareness(HWND hwnd) { - return QWindowsContext::user32dll.getWindowDpiAwarenessContext && QWindowsContext::user32dll.getWindowDpiAwarenessContext + return QWindowsContext::user32dll.getWindowDpiAwarenessContext && QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext ? QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext(QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd)) : -1; } @@ -213,6 +213,7 @@ void QWindowsUser32DLL::init() enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling"); getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext"); getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext"); + systemParametersInfoForDpi = (SystemParametersInfoForDpi)library.resolve("SystemParametersInfoForDpi"); } } @@ -916,6 +917,45 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) return result; } +bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void *out, + unsigned dpi) +{ + const BOOL result = QWindowsContext::user32dll.systemParametersInfoForDpi != nullptr && dpi != 0 + ? QWindowsContext::user32dll.systemParametersInfoForDpi(action, param, out, 0, dpi) + : SystemParametersInfo(action, param, out, 0); + return result == TRUE; +} + +bool QWindowsContext::systemParametersInfoForScreen(unsigned action, unsigned param, void *out, + const QPlatformScreen *screen) +{ + return systemParametersInfo(action, param, out, screen ? screen->logicalDpi().first : 0); +} + +bool QWindowsContext::systemParametersInfoForWindow(unsigned action, unsigned param, void *out, + const QPlatformWindow *win) +{ + return systemParametersInfoForScreen(action, param, out, win ? win->screen() : nullptr); +} + +bool QWindowsContext::nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi) +{ + memset(ncm, 0, sizeof(NONCLIENTMETRICS)); + ncm->cbSize = sizeof(NONCLIENTMETRICS); + return systemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm->cbSize, ncm, dpi); +} + +bool QWindowsContext::nonClientMetricsForScreen(NONCLIENTMETRICS *ncm, + const QPlatformScreen *screen) +{ + return nonClientMetrics(ncm, screen ? screen->logicalDpi().first : 0); +} + +bool QWindowsContext::nonClientMetricsForWindow(NONCLIENTMETRICS *ncm, const QPlatformWindow *win) +{ + return nonClientMetricsForScreen(ncm, win ? win->screen() : nullptr); +} + static inline QWindowsInputContext *windowsInputContext() { return qobject_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext()); @@ -960,6 +1000,7 @@ static inline bool isInputMessage(UINT m) case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: + case WM_INPUT: case WM_TOUCH: case WM_MOUSEHOVER: case WM_MOUSELEAVE: diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 19e9c26130..fd6c72668c 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -70,6 +70,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaTrayIcon) class QWindow; class QPlatformScreen; +class QPlatformWindow; class QWindowsMenuBar; class QWindowsScreenManager; class QWindowsTabletSupport; @@ -104,6 +105,7 @@ struct QWindowsUser32DLL typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND); typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND); typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int); + typedef BOOL (WINAPI *SystemParametersInfoForDpi)(UINT, UINT, PVOID, UINT, UINT); // Windows pointer functions (Windows 8 or later). EnableMouseInPointer enableMouseInPointer = nullptr; @@ -132,6 +134,7 @@ struct QWindowsUser32DLL EnableNonClientDpiScaling enableNonClientDpiScaling = nullptr; GetWindowDpiAwarenessContext getWindowDpiAwarenessContext = nullptr; GetAwarenessFromDpiAwarenessContext getAwarenessFromDpiAwarenessContext = nullptr; + SystemParametersInfoForDpi systemParametersInfoForDpi = nullptr; }; // Shell scaling library (Windows 8.1 onwards) @@ -237,6 +240,17 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + static bool systemParametersInfo(unsigned action, unsigned param, void *out, unsigned dpi = 0); + static bool systemParametersInfoForScreen(unsigned action, unsigned param, void *out, + const QPlatformScreen *screen = nullptr); + static bool systemParametersInfoForWindow(unsigned action, unsigned param, void *out, + const QPlatformWindow *win = nullptr); + static bool nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi = 0); + static bool nonClientMetricsForScreen(NONCLIENTMETRICS *ncm, + const QPlatformScreen *screen = nullptr); + static bool nonClientMetricsForWindow(NONCLIENTMETRICS *ncm, + const QPlatformWindow *win = nullptr); + static DWORD readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue); QTouchDevice *touchDevice() const; diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index b7d225cb00..ee82b2f022 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -652,6 +652,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, */ bool QWindowsDrag::m_canceled = false; +bool QWindowsDrag::m_dragging = false; QWindowsDrag::QWindowsDrag() = default; @@ -699,7 +700,10 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag) const DWORD allowedEffects = translateToWinDragEffects(possibleActions); qCDebug(lcQpaMime) << '>' << __FUNCTION__ << "possible Actions=0x" << hex << int(possibleActions) << "effects=0x" << allowedEffects << dec; + // Indicate message handlers we are in DoDragDrop() event loop. + QWindowsDrag::m_dragging = true; const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect); + QWindowsDrag::m_dragging = false; const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect(); if (r == DRAGDROP_S_DROP) { if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) { diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h index f116e50cbf..5f30c59882 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.h +++ b/src/plugins/platforms/windows/qwindowsdrag.h @@ -92,6 +92,7 @@ public: static QWindowsDrag *instance(); void cancelDrag() override { QWindowsDrag::m_canceled = true; } static bool isCanceled() { return QWindowsDrag::m_canceled; } + static bool isDragging() { return QWindowsDrag::m_dragging; } IDataObject *dropDataObject() const { return m_dropDataObject; } void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; } @@ -102,6 +103,7 @@ public: private: static bool m_canceled; + static bool m_dragging; QWindowsDropMimeData m_dropData; IDataObject *m_dropDataObject = nullptr; diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index c1c275144f..fcdd179a31 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -207,26 +207,26 @@ static inline MouseEvent eventFromMsg(const MSG &msg) return {QEvent::MouseButtonPress, Qt::LeftButton}; case WM_LBUTTONUP: return {QEvent::MouseButtonRelease, Qt::LeftButton}; - case WM_LBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::LeftButton}; + case WM_LBUTTONDBLCLK: // Qt QPA does not handle double clicks, send as press + return {QEvent::MouseButtonPress, Qt::LeftButton}; case WM_MBUTTONDOWN: return {QEvent::MouseButtonPress, Qt::MidButton}; case WM_MBUTTONUP: return {QEvent::MouseButtonRelease, Qt::MidButton}; case WM_MBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::MidButton}; + return {QEvent::MouseButtonPress, Qt::MidButton}; case WM_RBUTTONDOWN: return {QEvent::MouseButtonPress, Qt::RightButton}; case WM_RBUTTONUP: return {QEvent::MouseButtonRelease, Qt::RightButton}; case WM_RBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::RightButton}; + return {QEvent::MouseButtonPress, Qt::RightButton}; case WM_XBUTTONDOWN: return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; case WM_XBUTTONUP: return {QEvent::MouseButtonRelease, extraButton(msg.wParam)}; case WM_XBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, extraButton(msg.wParam)}; + return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; case WM_NCMOUSEMOVE: return {QEvent::NonClientAreaMouseMove, Qt::NoButton}; case WM_NCLBUTTONDOWN: @@ -234,19 +234,19 @@ static inline MouseEvent eventFromMsg(const MSG &msg) case WM_NCLBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton}; case WM_NCLBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton}; case WM_NCMBUTTONDOWN: return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; case WM_NCMBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton}; case WM_NCMBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; case WM_NCRBUTTONDOWN: return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; case WM_NCRBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton}; case WM_NCRBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; default: // WM_MOUSELEAVE break; } diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index c5acc38e7c..21dc0cd577 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -50,6 +50,9 @@ #include "qwindowswindow.h" #include "qwindowsintegration.h" #include "qwindowsscreen.h" +#if QT_CONFIG(draganddrop) +# include "qwindowsdrag.h" +#endif #include <qpa/qwindowsysteminterface.h> #include <QtGui/qguiapplication.h> @@ -60,6 +63,7 @@ #include <QtCore/qvarlengtharray.h> #include <QtCore/qloggingcategory.h> #include <QtCore/qoperatingsystemversion.h> +#include <QtCore/qqueue.h> #include <algorithm> @@ -75,6 +79,111 @@ enum { QT_PT_TOUCHPAD = 5, // MinGW is missing PT_TOUCHPAD }; +struct PointerTouchEventInfo { + QPointer<QWindow> window; + QList<QWindowSystemInterface::TouchPoint> points; + Qt::KeyboardModifiers modifiers; +}; + +struct PointerTabletEventInfo { + QPointer<QWindow> window; + QPointF local; + QPointF global; + int device; + int pointerType; + Qt::MouseButtons buttons; + qreal pressure; + int xTilt; + int yTilt; + qreal tangentialPressure; + qreal rotation; + int z; + qint64 uid; + Qt::KeyboardModifiers modifiers; +}; + +static QQueue<PointerTouchEventInfo> touchEventQueue; +static QQueue<PointerTabletEventInfo> tabletEventQueue; + +static void enqueueTouchEvent(QWindow *window, + const QList<QWindowSystemInterface::TouchPoint> &points, + Qt::KeyboardModifiers modifiers) +{ + PointerTouchEventInfo eventInfo; + eventInfo.window = window; + eventInfo.points = points; + eventInfo.modifiers = modifiers; + touchEventQueue.enqueue(eventInfo); +} + +static void enqueueTabletEvent(QWindow *window, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, + int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, + int z, qint64 uid, Qt::KeyboardModifiers modifiers) +{ + PointerTabletEventInfo eventInfo; + eventInfo.window = window; + eventInfo.local = local; + eventInfo.global = global; + eventInfo.device = device; + eventInfo.pointerType = pointerType; + eventInfo.buttons = buttons; + eventInfo.pressure = pressure; + eventInfo.xTilt = xTilt; + eventInfo.yTilt = yTilt; + eventInfo.tangentialPressure = tangentialPressure; + eventInfo.rotation = rotation; + eventInfo.z = z; + eventInfo.uid = uid; + eventInfo.modifiers = modifiers; + tabletEventQueue.enqueue(eventInfo); +} + +static void flushTouchEvents(QTouchDevice *touchDevice) +{ + while (!touchEventQueue.isEmpty()) { + PointerTouchEventInfo eventInfo = touchEventQueue.dequeue(); + if (eventInfo.window) { + QWindowSystemInterface::handleTouchEvent(eventInfo.window, + touchDevice, + eventInfo.points, + eventInfo.modifiers); + } + } +} + +static void flushTabletEvents() +{ + while (!tabletEventQueue.isEmpty()) { + PointerTabletEventInfo eventInfo = tabletEventQueue.dequeue(); + if (eventInfo.window) { + QWindowSystemInterface::handleTabletEvent(eventInfo.window, + eventInfo.local, + eventInfo.global, + eventInfo.device, + eventInfo.pointerType, + eventInfo.buttons, + eventInfo.pressure, + eventInfo.xTilt, + eventInfo.yTilt, + eventInfo.tangentialPressure, + eventInfo.rotation, + eventInfo.z, + eventInfo.uid, + eventInfo.modifiers); + } + } +} + +static bool draggingActive() +{ +#if QT_CONFIG(draganddrop) + return QWindowsDrag::isDragging(); +#else + return false; +#endif +} + bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { *result = 0; @@ -171,7 +280,7 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q return false; } -static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QPoint globalPos, QEvent::Type *eventType, Qt::MouseButton *mouseButton) +static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QEvent::Type *eventType, Qt::MouseButton *mouseButton) { static const QHash<POINTER_BUTTON_CHANGE_TYPE, Qt::MouseButton> buttonMapping { {POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton}, @@ -225,28 +334,6 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp } *mouseButton = buttonMapping.value(changeType, Qt::NoButton); - - // Pointer messages lack a double click indicator. Check if this is the case here. - if (*eventType == QEvent::MouseButtonPress || - *eventType == QEvent::NonClientAreaMouseButtonPress) { - static LONG lastTime = 0; - static Qt::MouseButton lastButton = Qt::NoButton; - static QEvent::Type lastEvent = QEvent::None; - static QPoint lastPos; - LONG messageTime = GetMessageTime(); - if (*mouseButton == lastButton - && *eventType == lastEvent - && messageTime - lastTime < (LONG)GetDoubleClickTime() - && qAbs(globalPos.x() - lastPos.x()) < GetSystemMetrics(SM_CXDOUBLECLK) - && qAbs(globalPos.y() - lastPos.y()) < GetSystemMetrics(SM_CYDOUBLECLK)) { - *eventType = nonClient ? QEvent::NonClientAreaMouseButtonDblClick : - QEvent::MouseButtonDblClick; - } - lastTime = messageTime; - lastButton = *mouseButton; - lastEvent = *eventType; - lastPos = globalPos; - } } static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos) @@ -358,7 +445,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h QEvent::Type eventType; Qt::MouseButton button; - getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, globalPos, &eventType, &button); + getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, &eventType, &button); if (et & QtWindows::NonClientEventFlag) { QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType, @@ -426,6 +513,9 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. + if (draggingActive()) + return false; // Let DoDragDrop() loop handle it. + if (count < 1) return false; @@ -452,6 +542,8 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, QList<QWindowSystemInterface::TouchPoint> touchPoints; + bool primaryPointer = false; + if (QWindowsContext::verbose > 1) qCDebug(lcQpaEvents).noquote().nospace() << showbase << __FUNCTION__ @@ -494,16 +586,23 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved; m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition); } + if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY) + primaryPointer = true; + touchPoints.append(touchPoint); // Avoid getting repeated messages for this frame if there are multiple pointerIds QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId); } - - QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, - QWindowsKeyMapper::queryKeyboardModifiers()); - - return true; + if (primaryPointer) { + // Postpone event delivery to avoid hanging inside DoDragDrop(). + // Only the primary pointer will generate mouse messages. + enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers()); + } else { + QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, + QWindowsKeyMapper::queryKeyboardModifiers()); + } + return false; // Allow mouse messages to be generated. } bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, @@ -512,6 +611,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. + if (draggingActive()) + return false; // Let DoDragDrop() loop handle it. + POINTER_PEN_INFO *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo); RECT pRect, dRect; @@ -592,20 +694,25 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin } const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons, - pressure, xTilt, yTilt, tangentialPressure, rotation, z, - pointerId, keyModifiers); - break; + // Postpone event delivery to avoid hanging inside DoDragDrop(). + enqueueTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons, + pressure, xTilt, yTilt, tangentialPressure, rotation, z, + pointerId, keyModifiers); + return false; // Allow mouse messages to be generated. } } return true; } -// SetCursorPos()/TrackMouseEvent() will generate old-style WM_MOUSE messages. Handle them here. +// Process old-style mouse messages here. bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { Q_UNUSED(et); + // Generate enqueued events. + flushTouchEvents(m_touchDevice); + flushTabletEvents(); + *result = 0; if (msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) return false; diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index d01a7b0a8a..4b70e915a8 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -507,9 +507,7 @@ void QWindowsTheme::refreshFonts() if (!QGuiApplication::desktopSettingsAware()) return; NONCLIENTMETRICS ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); - + QWindowsContext::nonClientMetrics(&ncm); const QFont menuFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMenuFont); const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont); const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 9c31409644..f340f16679 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2416,6 +2416,13 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled) } } +static int getBorderWidth(const QPlatformScreen *screen) +{ + NONCLIENTMETRICS ncm; + QWindowsContext::nonClientMetricsForScreen(&ncm, screen); + return ncm.iBorderWidth + ncm.iPaddedBorderWidth + 2; +} + void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const { // We don't apply the min/max size hint as we change the dpi, because we did not adjust the @@ -2425,10 +2432,11 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const hint.applyToMinMaxInfo(m_data.hwnd, mmi); } - if ((testFlag(WithinMaximize) || (window()->windowStates() & Qt::WindowMinimized)) - && (m_data.flags & Qt::FramelessWindowHint)) { - // This block fixes QTBUG-8361: Frameless windows shouldn't cover the - // taskbar when maximized + // This block fixes QTBUG-8361, QTBUG-4362: Frameless/title-less windows shouldn't cover the + // taskbar when maximized + if ((testFlag(WithinMaximize) || window()->windowStates().testFlag(Qt::WindowMinimized)) + && (m_data.flags.testFlag(Qt::FramelessWindowHint) + || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))) { const QScreen *screen = window()->screen(); // Documentation of MINMAXINFO states that it will only work for the primary screen @@ -2442,6 +2450,14 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const // If you have the taskbar on top, or on the left you don't want it at (0,0): mmi->ptMaxPosition.x = availableGeometry.x(); mmi->ptMaxPosition.y = availableGeometry.y(); + if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) { + const int borderWidth = getBorderWidth(screen->handle()); + mmi->ptMaxSize.x += borderWidth * 2; + mmi->ptMaxSize.y += borderWidth * 2; + mmi->ptMaxTrackSize = mmi->ptMaxSize; + mmi->ptMaxPosition.x -= borderWidth; + mmi->ptMaxPosition.y -= borderWidth; + } } else if (!screen){ qWarning("window()->screen() returned a null screen"); } |