macOS: Send text input and key events to focus object of window, not app

The key events and input method callbacks coming from Cocoa are targeted
at our specific NSView, so we should deliver them to the focus object of
the corresponding QWindow, not the global application focus object.

This means that we'll deliver key events to windows also when they are
not key (active), but this is intentional, as we would otherwise fail
to deliver input method events coming from e.g. the emoji/symbol picker,
which steals the key window when active.

Task-number: QTBUG-61359
Change-Id: I61326c08ad8bbd0c535b3cc8a67d0ceeec7ee910
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Tor Arne Vestbø 2017-06-12 17:58:41 +02:00
parent 3851a8ff20
commit 198b67d14b

View File

@ -1544,7 +1544,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1);
}
QObject *fo = QGuiApplication::focusObject();
QObject *fo = m_platformWindow->window()->focusObject();
if (m_sendKeyEvent && fo) {
QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
if (QCoreApplication::sendEvent(fo, &queryEvent)) {
@ -1694,8 +1694,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
commitString = QString::fromCFString(reinterpret_cast<CFStringRef>(aString));
};
}
QObject *fo = QGuiApplication::focusObject();
if (fo) {
if (QObject *fo = m_platformWindow->window()->focusObject()) {
QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
if (QCoreApplication::sendEvent(fo, &queryEvent)) {
if (queryEvent.value(Qt::ImEnabled).toBool()) {
@ -1762,8 +1761,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
m_composingText = preeditString;
QObject *fo = QGuiApplication::focusObject();
if (fo) {
if (QObject *fo = m_platformWindow->window()->focusObject()) {
QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
if (QCoreApplication::sendEvent(fo, &queryEvent)) {
if (queryEvent.value(Qt::ImEnabled).toBool()) {
@ -1779,8 +1777,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (void) unmarkText
{
if (!m_composingText.isEmpty()) {
QObject *fo = QGuiApplication::focusObject();
if (fo) {
if (QObject *fo = m_platformWindow->window()->focusObject()) {
QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
if (QCoreApplication::sendEvent(fo, &queryEvent)) {
if (queryEvent.value(Qt::ImEnabled).toBool()) {
@ -1802,7 +1799,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (NSAttributedString *) attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
{
Q_UNUSED(actualRange)
QObject *fo = QGuiApplication::focusObject();
QObject *fo = m_platformWindow->window()->focusObject();
if (!fo)
return nil;
QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection);
@ -1837,7 +1834,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
{
NSRange selectedRange = {0, 0};
QObject *fo = QGuiApplication::focusObject();
QObject *fo = m_platformWindow->window()->focusObject();
if (!fo)
return selectedRange;
QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection);
@ -1859,7 +1856,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
{
Q_UNUSED(aRange)
Q_UNUSED(actualRange)
QObject *fo = QGuiApplication::focusObject();
QObject *fo = m_platformWindow->window()->focusObject();
if (!fo)
return NSZeroRect;
@ -1899,7 +1896,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (m_platformWindow->window() != QGuiApplication::focusWindow())
return nil;
QObject *fo = QGuiApplication::focusObject();
QObject *fo = m_platformWindow->window()->focusObject();
if (!fo)
return nil;