summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-01 10:03:53 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-01 16:25:19 +0200
commita09a8d509a69ed16d8afbe15296b8332cacd6c66 (patch)
tree28645b437fd0390d903f753a44ba79626eecb8ac /src/plugins/platforms/cocoa
parent4b28152da64f7f23a1bbb810d8cdb7626a5f0b8e (diff)
parent83f06da1c6bffff61af78cbe75a0691d53742b53 (diff)
Merge remote-tracking branch 'origin/5.3' into dev
Conflicts: mkspecs/qnx-x86-qcc/qplatformdefs.h src/corelib/global/qglobal.h src/network/socket/qnativesocketengine_winrt.cpp src/plugins/platforms/android/androidjniaccessibility.cpp src/plugins/platforms/windows/qwindowswindow.cpp Manually adjusted: mkspecs/qnx-armle-v7-qcc/qplatformdefs.h to include 9ce697f2d54be6d94381c72af28dda79cbc027d4 Thanks goes to Sergio for the qnx mkspecs adjustments. Change-Id: I53b1fd6bc5bc884e5ee2c2b84975f58171a1cb8e
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm41
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h10
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm70
5 files changed, 108 insertions, 25 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index a2f9f8c984..2f5355b180 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -223,7 +223,14 @@ static void cleanupCocoaApplicationDelegate()
// events while the event loop is still running.
const QWindowList topLevels = QGuiApplication::topLevelWindows();
for (int i = 0; i < topLevels.size(); ++i) {
- QWindowSystemInterface::handleCloseEvent(topLevels.at(i));
+ QWindow *topLevelWindow = topLevels.at(i);
+ // Widgets have alreay received a CloseEvent from the QApplication
+ // QCloseEvent handler. (see canQuit above). Prevent running the
+ // CloseEvent logic twice, call close() directly.
+ if (topLevelWindow->inherits("QWidgetWindow"))
+ topLevelWindow->close();
+ else
+ QWindowSystemInterface::handleCloseEvent(topLevelWindow);
}
QWindowSystemInterface::flushWindowSystemEvents();
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index e7f8992c6d..4328487f63 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -870,6 +870,9 @@ void QCocoaEventDispatcherPrivate::processPostedEvents()
return;
}
+ if (cleanupModalSessionsNeeded && currentExecIsNSAppRun)
+ cleanupModalSessions();
+
if (processEventsCalled > 0 && interrupt) {
if (currentExecIsNSAppRun) {
// The event dispatcher has been interrupted. But since
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index d04dc958e1..4be49ed68f 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -158,23 +158,42 @@ qreal QCocoaScreen::devicePixelRatio() const
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
{
- // Get a z-ordered list of windows. Iterate through it until
- // we find a (Qt) window which contains the point.
- for (NSWindow *nsWindow in [NSApp orderedWindows]) {
- if (![nsWindow isKindOfClass:[QNSWindow class]])
+ NSPoint screenPoint = qt_mac_flipPoint(point);
+
+ // Search (hit test) for the top-level window. [NSWidow windowNumberAtPoint:
+ // belowWindowWithWindowNumber] may return windows that are not interesting
+ // to Qt. The search iterates until a suitable window or no window is found.
+ NSInteger topWindowNumber = 0;
+ QWindow *window = 0;
+ do {
+ // Get the top-most window, below any previously rejected window.
+ topWindowNumber = [NSWindow windowNumberAtPoint:screenPoint
+ belowWindowWithWindowNumber:topWindowNumber];
+
+ // Continue the search if the window does not belong to this process.
+ NSWindow *nsWindow = [NSApp windowWithWindowNumber:topWindowNumber];
+ if (nsWindow == 0)
continue;
- QNSWindow *qnsWindow = static_cast<QNSWindow *>(nsWindow);
- QCocoaWindow *cocoaWindow = qnsWindow.helper.platformWindow;
+
+ // Continue the search if the window does not belong to Qt.
+ if (![nsWindow conformsToProtocol:@protocol(QNSWindowProtocol)])
+ continue;
+
+ id<QNSWindowProtocol> proto = static_cast<id<QNSWindowProtocol> >(nsWindow);
+ QCocoaWindow *cocoaWindow = proto.helper.platformWindow;
if (!cocoaWindow)
continue;
- QWindow *window = cocoaWindow->window();
+ window = cocoaWindow->window();
+
+ // Continue the search if the window is not a top-level window.
if (!window->isTopLevel())
continue;
- if (window->geometry().contains(point))
- return window;
- }
- return QPlatformScreen::topLevelAt(point);
+ // Stop searching. The current window is the correct window.
+ break;
+ } while (topWindowNumber > 0);
+
+ return window;
}
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index a0db46bf4b..53eee4a95d 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -54,6 +54,8 @@ class QCocoaBackingStore;
class QCocoaGLContext;
QT_END_NAMESPACE
+Q_FORWARD_DECLARE_OBJC_CLASS(QNSViewMouseMoveHelper);
+
@interface QNSView : NSView <NSTextInputClient> {
QCocoaBackingStore* m_backingStore;
QPoint m_backingStoreOffset;
@@ -74,6 +76,7 @@ QT_END_NAMESPACE
bool m_shouldSetGLContextinDrawRect;
#endif
NSString *m_inputSource;
+ QNSViewMouseMoveHelper *m_mouseMoveHelper;
}
- (id)init;
@@ -106,9 +109,10 @@ QT_END_NAMESPACE
- (void)mouseDown:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent *)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
-- (void)mouseMoved:(NSEvent *)theEvent;
-- (void)mouseEntered:(NSEvent *)theEvent;
-- (void)mouseExited:(NSEvent *)theEvent;
+- (void)mouseMovedImpl:(NSEvent *)theEvent;
+- (void)mouseEnteredImpl:(NSEvent *)theEvent;
+- (void)mouseExitedImpl:(NSEvent *)theEvent;
+- (void)cursorUpdateImpl:(NSEvent *)theEvent;
- (void)rightMouseDown:(NSEvent *)theEvent;
- (void)rightMouseDragged:(NSEvent *)theEvent;
- (void)rightMouseUp:(NSEvent *)theEvent;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index b023edf271..4a562f8a4e 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -77,6 +77,53 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
- (CGFloat)deviceDeltaZ;
@end
+@interface QNSViewMouseMoveHelper : NSObject
+{
+ QNSView *view;
+}
+
+- (id)initWithView:(QNSView *)theView;
+
+- (void)mouseMoved:(NSEvent *)theEvent;
+- (void)mouseEntered:(NSEvent *)theEvent;
+- (void)mouseExited:(NSEvent *)theEvent;
+- (void)cursorUpdate:(NSEvent *)theEvent;
+
+@end
+
+@implementation QNSViewMouseMoveHelper
+
+- (id)initWithView:(QNSView *)theView
+{
+ self = [super init];
+ if (self) {
+ view = theView;
+ }
+ return self;
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ [view mouseMovedImpl:theEvent];
+}
+
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ [view mouseEnteredImpl:theEvent];
+}
+
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ [view mouseExitedImpl:theEvent];
+}
+
+- (void)cursorUpdate:(NSEvent *)theEvent
+{
+ [view cursorUpdateImpl:theEvent];
+}
+
+@end
+
@implementation QNSView
+ (void)initialize
@@ -104,6 +151,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
currentCustomDragTypes = 0;
m_sendUpAsRightButton = false;
m_inputSource = 0;
+ m_mouseMoveHelper = [[QNSViewMouseMoveHelper alloc] initWithView:self];
if (!touchDevice) {
touchDevice = new QTouchDevice;
@@ -123,6 +171,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_subscribesForGlobalFrameNotifications = false;
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ [m_mouseMoveHelper release];
delete currentCustomDragTypes;
@@ -761,13 +810,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame]
options:trackingOptions
- owner:self
+ owner:m_mouseMoveHelper
userInfo:nil]
autorelease];
[self addTrackingArea:ta];
}
--(void)cursorUpdate:(NSEvent *)theEvent
+-(void)cursorUpdateImpl:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
// Set the cursor manually if there is no NSWindow.
@@ -784,10 +833,10 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
[self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor];
}
-- (void)mouseMoved:(NSEvent *)theEvent
+- (void)mouseMovedImpl:(NSEvent *)theEvent
{
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseMoved:theEvent];
+ return;
QPointF windowPoint;
QPointF screenPoint;
@@ -814,12 +863,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
[self handleMouseEvent: theEvent];
}
-- (void)mouseEntered:(NSEvent *)theEvent
+- (void)mouseEnteredImpl:(NSEvent *)theEvent
{
+ Q_UNUSED(theEvent)
m_platformWindow->m_windowUnderMouse = true;
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseEntered:theEvent];
+ return;
// Top-level windows generate enter events for sub-windows.
if (!m_platformWindow->m_nsWindow)
@@ -832,13 +882,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
}
-- (void)mouseExited:(NSEvent *)theEvent
+- (void)mouseExitedImpl:(NSEvent *)theEvent
{
+ Q_UNUSED(theEvent);
m_platformWindow->m_windowUnderMouse = false;
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseExited:theEvent];
- Q_UNUSED(theEvent);
+ return;
// Top-level windows generate leave events for sub-windows.
if (!m_platformWindow->m_nsWindow)
@@ -1324,7 +1374,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QChar ch = QChar::ReplacementCharacter;
int keyCode = Qt::Key_unknown;
if ([characters length] != 0) {
- if ((modifiers & Qt::MetaModifier) && ([charactersIgnoringModifiers length] != 0))
+ if (((modifiers & Qt::MetaModifier) || (modifiers & Qt::AltModifier)) && ([charactersIgnoringModifiers length] != 0))
ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
else
ch = QChar([characters characterAtIndex:0]);