summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorSamuel Gaist <samuel.gaist@edeltech.ch>2014-07-02 16:46:24 +0200
committerDavid Faure <david.faure@kdab.com>2014-07-10 21:54:19 +0200
commit50c04d631858639c630e85456e7e003a80e33493 (patch)
tree21dd2c6cb9026395bfdf10056dfe35eca0f641b9 /src/plugins/platforms/cocoa
parent53ed4de02278b17708199891f9b56c6e6e04103b (diff)
Session management for OS X
This patch aims to implement the session management available on OS X. Currently applicationShouldTerminate is just a go through that closes everything and ends the application. The new implementation calls first appCommitData and cancels the termination properly if required. This means that if a user wishes to logout, Qt applications can now cancel that like e.g. answering to Safari asking whether it is ok to close because of a number of opened tab/window. Task-number: QTBUG-33034 Change-Id: Icedc8590a1c0934d9bc87d3a43d6702a9903bfb8 Reviewed-by: Jake Petroules <jake.petroules@petroules.com>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm31
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoasessionmanager.cpp70
-rw-r--r--src/plugins/platforms/cocoa/qcocoasessionmanager.h79
6 files changed, 186 insertions, 16 deletions
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index ad6cb3a1fc..b8befcd497 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -41,7 +41,8 @@ OBJECTIVE_SOURCES += main.mm \
qcocoakeymapper.mm \
qcocoamimetypes.mm
-SOURCES += messages.cpp
+SOURCES += messages.cpp \
+ qcocoasessionmanager.cpp
HEADERS += qcocoaintegration.h \
qcocoatheme.h \
@@ -76,7 +77,8 @@ HEADERS += qcocoaintegration.h \
qcocoaintrospection.h \
qcocoakeymapper.h \
messages.h \
- qcocoamimetypes.h
+ qcocoamimetypes.h \
+ qcocoasessionmanager.h
contains(QT_CONFIG, opengl.*) {
OBJECTIVE_SOURCES += qcocoaglcontext.mm
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index efe3269d42..6c39f1eb5a 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -78,11 +79,13 @@
#import "qnswindowdelegate.h"
#import "qcocoamenuloader.h"
#include "qcocoaintegration.h"
+#include "qcocoasessionmanager.h"
#include <qevent.h>
#include <qurl.h>
#include <qdebug.h>
#include <qguiapplication.h>
#include <private/qguiapplication_p.h>
+#include <private/qsessionmanager_p.h>
#include "qt_mac_p.h"
#include <qpa/qwindowsysteminterface.h>
@@ -216,6 +219,17 @@ static void cleanupCocoaApplicationDelegate()
return NSTerminateNow;
}
+ QGuiApplicationPrivate *qGuiAppPriv = QGuiApplicationPrivate::instance();
+
+#ifndef QT_NO_SESSIONMANAGER
+ QSessionManagerPrivate *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(qGuiAppPriv->session_manager));
+ QCocoaSessionManager *cocoaSessionManager = static_cast<QCocoaSessionManager *>(managerPrivate->platformSessionManager);
+ cocoaSessionManager->appCommitData();
+
+ if (cocoaSessionManager->wasCanceled())
+ return NSTerminateCancel;
+#endif
+
if ([self canQuit]) {
if (!startedQuit) {
startedQuit = true;
@@ -239,7 +253,7 @@ static void cleanupCocoaApplicationDelegate()
}
}
- if (QGuiApplicationPrivate::instance()->threadData->eventLoops.isEmpty()) {
+ if (qGuiAppPriv->threadData->eventLoops.isEmpty()) {
// INVARIANT: No event loop is executing. This probably
// means that Qt is used as a plugin, or as a part of a native
// Cocoa application. In any case it should be fine to
@@ -270,10 +284,6 @@ static void cleanupCocoaApplicationDelegate()
*/
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
[eventManager setEventHandler:self
- andSelector:@selector(appleEventQuit:withReplyEvent:)
- forEventClass:kCoreEventClass
- andEventID:kAEQuitApplication];
- [eventManager setEventHandler:self
andSelector:@selector(getUrl:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
@@ -283,7 +293,6 @@ static void cleanupCocoaApplicationDelegate()
- (void) removeAppleEventHandlers
{
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
- [eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication];
[eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL];
}
@@ -330,7 +339,8 @@ static void cleanupCocoaApplicationDelegate()
&& [reflectionDelegate respondsToSelector:
@selector(applicationShouldTerminateAfterLastWindowClosed:)])
return [reflectionDelegate applicationShouldTerminateAfterLastWindowClosed:sender];
- return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together.
+
+ return qApp->quitOnLastWindowClosed();
}
@@ -436,13 +446,6 @@ static void cleanupCocoaApplicationDelegate()
QWindowSystemInterface::handleFileOpenEvent(QUrl(QCFString::toQString(urlString)));
}
-- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
-{
- Q_UNUSED(event);
- Q_UNUSED(replyEvent);
- [NSApp terminate:self];
-}
-
- (void)qtDispatcherToQAction:(id)sender
{
Q_UNUSED(sender);
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 5ca2ccc571..9942ac09cc 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -141,6 +141,14 @@ public:
void setToolbar(QWindow *window, NSToolbar *toolbar);
NSToolbar *toolbar(QWindow *window) const;
void clearToolbars();
+
+ void setWindow(NSWindow* nsWindow, QCocoaWindow *window);
+ QCocoaWindow *window(NSWindow *window);
+
+#ifndef QT_NO_SESSIONMANAGER
+ QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const;
+#endif
+
private:
static QCocoaIntegration *mInstance;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 4be49ed68f..49e602f45c 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -54,6 +54,7 @@
#include "qcocoainputcontext.h"
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
+#include "qcocoasessionmanager.h"
#include <qpa/qplatformaccessibility.h>
#include <QtCore/qcoreapplication.h>
@@ -416,6 +417,13 @@ QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
return mScreens.at(index);
}
+#ifndef QT_NO_SESSIONMANAGER
+QPlatformSessionManager *QCocoaIntegration::createPlatformSessionManager(const QString &id, const QString &key) const
+{
+ return new QCocoaSessionManager(id, key);
+}
+#endif
+
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
diff --git a/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp b/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp
new file mode 100644
index 0000000000..9d0df65bc8
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt 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$
+**
+****************************************************************************/
+
+#ifndef QT_NO_SESSIONMANAGER
+#include <qcocoasessionmanager.h>
+#include <qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+QCocoaSessionManager::QCocoaSessionManager(const QString &id, const QString &key)
+ : QPlatformSessionManager(id, key),
+ m_canceled(false)
+{
+}
+
+QCocoaSessionManager::~QCocoaSessionManager()
+{
+}
+
+void QCocoaSessionManager::cancel()
+{
+ m_canceled = true;
+}
+
+bool QCocoaSessionManager::wasCanceled() const
+{
+ return m_canceled;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SESSIONMANAGER
diff --git a/src/plugins/platforms/cocoa/qcocoasessionmanager.h b/src/plugins/platforms/cocoa/qcocoasessionmanager.h
new file mode 100644
index 0000000000..fe9ba1d075
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasessionmanager.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt 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$
+**
+****************************************************************************/
+
+#ifndef QCOCOASESSIONMANAGER_H
+#define QCOCOASESSIONMANAGER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
+#ifndef QT_NO_SESSIONMANAGER
+
+#include <qpa/qplatformsessionmanager.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QCocoaSessionManager : public QPlatformSessionManager
+{
+public:
+ QCocoaSessionManager(const QString &id, const QString &key);
+ virtual ~QCocoaSessionManager();
+
+ void cancel() Q_DECL_OVERRIDE;
+ bool wasCanceled() const;
+
+private:
+ bool m_canceled;
+
+ Q_DISABLE_COPY(QCocoaSessionManager)
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SESSIONMANAGER
+
+#endif // QCOCOASESSIONMANAGER_H