summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoaservices.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm39
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm46
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 &region, 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 &region)
if (m_nsWindow)
[m_nsWindow setBackgroundColor:[NSColor clearColor]];
- [m_contentView setMaskRegion:&region];
+ [m_qtView setMaskRegion:&region];
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: