Skip to content
Permalink
Browse files

Fix Qt 5 upgrade broke shutdown ask on quit suppression (#1362)

In Qt 5 QApplication no longer has the commitData function previously
overridden to detect system shutdown. Now using commitDataRequest signal
which is available in Qt 4 and 5 on the object instead.
  • Loading branch information...
hacst committed Aug 17, 2014
1 parent 9d668eb commit f1e3e096f77c635e8caeba06632fca023d65ae41
Showing with 186 additions and 92 deletions.
  1. +115 −0 src/mumble/MumbleApplication.cpp
  2. +66 −0 src/mumble/MumbleApplication.h
  3. +2 −90 src/mumble/main.cpp
  4. +3 −2 src/mumble/mumble.pro
@@ -0,0 +1,115 @@
/* Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of the Mumble Developers nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "mumble_pch.hpp"

#include "MumbleApplication.h"

#include "MainWindow.h"
#include "GlobalShortcut.h"
#include "Global.h"

MumbleApplication::MumbleApplication(int &pargc, char **pargv)
: QApplication(pargc, pargv) {

connect(this,
SIGNAL(commitDataRequest(QSessionManager&)),
SLOT(onCommitDataRequest(QSessionManager&)),
Qt::DirectConnection);
}

void MumbleApplication::onCommitDataRequest(QSessionManager &) {
// Make sure the config is saved and supress the ask on quit message
if (g.mw) {
g.s.save();
g.mw->bSuppressAskOnQuit = true;
qWarning() << "Session likely ending. Suppressing ask on quit";
}
}

bool MumbleApplication::event(QEvent *e) {
if (e->type() == QEvent::FileOpen) {
QFileOpenEvent *foe = static_cast<QFileOpenEvent *>(e);
if (! g.mw) {
this->quLaunchURL = foe->url();
} else {
g.mw->openUrl(foe->url());
}
return true;
}
return QApplication::event(e);
}

#ifdef Q_OS_WIN
# if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
bool MumbleApplication::nativeEventFilter(const QByteArray &eventType, void *message, long *result) {
Q_UNUSED(eventType);
MSG *msg = reinterpret_cast<MSG *>(message);

if (QThread::currentThread() == thread()) {
if (Global::g_global_struct && g.ocIntercept) {
switch (msg->message) {
case WM_MOUSELEAVE:
*result = 0;
return true;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
GlobalShortcutEngine::engine->prepareInput();
default:
break;
}
}
}
return false;
}
# else
bool MumbleApplication::winEventFilter(MSG *msg, long *result) {
if (QThread::currentThread() == thread()) {
if (Global::g_global_struct && g.ocIntercept) {
switch (msg->message) {
case WM_MOUSELEAVE:
*result = 0;
return true;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
GlobalShortcutEngine::engine->prepareInput();
default:
break;
}
}
}
return QApplication::winEventFilter(msg, result);
}
# endif
#endif
@@ -0,0 +1,66 @@
/* Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of the Mumble Developers nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef MUMBLE_MUMBLE_MUMBLEAPPLICATION_H
#define MUMBLE_MUMBLE_MUMBLEAPPLICATION_H

#include <QApplication>

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && defined(Q_OS_WIN)
# define QAPP_INHERIT_EVENT_FILTER , public QAbstractNativeEventFilter
#else
# define QAPP_INHERIT_EVENT_FILTER
#endif

/**
* @brief Implements custom system shutdown behavior as well as event filtering.
*/
class MumbleApplication : public QApplication QAPP_INHERIT_EVENT_FILTER {
Q_OBJECT
public:
MumbleApplication(int &pargc, char **pargv);

bool event(QEvent *e);
#ifdef Q_OS_WIN
# if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
bool MumbleApplication::nativeEventFilter(const QByteArray &eventType, void *message, long *result);
# else
bool winEventFilter(MSG *msg, long *result);
# endif
#endif

QUrl quLaunchURL;

public slots:
/// Saves state and suppresses ask on quit before system shutdown.
void onCommitDataRequest(QSessionManager&);
};

#endif // MUMBLE_MUMBLE_MUMBLEAPPLICATION_H
@@ -55,6 +55,7 @@
#include "NetworkConfig.h"
#include "CrashReporter.h"
#include "SocketRPC.h"
#include "MumbleApplication.h"

#if defined(USE_STATIC_QT_PLUGINS) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
Q_IMPORT_PLUGIN(qtaccessiblewidgets)
@@ -77,95 +78,6 @@ namespace boost {
extern void os_init();
extern char *os_lang;

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && defined(Q_OS_WIN)
# define QAPP_INHERIT_EVENT_FILTER , public QAbstractNativeEventFilter
#else
# define QAPP_INHERIT_EVENT_FILTER
#endif

class QAppMumble : public QApplication QAPP_INHERIT_EVENT_FILTER {
public:
QUrl quLaunchURL;
QAppMumble(int &pargc, char **pargv) : QApplication(pargc, pargv) {}
void commitData(QSessionManager&);
bool event(QEvent *e);
#ifdef Q_OS_WIN
# if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
bool QAppMumble::nativeEventFilter(const QByteArray &eventType, void *message, long *result);
# else
bool winEventFilter(MSG *msg, long *result);
# endif
#endif
};

void QAppMumble::commitData(QSessionManager &) {
// Make sure the config is saved and supress the ask on quite message
if (g.mw) {
g.s.save();
g.mw->bSuppressAskOnQuit = true;
}
}

bool QAppMumble::event(QEvent *e) {
if (e->type() == QEvent::FileOpen) {
QFileOpenEvent *foe = static_cast<QFileOpenEvent *>(e);
if (! g.mw) {
this->quLaunchURL = foe->url();
} else {
g.mw->openUrl(foe->url());
}
return true;
}
return QApplication::event(e);
}

#ifdef Q_OS_WIN
# if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
bool QAppMumble::nativeEventFilter(const QByteArray &eventType, void *message, long *result) {
Q_UNUSED(eventType);
MSG *msg = reinterpret_cast<MSG *>(message);

if (QThread::currentThread() == thread()) {
if (Global::g_global_struct && g.ocIntercept) {
switch (msg->message) {
case WM_MOUSELEAVE:
*result = 0;
return true;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
GlobalShortcutEngine::engine->prepareInput();
default:
break;
}
}
}
return false;
}
# else
bool QAppMumble::winEventFilter(MSG *msg, long *result) {
if (QThread::currentThread() == thread()) {
if (Global::g_global_struct && g.ocIntercept) {
switch (msg->message) {
case WM_MOUSELEAVE:
*result = 0;
return true;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
GlobalShortcutEngine::engine->prepareInput();
default:
break;
}
}
}
return QApplication::winEventFilter(msg, result);
}
# endif
#endif

#if defined(Q_OS_WIN) && !defined(QT_NO_DEBUG)
extern "C" _declspec(dllexport) int main(int argc, char **argv) {
#else
@@ -184,7 +96,7 @@ int main(int argc, char **argv) {
#endif

// Initialize application object.
QAppMumble a(argc, argv);
MumbleApplication a(argc, argv);
a.setApplicationName(QLatin1String("Mumble"));
a.setOrganizationName(QLatin1String("Mumble"));
a.setOrganizationDomain(QLatin1String("mumble.sourceforge.net"));
@@ -68,8 +68,9 @@ HEADERS *= BanEditor.h ACLEditor.h ConfigWidget.h Log.h AudioConfigDialog.h Aud
OverlayUserGroup.h \
OverlayConfig.h \
OverlayEditor.h \
OverlayEditorScene.h
SOURCES *= BanEditor.cpp ACLEditor.cpp ConfigWidget.cpp Log.cpp AudioConfigDialog.cpp AudioStats.cpp AudioInput.cpp AudioOutput.cpp AudioOutputSample.cpp AudioOutputSpeech.cpp AudioOutputUser.cpp main.cpp CELTCodec.cpp CustomElements.cpp MainWindow.cpp ServerHandler.cpp About.cpp ConnectDialog.cpp Settings.cpp Database.cpp VersionCheck.cpp Global.cpp UserModel.cpp Audio.cpp ConfigDialog.cpp Plugins.cpp PTTButtonWidget.cpp LookConfig.cpp OverlayClient.cpp OverlayConfig.cpp OverlayEditor.cpp OverlayEditorScene.cpp OverlayUser.cpp OverlayUserGroup.cpp Overlay.cpp OverlayText.cpp SharedMemory.cpp AudioWizard.cpp ViewCert.cpp Messages.cpp TextMessage.cpp GlobalShortcut.cpp NetworkConfig.cpp LCD.cpp Usage.cpp Cert.cpp ClientUser.cpp UserEdit.cpp UserListModel.cpp Tokens.cpp UserView.cpp RichTextEditor.cpp UserInformation.cpp SocketRPC.cpp VoiceRecorder.cpp VoiceRecorderDialog.cpp WebFetch.cpp
OverlayEditorScene.h \
MumbleApplication.h
SOURCES *= BanEditor.cpp ACLEditor.cpp ConfigWidget.cpp Log.cpp AudioConfigDialog.cpp AudioStats.cpp AudioInput.cpp AudioOutput.cpp AudioOutputSample.cpp AudioOutputSpeech.cpp AudioOutputUser.cpp main.cpp CELTCodec.cpp CustomElements.cpp MainWindow.cpp ServerHandler.cpp About.cpp ConnectDialog.cpp Settings.cpp Database.cpp VersionCheck.cpp Global.cpp UserModel.cpp Audio.cpp ConfigDialog.cpp Plugins.cpp PTTButtonWidget.cpp LookConfig.cpp OverlayClient.cpp OverlayConfig.cpp OverlayEditor.cpp OverlayEditorScene.cpp OverlayUser.cpp OverlayUserGroup.cpp Overlay.cpp OverlayText.cpp SharedMemory.cpp AudioWizard.cpp ViewCert.cpp Messages.cpp TextMessage.cpp GlobalShortcut.cpp NetworkConfig.cpp LCD.cpp Usage.cpp Cert.cpp ClientUser.cpp UserEdit.cpp UserListModel.cpp Tokens.cpp UserView.cpp RichTextEditor.cpp UserInformation.cpp SocketRPC.cpp VoiceRecorder.cpp VoiceRecorderDialog.cpp WebFetch.cpp MumbleApplication.cpp
SOURCES *= smallft.cpp
DIST *= ../../icons/mumble.ico licenses.h smallft.h ../../icons/mumble.xpm murmur_pch.h mumble.plist
RESOURCES *= mumble.qrc mumble_translations.qrc mumble_flags.qrc

0 comments on commit f1e3e09

Please sign in to comment.
You can’t perform that action at this time.