diff options
Diffstat (limited to 'src/core/web_event_factory.cpp')
-rw-r--r-- | src/core/web_event_factory.cpp | 339 |
1 files changed, 238 insertions, 101 deletions
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 1b0723cb5..617eea2d0 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only /* * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> @@ -71,6 +35,9 @@ #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/keyboard_code_conversion.h" +#include "native_web_keyboard_event_qt.h" +#include "render_widget_host_view_qt_delegate.h" + #include <QtGui/private/qtgui-config_p.h> #include <QCoreApplication> @@ -80,10 +47,12 @@ #include <QMouseEvent> #include <QStyleHints> #if QT_CONFIG(tabletevent) -#include <QTabletEvent> +#include <QPointingDevice> #endif #include <QWheelEvent> +namespace QtWebEngineCore { + using namespace blink; enum class KeyboardDriver { Unknown, Windows, Cocoa, Xkb, Evdev }; @@ -157,8 +126,11 @@ static Qt::KeyboardModifiers qtModifiersForEvent(const QInputEvent *ev) // // On Linux, the Control modifier transformation is applied [1]. For example, // pressing Ctrl+@ generates the text "\u0000". We would like "@" instead. +// Windows also translates some control key combinations into ASCII control +// characters [2]. // // [1]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier +// [2]: https://docs.microsoft.com/en-us/windows/win32/learnwin32/keyboard-input#character-messages // // On macOS, if the Control modifier is used, then no text is generated at all. // We need some text. @@ -171,8 +143,15 @@ static QString qtTextForKeyEvent(const QKeyEvent *ev, int qtKey, Qt::KeyboardMod { QString text = ev->text(); - if ((qtModifiers & Qt::ControlModifier) && keyboardDriver() == KeyboardDriver::Xkb) + if (keyboardDriver() == KeyboardDriver::Xkb && (qtModifiers & Qt::ControlModifier)) { text.clear(); + } + + // Keep text for Ctrl+Alt key combinations on Windows. It is an alternative for AltGr. + if (keyboardDriver() == KeyboardDriver::Windows + && (qtModifiers & Qt::ControlModifier) && !(qtModifiers & Qt::AltModifier)) { + text.clear(); + } return text; } @@ -191,10 +170,20 @@ static quint32 nativeKeyCodeForKeyEvent(const QKeyEvent *ev) // Cygwin/X, etc). Also evdev key codes are *not* supported for the same // reason. #if defined(Q_OS_WINDOWS) - return keyboardDriver() == KeyboardDriver::Windows ? ev->nativeScanCode() : 0; + if (keyboardDriver() == KeyboardDriver::Windows) { + // see GetScanCodeFromLParam in events_win_utils.cc: + quint32 scancode = ev->nativeScanCode() & 0xff; + if (ev->nativeScanCode() & 0x100) + scancode |= 0xe000; + return scancode; + } + return 0; #elif defined(Q_OS_MACOS) return keyboardDriver() == KeyboardDriver::Cocoa ? ev->nativeVirtualKey() : 0; #elif defined(Q_OS_LINUX) + // Do not set native code to menu key if it was mapped to something else. + if (ev->nativeScanCode() == 135 && ev->key() != Qt::Key_Menu) + return 0; return keyboardDriver() == KeyboardDriver::Xkb ? ev->nativeScanCode() : 0; #else return 0; // 0 means unknown, KeyboardEvent.code will be empty string. @@ -570,6 +559,8 @@ static int windowsKeyCodeForQtKey(int qtKey, bool isKeypad) case Qt::Key_QuoteDbl: return VK_OEM_7; // case '\'': case '"': return 0xDE; // VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard. + case Qt::Key_AltGr: + return 0xE1; // (E1) VK_OEM_AX = ui::VKEY_ALTGR see ui/events/keycodes/keyboard_codes_win.h // VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard case Qt::Key_AudioRewind: @@ -926,7 +917,6 @@ static ui::DomKey domKeyForQtKey(int qtKey) return ui::DomKey::ZENKAKU; case Qt::Key_Zenkaku_Hankaku: return ui::DomKey::ZENKAKU_HANKAKU; - // Dead keys (ui/events/keycodes/keyboard_code_conversion_xkb.cc) case Qt::Key_Dead_Grave: return ui::DomKey::DeadKeyFromCombiningCharacter(0x0300); @@ -994,7 +984,6 @@ static ui::DomKey domKeyForQtKey(int qtKey) return ui::DomKey::DeadKeyFromCombiningCharacter(0x00A4); case Qt::Key_Dead_Greek: return ui::DomKey::DeadKeyFromCombiningCharacter(0x037E); - // General-Purpose Function Keys case Qt::Key_F1: return ui::DomKey::F1; @@ -1213,8 +1202,12 @@ static WebMouseEvent::Button mouseButtonForEvent(T *event) return WebMouseEvent::Button::kLeft; else if (event->button() == Qt::RightButton) return WebMouseEvent::Button::kRight; - else if (event->button() == Qt::MidButton) + else if (event->button() == Qt::MiddleButton) return WebMouseEvent::Button::kMiddle; + else if (event->button() == Qt::BackButton) + return WebMouseEvent::Button::kBack; + else if (event->button() == Qt::ForwardButton) + return WebMouseEvent::Button::kForward; if (event->type() != QEvent::MouseMove && event->type() != QEvent::TabletMove) return WebMouseEvent::Button::kNoButton; @@ -1225,8 +1218,12 @@ static WebMouseEvent::Button mouseButtonForEvent(T *event) return WebMouseEvent::Button::kLeft; else if (event->buttons() & Qt::RightButton) return WebMouseEvent::Button::kRight; - else if (event->buttons() & Qt::MidButton) + else if (event->buttons() & Qt::MiddleButton) return WebMouseEvent::Button::kMiddle; + else if (event->buttons() & Qt::BackButton) + return WebMouseEvent::Button::kBack; + else if (event->buttons() & Qt::ForwardButton) + return WebMouseEvent::Button::kForward; return WebMouseEvent::Button::kNoButton; } @@ -1239,11 +1236,38 @@ static unsigned mouseButtonsModifiersForEvent(const T* event) ret |= WebInputEvent::kLeftButtonDown; if (event->buttons() & Qt::RightButton) ret |= WebInputEvent::kRightButtonDown; - if (event->buttons() & Qt::MidButton) + if (event->buttons() & Qt::MiddleButton) ret |= WebInputEvent::kMiddleButtonDown; + if (event->buttons() & Qt::BackButton) + ret |= WebInputEvent::kBackButtonDown; + if (event->buttons() & Qt::ForwardButton) + ret |= WebInputEvent::kForwardButtonDown; return ret; } +static WebInputEvent::Modifiers lockKeyModifiers(const quint32 nativeModifiers) +{ + unsigned result = 0; + if (keyboardDriver() == KeyboardDriver::Xkb) { + if (nativeModifiers & 0x42) /* Caps_Lock */ + result |= WebInputEvent::kCapsLockOn; + if (nativeModifiers & 0x4d) /* Num_Lock */ + result |= WebInputEvent::kNumLockOn; + } else if (keyboardDriver() == KeyboardDriver::Windows) { + if (nativeModifiers & 0x100) /* CapsLock */ + result |= WebInputEvent::kCapsLockOn; + if (nativeModifiers & 0x200) /* NumLock */ + result |= WebInputEvent::kNumLockOn; + if (nativeModifiers & 0x400) /* ScrollLock */ + result |= WebInputEvent::kScrollLockOn; + } else if (keyboardDriver() == KeyboardDriver::Cocoa) { + if (nativeModifiers & 0x10000) /* NSEventModifierFlagCapsLock */ + result |= WebInputEvent::kCapsLockOn; + } + + return static_cast<WebInputEvent::Modifiers>(result); +} + // If only a modifier key is pressed, Qt only reports the key code. // But Chromium also expects the modifier being set. static inline WebInputEvent::Modifiers modifierForKeyCode(int key) @@ -1292,12 +1316,54 @@ static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* even if (keyEvent->isAutoRepeat()) result |= WebInputEvent::kIsAutoRepeat; result |= modifierForKeyCode(qtKeyForKeyEvent(keyEvent)); + result |= lockKeyModifiers(keyEvent->nativeModifiers()); + break; } default: break; } - return (WebInputEvent::Modifiers)result; + return static_cast<WebInputEvent::Modifiers>(result); +} + +static inline Qt::KeyboardModifiers keyboardModifiersForModifier(unsigned int modifier) +{ + Qt::KeyboardModifiers modifiers = {}; + if (modifier & WebInputEvent::kControlKey) + modifiers |= Qt::ControlModifier; + if (modifier & WebInputEvent::kMetaKey) + modifiers |= Qt::MetaModifier; + if (modifier & WebInputEvent::kShiftKey) + modifiers |= Qt::ShiftModifier; + if (modifier & WebInputEvent::kAltKey) + modifiers |= Qt::AltModifier; + if (modifier & WebInputEvent::kIsKeyPad) + modifiers |= Qt::KeypadModifier; + + if (keyboardDriver() == KeyboardDriver::Cocoa && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + bool controlModifier = modifiers.testFlag(Qt::ControlModifier); + bool metaModifier = modifiers.testFlag(Qt::MetaModifier); + modifiers.setFlag(Qt::ControlModifier, metaModifier); + modifiers.setFlag(Qt::MetaModifier, controlModifier); + } + + return modifiers; +} + +static inline Qt::MouseButtons mouseButtonsForModifier(unsigned int modifier) +{ + Qt::MouseButtons buttons = {}; + if (modifier & WebInputEvent::kLeftButtonDown) + buttons |= Qt::LeftButton; + if (modifier & WebInputEvent::kRightButtonDown) + buttons |= Qt::RightButton; + if (modifier & WebInputEvent::kMiddleButtonDown) + buttons |= Qt::MiddleButton; + if (modifier & WebInputEvent::kBackButtonDown) + buttons |= Qt::BackButton; + if (modifier & WebInputEvent::kForwardButtonDown) + buttons |= Qt::ForwardButton; + return buttons; } static WebInputEvent::Type webEventTypeForEvent(const QEvent* event) @@ -1305,36 +1371,36 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event) switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::TabletPress: - return WebInputEvent::kMouseDown; + return WebInputEvent::Type::kMouseDown; case QEvent::MouseButtonRelease: case QEvent::TabletRelease: - return WebInputEvent::kMouseUp; + return WebInputEvent::Type::kMouseUp; case QEvent::Enter: - return WebInputEvent::kMouseEnter; + return WebInputEvent::Type::kMouseEnter; case QEvent::Leave: - return WebInputEvent::kMouseLeave; + return WebInputEvent::Type::kMouseLeave; case QEvent::MouseMove: case QEvent::TabletMove: - return WebInputEvent::kMouseMove; + return WebInputEvent::Type::kMouseMove; case QEvent::Wheel: - return WebInputEvent::kMouseWheel; + return WebInputEvent::Type::kMouseWheel; case QEvent::KeyPress: - return WebInputEvent::kRawKeyDown; + return WebInputEvent::Type::kRawKeyDown; case QEvent::KeyRelease: - return WebInputEvent::kKeyUp; + return WebInputEvent::Type::kKeyUp; case QEvent::HoverMove: - return WebInputEvent::kMouseMove; + return WebInputEvent::Type::kMouseMove; case QEvent::TouchBegin: - return WebInputEvent::kTouchStart; + return WebInputEvent::Type::kTouchStart; case QEvent::TouchUpdate: - return WebInputEvent::kTouchMove; + return WebInputEvent::Type::kTouchMove; case QEvent::TouchEnd: - return WebInputEvent::kTouchEnd; + return WebInputEvent::Type::kTouchEnd; case QEvent::TouchCancel: - return WebInputEvent::kTouchCancel; + return WebInputEvent::Type::kTouchCancel; default: Q_ASSERT(false); - return WebInputEvent::kMouseMove; + return WebInputEvent::Type::kMouseMove; } } @@ -1342,12 +1408,14 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event) static WebPointerProperties::PointerType pointerTypeForTabletEvent(const QTabletEvent *ev) { switch (ev->pointerType()) { - case QTabletEvent::UnknownPointer: + case QPointingDevice::PointerType::Unknown: return WebPointerProperties::PointerType::kUnknown; - case QTabletEvent::Pen: + case QPointingDevice::PointerType::Pen: return WebPointerProperties::PointerType::kPen; - case QTabletEvent::Eraser: + case QPointingDevice::PointerType::Eraser: return WebPointerProperties::PointerType::kEraser; + case QPointingDevice::PointerType::Finger: + return WebPointerProperties::PointerType::kTouch; default: return WebPointerProperties::PointerType::kMouse; } @@ -1357,8 +1425,8 @@ static WebPointerProperties::PointerType pointerTypeForTabletEvent(const QTablet WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev) { WebMouseEvent webKitEvent(webEventTypeForEvent(ev), - WebFloatPoint(ev->x(), ev->y()), - WebFloatPoint(ev->globalX(), ev->globalY()), + gfx::PointF(ev->position().x(), ev->position().y()), + gfx::PointF(ev->globalPosition().x(), ev->globalPosition().y()), mouseButtonForEvent<QMouseEvent>(ev), 0, modifiersForEvent(ev), @@ -1376,9 +1444,11 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev) webKitEvent.SetModifiers(modifiersForEvent(ev)); webKitEvent.SetType(webEventTypeForEvent(ev)); - webKitEvent.SetPositionInWidget(ev->pos().x(), ev->pos().y()); - webKitEvent.movement_x = ev->pos().x() - ev->oldPos().x(); - webKitEvent.movement_y = ev->pos().y() - ev->oldPos().y(); + webKitEvent.SetPositionInWidget(ev->position().x(), ev->position().y()); + webKitEvent.SetPositionInScreen(ev->globalPosition().x(), ev->globalPosition().y()); + webKitEvent.movement_x = ev->position().x() - ev->oldPos().x(); + webKitEvent.movement_y = ev->position().y() - ev->oldPos().y(); + webKitEvent.is_raw_movement_event = true; webKitEvent.pointer_type = WebPointerProperties::PointerType::kMouse; return webKitEvent; @@ -1388,8 +1458,8 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev) WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev) { WebMouseEvent webKitEvent(webEventTypeForEvent(ev), - WebFloatPoint(ev->x(), ev->y()), - WebFloatPoint(ev->globalX(), ev->globalY()), + gfx::PointF(ev->position().x(), ev->position().y()), + gfx::PointF(ev->globalPosition().x(), ev->globalPosition().y()), mouseButtonForEvent<QTabletEvent>(ev), 0, modifiersForEvent(ev), @@ -1411,42 +1481,48 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev) WebMouseEvent webKitEvent; webKitEvent.SetTimeStamp(base::TimeTicks::Now()); - webKitEvent.SetType(WebInputEvent::kMouseLeave); + webKitEvent.SetType(WebInputEvent::Type::kMouseLeave); return webKitEvent; } -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev) { WebGestureEvent webKitEvent; webKitEvent.SetTimeStamp(base::TimeTicks::Now()); webKitEvent.SetModifiers(modifiersForEvent(ev)); - webKitEvent.SetPositionInWidget(WebFloatPoint(ev->localPos().x(), - ev->localPos().y())); + webKitEvent.SetPositionInWidget(gfx::PointF(ev->position().x(), + ev->position().y())); - webKitEvent.SetPositionInScreen(WebFloatPoint(ev->screenPos().x(), - ev->screenPos().y())); + webKitEvent.SetPositionInScreen(gfx::PointF(ev->globalPosition().x(), + ev->globalPosition().y())); webKitEvent.SetSourceDevice(blink::WebGestureDevice::kTouchpad); Qt::NativeGestureType gestureType = ev->gestureType(); switch (gestureType) { case Qt::ZoomNativeGesture: - webKitEvent.SetType(WebInputEvent::kGesturePinchUpdate); + webKitEvent.SetType(WebInputEvent::Type::kGesturePinchUpdate); webKitEvent.data.pinch_update.scale = static_cast<float>(ev->value() + 1.0); break; case Qt::SmartZoomNativeGesture: - webKitEvent.SetType(WebInputEvent::kGestureDoubleTap); + webKitEvent.SetType(WebInputEvent::Type::kGestureDoubleTap); webKitEvent.data.tap.tap_count = 1; break; case Qt::BeginNativeGesture: + webKitEvent.SetType(WebInputEvent::Type::kGesturePinchBegin); + webKitEvent.SetNeedsWheelEvent(true); + break; case Qt::EndNativeGesture: + webKitEvent.SetType(WebInputEvent::Type::kGesturePinchEnd); + webKitEvent.SetNeedsWheelEvent(true); + break; case Qt::RotateNativeGesture: case Qt::PanNativeGesture: case Qt::SwipeNativeGesture: // Not implemented by Chromium for now. - webKitEvent.SetType(blink::WebInputEvent::kUndefined); + webKitEvent.SetType(blink::WebInputEvent::Type::kUndefined); break; } @@ -1465,16 +1541,23 @@ static void setBlinkWheelEventDelta(blink::WebMouseWheelEvent &webEvent) webEvent.delta_y = webEvent.wheel_ticks_y * wheelScrollLines * cDefaultQtScrollStep; } +static QPoint getWheelEventDelta(const blink::WebGestureEvent &webEvent) +{ + static const float cDefaultQtScrollStep = 20.f; + static const int wheelScrollLines = QGuiApplication::styleHints()->wheelScrollLines(); + static const float deltasPerStep = static_cast<float>(QWheelEvent::DefaultDeltasPerStep); + return QPoint(webEvent.data.scroll_update.delta_x * deltasPerStep / (wheelScrollLines * cDefaultQtScrollStep), + webEvent.data.scroll_update.delta_y * deltasPerStep / (wheelScrollLines * cDefaultQtScrollStep)); +} + blink::WebMouseWheelEvent::Phase toBlinkPhase(QWheelEvent *ev) { switch (ev->phase()) { case Qt::NoScrollPhase: -#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) case Qt::ScrollMomentum: -#endif return blink::WebMouseWheelEvent::kPhaseNone; case Qt::ScrollBegin: - return ev->angleDelta().isNull() ? blink::WebMouseWheelEvent::kPhaseMayBegin : blink::WebMouseWheelEvent::kPhaseBegan; + return blink::WebMouseWheelEvent::kPhaseBegan; case Qt::ScrollUpdate: return blink::WebMouseWheelEvent::kPhaseChanged; case Qt::ScrollEnd: @@ -1484,21 +1567,41 @@ blink::WebMouseWheelEvent::Phase toBlinkPhase(QWheelEvent *ev) return blink::WebMouseWheelEvent::kPhaseNone; } +blink::WebMouseWheelEvent::Phase getMomentumPhase(QWheelEvent *ev) +{ + switch (ev->phase()) { + case Qt::ScrollMomentum: + return blink::WebMouseWheelEvent::kPhaseBegan; + case Qt::ScrollEnd: + return blink::WebMouseWheelEvent::kPhaseEnded; + case Qt::NoScrollPhase: + case Qt::ScrollBegin: + case Qt::ScrollUpdate: + return blink::WebMouseWheelEvent::kPhaseNone; + } + Q_UNREACHABLE(); + return blink::WebMouseWheelEvent::kPhaseNone; +} + blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev) { WebMouseWheelEvent webEvent; webEvent.SetType(webEventTypeForEvent(ev)); webEvent.SetModifiers(modifiersForEvent(ev)); webEvent.SetTimeStamp(base::TimeTicks::Now()); - webEvent.SetPositionInWidget(ev->x(), ev->y()); - webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); + webEvent.SetPositionInWidget(static_cast<float>(ev->position().x()), + static_cast<float>(ev->position().y())); + webEvent.SetPositionInScreen(static_cast<float>(ev->globalPosition().x()), + static_cast<float>(ev->globalPosition().y())); - webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; - webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_x = ev->angleDelta().x() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep); + webEvent.wheel_ticks_y = ev->angleDelta().y() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep); webEvent.phase = toBlinkPhase(ev); #if defined(Q_OS_DARWIN) - // has_precise_scrolling_deltas is a macOS term meaning it is a system scroll gesture, see qnsview_mouse.mm - webEvent.has_precise_scrolling_deltas = (ev->source() == Qt::MouseEventSynthesizedBySystem); + // PrecisePixel is a macOS term meaning it is a system scroll gesture, see qnsview_mouse.mm + webEvent.momentum_phase = getMomentumPhase(ev); + if (ev->source() == Qt::MouseEventSynthesizedBySystem) + webEvent.delta_units = ui::ScrollGranularity::kScrollByPrecisePixel; #endif setBlinkWheelEventDelta(webEvent); @@ -1515,30 +1618,60 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent, if (toBlinkPhase(ev) != webEvent.phase) return false; #if defined(Q_OS_DARWIN) - if (webEvent.has_precise_scrolling_deltas != (ev->source() == Qt::MouseEventSynthesizedBySystem)) + if (getMomentumPhase(ev) != webEvent.momentum_phase) + return false; + + if ((webEvent.delta_units == ui::ScrollGranularity::kScrollByPrecisePixel) + != (ev->source() == Qt::MouseEventSynthesizedBySystem)) return false; #endif webEvent.SetTimeStamp(base::TimeTicks::Now()); - webEvent.SetPositionInWidget(ev->x(), ev->y()); - webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); + webEvent.SetPositionInWidget(static_cast<float>(ev->position().x()), + static_cast<float>(ev->position().y())); + webEvent.SetPositionInScreen(static_cast<float>(ev->globalPosition().x()), + static_cast<float>(ev->globalPosition().y())); - webEvent.wheel_ticks_x += static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; - webEvent.wheel_ticks_y += static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_x = ev->angleDelta().x() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep); + webEvent.wheel_ticks_y = ev->angleDelta().y() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep); setBlinkWheelEventDelta(webEvent); return true; } +static QPointF toQt(gfx::PointF p) +{ + return QPointF(p.x(), p.y()); +} + +void WebEventFactory::sendUnhandledWheelEvent(const blink::WebGestureEvent &event, + RenderWidgetHostViewQtDelegate *delegate) +{ + Q_ASSERT(event.GetType() == blink::WebInputEvent::Type::kGestureScrollUpdate); + + QWheelEvent ev(toQt(event.PositionInWidget()), + toQt(event.PositionInScreen()), + QPoint(event.data.scroll_update.delta_x, event.data.scroll_update.delta_y), + getWheelEventDelta(event), + mouseButtonsForModifier(event.GetModifiers()), + keyboardModifiersForModifier(event.GetModifiers()), + Qt::NoScrollPhase, false); + delegate->unhandledWheelEvent(&ev); +} + content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *ev) { - content::NativeWebKeyboardEvent webKitEvent(reinterpret_cast<gfx::NativeEvent>(ev)); + content::NativeWebKeyboardEvent webKitEvent(ToNativeEvent(ev)); webKitEvent.SetTimeStamp(base::TimeTicks::Now()); - webKitEvent.SetModifiers(modifiersForEvent(ev)); + bool isBackTabWithoutModifier = + ev->key() == Qt::Key_Backtab && ev->modifiers() == Qt::NoModifier; + webKitEvent.SetModifiers(isBackTabWithoutModifier ? WebInputEvent::kShiftKey + : modifiersForEvent(ev)); webKitEvent.SetType(webEventTypeForEvent(ev)); int qtKey = qtKeyForKeyEvent(ev); - Qt::KeyboardModifiers qtModifiers = qtModifiersForEvent(ev); + Qt::KeyboardModifiers qtModifiers = + isBackTabWithoutModifier ? Qt::ShiftModifier : qtModifiersForEvent(ev); QString qtText = qtTextForKeyEvent(ev, qtKey, qtModifiers); webKitEvent.native_key_code = nativeKeyCodeForKeyEvent(ev); @@ -1573,10 +1706,12 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e ui::DomCodeToUsLayoutKeyboardCode(static_cast<ui::DomCode>(webKitEvent.dom_code)); const ushort* text = qtText.utf16(); - size_t textSize = std::min(sizeof(webKitEvent.text), size_t(qtText.length() * 2)); - memcpy(&webKitEvent.text, text, textSize); - memcpy(&webKitEvent.unmodified_text, text, textSize); - + size_t size = std::char_traits<char16_t>::length((char16_t *)text); + if (size <= blink::WebKeyboardEvent::kTextLengthCap - 1) { // should be null terminated + size_t textSize = std::min(sizeof(webKitEvent.text), size * sizeof(char16_t)); + memcpy(&webKitEvent.text, text, textSize); + memcpy(&webKitEvent.unmodified_text, text, textSize); + } if (webKitEvent.windows_key_code == VK_RETURN) { // This is the same behavior as GTK: // We need to treat the enter key as a key press of character \r. This @@ -1664,3 +1799,5 @@ bool WebEventFactory::getEditCommand(QKeyEvent *event, std::string *editCommand) return false; } + +} // namespace QtWebEngineCore |