26 const char16_t unicode =
text.
at(0).unicode();
27 if (unicode >= 0xF700 && unicode <= 0xF8FF)
37 qCDebug(lcQpaKeys) <<
"Trying potential shortcuts in" <<
window
38 <<
"for" << shortcutEvent;
40 if (shortcutEvent.sendWindowSystemEvent(
window)) {
41 qCDebug(lcQpaKeys) <<
"Found matching shortcut; will not send as key event";
44 qCDebug(lcQpaKeys) <<
"No matching shortcuts; continuing with key event delivery";
48@implementation QNSView (Keys)
50- (bool)performKeyEquivalent:(NSEvent *)nsevent
55 const bool ctrlDown = [nsevent modifierFlags] & NSEventModifierFlagControl;
56 const bool isTabKey = nsevent.keyCode == kVK_Tab;
63- (bool)handleKeyEvent:(NSEvent *)nsevent
65 qCDebug(lcQpaKeys) <<
"Handling" << nsevent;
78 bool didInterpretKeyEvent =
false;
87 QObject *focusObject = m_platformWindow ? m_platformWindow->window()->focusObject() :
nullptr;
90 auto hints =
static_cast<Qt::InputMethodHints
>(queryResult.value(
Qt::ImHints).toUInt());
93 const bool isDeadKey = !nsevent.characters.length;
111 if (!(nsevent.modifierFlags & (NSEventModifierFlagCommand | NSEventModifierFlagControl)))
112 [NSCursor setHiddenUntilMouseMoves:YES];
114 qCDebug(lcQpaKeys) <<
"Interpreting key event for focus object" << focusObject;
116 if (![
self.inputContext handleEvent:nsevent]) {
117 qCDebug(lcQpaKeys) <<
"Input context did not consume event";
121 didInterpretKeyEvent =
true;
132 bool accepted =
true;
138 qCDebug(lcQpaKeys) <<
"Sending as" << keyEvent;
139 accepted = keyEvent.sendWindowSystemEvent(
window);
144- (
void)keyDown:(NSEvent *)nsevent
146 if ([self isTransparentForUserInput])
147 return [
super keyDown:nsevent];
149 const bool accepted = [
self handleKeyEvent:nsevent];
159 if (!shouldPropagate)
163 [
super keyDown:nsevent];
166- (
void)keyUp:(NSEvent *)nsevent
168 if ([self isTransparentForUserInput])
169 return [
super keyUp:nsevent];
171 const bool keyUpAccepted = [
self handleKeyEvent:nsevent];
177 if (!keyUpAccepted && !keyDownAccepted)
178 [
super keyUp:nsevent];
181- (
void)cancelOperation:(
id)sender
185 NSEvent *currentEvent = NSApp.currentEvent;
186 if (!currentEvent || currentEvent.type != NSEventTypeKeyDown)
199 [
self handleKeyEvent:currentEvent];
202- (
void)flagsChanged:(NSEvent *)nsevent
207 qCDebug(lcQpaKeys) <<
"Flags changed resulting in" << keyEvent.modifiers;
210 static NSEventModifierFlags m_lastKnownModifiers;
211 NSEventModifierFlags lastKnownModifiers = m_lastKnownModifiers;
212 NSEventModifierFlags newModifiers = lastKnownModifiers ^ keyEvent.nativeModifiers;
213 m_lastKnownModifiers = keyEvent.nativeModifiers;
215 static constexpr std::tuple<NSEventModifierFlags, Qt::Key> modifierMap[] = {
223 for (
auto [macModifier,
qtKey] : modifierMap) {
224 if (!(newModifiers & macModifier))
236 modifierEvent.
type = lastKnownModifiers & macModifier
239 modifierEvent.key =
qtKey;
242 modifierEvent.modifiers ^= QAppleKeyMapper::fromCocoaModifiers(macModifier);
243 modifierEvent.nativeModifiers ^= macModifier;
248 qCDebug(lcQpaKeys) <<
"Sending" << modifierEvent;
249 modifierEvent.sendWindowSystemEvent(
window);
259 timestamp = nsevent.timestamp * 1000;
260 nativeModifiers = nsevent.modifierFlags;
261 modifiers = QAppleKeyMapper::fromCocoaModifiers(nativeModifiers);
263 switch (nsevent.type) {
269 switch (nsevent.type) {
270 case NSEventTypeKeyDown:
271 case NSEventTypeKeyUp:
272 case NSEventTypeFlagsChanged:
273 nativeVirtualKey = nsevent.keyCode;
278 if (nsevent.type == NSEventTypeKeyDown || nsevent.type == NSEventTypeKeyUp) {
279 NSString *charactersIgnoringModifiers = nsevent.charactersIgnoringModifiers;
282 QChar character = QChar::ReplacementCharacter;
289 if (
characters.length || charactersIgnoringModifiers.length) {
290 if (nativeModifiers & (NSEventModifierFlagControl | NSEventModifierFlagOption)
291 && charactersIgnoringModifiers.length)
292 character =
QChar([charactersIgnoringModifiers characterAtIndex:0]);
295 key = QAppleKeyMapper::fromCocoaKey(character);
300 isRepeat = nsevent.ARepeat;
309 key,
modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
314 static const int count = 1;
330 debug.nospace().verbosity(0) <<
"KeyEvent("
331 << e.
type <<
", timestamp=" << e.timestamp
333 <<
", text="<< e.
text <<
", isRepeat=" << e.isRepeat
334 <<
", nativeVirtualKey=" << e.nativeVirtualKey
335 <<
", nativeModifiers=" << e.nativeModifiers
static bool testAttribute(Qt::ApplicationAttribute attribute)
Returns true if attribute attribute is set; otherwise returns false.
bool remove(const T &value)
iterator insert(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
qsizetype length() const noexcept
Returns the number of characters in this string.
static bool flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Make Qt Gui process all events on the event queue immediately.
static bool handleExtendedKeyEvent(QWindow *window, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
static bool handleShortcutEvent(QWindow *window, ulong timestamp, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
EGLImageKHR int int EGLuint64KHR * modifiers
@ ImhFormattedNumbersOnly
@ AA_MacDontSwapCtrlAndMeta
InputMethodQueryResult queryInputMethod(QObject *object, Qt::InputMethodQueries queries)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
#define qCDebug(category,...)
NSEvent * m_currentlyInterpretedKeyEvent
QSet< quint32 > m_acceptedKeyDowns
bool m_sendKeyEventWithoutText
static bool sendAsShortcut(const KeyEvent &keyEvent, QWindow *window)
static bool isSpecialKey(const QString &text)
GLenum GLenum GLsizei count
static QString qtKey(CFStringRef cfkey)
QList< QChar > characters
KeyEvent(EventType type, emscripten::val webEvent)
QFlags< Qt::KeyboardModifier > modifiers