iOS: send arrow keys to Qt to handle cursor movement
Controlling cursor position through input methods in Qt is very limited. You cannot e.g move the cursor vertically, or select text that spans several paragraphs. The reason for the latter is that Qt works with input methods on a per-paragraph basis, which effectively locks UIKit to only being able to move the cursor and select text within a single paragraph. Fixing up input methods to support more advanced navigation means changing the whole design (working on a whole document, instead of per paragraph), and is out of scope. Instead we choose to listen for arrow keys and forward them to Qt in the same fashing as we already do for backspace and enter. This will make the iOS port on-par with the other platforms, which also sends control characters like these on the side of IM events. Note that registering shortcuts and overriding default IM navigation behavior will only take effect when a hardware keyboard is connected. Only then will [UIresponder keyCommands] be called from UIKit. Change-Id: I634205e0578447c4aa6e9fdff342ee3b281901ea Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
This commit is contained in:
parent
06be9f026f
commit
82538aebe4
@ -328,6 +328,8 @@
|
||||
QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyRelease, key, modifiers);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_SHORTCUT
|
||||
|
||||
- (void)cut:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
@ -360,6 +362,69 @@
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
- (void)keyCommandTriggered:(UIKeyCommand *)keyCommand
|
||||
{
|
||||
Qt::Key key = Qt::Key_unknown;
|
||||
Qt::KeyboardModifiers modifiers = Qt::NoModifier;
|
||||
|
||||
if (keyCommand.input == UIKeyInputLeftArrow)
|
||||
key = Qt::Key_Left;
|
||||
else if (keyCommand.input == UIKeyInputRightArrow)
|
||||
key = Qt::Key_Right;
|
||||
else if (keyCommand.input == UIKeyInputUpArrow)
|
||||
key = Qt::Key_Up;
|
||||
else if (keyCommand.input == UIKeyInputDownArrow)
|
||||
key = Qt::Key_Down;
|
||||
else
|
||||
Q_UNREACHABLE();
|
||||
|
||||
if (keyCommand.modifierFlags & UIKeyModifierAlternate)
|
||||
modifiers |= Qt::AltModifier;
|
||||
if (keyCommand.modifierFlags & UIKeyModifierShift)
|
||||
modifiers |= Qt::ShiftModifier;
|
||||
if (keyCommand.modifierFlags & UIKeyModifierCommand)
|
||||
modifiers |= Qt::ControlModifier;
|
||||
|
||||
[self sendKeyPressRelease:key modifiers:modifiers];
|
||||
}
|
||||
|
||||
- (void)addKeyCommandsToArray:(NSMutableArray *)array key:(NSString *)key
|
||||
{
|
||||
SEL s = @selector(keyCommandTriggered:);
|
||||
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:0 action:s]];
|
||||
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierShift action:s]];
|
||||
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierAlternate action:s]];
|
||||
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierAlternate|UIKeyModifierShift action:s]];
|
||||
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierCommand action:s]];
|
||||
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierCommand|UIKeyModifierShift action:s]];
|
||||
}
|
||||
|
||||
- (NSArray *)keyCommands
|
||||
{
|
||||
// Since keyCommands is called for every key
|
||||
// press/release, we cache the result
|
||||
static dispatch_once_t once;
|
||||
static NSMutableArray *array;
|
||||
|
||||
dispatch_once(&once, ^{
|
||||
// We let Qt move the cursor around when the arrow keys are being used. This
|
||||
// is normally implemented through UITextInput, but since IM in Qt have poor
|
||||
// support for moving the cursor vertically, and even less support for selecting
|
||||
// text across multiple paragraphs, we do this through key events.
|
||||
array = [NSMutableArray new];
|
||||
[self addKeyCommandsToArray:array key:UIKeyInputUpArrow];
|
||||
[self addKeyCommandsToArray:array key:UIKeyInputDownArrow];
|
||||
[self addKeyCommandsToArray:array key:UIKeyInputLeftArrow];
|
||||
[self addKeyCommandsToArray:array key:UIKeyInputRightArrow];
|
||||
});
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
#endif // QT_NO_SHORTCUT
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
- (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties
|
||||
{
|
||||
// As documented, we should not report textWillChange/textDidChange unless the text
|
||||
|
@ -107,6 +107,8 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const
|
||||
switch (hint) {
|
||||
case QPlatformTheme::StyleNames:
|
||||
return QStringList(QStringLiteral("fusion"));
|
||||
case KeyboardScheme:
|
||||
return QVariant(int(MacKeyboardScheme));
|
||||
default:
|
||||
return QPlatformTheme::themeHint(hint);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user