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.cpp74
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.h2
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp34
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsmenu.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp6
13 files changed, 135 insertions, 38 deletions
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 072012064f..98a4b261fd 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -246,14 +246,12 @@ struct QWindowsContextPrivate {
QScopedPointer<QWindowsTabletSupport> m_tabletSupport;
#endif
const HRESULT m_oleInitializeResult;
- const QByteArray m_eventType;
QWindow *m_lastActiveWindow = nullptr;
bool m_asyncExpose = false;
};
QWindowsContextPrivate::QWindowsContextPrivate()
: m_oleInitializeResult(OleInitialize(NULL))
- , m_eventType(QByteArrayLiteral("windows_generic_MSG"))
{
QWindowsContext::user32dll.init();
QWindowsContext::shcoredll.init();
@@ -866,6 +864,33 @@ static bool shouldHaveNonClientDpiScaling(const QWindow *window)
;
}
+static inline bool isInputMessage(UINT m)
+{
+ switch (m) {
+ case WM_IME_STARTCOMPOSITION:
+ case WM_IME_ENDCOMPOSITION:
+ case WM_IME_COMPOSITION:
+ case WM_TOUCH:
+ case WM_MOUSEHOVER:
+ case WM_MOUSELEAVE:
+ case WM_NCHITTEST:
+ case WM_NCMOUSEHOVER:
+ case WM_NCMOUSELEAVE:
+ case WM_SIZING:
+ case WM_MOVING:
+ case WM_SYSCOMMAND:
+ case WM_COMMAND:
+ case WM_DWMNCRENDERINGCHANGED:
+ case WM_PAINT:
+ return true;
+ default:
+ break;
+ }
+ return (m >= WM_MOUSEFIRST && m <= WM_MOUSELAST)
+ || (m >= WM_NCMOUSEMOVE && m <= WM_NCXBUTTONDBLCLK)
+ || (m >= WM_KEYFIRST && m <= WM_KEYLAST);
+}
+
/*!
\brief Main windows procedure registered for windows.
@@ -901,21 +926,14 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
QWindowsWindow *platformWindow = findPlatformWindow(hwnd);
*platformWindowPtr = platformWindow;
- // Run the native event filters.
- long filterResult = 0;
- QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
- if (dispatcher && dispatcher->filterNativeEvent(d->m_eventType, &msg, &filterResult)) {
- *result = LRESULT(filterResult);
+ // Run the native event filters. QTBUG-67095: Exclude input messages which are sent
+ // by QEventDispatcherWin32::processEvents()
+ if (!isInputMessage(msg.message) && filterNativeEvent(&msg, result))
+ return true;
+
+ if (platformWindow && filterNativeEvent(platformWindow->window(), &msg, result))
return true;
- }
- if (platformWindow) {
- filterResult = 0;
- if (QWindowSystemInterface::handleNativeEvent(platformWindow->window(), d->m_eventType, &msg, &filterResult)) {
- *result = LRESULT(filterResult);
- return true;
- }
- }
if (et & QtWindows::InputMethodEventFlag) {
QWindowsInputContext *windowsInputContext = ::windowsInputContext();
// Disable IME assuming this is a special implementation hooking into keyboard input.
@@ -1393,4 +1411,30 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR
return result;
}
+
+static inline QByteArray nativeEventType() { return QByteArrayLiteral("windows_generic_MSG"); }
+
+// Send to QAbstractEventDispatcher
+bool QWindowsContext::filterNativeEvent(MSG *msg, LRESULT *result)
+{
+ QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
+ long filterResult = 0;
+ if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) {
+ *result = LRESULT(filterResult);
+ return true;
+ }
+ return false;
+}
+
+// Send to QWindowSystemInterface
+bool QWindowsContext::filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result)
+{
+ long filterResult = 0;
+ if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), &msg, &filterResult)) {
+ *result = LRESULT(filterResult);
+ return true;
+ }
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index f2ec307be2..0a7f20ca83 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -212,6 +212,9 @@ public:
QTouchDevice *touchDevice() const;
+ static bool filterNativeEvent(MSG *msg, LRESULT *result);
+ static bool filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result);
+
private:
void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w);
#ifndef QT_NO_CONTEXTMENU
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 593ff3cef1..e427ee162a 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -56,6 +56,7 @@
#include <QtGui/QRasterWindow>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface_p.h>
+#include <QtGui/private/qdnd_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index 2b4ca2dce1..d934679488 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -44,6 +44,7 @@
#include "qwindowsinternalmimedata.h"
#include <qpa/qplatformdrag.h>
+#include <QtGui/qdrag.h>
#include <QtGui/QPixmap>
struct IDropTargetHelper;
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index b9dd2c557e..2dbca6047c 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -530,6 +530,14 @@ bool QWindowsInputContext::endComposition(HWND hwnd)
if (m_compositionContext.focusObject.isNull())
return false;
+ // QTBUG-58300: Ignore WM_IME_ENDCOMPOSITION when CTRL is pressed to prevent
+ // for example the text being cleared when pressing CTRL+A
+ if (m_locale.language() == QLocale::Korean
+ && QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) {
+ reset();
+ return true;
+ }
+
m_endCompositionRecursionGuard = true;
imeNotifyCancelComposition(m_compositionContext.hwnd);
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 287b65cd5d..0a9e8b9d91 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -552,7 +552,7 @@ QPlatformDrag *QWindowsIntegration::drag() const
{
return &d->m_drag;
}
-# endif // !QT_NO_DRAGANDDROP
+# endif // QT_CONFIG(draganddrop)
#endif // !QT_NO_CLIPBOARD
QPlatformInputContext * QWindowsIntegration::inputContext() const
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.h b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
index a7df1ee6e0..a44f5b509c 100644
--- a/src/plugins/platforms/windows/qwindowsinternalmimedata.h
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
@@ -42,7 +42,7 @@
#include <QtCore/qt_windows.h>
-#include <QtGui/private/qdnd_p.h> // QInternalMime
+#include <QtGui/private/qinternalmimedata_p.h>
#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index af62936a18..950d8ecd36 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -102,6 +102,7 @@ QWindowsKeyMapper::QWindowsKeyMapper()
QGuiApplication *app = static_cast<QGuiApplication *>(QGuiApplication::instance());
QObject::connect(app, &QGuiApplication::applicationStateChanged,
app, clearKeyRecorderOnApplicationInActive);
+ changeKeyboard();
}
QWindowsKeyMapper::~QWindowsKeyMapper()
@@ -317,9 +318,9 @@ static const uint KeyTbl[] = { // Keyboard mapping table
Qt::Key_9, // 105 0x69 VK_NUMPAD9 | Numeric keypad 9 key
Qt::Key_Asterisk, // 106 0x6A VK_MULTIPLY | Multiply key
Qt::Key_Plus, // 107 0x6B VK_ADD | Add key
- Qt::Key_Comma, // 108 0x6C VK_SEPARATOR | Separator key
+ Qt::Key_unknown, // 108 0x6C VK_SEPARATOR | Separator key (locale-dependent)
Qt::Key_Minus, // 109 0x6D VK_SUBTRACT | Subtract key
- Qt::Key_Period, // 110 0x6E VK_DECIMAL | Decimal key
+ Qt::Key_unknown, // 110 0x6E VK_DECIMAL | Decimal key (locale-dependent)
Qt::Key_Slash, // 111 0x6F VK_DIVIDE | Divide key
Qt::Key_F1, // 112 0x70 VK_F1 | F1 key
Qt::Key_F2, // 113 0x71 VK_F2 | F2 key
@@ -810,7 +811,7 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
// Reset layout map when system keyboard layout is changed
if (msg.message == WM_INPUTLANGCHANGE) {
- deleteLayouts();
+ changeKeyboard();
return true;
}
@@ -830,7 +831,7 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
if (PeekMessage(&peekedMsg, hwnd, 0, 0, PM_NOREMOVE) && peekedMsg.message == WM_DEADCHAR)
return true;
- return translateKeyEventInternal(widget, msg, false);
+ return translateKeyEventInternal(widget, msg, false, result);
}
bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, const MSG &msg)
@@ -854,15 +855,19 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
// QTBUG-43343: Make sure to return false if Qt does not handle the key, otherwise,
// the keys are not passed to the active media player.
+# if QT_CONFIG(shortcut)
const QKeySequence sequence(Qt::Modifier(state) + qtKey);
return QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(sequence);
+# else
+ return false;
+# endif
#else
Q_UNREACHABLE();
return false;
#endif
}
-bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */)
+bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */, LRESULT *lResult)
{
const UINT msgType = msg.message;
@@ -1056,6 +1061,10 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
QChar uch;
if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) {
+ if (QWindowsContext::filterNativeEvent(&wm_char, lResult))
+ return true;
+ if (receiver && QWindowsContext::filterNativeEvent(receiver, &wm_char, lResult))
+ return true;
// Found a ?_CHAR
uch = QChar(ushort(wm_char.wParam));
if (uch.isHighSurrogate()) {
@@ -1264,8 +1273,19 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
for (size_t i = 1; i < NumMods; ++i) {
Qt::KeyboardModifiers neededMods = ModsTbl[i];
quint32 key = kbItem.qtKey[i];
- if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
- result << int(key + (keyMods & ~neededMods));
+ if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) {
+ const Qt::KeyboardModifiers missingMods = keyMods & ~neededMods;
+ const int matchedKey = int(key) + missingMods;
+ const QList<int>::iterator it =
+ std::find_if(result.begin(), result.end(),
+ [key] (int k) { return (k & ~Qt::KeyboardModifierMask) == key; });
+ // QTBUG-67200: Use the match with the least modifiers (prefer
+ // Shift+9 over Alt + Shift + 9) resulting in more missing modifiers.
+ if (it == result.end())
+ result << matchedKey;
+ else if (missingMods > (*it & Qt::KeyboardModifierMask))
+ *it = matchedKey;
+ }
}
return result;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h
index 2657644780..c6b46b0c30 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.h
+++ b/src/plugins/platforms/windows/qwindowskeymapper.h
@@ -90,7 +90,7 @@ public:
QList<int> possibleKeys(const QKeyEvent *e) const;
private:
- bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab);
+ bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab, LRESULT *lResult);
bool translateMultimediaKeyEventInternal(QWindow *receiver, const MSG &msg);
void updateKeyMap(const MSG &msg);
diff --git a/src/plugins/platforms/windows/qwindowsmenu.cpp b/src/plugins/platforms/windows/qwindowsmenu.cpp
index b89e1b66a3..71802b9017 100644
--- a/src/plugins/platforms/windows/qwindowsmenu.cpp
+++ b/src/plugins/platforms/windows/qwindowsmenu.cpp
@@ -390,6 +390,7 @@ void QWindowsMenuItem::setChecked(bool isChecked)
menuItemSetChangeState(parentMenuHandle(), m_id, FALSE, m_checked, MF_CHECKED, MF_UNCHECKED);
}
+#if QT_CONFIG(shortcut)
void QWindowsMenuItem::setShortcut(const QKeySequence &shortcut)
{
qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << shortcut << ')' << this;
@@ -399,6 +400,7 @@ void QWindowsMenuItem::setShortcut(const QKeySequence &shortcut)
if (m_parentMenu != nullptr)
updateText();
}
+#endif
void QWindowsMenuItem::setEnabled(bool enabled)
{
@@ -441,10 +443,12 @@ UINT QWindowsMenuItem::state() const
QString QWindowsMenuItem::nativeText() const
{
QString result = m_text;
+#if QT_CONFIG(shortcut)
if (!m_shortcut.isEmpty()) {
result += QLatin1Char('\t');
result += m_shortcut.toString(QKeySequence::NativeText);
}
+#endif
return result;
}
@@ -894,8 +898,10 @@ void QWindowsMenuItem::formatDebug(QDebug &d) const
d << ", subMenu=" << static_cast<const void *>(m_subMenu);
d << ", tag=" << showbase << hex
<< tag() << noshowbase << dec << ", id=" << m_id;
+#if QT_CONFIG(shortcut)
if (!m_shortcut.isEmpty())
d << ", shortcut=" << m_shortcut;
+#endif
if (m_visible)
d << " [visible]";
if (m_enabled)
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 34e6041687..0439797a7d 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -40,7 +40,7 @@
#include "qwindowsmime.h"
#include "qwindowscontext.h"
-#include <QtGui/private/qdnd_p.h>
+#include <QtGui/private/qinternalmimedata_p.h>
#include <QtCore/QByteArrayMatcher>
#include <QtCore/QTextCodec>
#include <QtCore/QMap>
@@ -1255,7 +1255,7 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData
} else {
#if QT_CONFIG(draganddrop)
data = QInternalMimeData::renderDataHelper(outFormats.value(getCf(formatetc)), mimeData);
-#endif //QT_NO_DRAGANDDROP
+#endif // QT_CONFIG(draganddrop)
}
return setData(data, pmedium);
}
@@ -1363,7 +1363,7 @@ bool QLastResortMimes::canConvertFromMime(const FORMATETC &formatetc, const QMim
Q_UNUSED(formatetc);
return formatetc.tymed & TYMED_HGLOBAL
&& formats.contains(formatetc.cfFormat);
-#endif //QT_NO_DRAGANDDROP
+#endif // QT_CONFIG(draganddrop)
}
bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
@@ -1376,7 +1376,7 @@ bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeDa
Q_UNUSED(formatetc);
Q_UNUSED(pmedium);
return false;
-#endif //QT_NO_DRAGANDDROP
+#endif // QT_CONFIG(draganddrop)
}
QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, const QMimeData * /*mimeData*/) const
@@ -1484,7 +1484,7 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const
format = clipFormat;
}
}
-#endif //QT_NO_DRAGANDDROP
+#endif // QT_CONFIG(draganddrop)
}
return format;
@@ -1559,7 +1559,7 @@ QVector<FORMATETC> QWindowsMimeConverter::allFormatsForMime(const QMimeData *mim
{
ensureInitialized();
QVector<FORMATETC> formatics;
-#ifdef QT_NO_DRAGANDDROP
+#if !QT_CONFIG(draganddrop)
Q_UNUSED(mimeData);
#else
formatics.reserve(20);
@@ -1568,7 +1568,7 @@ QVector<FORMATETC> QWindowsMimeConverter::allFormatsForMime(const QMimeData *mim
for (int i = m_mimes.size() - 1; i >= 0; --i)
formatics += m_mimes.at(i)->formatsForMime(formats.at(f), mimeData);
}
-#endif //QT_NO_DRAGANDDROP
+#endif // QT_CONFIG(draganddrop)
return formatics;
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 814291c54a..17851618b4 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -395,10 +395,24 @@ static bool isValidWheelReceiver(QWindow *candidate)
static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int delta,
Qt::Orientation orientation, Qt::KeyboardModifiers mods)
{
+ // Redirect wheel event to one of the following, in order of preference:
+ // 1) The window under mouse
+ // 2) The window receiving the event
// If a window is blocked by modality, it can't get the event.
- if (isValidWheelReceiver(window)) {
- QWindowSystemInterface::handleWheelEvent(window,
- QWindowsGeometryHint::mapFromGlobal(window, globalPos),
+
+ QWindow *receiver = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE);
+ while (receiver && receiver->flags().testFlag(Qt::WindowTransparentForInput))
+ receiver = receiver->parent();
+ bool handleEvent = true;
+ if (!isValidWheelReceiver(receiver)) {
+ receiver = window;
+ if (!isValidWheelReceiver(receiver))
+ handleEvent = false;
+ }
+
+ if (handleEvent) {
+ QWindowSystemInterface::handleWheelEvent(receiver,
+ QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
globalPos, delta, orientation, mods);
}
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index f1762146ec..a2883e2601 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1144,11 +1144,11 @@ void QWindowsWindow::initialize()
const Qt::WindowState state = w->windowState();
if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen
&& creationContext->requestedGeometryIn != creationContext->obtainedGeometry) {
- QWindowSystemInterface::handleGeometryChange(w, creationContext->obtainedGeometry);
+ QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, creationContext->obtainedGeometry);
}
QPlatformScreen *obtainedScreen = screenForGeometry(creationContext->obtainedGeometry);
if (obtainedScreen && screen() != obtainedScreen)
- QWindowSystemInterface::handleWindowScreenChanged(w, obtainedScreen->screen());
+ QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(w, obtainedScreen->screen());
}
}
@@ -1248,7 +1248,7 @@ void QWindowsWindow::setDropSiteEnabled(bool dropEnabled)
RevokeDragDrop(m_data.hwnd);
m_dropTarget = 0;
}
-#endif // !QT_NO_CLIPBOARD && !QT_NO_DRAGANDDROP
+#endif // QT_CONFIG(clipboard) && QT_CONFIG(draganddrop)
}
// Returns topmost QWindowsWindow ancestor even if there are embedded windows in the chain.