summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm49
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