summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoawindow.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoawindow.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm116
1 files changed, 93 insertions, 23 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 5c30e7f38b..b5e8ff2246 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -83,13 +83,19 @@
- (BOOL)canBecomeKeyWindow
{
- return NO;
+ // Most panels can be come the key window. Exceptions are:
+ if (m_cocoaPlatformWindow->window()->windowType() == Qt::ToolTip)
+ return NO;
+ if (m_cocoaPlatformWindow->window()->windowType() == Qt::SplashScreen)
+ return NO;
+ return YES;
}
@end
QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw)
+ , m_nsWindow(0)
, m_glContext(0)
, m_inConstructor(true)
{
@@ -98,8 +104,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
m_contentView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this];
setGeometry(tlw->geometry());
- m_nsWindow = createNSWindow();
- setNSWindow(m_nsWindow);
+ recreateWindow(parent());
m_inConstructor = false;
}
@@ -119,10 +124,18 @@ void QCocoaWindow::setGeometry(const QRect &rect)
qDebug() << "QCocoaWindow::setGeometry" << this << rect;
#endif
QPlatformWindow::setGeometry(rect);
+ setCocoaGeometry(rect);
+}
- NSRect bounds = qt_mac_flipRect(rect, window());
- [m_nsWindow setContentSize : bounds.size];
- [m_nsWindow setFrameOrigin : bounds.origin];
+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];
+ } else {
+ [m_contentView setFrame : NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
+ }
}
void QCocoaWindow::setVisible(bool visible)
@@ -151,13 +164,16 @@ void QCocoaWindow::setVisible(bool visible)
// Make sure the QWindow has a frame ready before we show the NSWindow.
QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
- if ([m_nsWindow canBecomeKeyWindow])
- [m_nsWindow makeKeyAndOrderFront:nil];
- else
- [m_nsWindow orderFront: nil];
+ if (m_nsWindow) {
+ if ([m_nsWindow canBecomeKeyWindow])
+ [m_nsWindow makeKeyAndOrderFront:nil];
+ else
+ [m_nsWindow orderFront: nil];
+ }
} else {
// qDebug() << "close" << this;
- [m_nsWindow orderOut:m_nsWindow];
+ if (m_nsWindow)
+ [m_nsWindow orderOut:m_nsWindow];
}
}
@@ -170,6 +186,8 @@ Qt::WindowFlags QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
void QCocoaWindow::setWindowTitle(const QString &title)
{
QCocoaAutoReleasePool pool;
+ if (!m_nsWindow)
+ return;
CFStringRef windowTitle = QCFString::toCFStringRef(title);
[m_nsWindow setTitle: const_cast<NSString *>(reinterpret_cast<const NSString *>(windowTitle))];
@@ -180,17 +198,21 @@ void QCocoaWindow::raise()
{
//qDebug() << "raise" << this;
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
- [m_nsWindow orderFront: m_nsWindow];
+ if (m_nsWindow)
+ [m_nsWindow orderFront: m_nsWindow];
}
void QCocoaWindow::lower()
{
- [m_nsWindow orderBack: m_nsWindow];
+ if (m_nsWindow)
+ [m_nsWindow orderBack: m_nsWindow];
}
void QCocoaWindow::propagateSizeHints()
{
QCocoaAutoReleasePool pool;
+ if (!m_nsWindow)
+ return;
[m_nsWindow setMinSize : qt_mac_toNSSize(window()->minimumSize())];
[m_nsWindow setMaxSize : qt_mac_toNSSize(window()->maximumSize())];
@@ -213,6 +235,9 @@ void QCocoaWindow::propagateSizeHints()
bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
{
+ if (!m_nsWindow)
+ return false;
+
if (grab && ![m_nsWindow isKeyWindow])
[m_nsWindow makeKeyWindow];
else if (!grab && [m_nsWindow isKeyWindow])
@@ -222,6 +247,9 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
bool QCocoaWindow::setMouseGrabEnabled(bool grab)
{
+ if (!m_nsWindow)
+ return false;
+
if (grab && ![m_nsWindow isKeyWindow])
[m_nsWindow makeKeyWindow];
else if (!grab && [m_nsWindow isKeyWindow])
@@ -231,23 +259,19 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab)
WId QCocoaWindow::winId() const
{
- return WId(m_nsWindow);
+ return WId(m_contentView);
}
-void QCocoaWindow::setParent(const QPlatformWindow *window)
+void QCocoaWindow::setParent(const QPlatformWindow *parentWindow)
{
// recreate the window for compatibility
- clearNSWindow(m_nsWindow);
- [m_nsWindow close];
- [m_nsWindow release];
-
- m_nsWindow = createNSWindow();
- setNSWindow(m_nsWindow);
+ recreateWindow(parentWindow);
+ setCocoaGeometry(geometry());
}
NSView *QCocoaWindow::contentView() const
{
- return [m_nsWindow contentView];
+ return m_contentView;
}
void QCocoaWindow::windowWillMove()
@@ -266,6 +290,9 @@ void QCocoaWindow::windowDidMove()
void QCocoaWindow::windowDidResize()
{
+ if (!m_nsWindow)
+ return;
+
NSRect rect = [[m_nsWindow contentView]frame];
// Call setFrameSize which will trigger a frameDidChangeNotification on QNSView.
[[m_nsWindow contentView] setFrameSize:rect.size];
@@ -276,6 +303,15 @@ void QCocoaWindow::windowWillClose()
QWindowSystemInterface::handleSynchronousCloseEvent(window());
}
+bool QCocoaWindow::windowIsPopupType() const
+{
+ Qt::WindowType type = window()->windowType();
+ if (type == Qt::Tool)
+ return false; // Qt::Tool has the Popup bit set but isn't, at least on Mac.
+
+ return ((type & Qt::Popup) == Qt::Popup);
+}
+
void QCocoaWindow::setCurrentContext(QCocoaGLContext *context)
{
m_glContext = context;
@@ -286,6 +322,27 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
return m_glContext;
}
+void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
+{
+ // Remove current window (if any)
+ if (m_nsWindow) {
+ clearNSWindow(m_nsWindow);
+ [m_nsWindow close];
+ [m_nsWindow release];
+ m_nsWindow = 0;
+ }
+
+ if (!parentWindow) {
+ // Create a new NSWindow if this is a top-level window.
+ m_nsWindow = createNSWindow();
+ setNSWindow(m_nsWindow);
+ } else {
+ // Child windows have no NSWindow, link the NSViews instead.
+ const QCocoaWindow *parentCococaWindow = static_cast<const QCocoaWindow *>(parentWindow);
+ [parentCococaWindow->m_contentView addSubview : m_contentView];
+ }
+}
+
NSWindow * QCocoaWindow::createNSWindow()
{
QCocoaAutoReleasePool pool;
@@ -300,7 +357,7 @@ NSWindow * QCocoaWindow::createNSWindow()
// Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen)
if ((type & Qt::Popup) == Qt::Popup) {
- if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::SplashScreen) {
+ if (windowIsPopupType()) {
styleMask = NSBorderlessWindowMask;
} else {
styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask |
@@ -314,6 +371,7 @@ NSWindow * QCocoaWindow::createNSWindow()
defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
// before the window is shown and needs a proper window.).
[window setHasShadow:YES];
+ window->m_cocoaPlatformWindow = this;
createdWindow = window;
} else {
styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
@@ -324,6 +382,15 @@ NSWindow * QCocoaWindow::createNSWindow()
defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
// before the window is shown and needs a proper window.).
window->m_cocoaPlatformWindow = this;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ // All windows with the WindowMaximizeButtonHint set also get a full-screen button.
+ if (flags & Qt::WindowMaximizeButtonHint)
+ [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+ }
+#endif
+
createdWindow = window;
}
return createdWindow;
@@ -378,6 +445,9 @@ void QCocoaWindow::clearNSWindow(NSWindow *window)
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::windowGeometry() const
{
+ if (!m_nsWindow)
+ return geometry();
+
NSRect rect = [m_nsWindow frame];
QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window());
int flippedY = onScreen->geometry().height() - rect.origin.y - rect.size.height; // account for nswindow inverted y.