macOS: Pass on mouse press if input context didn't handle it

We follow the approach of [NSTextView mouseDown:] by bailing out if the
input context handled the event, and otherwise passing it along to the
input item.

This allows moving the cursor with a single click in the input item,
which will also commit the current preedit string as is, depending on
the input context.

For some reason 2-Set Korean input results in plain insertText calls
for each step of the composition with an NSTextView, while we get
marked text. The result is that when composing with 2-Set Korean,
a native NSTextView will only require a single click to move the
cursor, while for us it requires two, since the input context says
it handled the event.

We opt to follow the behavior of NSTextView to bail out if the
input context handled the event, instead of trying to emulate
the observed behavior for 2-Set Korean by always passing the
mouse event on, as the former seems like a safer approach.

This is also in line with the recommendations from Apple:

 https://lists.apple.com/archives/cocoa-dev/2012/May/msg00539.html

Pick-to: 6.2
Change-Id: I372ac62ee3b8b20531cd7cfa2d412a5efea3eb68
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Tor Arne Vestbø 2021-10-14 17:58:50 +02:00
parent 0488fde042
commit 3007050db7

View File

@ -429,7 +429,6 @@ static const QPointingDevice *pointingDeviceFor(qint64 deviceID)
return;
}
bool handleMouseEvent = true;
// FIXME: AppKit doesn't limit itself to passing the event on to the input method
// based on there being marked text or not. It also transfers first responder to
// the view before calling mouseDown, whereas we only transfer focus once the mouse
@ -437,20 +436,25 @@ static const QPointingDevice *pointingDeviceFor(qint64 deviceID)
if ([self hasMarkedText]) {
if (QPlatformInputContext::inputItemClipRectangle().contains(qtWindowPoint)) {
qCDebug(lcQpaInputMethods) << "Asking input context to handle mouse press";
[NSTextInputContext.currentInputContext handleEvent:theEvent];
handleMouseEvent = false;
if ([NSTextInputContext.currentInputContext handleEvent:theEvent]) {
// NSTextView bails out if the input context handled the event,
// which is e.g. the case for 2-Set Korean input. We follow suit,
// even if that means having to click twice to move the cursor
// for these input methods when they are composing.
qCDebug(lcQpaInputMethods) << "Input context handled event; bailing out.";
return;
}
}
}
if (handleMouseEvent) {
if (!m_dontOverrideCtrlLMB && (theEvent.modifierFlags & NSEventModifierFlagControl)) {
m_buttons |= Qt::RightButton;
m_sendUpAsRightButton = true;
} else {
m_buttons |= Qt::LeftButton;
}
[self handleMouseEvent:theEvent];
if (!m_dontOverrideCtrlLMB && (theEvent.modifierFlags & NSEventModifierFlagControl)) {
m_buttons |= Qt::RightButton;
m_sendUpAsRightButton = true;
} else {
m_buttons |= Qt::LeftButton;
}
[self handleMouseEvent:theEvent];
}
- (void)mouseDragged:(NSEvent *)theEvent