diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-03-06 00:11:52 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-06 00:11:52 +0100 |
commit | b86106387350f673a20d3b0a2413023f6205169b (patch) | |
tree | 2dfc079f1eecbbf9fde8733430a3a1e2f04d9a42 /src/plugins/platforms/cocoa | |
parent | 88918abddeb323340c4a49dda035898a740373da (diff) | |
parent | 5e8ae03578ecd0538a774505f2f7e2fc626b0ab7 (diff) |
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.mm | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenubar.mm | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenuitem.mm | 5 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoanativeinterface.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoanativeinterface.mm | 7 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaservices.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.h | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 39 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 46 |
10 files changed, 108 insertions, 16 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index a2f6910688..4881dcef71 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -73,7 +73,9 @@ QPaintDevice *QCocoaBackingStore::paintDevice() } #endif - m_qImage = QImage(m_requestedSize * scaleFactor, QImage::Format_ARGB32_Premultiplied); + QImage::Format format = window()->format().hasAlpha() + ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + m_qImage = QImage(m_requestedSize * scaleFactor, format); m_qImage.setDevicePixelRatio(scaleFactor); } return &m_qImage; @@ -92,7 +94,7 @@ void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint m_cgImage = 0; if (!m_qImage.isNull()) { if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(win->handle())) - [cocoaWindow->m_contentView flushBackingStore:this region:region offset:offset]; + [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; } } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index f33d4cb68b..d0fcf93b8c 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -172,13 +172,13 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height windowSize.setHeight(windowRect.height()); } - QPixmap windowPixmap(windowSize); + QPixmap windowPixmap(windowSize * devicePixelRatio()); windowPixmap.fill(Qt::transparent); for (uint i = 0; i < displayCount; ++i) { const CGRect bounds = CGDisplayBounds(displays[i]); - int w = (width < 0 ? bounds.size.width : width); - int h = (height < 0 ? bounds.size.height : height); + int w = (width < 0 ? bounds.size.width : width) * devicePixelRatio(); + int h = (height < 0 ? bounds.size.height : height) * devicePixelRatio(); QRect displayRect = QRect(x, y, w, h); QCFType<CGImageRef> image = CGDisplayCreateImageForRect(displays[i], CGRectMake(displayRect.x(), displayRect.y(), displayRect.width(), displayRect.height())); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index bae52c91b8..c0c8caed05 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -77,8 +77,10 @@ QCocoaMenuBar::~QCocoaMenuBar() [m_nativeMenu release]; static_menubars.removeOne(this); - if (m_window) + if (m_window && m_window->menubar() == this) { m_window->setMenubar(0); + updateMenuBarImmediately(); + } } void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index d78ff73bb6..bdcad6f490 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -315,9 +315,12 @@ NSMenuItem *QCocoaMenuItem::sync() return m_native; } +QT_BEGIN_NAMESPACE +extern QString qt_mac_applicationmenu_string(int type); +QT_END_NAMESPACE + QString QCocoaMenuItem::mergeText() { - extern QString qt_mac_applicationmenu_string(int type); QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); if (m_native == [loader aboutMenuItem]) { return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index 9506f86238..2f79b49534 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -102,6 +102,9 @@ private: // QImage <-> CGImage conversion functions static CGImageRef qImageToCGImage(const QImage &image); static QImage cgImageToQImage(CGImageRef image); + + // Embedding NSViews as child QWindows + static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView); }; #endif // QCOCOANATIVEINTERFACE_H diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index bd3a909137..9990537c1f 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -113,6 +113,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qImageToCGImage); if (resource.toLower() == "cgimagetoqimage") return NativeResourceForIntegrationFunction(QCocoaNativeInterface::cgImageToQImage); + if (resource.toLower() == "setwindowcontentview") + return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView); return 0; } @@ -198,5 +200,10 @@ QImage QCocoaNativeInterface::cgImageToQImage(CGImageRef image) return qt_mac_toQImage(image); } +void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void *contentView) +{ + QCocoaWindow *cocoaPlatformWindow = static_cast<QCocoaWindow *>(window); + cocoaPlatformWindow->setContentView(reinterpret_cast<NSView *>(contentView)); +} QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaservices.mm b/src/plugins/platforms/cocoa/qcocoaservices.mm index dea23e7e53..e4cec8c5f8 100644 --- a/src/plugins/platforms/cocoa/qcocoaservices.mm +++ b/src/plugins/platforms/cocoa/qcocoaservices.mm @@ -55,7 +55,7 @@ bool QCocoaServices::openUrl(const QUrl &url) const QString scheme = url.scheme(); if (scheme.isEmpty()) return openDocument(url); - return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toString())]]; + return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toString(QUrl::FullyEncoded))]]; } bool QCocoaServices::openDocument(const QUrl &url) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 70df7451f7..84dcaad206 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -121,6 +121,7 @@ public: void setParent(const QPlatformWindow *window); NSView *contentView() const; + void setContentView(NSView *contentView); void windowWillMove(); void windowDidMove(); @@ -164,8 +165,11 @@ public: // for QNSView friend class QCocoaBackingStore; friend class QCocoaNativeInterface; - QNSView *m_contentView; + NSView *m_contentView; + QNSView *m_qtView; NSWindow *m_nsWindow; + bool m_contentViewIsEmbedded; // true if the m_contentView is embedded in a "foregin" NSView hiearchy + QNSWindowDelegate *m_nsWindowDelegate; Qt::WindowFlags m_windowFlags; Qt::WindowState m_synchedWindowState; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index fe6a9ad50b..4c58c22644 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -58,6 +58,11 @@ #include <QDebug> +enum { + defaultWindowWidth = 160, + defaultWindowHeight = 160 +}; + static bool isMouseEvent(NSEvent *ev) { switch ([ev type]) { @@ -186,6 +191,7 @@ static bool isMouseEvent(NSEvent *ev) QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) , m_nsWindow(0) + , m_contentViewIsEmbedded(false) , m_nsWindowDelegate(0) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) @@ -200,7 +206,8 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) #endif QCocoaAutoReleasePool pool; - m_contentView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; + m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; + m_contentView = m_qtView; setGeometry(tlw->geometry()); recreateWindow(parent()); @@ -237,6 +244,10 @@ void QCocoaWindow::setGeometry(const QRect &rect) void QCocoaWindow::setCocoaGeometry(const QRect &rect) { QCocoaAutoReleasePool pool; + + if (m_contentViewIsEmbedded) + return; + if (m_nsWindow) { NSRect bounds = qt_mac_flipRect(rect, window()); [m_nsWindow setContentSize : bounds.size]; @@ -538,7 +549,7 @@ void QCocoaWindow::setMask(const QRegion ®ion) if (m_nsWindow) [m_nsWindow setBackgroundColor:[NSColor clearColor]]; - [m_contentView setMaskRegion:®ion]; + [m_qtView setMaskRegion:®ion]; updateOpaque(); } @@ -583,6 +594,19 @@ NSView *QCocoaWindow::contentView() const return m_contentView; } +void QCocoaWindow::setContentView(NSView *contentView) +{ + // Remove and release the previous content view + [m_contentView removeFromSuperview]; + [m_contentView release]; + + // Insert and retain the new content view + [contentView retain]; + m_contentView = contentView; + m_qtView = 0; // The new content view is not a QNSView. + recreateWindow(parent()); // Adds the content view to parent NSView +} + void QCocoaWindow::windowWillMove() { // Close any open popups on window move @@ -595,7 +619,7 @@ void QCocoaWindow::windowWillMove() void QCocoaWindow::windowDidMove() { - [m_contentView updateGeometry]; + [m_qtView updateGeometry]; } void QCocoaWindow::windowDidResize() @@ -603,7 +627,7 @@ void QCocoaWindow::windowDidResize() if (!m_nsWindow) return; - [m_contentView updateGeometry]; + [m_qtView updateGeometry]; } void QCocoaWindow::windowWillClose() @@ -644,7 +668,9 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) m_nsWindowDelegate = 0; } - if (!parentWindow) { + if (window()->type() == Qt::SubWindow) { + // Subwindows don't have a NSWindow. + } else if (!parentWindow) { // Create a new NSWindow if this is a top-level window. m_nsWindow = createNSWindow(); setNSWindow(m_nsWindow); @@ -679,7 +705,8 @@ NSWindow * QCocoaWindow::createNSWindow() { QCocoaAutoReleasePool pool; - NSRect frame = qt_mac_flipRect(window()->geometry(), window()); + QRect rect = initialGeometry(window(), window()->geometry(), defaultWindowWidth, defaultWindowHeight); + NSRect frame = qt_mac_flipRect(rect, window()); Qt::WindowType type = window()->type(); Qt::WindowFlags flags = window()->flags(); diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index a8d8baa942..8f88387966 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -173,6 +173,36 @@ static QTouchDevice *touchDevice = 0; QWindowSystemInterface::handleExposeEvent(m_window, m_window->geometry()); } +- (void)viewDidMoveToSuperview +{ + if (!(m_window->type() & Qt::SubWindow)) + return; + + if ([self superview]) { + m_platformWindow->m_contentViewIsEmbedded = true; + QWindowSystemInterface::handleGeometryChange(m_window, m_platformWindow->geometry()); + QWindowSystemInterface::handleExposeEvent(m_window, m_platformWindow->geometry()); + QWindowSystemInterface::flushWindowSystemEvents(); + } else { + m_platformWindow->m_contentViewIsEmbedded = false; + } +} + +- (void)viewWillMoveToWindow:(NSWindow *)newWindow +{ + // ### Merge "normal" window code path with this one for 5.1. + if (!(m_window->type() & Qt::SubWindow)) + return; + + if (newWindow) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowNotification:) + name:nil // Get all notifications + object:newWindow]; + } else { + [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]]; + } +} - (void)updateGeometry { QRect geometry; @@ -181,6 +211,9 @@ static QTouchDevice *touchDevice = 0; NSRect rect = [self frame]; NSRect windowRect = [[self window] frame]; geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height); + } else if (m_window->type() & Qt::SubWindow) { + // embedded child window, use the frame rect ### merge with case below + geometry = qt_mac_toQRect([self bounds]); } else { // child window, use the frame rect geometry = qt_mac_toQRect([self frame]); @@ -198,6 +231,12 @@ static QTouchDevice *touchDevice = 0; // an infinite loop when this notification is triggered again.) m_platformWindow->QPlatformWindow::setGeometry(geometry); + // Don't send the geometry change if the QWindow is designated to be + // embedded in a foregin view hiearchy but has not actually been + // embedded yet - it's too early. + if ((m_window->type() & Qt::SubWindow) && !m_platformWindow->m_contentViewIsEmbedded) + return; + // Send a geometry change event to Qt, if it's ready to handle events if (!m_platformWindow->m_inConstructor) { QWindowSystemInterface::handleGeometryChange(m_window, geometry); @@ -322,7 +361,12 @@ static QTouchDevice *touchDevice = 0; ); CGImageRef bsCGImage = m_backingStore->getBackingStoreCGImage(); CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect); - CGContextSetBlendMode(cgContext, kCGBlendModeCopy); + + // Optimization: Copy frame buffer content instead of blending for + // top-level windows where Qt fills the entire window content area. + if (m_platformWindow->m_nsWindow) + CGContextSetBlendMode(cgContext, kCGBlendModeCopy); + CGContextDrawImage(cgContext, dirtyWindowRect, cleanImg); // Clean-up: |