summaryrefslogtreecommitdiffstats
path: root/src/core/native_web_keyboard_event_qt_mac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/native_web_keyboard_event_qt_mac.mm')
-rw-r--r--src/core/native_web_keyboard_event_qt_mac.mm155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/core/native_web_keyboard_event_qt_mac.mm b/src/core/native_web_keyboard_event_qt_mac.mm
new file mode 100644
index 000000000..0f5b12db4
--- /dev/null
+++ b/src/core/native_web_keyboard_event_qt_mac.mm
@@ -0,0 +1,155 @@
+// Copyright (C) 2023 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 2011 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE.Chromium file.
+
+// This is a workaround to be able to include Qt headers without
+// "redefinition of 'NSString' as different kind of symbol" errors.
+// TODO: Remove this when namespace ambiguity issues are fixed properly,
+// see get_forward_declaration_macro() in cmake/Functions.cmake
+#undef Q_FORWARD_DECLARE_OBJC_CLASS
+
+#include "native_web_keyboard_event_qt.h"
+
+#include <AppKit/AppKit.h>
+
+#include "base/apple/owned_objc.h"
+
+#include <QtGui/QKeyEvent>
+#include <QtGui/private/qapplekeymapper_p.h>
+
+namespace QtWebEngineCore {
+
+base::apple::OwnedNSEvent ToNativeEvent(QKeyEvent *keyEvent)
+{
+ NSEventType type;
+ switch (keyEvent->type()) {
+ case QEvent::KeyPress:
+ type = NSEventTypeKeyDown;
+ break;
+ case QEvent::KeyRelease:
+ type = NSEventTypeKeyUp;
+ break;
+ default:
+ Q_UNREACHABLE();
+ return base::apple::OwnedNSEvent();
+ }
+
+ NSString *text = keyEvent->text().toNSString();
+ if (text.length == 0) {
+ Qt::Key key = static_cast<Qt::Key>(keyEvent->key());
+ QChar cocoaKey = QAppleKeyMapper::toCocoaKey(key);
+ text = QStringView(&cocoaKey, 1).toNSString();
+ }
+
+ return base::apple::OwnedNSEvent([NSEvent
+ keyEventWithType:type
+ location:NSZeroPoint
+ modifierFlags:QAppleKeyMapper::toCocoaModifiers(keyEvent->modifiers())
+ timestamp:keyEvent->timestamp() / 1000
+ windowNumber:0
+ context:nil
+ characters:text
+ charactersIgnoringModifiers:text
+ isARepeat:keyEvent->isAutoRepeat()
+ keyCode:keyEvent->nativeVirtualKey()
+ ]);
+}
+
+// Based on qtbase/src/plugins/platforms/cocoa/qnsview_keys.mm (KeyEvent::KeyEvent())
+QKeyEvent *ToKeyEvent(base::apple::OwnedNSEvent event)
+{
+ NSEvent *nsevent = event.Get();
+
+ QEvent::Type type = QEvent::None;
+ switch (nsevent.type) {
+ case NSEventTypeKeyDown:
+ type = QEvent::KeyPress;
+ break;
+ case NSEventTypeKeyUp:
+ type = QEvent::KeyRelease;
+ break;
+ default:
+ Q_UNREACHABLE();
+ return nullptr;
+ }
+
+ // Scan codes are hardware dependent codes for each key. There is no way to get these
+ // from Carbon or Cocoa, so leave it 0, as documented in QKeyEvent::nativeScanCode().
+ quint32 nativeScanCode = 0;
+ quint32 nativeVirtualKey = nsevent.keyCode;
+
+ NSEventModifierFlags nativeModifiers = nsevent.modifierFlags;
+ Qt::KeyboardModifiers modifiers = QAppleKeyMapper::fromCocoaModifiers(nativeModifiers);
+
+ NSString *charactersIgnoringModifiers = nsevent.charactersIgnoringModifiers;
+ NSString *characters = nsevent.characters;
+
+ // If a dead key occurs as a result of pressing a key combination then
+ // characters will have 0 length, but charactersIgnoringModifiers will
+ // have a valid character in it. This enables key combinations such as
+ // ALT+E to be used as a shortcut with an English keyboard even though
+ // pressing ALT+E will give a dead key while doing normal text input.
+ Qt::Key key = Qt::Key_unknown;
+ if (characters.length || charactersIgnoringModifiers.length) {
+ QChar character = QChar::ReplacementCharacter;
+ if (nativeModifiers & (NSEventModifierFlagControl | NSEventModifierFlagOption)
+ && charactersIgnoringModifiers.length)
+ character = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+ else if (characters.length)
+ character = QChar([characters characterAtIndex:0]);
+ key = QAppleKeyMapper::fromCocoaKey(character);
+ }
+
+ QString text = QString::fromNSString(characters);
+ bool autorep = nsevent.ARepeat;
+
+ return new QKeyEvent(type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
+ text, autorep);
+}
+
+} // namespace QtWebEngineCore
+
+namespace content {
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(const blink::WebKeyboardEvent &web_event, gfx::NativeView)
+ : blink::WebKeyboardEvent(web_event)
+ , skip_if_unhandled(false)
+{
+}
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type type, int modifiers,
+ base::TimeTicks timestamp)
+ : blink::WebKeyboardEvent(type, modifiers, timestamp)
+ , skip_if_unhandled(false)
+{
+}
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
+ : os_event(native_event) // FIXME: Copy?
+ , skip_if_unhandled(false)
+{
+}
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent& other)
+ : blink::WebKeyboardEvent(other)
+ , os_event(other.os_event) // FIXME: Copy?
+ , skip_if_unhandled(other.skip_if_unhandled)
+{
+}
+
+NativeWebKeyboardEvent &NativeWebKeyboardEvent::operator=(const NativeWebKeyboardEvent &other)
+{
+ blink::WebKeyboardEvent::operator=(other);
+
+ os_event = other.os_event; // FIXME: Copy?
+ skip_if_unhandled = other.skip_if_unhandled;
+
+ return *this;
+}
+
+NativeWebKeyboardEvent::~NativeWebKeyboardEvent() = default;
+
+} // namespace content