diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 49 |
2 files changed, 47 insertions, 6 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 59df75b980..e5f136d0cd 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -43,6 +43,7 @@ #include <AppKit/AppKit.h> #include <QtCore/QPointer> +#include <QtCore/QSet> #include <QtGui/QImage> #include <QtGui/QAccessible> @@ -85,6 +86,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); bool m_exposedOnMoveToWindow; NSEvent *m_currentlyInterpretedKeyEvent; bool m_isMenuView; + QSet<quint32> m_acceptedKeyDowns; } - (id)init; @@ -142,7 +144,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (int) convertKeyCode : (QChar)keyCode; + (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags; -- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType; +- (bool)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType; - (void)keyDown:(NSEvent *)theEvent; - (void)keyUp:(NSEvent *)theEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index ecc9f2db11..fb83f3211a 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -911,6 +911,25 @@ QT_WARNING_POP } } + QPointF qtWindowPoint; + QPointF qtScreenPoint; + [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; + Q_UNUSED(qtScreenPoint); + + bool masked = m_maskRegion.contains(qtWindowPoint.toPoint()); + + // Maintain masked state for the button for use by MouseDragged and Up. + if (masked) + m_acceptedMouseDowns.remove(Qt::LeftButton); + else + m_acceptedMouseDowns.insert(Qt::LeftButton); + + // Forward masked out events to the next responder + if (masked) { + [super mouseDown:theEvent]; + return; + } + if ([self hasMarkedText]) { [[NSTextInputContext currentInputContext] handleEvent:theEvent]; } else { @@ -1483,7 +1502,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) return qtMods; } -- (void)handleKeyEvent:(NSEvent *)nsevent eventType:(int)eventType +- (bool)handleKeyEvent:(NSEvent *)nsevent eventType:(int)eventType { ulong timestamp = [nsevent timestamp] * 1000; ulong nativeModifiers = [nsevent modifierFlags]; @@ -1553,26 +1572,46 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) m_sendKeyEvent = true; } - if (m_sendKeyEvent && m_composingText.isEmpty()) + bool accepted = true; + if (m_sendKeyEvent && m_composingText.isEmpty()) { QWindowSystemInterface::handleExtendedKeyEvent(window, timestamp, QEvent::Type(eventType), keyCode, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1, false); - + accepted = QWindowSystemInterface::flushWindowSystemEvents(); + } m_sendKeyEvent = false; m_resendKeyEvent = false; + return accepted; } - (void)keyDown:(NSEvent *)nsevent { if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super keyDown:nsevent]; - [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)]; + + const bool accepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)]; + + // Track keyDown acceptance state for later acceptance of the keyUp. + if (accepted) + m_acceptedKeyDowns.insert([nsevent keyCode]); + + // Propagate the keyDown to the next responder if Qt did not accept it. + if (!accepted) + [super keyDown:nsevent]; } - (void)keyUp:(NSEvent *)nsevent { if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super keyUp:nsevent]; - [self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)]; + + const bool keyUpAccepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)]; + + // Propagate the keyUp if neither Qt accepted it nor the corresponding KeyDown was + // accepted. Qt text controls wil often not use and ignore keyUp events, but we + // want to avoid propagating unmatched keyUps. + const bool keyDownAccepted = m_acceptedKeyDowns.remove([nsevent keyCode]); + if (!keyUpAccepted && !keyDownAccepted) + [super keyUp:nsevent]; } - (void)cancelOperation:(id)sender |