From: Morten Sorvig Date: Fri, 1 Jul 2011 12:22:16 +0000 (+0200) Subject: Cocoa: Window type and flags handling. X-Git-Tag: qt-v5.0.0-alpha1~3626^2~283 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9252742ba8dda41aa12d29198422cf59f1628fb3;p=profile%2Fivi%2Fqtbase.git Cocoa: Window type and flags handling. Bring over code from Qt4's qwidget_mac.mm. --- diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 9ce449a..dc7907d 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -73,11 +73,16 @@ public: void setCurrentContext(QCocoaGLContext *context); QCocoaGLContext *currentContext() const; +protected: + void determineWindowClass(); + NSWindow *createWindow(); private: friend class QCocoaBackingStore; NSWindow *m_nsWindow; QNSView *m_contentView; NSView *m_windowSurfaceView; + quint32 m_windowAttributes; + quint32 m_windowClass; QCocoaGLContext *m_glContext; }; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 984e616..550c429 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -44,9 +44,12 @@ #include "qcocoaglcontext.h" #include "qnsview.h" #include - +#include #include +#include +#include + #include QCocoaWindow::QCocoaWindow(QWindow *tlw) @@ -54,13 +57,9 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_glContext(0) { QCocoaAutoReleasePool pool; - const QRect geo = tlw->geometry(); - NSRect frame = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height()); - m_nsWindow = [[NSWindow alloc] initWithContentRect:frame - styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask - backing:NSBackingStoreBuffered - defer:YES]; + determineWindowClass(); + m_nsWindow = createWindow(); QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this]; [m_nsWindow setDelegate:delegate]; @@ -70,6 +69,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) m_contentView = [[QNSView alloc] initWithQWindow:tlw]; if (tlw->surfaceType() == QWindow::OpenGLSurface) { + const QRect geo = window()->geometry(); NSRect glFrame = NSMakeRect(0, 0, geo.width(), geo.height()); m_windowSurfaceView = [[NSOpenGLView alloc] initWithFrame : glFrame pixelFormat : QCocoaGLContext::createNSOpenGLPixelFormat() ]; [m_contentView setAutoresizesSubviews : YES]; @@ -168,3 +168,166 @@ QCocoaGLContext *QCocoaWindow::currentContext() const return m_glContext; } +/* + Determine the window class based on the window type and + window flags, and widget attr Sets m_windowAttributes + and m_windowClass. +*/ +void QCocoaWindow::determineWindowClass() +{ + Qt::WindowType type = window()->windowType(); + Qt::WindowFlags flags = window()->windowFlags(); + + const bool popup = (type == Qt::Popup); + + if (type == Qt::ToolTip || type == Qt::SplashScreen || popup) + flags |= Qt::FramelessWindowHint; + + m_windowClass = kSheetWindowClass; + + if (popup || type == Qt::SplashScreen) + m_windowClass = kModalWindowClass; + else if (type == Qt::ToolTip) + m_windowClass = kHelpWindowClass; + else if (type == Qt::Tool) + m_windowClass = kFloatingWindowClass; + else + m_windowClass = kDocumentWindowClass; + + m_windowAttributes = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute); + +// if(qt_mac_is_macsheet(window())) { +// m_windowClass = kSheetWindowClass; +// } else + + { + // Shift things around a bit to get the correct window class based on the presence + // (or lack) of the border. + + bool customize = flags & Qt::CustomizeWindowHint; + bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint))); + if (framelessWindow) { + if (m_windowClass == kDocumentWindowClass) { + m_windowAttributes |= kWindowNoTitleBarAttribute; + } else if (m_windowClass == kFloatingWindowClass) { + m_windowAttributes |= kWindowNoTitleBarAttribute; + } else if (m_windowClass == kMovableModalWindowClass) { + m_windowClass = kModalWindowClass; + } + } else { + m_windowAttributes |= NSTitledWindowMask; + if (m_windowClass != kModalWindowClass) + m_windowAttributes |= NSResizableWindowMask; + } + + // Only add extra decorations (well, buttons) for widgets that can have them + // and have an actual border we can put them on. + + if(m_windowClass != kModalWindowClass && m_windowClass != kMovableModalWindowClass + && m_windowClass != kSheetWindowClass && m_windowClass != kPlainWindowClass + && !framelessWindow && m_windowClass != kDrawerWindowClass + && m_windowClass != kHelpWindowClass) { + if (flags & Qt::WindowMinimizeButtonHint) + m_windowAttributes |= NSMiniaturizableWindowMask; + if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint) + m_windowAttributes |= NSClosableWindowMask; + } else { + // Clear these hints so that we aren't call them on invalid windows + flags &= ~(Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint + | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint); + } + + } + + if((popup || type == Qt::Tool) && !window()->isModal()) + m_windowAttributes |= kWindowHideOnSuspendAttribute; + m_windowAttributes |= kWindowLiveResizeAttribute; +} + +/* + +*/ +NSWindow * QCocoaWindow::createWindow() +{ + // Determine if we need to add in our "custom window" attribute. Cocoa is rather clever + // in deciding if we need the maximize button or not (i.e., it's resizeable, so you + // must need a maximize button). So, the only buttons we have control over are the + // close and minimize buttons. If someone wants to customize and NOT have the maximize + // button, then we have to do our hack. We only do it for these cases because otherwise + // the window looks different when activated. This "QtMacCustomizeWindow" attribute is + // intruding on a public space and WILL BREAK in the future. + // One can hope that there is a more public API available by that time. +/* + Qt::WindowFlags flags = widget ? widget->windowFlags() : Qt::WindowFlags(0); + if ((flags & Qt::CustomizeWindowHint)) { + if ((flags & (Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint + | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint)) + && !(flags & Qt::WindowMaximizeButtonHint)) + wattr |= QtMacCustomizeWindow; + } +*/ + // If we haven't created the desktop widget, you have to pass the rectangle + // in "cocoa coordinates" (i.e., top points to the lower left coordinate). + // Otherwise, we do the conversion for you. Since we are the only ones that + // create the desktop widget, this is OK (but confusing). +/* + NSRect geo = NSMakeRect(crect.left(), + (qt_root_win != 0) ? flipYCoordinate(crect.bottom() + 1) : crect.top(), + crect.width(), crect.height()); +*/ + QRect geo = window()->geometry(); + NSRect frame = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height()); + + QCocoaAutoReleasePool pool; + NSWindow *window; + + switch (m_windowClass) { + case kMovableModalWindowClass: + case kModalWindowClass: + case kSheetWindowClass: + case kFloatingWindowClass: + case kOverlayWindowClass: + case kHelpWindowClass: { + NSPanel *panel; + + BOOL needFloating = NO; + BOOL worksWhenModal = (this->window()->windowType() == Qt::Popup); + + // Add in the extra flags if necessary. + switch (m_windowClass) { + case kSheetWindowClass: + m_windowAttributes |= NSDocModalWindowMask; + break; + case kFloatingWindowClass: + case kHelpWindowClass: + needFloating = YES; + m_windowAttributes |= NSUtilityWindowMask; + break; + default: + break; + } + + panel = [[NSPanel alloc] initWithContentRect:frame + styleMask:m_windowAttributes + backing:NSBackingStoreBuffered + defer:YES]; +// ### crashes +// [panel setFloatingPanel:needFloating]; +// [panel setWorksWhenModal:worksWhenModal]; + window = panel; + break; + } + + default: + m_nsWindow = [[NSWindow alloc] initWithContentRect:frame + styleMask:m_windowAttributes + backing:NSBackingStoreBuffered + defer:YES]; + break; + } + + //qt_syncCocoaTitleBarButtons(window, widget); + return window; +} + +