diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoahelpers.h | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoahelpers.mm | 19 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_complextext.mm | 18 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_keys.mm | 29 |
4 files changed, 63 insertions, 9 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 25069bb56d..713b19dad5 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -71,6 +71,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow) Q_DECLARE_LOGGING_CATEGORY(lcQpaDrawing) Q_DECLARE_LOGGING_CATEGORY(lcQpaMouse) +Q_DECLARE_LOGGING_CATEGORY(lcQpaKeys) Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen) Q_DECLARE_LOGGING_CATEGORY(lcQpaApplication) Q_DECLARE_LOGGING_CATEGORY(lcQpaClipboard) @@ -358,6 +359,11 @@ QSendSuperHelper<Args...> qt_objcDynamicSuperHelper(id receiver, SEL selector, A // Same as calling super, but the super_class field resolved at runtime instead of compile time #define qt_objcDynamicSuper(...) qt_objcDynamicSuperHelper(self, _cmd, ##__VA_ARGS__) +// ------------------------------------------------------------------------- + +QDebug operator<<(QDebug, const NSRange &); +QDebug operator<<(QDebug, SEL); + #endif // __OBJC__ #endif //QCOCOAHELPERS_H diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 299c655d14..723cfcb952 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window"); Q_LOGGING_CATEGORY(lcQpaDrawing, "qt.qpa.drawing"); Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse", QtCriticalMsg); +Q_LOGGING_CATEGORY(lcQpaKeys, "qt.qpa.input.keys", QtCriticalMsg); Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen", QtCriticalMsg); Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application"); Q_LOGGING_CATEGORY(lcQpaClipboard, "qt.qpa.clipboard") @@ -508,4 +509,22 @@ void q_IOObjectRelease(io_object_t obj) Q_ASSERT(!ret); } +// ------------------------------------------------------------------------- + +QDebug operator<<(QDebug debug, const NSRange &range) +{ + if (range.location == NSNotFound) { + QDebugStateSaver saver(debug); + debug.nospace() << "{NSNotFound, " << range.length << "}"; + } else { + debug << NSStringFromRange(range); + } + return debug; +} + +QDebug operator<<(QDebug debug, SEL selector) +{ + debug << NSStringFromSelector(selector); + return debug; +} @end diff --git a/src/plugins/platforms/cocoa/qnsview_complextext.mm b/src/plugins/platforms/cocoa/qnsview_complextext.mm index 48cea12a14..fb19270017 100644 --- a/src/plugins/platforms/cocoa/qnsview_complextext.mm +++ b/src/plugins/platforms/cocoa/qnsview_complextext.mm @@ -46,6 +46,9 @@ if (m_composingText.isEmpty()) return; + qCDebug(lcQpaKeys) << "Canceling composition" << m_composingText + << "for focus object" << m_composingFocusObject; + if (m_composingFocusObject) { QInputMethodQueryEvent queryEvent(Qt::ImEnabled); if (QCoreApplication::sendEvent(m_composingFocusObject, &queryEvent)) { @@ -62,6 +65,11 @@ - (void)unmarkText { + // FIXME: Match cancelComposingText in early exit and focus object handling + + qCDebug(lcQpaKeys) << "Unmarking" << m_composingText + << "for focus object" << m_composingFocusObject; + if (!m_composingText.isEmpty()) { if (QObject *fo = m_platformWindow->window()->focusObject()) { QInputMethodQueryEvent queryEvent(Qt::ImEnabled); @@ -85,17 +93,20 @@ - (void)insertNewline:(id)sender { Q_UNUSED(sender); + qCDebug(lcQpaKeys) << "Inserting newline"; m_resendKeyEvent = true; } - (void)doCommandBySelector:(SEL)aSelector { + qCDebug(lcQpaKeys) << "Trying to perform command" << aSelector; [self tryToPerform:aSelector with:self]; } - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { - Q_UNUSED(replacementRange); + qCDebug(lcQpaKeys).nospace() << "Inserting \"" << aString << "\"" + << ", replacing range " << replacementRange; if (m_sendKeyEvent && m_composingText.isEmpty() && [aString isEqualToString:m_inputSource]) { // don't send input method events for simple text input (let handleKeyEvent send key events instead) @@ -129,7 +140,10 @@ - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { - Q_UNUSED(replacementRange); + qCDebug(lcQpaKeys).nospace() << "Marking \"" << aString << "\"" + << " with selected range " << selectedRange + << ", replacing range " << replacementRange; + QString preeditString; QList<QInputMethodEvent::Attribute> attrs; diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm index 57f7fe1fdd..1975ac5f3a 100644 --- a/src/plugins/platforms/cocoa/qnsview_keys.mm +++ b/src/plugins/platforms/cocoa/qnsview_keys.mm @@ -94,15 +94,23 @@ window = popup->window(); } + qCDebug(lcQpaKeys) << "Handling" << nsevent << "as" << Qt::Key(keyCode) + << "with" << modifiers << "and resulting text" << text; + if (eventType == QEvent::KeyPress) { if (m_composingText.isEmpty()) { - m_sendKeyEvent = !QWindowSystemInterface::handleShortcutEvent(window, timestamp, keyCode, - modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1); - - // Handling a shortcut may result in closing the window - if (!m_platformWindow) - return true; + qCDebug(lcQpaKeys) << "Trying potential shortcuts in" << window; + if (QWindowSystemInterface::handleShortcutEvent(window, timestamp, keyCode, modifiers, + nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1)) { + qCDebug(lcQpaKeys) << "Found matching shortcut; will not send as key event"; + m_sendKeyEvent = false; + // Handling a shortcut may result in closing the window + if (!m_platformWindow) + return true; + } else { + qCDebug(lcQpaKeys) << "No matching shortcuts; continuing with key event delivery"; + } } QObject *fo = m_platformWindow->window()->focusObject(); @@ -115,13 +123,16 @@ const bool ignoreHidden = (hints & Qt::ImhHiddenText) && !text.isEmpty() && !m_lastKeyDead; if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || ignoreHidden)) { // pass the key event to the input method. note that m_sendKeyEvent may be set to false during this call + qCDebug(lcQpaKeys) << "Interpreting key event for focus object" << fo; m_currentlyInterpretedKeyEvent = nsevent; [self interpretKeyEvents:@[nsevent]]; // If the receiver opens an editor in response to a key press, then the focus will change, the input // method will be reset, and the first key press will be gone. If the focus object changes, then we // need to pass the key event to the input method once more. - if (qApp->focusObject() != fo) + if (qApp->focusObject() != fo) { + qCDebug(lcQpaKeys) << "Interpreting key event again for new focus object" << qApp->focusObject(); [self interpretKeyEvents:@[nsevent]]; + } m_currentlyInterpretedKeyEvent = 0; // if the last key we sent was dead, then pass the next key to the IM as well to complete composition m_lastKeyDead = text.isEmpty(); @@ -134,6 +145,7 @@ bool accepted = true; if (m_sendKeyEvent && m_composingText.isEmpty()) { + qCDebug(lcQpaKeys) << "Sending as regular key event"; QWindowSystemInterface::handleExtendedKeyEvent(window, timestamp, QEvent::Type(eventType), keyCode, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1, false); accepted = QWindowSystemInterface::flushWindowSystemEvents(); @@ -205,6 +217,9 @@ ulong nativeModifiers = [nsevent modifierFlags]; Qt::KeyboardModifiers modifiers = QAppleKeyMapper::fromCocoaModifiers(nativeModifiers); + qCDebug(lcQpaKeys) << "Flags changed with" << nsevent + << "resulting in" << modifiers; + // 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(). const quint32 nativeScanCode = 0; |