diff options
Diffstat (limited to 'src/plugins/platforms/windows')
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(); |