summaryrefslogtreecommitdiffstats
path: root/src/core/web_event_factory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/web_event_factory.cpp')
-rw-r--r--src/core/web_event_factory.cpp339
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