diff options
author | Stephen Kelly <stephen.kelly@kdab.com> | 2013-03-13 23:35:18 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-13 23:35:18 +0100 |
commit | 2a388e503f49cb8e33d023e66e835cea9990df6f (patch) | |
tree | 45cb3b48a41aeb3bf7370ed13bfefa6f9c367206 /src/plugins/platforms | |
parent | 463dac4e00b1dba0f44ab6178f035bcdd0ce4a81 (diff) | |
parent | 72e5124b8517662ca2cd25deb5806bc04d20c022 (diff) |
Merge "Merge remote-tracking branch 'origin/release' into stable" into refs/staging/stable
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 8 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 33 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 32 |
5 files changed, 71 insertions, 10 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 55f94df45a..e756c375f3 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -202,6 +202,14 @@ static void cleanupCocoaApplicationDelegate() if ([self canQuit]) { if (!startedQuit) { startedQuit = true; + // Close open windows. This is done in order to deliver de-expose + // events while the event loop is still running. + const QWindowList topLevels = QGuiApplication::topLevelWindows(); + for (int i = 0; i < topLevels.size(); ++i) { + QWindow *window = topLevels.at(i); + topLevels.at(i)->close(); + } + QGuiApplication::exit(0); startedQuit = false; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 2422788f7a..08c516b4f4 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -108,6 +108,7 @@ public: void setWindowIcon(const QIcon &icon); void raise(); void lower(); + bool isExposed() const; void propagateSizeHints(); void setOpacity(qreal level); void setMask(const QRegion ®ion); @@ -144,6 +145,8 @@ public: QCocoaMenuBar *menubar() const; qreal devicePixelRatio() const; + void exposeWindow(); + void obscureWindow(); protected: // NSWindow handling. The QCocoaWindow/QNSView can either be displayed // in an existing NSWindow or in one created by Qt. @@ -178,6 +181,7 @@ public: // for QNSView bool m_hasModalSession; bool m_frameStrutEventsEnabled; + bool m_isExposed; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 0091028896..30b6d6d84a 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -200,6 +200,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_menubar(0) , m_hasModalSession(false) , m_frameStrutEventsEnabled(false) + , m_isExposed(false) { #ifdef QT_COCOA_ENABLE_WINDOW_DEBUG qDebug() << "QCocoaWindow::QCocoaWindow" << this; @@ -284,9 +285,12 @@ void QCocoaWindow::setVisible(bool visible) } - // Make sure the QWindow has a frame ready before we show the NSWindow. - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - QWindowSystemInterface::flushWindowSystemEvents(); + // This call is here to handle initial window show correctly: + // - top-level windows need to have backing store content ready when the + // window is shown, sendin the expose event here makes that more likely. + // - QNSViews for child windows are initialy not hidden and won't get the + // viewDidUnhide message. + exposeWindow(); if (m_nsWindow) { // setWindowState might have been called while the window was hidden and @@ -338,8 +342,6 @@ void QCocoaWindow::setVisible(bool visible) } else { [m_contentView setHidden:YES]; } - if (!QCoreApplication::closingDown()) - QWindowSystemInterface::handleExposeEvent(window(), QRegion()); } } @@ -489,6 +491,11 @@ void QCocoaWindow::lower() [m_nsWindow orderBack: m_nsWindow]; } +bool QCocoaWindow::isExposed() const +{ + return m_isExposed; +} + void QCocoaWindow::propagateSizeHints() { QCocoaAutoReleasePool pool; @@ -873,6 +880,22 @@ qreal QCocoaWindow::devicePixelRatio() const } } +void QCocoaWindow::exposeWindow() +{ + if (!m_isExposed) { + m_isExposed = true; + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); + } +} + +void QCocoaWindow::obscureWindow() +{ + if (m_isExposed) { + m_isExposed = false; + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); + } +} + QMargins QCocoaWindow::frameMargins() const { NSRect frameW = [m_nsWindow frame]; diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index b4b3379a82..853b4b99e1 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -59,6 +59,7 @@ QT_END_NAMESPACE QPoint m_backingStoreOffset; CGImageRef m_maskImage; uchar *m_maskData; + bool m_shouldInvalidateWindowShadow; QWindow *m_window; QCocoaWindow *m_platformWindow; Qt::MouseButtons m_buttons; @@ -76,9 +77,12 @@ QT_END_NAMESPACE - (void)setQCocoaGLContext:(QCocoaGLContext *)context; - (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset; - (void)setMaskRegion:(const QRegion *)region; +- (void)invalidateWindowShadowIfNeeded; - (void)drawRect:(NSRect)dirtyRect; - (void)updateGeometry; - (void)windowNotification : (NSNotification *) windowNotification; +- (void)viewDidHide; +- (void)viewDidUnhide; - (BOOL)isFlipped; - (BOOL)acceptsFirstResponder; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 02635ea4ec..0c122eaf2d 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -80,6 +80,7 @@ static QTouchDevice *touchDevice = 0; m_backingStore = 0; m_maskImage = 0; m_maskData = 0; + m_shouldInvalidateWindowShadow = false; m_window = 0; m_buttons = Qt::NoButton; m_sendKeyEvent = false; @@ -266,10 +267,10 @@ static QTouchDevice *touchDevice = 0; QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowMinimized); } else if (notificationName == NSWindowDidDeminiaturizeNotification) { QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowNoState); - // Qt expects an expose event after restore/deminiaturize. This also needs - // to be a non-synchronous event to make sure it gets processed after - // the state change event sent above. - QWindowSystemInterface::handleExposeEvent(m_window, QRegion(m_window->geometry())); + } else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) { + m_platformWindow->obscureWindow(); + } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) { + m_platformWindow->exposeWindow(); } else { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 @@ -285,6 +286,16 @@ static QTouchDevice *touchDevice = 0; } } +- (void)viewDidHide +{ + m_platformWindow->obscureWindow(); +} + +- (void)viewDidUnhide +{ + m_platformWindow->exposeWindow(); +} + - (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset { m_backingStore = backingStore; @@ -295,13 +306,14 @@ static QTouchDevice *touchDevice = 0; - (void) setMaskRegion:(const QRegion *)region { + m_shouldInvalidateWindowShadow = true; if (m_maskImage) CGImageRelease(m_maskImage); if (region->isEmpty()) { m_maskImage = 0; } - const QRect &rect = qt_mac_toQRect([self frame]); + const QRect &rect = region->boundingRect(); QImage maskImage(rect.size(), QImage::Format_RGB888); maskImage.fill(Qt::white); QPainter p(&maskImage); @@ -314,6 +326,14 @@ static QTouchDevice *touchDevice = 0; m_maskImage = qt_mac_toCGImage(maskImage, true, &m_maskData); } +- (void)invalidateWindowShadowIfNeeded +{ + if (m_shouldInvalidateWindowShadow && m_platformWindow->m_nsWindow) { + [m_platformWindow->m_nsWindow invalidateShadow]; + m_shouldInvalidateWindowShadow = false; + } +} + - (void) drawRect:(NSRect)dirtyRect { if (!m_backingStore) @@ -368,6 +388,8 @@ static QTouchDevice *touchDevice = 0; CGContextRestoreGState(cgContext); CGImageRelease(cleanImg); CGImageRelease(subMask); + + [self invalidateWindowShadowIfNeeded]; } - (BOOL) isFlipped |