diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoawindow.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 2adea0f493..bc40bbb6ce 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1,40 +1,32 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -354,6 +346,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) , m_windowUnderMouse(false) + , m_ignoreWindowShouldClose(false) , m_inConstructor(true) , m_inSetVisible(false) , m_inSetGeometry(false) @@ -424,11 +417,26 @@ QCocoaWindow::~QCocoaWindow() m_parentCocoaWindow->removeChildWindow(this); } else if (parent()) { [m_contentView removeFromSuperview]; - } else if (m_qtView) { - [[NSNotificationCenter defaultCenter] removeObserver:m_qtView - name:nil object:m_nsWindow]; } + // Make sure to disconnect observer in all case if view is valid + // to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute + if (m_qtView) { + [[NSNotificationCenter defaultCenter] removeObserver:m_qtView]; + } + + // The QNSView object may outlive the corresponding QCocoaWindow object, + // for example during app shutdown when the QNSView is embedded in a + // foregin NSView hiearchy. Clear the pointers to the QWindow/QCocoaWindow + // here to make sure QNSView does not dereference stale pointers. + if (m_qtView) { + [m_qtView clearQWindowPointers]; + } + + // While it is unlikely that this window will be in the popup stack + // during deletetion we clear any pointers here to make sure. + QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); + foreach (QCocoaWindow *child, m_childWindows) { [m_nsWindow removeChildWindow:child->m_nsWindow]; child->m_parentCocoaWindow = 0; @@ -618,17 +626,17 @@ void QCocoaWindow::setVisible(bool visible) // We need to recreate if the modality has changed as the style mask will need updating if (m_windowModality != window()->modality()) recreateWindow(parent()); + + // Register popup windows. The Cocoa platform plugin will forward mouse events + // to them and close them when needed. + if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) + QCocoaIntegration::instance()->pushPopupWindow(this); + if (parentCocoaWindow) { // The parent window might have moved while this window was hidden, // update the window geometry if there is a parent. setGeometry(window()->geometry()); - // Register popup windows so that the parent window can close them when needed. - if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) { - // qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup); - parentCocoaWindow->m_activePopupWindow = window(); - } - if (window()->type() == Qt::Popup) { // QTBUG-30266: a window should not be resizable while a transient popup is open // Since this isn't a native popup, the window manager doesn't close the popup when you click outside @@ -730,8 +738,11 @@ void QCocoaWindow::setVisible(bool visible) [NSEvent removeMonitor:monitor]; monitor = nil; } + + if (window()->type() == Qt::Popup) + QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); + if (parentCocoaWindow && window()->type() == Qt::Popup) { - parentCocoaWindow->m_activePopupWindow = 0; if (m_resizableTransientParent && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask)) // QTBUG-30266: a window should not be resizable while a transient popup is open @@ -776,7 +787,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); NSInteger styleMask = NSBorderlessWindowMask; if (flags & Qt::FramelessWindowHint) - return styleMask; + return styleMask | NSResizableWindowMask; if ((type & Qt::Popup) == Qt::Popup) { if (!windowIsPopupType(type)) styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | @@ -1144,10 +1155,9 @@ void QCocoaWindow::setEmbeddedInForeignView(bool embedded) void QCocoaWindow::windowWillMove() { // Close any open popups on window move - if (m_activePopupWindow) { - QWindowSystemInterface::handleCloseEvent(m_activePopupWindow); + while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) { + QWindowSystemInterface::handleCloseEvent(popup->window()); QWindowSystemInterface::flushWindowSystemEvents(); - m_activePopupWindow = 0; } } @@ -1181,6 +1191,9 @@ void QCocoaWindow::windowDidEndLiveResize() bool QCocoaWindow::windowShouldClose() { + // might have been set from qnsview.mm + if (m_ignoreWindowShouldClose) + return false; bool accepted = false; QWindowSystemInterface::handleCloseEvent(window(), &accepted); QWindowSystemInterface::flushWindowSystemEvents(); @@ -1478,7 +1491,10 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) if ((m_synchedWindowState & Qt::WindowMinimized) != (newState & Qt::WindowMinimized)) { if (newState & Qt::WindowMinimized) { - [m_nsWindow performMiniaturize : m_nsWindow]; + if (m_nsWindow.styleMask & NSMiniaturizableWindowMask) + [m_nsWindow performMiniaturize : m_nsWindow]; + else + [m_nsWindow miniaturize : m_nsWindow]; } else { [m_nsWindow deminiaturize : m_nsWindow]; } |