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/qtwindowsglobal.h6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h1
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp73
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h2
8 files changed, 80 insertions, 25 deletions
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index f9a55c9940..63c083d233 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -57,7 +57,8 @@ enum
TouchEventFlag = 0x400000,
ClipboardEventFlag = 0x800000,
ApplicationEventFlag = 0x1000000,
- ThemingEventFlag = 0x2000000
+ ThemingEventFlag = 0x2000000,
+ GenericEventFlag = 0x4000000, // Misc
};
enum WindowsEventType // Simplify event types
@@ -108,6 +109,7 @@ enum WindowsEventType // Simplify event types
CompositionSettingsChanged = ThemingEventFlag + 2,
DisplayChangedEvent = 437,
SettingChangedEvent = DisplayChangedEvent + 1,
+ ScrollEvent = GenericEventFlag + 1,
ContextMenu = 123,
GestureEvent = 124,
UnknownEvent = 542
@@ -145,6 +147,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return QtWindows::CursorEvent;
case WM_MOUSELEAVE:
return QtWindows::MouseEvent;
+ case WM_HSCROLL:
+ return QtWindows::ScrollEvent;
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
return QtWindows::MouseWheelEvent;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 7264fdcbb6..7d7ea031a5 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -1037,6 +1037,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
}
#endif
+ case QtWindows::ScrollEvent:
+#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
+ return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result);
+#else
+ return d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result);
+#endif
case QtWindows::MouseWheelEvent:
case QtWindows::MouseEvent:
case QtWindows::LeaveEvent:
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
index 2f87d7d677..83a39989f6 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.h
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -73,6 +73,7 @@ public:
bool startComposition(HWND hwnd);
bool composition(HWND hwnd, LPARAM lParam);
bool endComposition(HWND hwnd);
+ inline bool isComposing() const { return m_compositionContext.isComposing; }
int reconvertString(RECONVERTSTRING *reconv);
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 0e26a17223..d47c7df9e0 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -36,6 +36,7 @@
#include "qwindowswindow.h"
#include "qwindowsguieventdispatcher.h"
#include "qwindowsscaling.h"
+#include "qwindowsinputcontext.h"
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
@@ -877,7 +878,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
const int msgType = msg.message;
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
- const quint32 vk_key = msg.wParam;
+ quint32 vk_key = msg.wParam;
quint32 nModifiers = 0;
QWindow *receiver = m_keyGrabber ? m_keyGrabber : window;
@@ -1071,6 +1072,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
// results, if we map this virtual key-code directly (for eg '?' US layouts). So try
// to find the correct key using the current message parameters & keyboard state.
if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
+ if (!QWindowsInputContext::instance()->isComposing())
+ vk_key = ImmGetVirtualKey((HWND)window->winId());
BYTE keyState[256];
wchar_t newKey[3] = {0};
GetKeyboardState(keyState);
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index b1ced95a71..db635b602b 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -42,6 +42,7 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/QWindow>
+#include <QtGui/QCursor>
#include <QtCore/QDebug>
#include <QtCore/QScopedArrayPointer>
@@ -386,6 +387,31 @@ static bool isValidWheelReceiver(QWindow *candidate)
return false;
}
+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.
+
+ QWindow *receiver = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE);
+ bool handleEvent = true;
+ if (!isValidWheelReceiver(receiver)) {
+ receiver = window;
+ if (!isValidWheelReceiver(receiver))
+ handleEvent = false;
+ }
+
+ if (handleEvent) {
+ const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor();
+ QWindowSystemInterface::handleWheelEvent(receiver,
+ posDip, globalPos / QWindowsScaling::factor(),
+ delta / QWindowsScaling::factor(),
+ orientation, mods);
+ }
+}
+
bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND,
MSG msg, LRESULT *)
{
@@ -408,27 +434,40 @@ bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND,
if (msg.message == WM_MOUSEHWHEEL)
delta = -delta;
- // 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.
const QPoint globalPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
- QWindow *receiver = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE);
- bool handleEvent = true;
- if (!isValidWheelReceiver(receiver)) {
- receiver = window;
- if (!isValidWheelReceiver(receiver))
- handleEvent = false;
- }
+ redirectWheelEvent(window, globalPos, delta, orientation, mods);
- if (handleEvent) {
- const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor();
- QWindowSystemInterface::handleWheelEvent(receiver,
- posDip, globalPos / QWindowsScaling::factor(),
- delta / QWindowsScaling::factor(),
- orientation, mods);
+ return true;
+}
+
+bool QWindowsMouseHandler::translateScrollEvent(QWindow *window, HWND,
+ MSG msg, LRESULT *)
+{
+ // This is a workaround against some touchpads that send WM_HSCROLL instead of WM_MOUSEHWHEEL.
+ // We could also handle vertical scroll here but there's no reason to, there's no bug for vertical
+ // (broken vertical scroll would have been noticed long time ago), so lets keep the change small
+ // and minimize the chance for regressions.
+
+ int delta = 0;
+ switch (LOWORD(msg.wParam)) {
+ case SB_LINELEFT:
+ delta = 120;
+ break;
+ case SB_LINERIGHT:
+ delta = -120;
+ break;
+ case SB_PAGELEFT:
+ delta = 240;
+ break;
+ case SB_PAGERIGHT:
+ delta = -240;
+ break;
+ default:
+ return false;
}
+ redirectWheelEvent(window, QCursor::pos(), delta, Qt::Horizontal, Qt::NoModifier);
+
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index 1bd6fa325a..ce3e6b6fc4 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -59,6 +59,8 @@ public:
bool translateTouchEvent(QWindow *widget, HWND hwnd,
QtWindows::WindowsEventType t, MSG msg,
LRESULT *result);
+ bool translateScrollEvent(QWindow *window, HWND hwnd,
+ MSG msg, LRESULT *result);
static inline Qt::MouseButtons keyStateToMouseButtons(int);
static inline Qt::KeyboardModifiers keyStateToModifiers(int);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index b1208d9793..6afa4e6591 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -918,7 +918,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
setFlag(OpenGL_ES2);
}
#endif // QT_NO_OPENGL
- updateDropSite();
+ updateDropSite(window()->isTopLevel());
registerTouchWindow();
setWindowState(aWindow->windowState());
@@ -996,10 +996,10 @@ void QWindowsWindow::destroyWindow()
}
}
-void QWindowsWindow::updateDropSite()
+void QWindowsWindow::updateDropSite(bool topLevel)
{
bool enabled = false;
- if (window()->isTopLevel()) {
+ if (topLevel) {
switch (window()->type()) {
case Qt::Window:
case Qt::Dialog:
@@ -1285,7 +1285,7 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent)
if (wasTopLevel != isTopLevel) {
setDropSiteEnabled(false);
setWindowFlags_sys(window()->flags(), unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
- updateDropSite();
+ updateDropSite(isTopLevel);
}
}
}
@@ -1539,7 +1539,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
m_data.flags = flags;
if (m_data.hwnd) {
m_data = setWindowFlags_sys(flags);
- updateDropSite();
+ updateDropSite(window()->isTopLevel());
}
}
// When switching to a frameless window, geometry
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 0089ad07a0..fff90b4b11 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -276,7 +276,7 @@ private:
void destroyWindow();
inline bool isDropSiteEnabled() const { return m_dropTarget != 0; }
void setDropSiteEnabled(bool enabled);
- void updateDropSite();
+ void updateDropSite(bool topLevel);
void handleGeometryChange();
void handleWindowStateChange(Qt::WindowState state);
inline void destroyIcon();