summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp43
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp175
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp24
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");
}