From f7e4987966205154fcbd819df31aef2dcece5397 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 22 Sep 2022 12:56:56 +0200 Subject: [PATCH] iOS: send control keys to Qt, even if IM is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perhaps dating as far back as 829e421ddcd5e8f (Qt 5.8), using the arrow keys on a bluetooth keyboard to navigate the cursor around in a TextArea/QTextEdit has been broken. Some work was done to remedy this with 15576c9610 (Qt 6.1) it seems, but still, using the arrow keys is broken in 5.15, 6.2 and dev. This patch will ensure that we send control key events, such as Qt::Key_Up and Qt::Key_Down, to Qt, also when the focus object accepts Input Methods. Fixes: QTBUG-101339 Pick-to: 6.4 6.2 5.15 Change-Id: I2d12438a822a607646080ab2edb17de8ea6d337c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/quiview.mm | 53 ++++++++++++++++------------ 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 63dfab674c..bb6d51355f 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -615,13 +615,33 @@ inline ulong getTimeStamp(UIEvent *event) return Qt::Key_unknown; } -- (bool)processPresses:(NSSet *)presses withType:(QEvent::Type)type { +- (bool)isControlKey:(Qt::Key)key +{ + switch (key) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Left: + case Qt::Key_Right: + return true; + default: + break; + } + + return false; +} + +- (bool)handlePresses:(NSSet *)presses eventType:(QEvent::Type)type +{ // Presses on Menu button will generate a Menu key event. By default, not handling // this event will cause the application to return to Headboard (tvOS launcher). // When handling the event (for example, as a back button), both press and // release events must be handled accordingly. + if (!qApp->focusWindow()) + return false; + + bool eventHandled = false; + const bool imEnabled = QIOSInputContext::instance()->inputMethodAccepted(); - bool handled = false; for (UIPress* press in presses) { Qt::KeyboardModifiers qtModifiers = Qt::NoModifier; if (@available(ios 13.4, *)) @@ -630,26 +650,15 @@ inline ulong getTimeStamp(UIEvent *event) int key = [self mapPressTypeToKey:press withModifiers:qtModifiers text:text]; if (key == Qt::Key_unknown) continue; - if (QWindowSystemInterface::handleKeyEvent(self.platformWindow->window(), type, key, - qtModifiers, text)) { - handled = true; - } + if (imEnabled && ![self isControlKey:Qt::Key(key)]) + continue; + + bool keyHandled = QWindowSystemInterface::handleKeyEvent( + self.platformWindow->window(), type, key, qtModifiers, text); + eventHandled = eventHandled || keyHandled; } - return handled; -} - -- (BOOL)handlePresses:(NSSet *)presses eventType:(QEvent::Type)type -{ - bool handlePress = false; - if (qApp->focusWindow()) { - QInputMethodQueryEvent queryEvent(Qt::ImEnabled); - if (qApp->focusObject() && QCoreApplication::sendEvent(qApp->focusObject(), &queryEvent)) - handlePress = queryEvent.value(Qt::ImEnabled).toBool(); - if (!handlePress && [self processPresses:presses withType:type]) - return true; - } - return false; + return eventHandled; } - (void)pressesBegan:(NSSet *)presses withEvent:(UIPressesEvent *)event @@ -661,14 +670,14 @@ inline ulong getTimeStamp(UIEvent *event) - (void)pressesChanged:(NSSet *)presses withEvent:(UIPressesEvent *)event { if (![self handlePresses:presses eventType:QEvent::KeyPress]) - [super pressesBegan:presses withEvent:event]; + [super pressesChanged:presses withEvent:event]; [super pressesChanged:presses withEvent:event]; } - (void)pressesEnded:(NSSet *)presses withEvent:(UIPressesEvent *)event { if (![self handlePresses:presses eventType:QEvent::KeyRelease]) - [super pressesBegan:presses withEvent:event]; + [super pressesEnded:presses withEvent:event]; [super pressesEnded:presses withEvent:event]; }