Session management for macOS

This patch aims to implement the session management available on macOS.
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.

Fixes: QTBUG-33034
Change-Id: Id5d7416cb74c762c5424a77c9c7664f0749da7f6
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Samuel Gaist 2015-03-02 21:13:35 +01:00 committed by Samuel Gaist
parent 7a55a984d8
commit f81f21151d
8 changed files with 274 additions and 1 deletions

View File

@ -87,6 +87,11 @@ qtConfig(accessibility) {
qcocoaaccessibility.h
}
qtConfig(sessionmanager) {
SOURCES += qcocoasessionmanager.cpp
HEADERS += qcocoasessionmanager.h
}
RESOURCES += qcocoaresources.qrc
LIBS += -framework AppKit -framework CoreServices -framework Carbon -framework IOKit -framework QuartzCore -framework CoreVideo -framework Metal -framework IOSurface -lcups

View File

@ -79,11 +79,14 @@
#include "qcocoamenuitem.h"
#include "qcocoansmenu.h"
#if QT_CONFIG(sessionmanager)
# include "qcocoasessionmanager.h"
#endif
#include <qevent.h>
#include <qurl.h>
#include <qdebug.h>
#include <qguiapplication.h>
#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include <qpa/qwindowsysteminterface.h>
#include <qwindowdefs.h>
@ -157,6 +160,17 @@ QT_USE_NAMESPACE
return NSTerminateNow;
}
#if QT_CONFIG(sessionmanager)
QCocoaSessionManager *cocoaSessionManager = QCocoaSessionManager::instance();
cocoaSessionManager->resetCancellation();
cocoaSessionManager->appCommitData();
if (cocoaSessionManager->wasCanceled()) {
qCDebug(lcQpaApplication) << "Session management canceled application termination";
return NSTerminateCancel;
}
#endif
if (!QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>()) {
qCDebug(lcQpaApplication) << "Application termination canceled";
return NSTerminateCancel;

View File

@ -92,6 +92,10 @@ public:
QCocoaVulkanInstance *getCocoaVulkanInstance() const;
#endif
#if QT_CONFIG(sessionmanager)
QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override;
#endif
QCoreTextFontDatabase *fontDatabase() const override;
QCocoaNativeInterface *nativeInterface() const override;
QPlatformInputContext *inputContext() const override;

View File

@ -52,6 +52,9 @@
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
#include "qcocoascreen.h"
#if QT_CONFIG(sessionmanager)
# include "qcocoasessionmanager.h"
#endif
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
@ -255,6 +258,13 @@ QCocoaIntegration::Options QCocoaIntegration::options() const
return mOptions;
}
#if QT_CONFIG(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) {

View File

@ -0,0 +1,88 @@
/****************************************************************************
**
** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QT_NO_SESSIONMANAGER
#include <private/qsessionmanager_p.h>
#include <private/qguiapplication_p.h>
#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()
{
}
bool QCocoaSessionManager::allowsInteraction()
{
return false;
}
void QCocoaSessionManager::resetCancellation()
{
m_canceled = false;
}
void QCocoaSessionManager::cancel()
{
m_canceled = true;
}
bool QCocoaSessionManager::wasCanceled() const
{
return m_canceled;
}
QCocoaSessionManager *QCocoaSessionManager::instance()
{
auto *qGuiAppPriv = QGuiApplicationPrivate::instance();
auto *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(qGuiAppPriv->session_manager));
return static_cast<QCocoaSessionManager *>(managerPrivate->platformSessionManager);
}
QT_END_NAMESPACE
#endif // QT_NO_SESSIONMANAGER

View File

@ -0,0 +1,81 @@
/****************************************************************************
**
** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.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 QCocoaSessionManager : public QPlatformSessionManager
{
public:
QCocoaSessionManager(const QString &id, const QString &key);
virtual ~QCocoaSessionManager();
bool allowsInteraction() override;
void cancel() override;
void resetCancellation();
bool wasCanceled() const;
static QCocoaSessionManager *instance();
private:
bool m_canceled;
Q_DISABLE_COPY(QCocoaSessionManager)
};
QT_END_NAMESPACE
#endif // QT_NO_SESSIONMANAGER
#endif // QCOCOASESSIONMANAGER_H

View File

@ -0,0 +1,10 @@
CONFIG += testcase
TARGET = tst_sessionmanagement_macos
OBJECTIVE_SOURCES += tst_sessionmanagement_macos.mm
QT = testlib gui core
LIBS += -framework AppKit
requires(mac)
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0

View File

@ -0,0 +1,61 @@
/****************************************************************************
**
** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QSignalSpy>
#include <QSessionManager>
#include <AppKit/AppKit.h>
// Q_DECLARE_METATYPE(QSessionManager)
class tst_SessionManagement_macOS : public QObject
{
Q_OBJECT
private slots:
void stopApplication();
};
/*
Test that session handling code is properly called
*/
void tst_SessionManagement_macOS::stopApplication()
{
int argc = 0;
QGuiApplication app(argc, nullptr);
QSignalSpy spy(&app, &QGuiApplication::commitDataRequest);
QTimer::singleShot(1000, []() {
[NSApp terminate:nil];
});
app.exec();
QCOMPARE(spy.count(), 1);
}
QTEST_APPLESS_MAIN(tst_SessionManagement_macOS)
#include "tst_sessionmanagement_macos.moc"