summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2013-03-13 23:35:18 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-13 23:35:18 +0100
commit2a388e503f49cb8e33d023e66e835cea9990df6f (patch)
tree45cb3b48a41aeb3bf7370ed13bfefa6f9c367206 /src/plugins/platforms
parent463dac4e00b1dba0f44ab6178f035bcdd0ce4a81 (diff)
parent72e5124b8517662ca2cd25deb5806bc04d20c022 (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.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm33
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm32
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 &region);
@@ -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