diff options
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 16 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaglcontext.mm | 12 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.mm | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenu.mm | 10 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 53 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 32 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnswindowdelegate.h | 2 |
9 files changed, 101 insertions, 28 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 7320fc11e6..95fe9129d3 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -100,11 +100,23 @@ static void cleanupCocoaApplicationDelegate() - (id)init { self = [super init]; - if (self) + if (self) { inLaunch = true; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(updateScreens:) + name:NSApplicationDidChangeScreenParametersNotification + object:NSApp]; + } return self; } +- (void)updateScreens:(NSNotification *)notification +{ + if (QCocoaIntegration *ci = dynamic_cast<QCocoaIntegration *>(QGuiApplicationPrivate::platformIntegration())) + ci->updateScreens(); +} + - (void)dealloc { sharedCocoaApplicationDelegate = nil; @@ -114,6 +126,8 @@ static void cleanupCocoaApplicationDelegate() [NSApp setDelegate:reflectionDelegate]; [reflectionDelegate release]; } + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; } diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index d4673baaef..3dee137038 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -133,18 +133,6 @@ void QCocoaGLContext::setActiveWindow(QWindow *window) cocoaWindow->setCurrentContext(this); [(QNSView *) cocoaWindow->contentView() setQCocoaGLContext:this]; - - // Enable high-dpi OpenGL for retina displays. Enabling has the side - // effect that Cooca will start calling glViewport(0, 0, width, height), - // overriding any glViewport calls in application code. This is usually not a - // problem, except if the applcation wants to have a "custom" viewport. - // (like the hellogl example) -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - if (cocoaWindow->devicePixelRatio() > 1) - [cocoaWindow->contentView() setWantsBestResolutionOpenGLSurface:YES]; - } -#endif } void QCocoaGLContext::doneCurrent() diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 6e690dd51e..7831888da1 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -125,6 +125,7 @@ public: QList<int> possibleKeys(const QKeyEvent *event) const; void updateScreens(); + QCocoaScreen *screenAtIndex(int index) const { return mScreens.at(index); } private: diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 50d68f8311..987520f307 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -352,6 +352,7 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons case BufferQueueingOpenGL: case WindowMasks: case MultipleWindows: + case ForeignWindows: return true; default: return QPlatformIntegration::hasCapability(cap); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 0a98819d16..df0ef390c9 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -98,6 +98,16 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); return self; } + +- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item +{ + Q_UNUSED(menu); + if (item && [item tag]) { + QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]); + cocoaItem->hovered(); + } +} + - (void) menuWillOpen:(NSMenu*)m { Q_UNUSED(m); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5d1600dba6..47341e2262 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -118,7 +118,7 @@ static bool isMouseEvent(NSEvent *ev) // Windows with a transient parent (such as combobox popup windows) // cannot become the main window: - if (m_cocoaPlatformWindow && m_cocoaPlatformWindow->window()->transientParent()) + if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->window()->transientParent()) canBecomeMain = NO; return canBecomeMain; @@ -159,7 +159,8 @@ static bool isMouseEvent(NSEvent *ev) return NO; // Only tool or dialog windows should become key: - if (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog) + if (m_cocoaPlatformWindow + && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog)) return YES; return NO; } @@ -195,6 +196,8 @@ const int QCocoaWindow::NoAlertRequest = -1; QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) + , m_contentView(nil) + , m_qtView(nil) , m_nsWindow(0) , m_contentViewIsEmbedded(false) , m_contentViewIsToBeEmbedded(false) @@ -215,8 +218,23 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) #endif QCocoaAutoReleasePool pool; - m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; - m_contentView = m_qtView; + if (tlw->type() == Qt::ForeignWindow) { + NSView *foreignView = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>()); + setContentView(foreignView); + } else { + m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; + m_contentView = m_qtView; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + // Enable high-dpi OpenGL for retina displays. Enabling has the side + // effect that Cocoa will start calling glViewport(0, 0, width, height), + // overriding any glViewport calls in application code. This is usually not a + // problem, except if the appilcation wants to have a "custom" viewport. + // (like the hellogl example) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 + && tlw->surfaceType() == QSurface::OpenGLSurface) + [m_contentView setWantsBestResolutionOpenGLSurface:YES]; +#endif + } setGeometry(tlw->geometry()); recreateWindow(parent()); tlw->setGeometry(geometry()); @@ -258,8 +276,7 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect) if (m_nsWindow) { NSRect bounds = qt_mac_flipRect(rect, window()); - [m_nsWindow setContentSize : bounds.size]; - [m_nsWindow setFrameOrigin : bounds.origin]; + [m_nsWindow setFrame:[m_nsWindow frameRectForContentRect:bounds] display:YES animate:NO]; } else { [m_contentView setFrame : NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; } @@ -308,6 +325,8 @@ void QCocoaWindow::setVisible(bool visible) exposeWindow(); if (m_nsWindow) { + QWindowSystemInterface::flushWindowSystemEvents(); + // setWindowState might have been called while the window was hidden and // will not change the NSWindow state in that case. Sync up here: syncWindowState(window()->windowState()); @@ -349,11 +368,22 @@ void QCocoaWindow::setVisible(bool visible) QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); cocoaEventDispatcherPrivate->endModalSession(window()); m_hasModalSession = false; + + [m_nsWindow orderOut:m_nsWindow]; + if (m_nsWindow == [NSApp keyWindow] && !cocoaEventDispatcherPrivate->currentModalSession()) { + // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher + // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that + // the current NSWindow is still key after being ordered out. Then, after checking we + // don't have any other modal session left, it's safe to make the main window key again. + NSWindow *mainWindow = [NSApp mainWindow]; + if (mainWindow && [mainWindow canBecomeKeyWindow]) + [mainWindow makeKeyWindow]; + } } else { if ([m_nsWindow isSheet]) [NSApp endSheet:m_nsWindow]; + [m_nsWindow orderOut:m_nsWindow]; } - [m_nsWindow orderOut:m_nsWindow]; } else { [m_contentView setHidden:YES]; } @@ -446,8 +476,6 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) NSInteger level = this->windowLevel(flags); [m_nsWindow setStyleMask:styleMask]; [m_nsWindow setLevel:level]; - [m_nsWindow setIgnoresMouseEvents:((flags & Qt::ToolTip) == Qt::ToolTip) ? YES : NO]; - // TODO deal with WindowTransparentForInput; setIgnoresMouseEvents is too extreme, you can't click the titlebar setWindowShadow(flags); } @@ -784,8 +812,10 @@ NSWindow * QCocoaWindow::createNSWindow() // before the window is shown and needs a proper window.). if ((type & Qt::Popup) == Qt::Popup) [window setHasShadow:YES]; - else + else { setWindowShadow(flags); + [window setHidesOnDeactivate: NO]; + } #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { @@ -987,7 +1017,8 @@ QWindow *QCocoaWindow::childWindowAt(QPoint windowPoint) if (QWindow *childWindow = qobject_cast<QWindow *>(child)) { if (childWindow->geometry().contains(windowPoint)) { QCocoaWindow* platformWindow = static_cast<QCocoaWindow*>(childWindow->handle()); - targetWindow = platformWindow->childWindowAt(windowPoint - childWindow->position()); + if (platformWindow->isExposed()) + targetWindow = platformWindow->childWindowAt(windowPoint - childWindow->position()); } } } diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 67b16b4b32..85f72a4dbb 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -69,6 +69,8 @@ QT_END_NAMESPACE bool m_sendUpAsRightButton; Qt::KeyboardModifiers currentWheelModifiers; bool m_subscribesForGlobalFrameNotifications; + QCocoaGLContext *m_glContext; + bool m_shouldSetGLContextinDrawRect; } - (id)init; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index c114ab20d0..42117a64a1 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -58,6 +58,7 @@ #include <private/qguiapplication_p.h> #include "qcocoabackingstore.h" #include "qcocoaglcontext.h" +#include "qcocoaintegration.h" #ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR #include <accessibilityinspector.h> @@ -85,6 +86,8 @@ static QTouchDevice *touchDevice = 0; m_buttons = Qt::NoButton; m_sendKeyEvent = false; m_subscribesForGlobalFrameNotifications = false; + m_glContext = 0; + m_shouldSetGLContextinDrawRect = false; currentCustomDragTypes = 0; m_sendUpAsRightButton = false; @@ -150,7 +153,13 @@ static QTouchDevice *touchDevice = 0; - (void) setQCocoaGLContext:(QCocoaGLContext *)context { - [context->nsOpenGLContext() setView:self]; + m_glContext = context; + [m_glContext->nsOpenGLContext() setView:self]; + if (![m_glContext->nsOpenGLContext() view]) { + //was unable to set view + m_shouldSetGLContextinDrawRect = true; + } + if (!m_subscribesForGlobalFrameNotifications) { // NSOpenGLContext expects us to repaint (or update) the view when // it changes position on screen. Since this happens unnoticed for @@ -268,6 +277,15 @@ static QTouchDevice *touchDevice = 0; m_platformWindow->obscureWindow(); } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) { m_platformWindow->exposeWindow(); + } else if (notificationName == NSWindowDidChangeScreenNotification) { + if (m_window) { + QCocoaIntegration *ci = static_cast<QCocoaIntegration *>(QGuiApplicationPrivate::platformIntegration()); + NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen]; + if (screenIndex != NSNotFound) { + QCocoaScreen *cocoaScreen = ci->screenAtIndex(screenIndex); + QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen()); + } + } } else { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 @@ -344,6 +362,11 @@ static QTouchDevice *touchDevice = 0; - (void) drawRect:(NSRect)dirtyRect { + if (m_glContext && m_shouldSetGLContextinDrawRect) { + [m_glContext->nsOpenGLContext() setView:self]; + m_shouldSetGLContextinDrawRect = false; + } + if (!m_backingStore) return; @@ -1304,14 +1327,17 @@ static QTouchDevice *touchDevice = 0; QCocoaDropData mimeData([sender draggingPasteboard]); response = QWindowSystemInterface::handleDrop(m_window, &mimeData, qt_windowPoint, qtAllowed); } + if (response.isAccepted()) { + QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag()); + nativeDrag->setAcceptedAction(response.acceptedAction()); + } return response.isAccepted(); } - (void)draggedImage:(NSImage*) img endedAt:(NSPoint) point operation:(NSDragOperation) operation { Q_UNUSED(img); - QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag()); - nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation)); + Q_UNUSED(operation); // keep our state, and QGuiApplication state (buttons member) in-sync, // or future mouse events will be processed incorrectly diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index a5b46a971f..9a616ba8e8 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -55,7 +55,7 @@ - (void)windowDidResize:(NSNotification *)notification; - (void)windowDidMove:(NSNotification *)notification; -- (void)windowWillClose:(NSNotification *)notification; +- (void)windowWillMove:(NSNotification *)notification; - (BOOL)windowShouldClose:(NSNotification *)notification; @end |