1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 02:36:34 +01:00

Update to latest upstream QtSingleApplication

This commit is contained in:
David Rosca 2018-10-15 20:39:47 +02:00
parent 6d445edb44
commit a039da158a
No known key found for this signature in database
GPG Key ID: EBC3FC294452C6D8
8 changed files with 421 additions and 437 deletions

View File

@ -1,69 +1,62 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/
#include "qtlocalpeer.h" #include "qtlocalpeer.h"
#include <QtCore/QCoreApplication> #include <QCoreApplication>
#include <QtCore/QTime> #include <QDataStream>
#include <QtCore/QDataStream> #include <QTime>
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
#include <QtCore/QLibrary> #include <QLibrary>
#include <QtCore/qt_windows.h> #include <qt_windows.h>
typedef BOOL(WINAPI* PProcessIdToSessionId)(DWORD, DWORD*); typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
static PProcessIdToSessionId pProcessIdToSessionId = 0; static PProcessIdToSessionId pProcessIdToSessionId = 0;
#endif #endif
#if defined(Q_OS_UNIX) #if defined(Q_OS_UNIX)
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#endif #endif
namespace QtLP_Private namespace QtLP_Private {
{
#include "qtlockedfile.cpp" #include "qtlockedfile.cpp"
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
#include "qtlockedfile_win.cpp" #include "qtlockedfile_win.cpp"
@ -85,7 +78,7 @@ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
#endif #endif
prefix = id.section(QLatin1Char('/'), -1); prefix = id.section(QLatin1Char('/'), -1);
} }
prefix.remove(QRegExp(QLatin1String("[^a-zA-Z]"))); prefix.remove(QRegExp("[^a-zA-Z]"));
prefix.truncate(6); prefix.truncate(6);
QByteArray idc = id.toUtf8(); QByteArray idc = id.toUtf8();
@ -119,25 +112,22 @@ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
bool QtLocalPeer::isClient() bool QtLocalPeer::isClient()
{ {
if (lockFile.isLocked()) { if (lockFile.isLocked())
return false; return false;
}
if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) { if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
return true; return true;
}
bool res = server->listen(socketName); bool res = server->listen(socketName);
#if defined(Q_OS_UNIX) #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
// ### Workaround // ### Workaround
if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName); QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
res = server->listen(socketName); res = server->listen(socketName);
} }
#endif #endif
if (!res) { if (!res)
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
}
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
return false; return false;
} }
@ -145,37 +135,37 @@ bool QtLocalPeer::isClient()
bool QtLocalPeer::sendMessage(const QString &message, int timeout) bool QtLocalPeer::sendMessage(const QString &message, int timeout)
{ {
if (!isClient()) { if (!isClient())
return false; return false;
}
QLocalSocket socket; QLocalSocket socket;
bool connOk = false; bool connOk = false;
for (int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
// Try twice, in case the other instance is just starting up // Try twice, in case the other instance is just starting up
socket.connectToServer(socketName); socket.connectToServer(socketName);
connOk = socket.waitForConnected(timeout / 2); connOk = socket.waitForConnected(timeout/2);
if (connOk || i) { if (connOk || i)
break; break;
}
int ms = 250; int ms = 250;
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
Sleep(DWORD(ms)); Sleep(DWORD(ms));
#else #else
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, nullptr); nanosleep(&ts, NULL);
#endif #endif
} }
if (!connOk) { if (!connOk)
return false; return false;
}
QByteArray uMsg(message.toUtf8()); QByteArray uMsg(message.toUtf8());
QDataStream ds(&socket); QDataStream ds(&socket);
ds.writeBytes(uMsg.constData(), uMsg.size()); ds.writeBytes(uMsg.constData(), uMsg.size());
bool res = socket.waitForBytesWritten(timeout); bool res = socket.waitForBytesWritten(timeout);
res &= socket.waitForReadyRead(timeout); // wait for ack if (res) {
res &= (socket.read(qstrlen(ack)) == ack); res &= socket.waitForReadyRead(timeout); // wait for ack
if (res)
res &= (socket.read(qstrlen(ack)) == ack);
}
return res; return res;
} }
@ -187,13 +177,20 @@ void QtLocalPeer::removeLockedFile()
void QtLocalPeer::receiveConnection() void QtLocalPeer::receiveConnection()
{ {
QLocalSocket* socket = server->nextPendingConnection(); QLocalSocket* socket = server->nextPendingConnection();
if (!socket) { if (!socket)
return; return;
}
while (socket->bytesAvailable() < (int)sizeof(quint32)) { while (true) {
if (socket->state() == QLocalSocket::UnconnectedState) {
qWarning("QtLocalPeer: Peer disconnected");
delete socket;
return;
}
if (socket->bytesAvailable() >= qint64(sizeof(quint32)))
break;
socket->waitForReadyRead(); socket->waitForReadyRead();
} }
QDataStream ds(socket); QDataStream ds(socket);
QByteArray uMsg; QByteArray uMsg;
quint32 remaining; quint32 remaining;
@ -205,16 +202,16 @@ void QtLocalPeer::receiveConnection()
got = ds.readRawData(uMsgBuf, remaining); got = ds.readRawData(uMsgBuf, remaining);
remaining -= got; remaining -= got;
uMsgBuf += got; uMsgBuf += got;
} } while (remaining && got >= 0 && socket->waitForReadyRead(2000));
while (remaining && got >= 0 && socket->waitForReadyRead(2000));
if (got < 0) { if (got < 0) {
qWarning("QtLocalPeer: Message reception failed %s", qPrintable(socket->errorString())); qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
delete socket; delete socket;
return; return;
} }
QString message(QString::fromUtf8(uMsg)); QString message(QString::fromUtf8(uMsg));
socket->write(ack, qstrlen(ack)); socket->write(ack, qstrlen(ack));
socket->waitForBytesWritten(1000); socket->waitForBytesWritten(1000);
socket->waitForDisconnected(1000); // make sure client reads ack
delete socket; delete socket;
emit messageReceived(message); //### (might take a long time to return) emit messageReceived(message); //### (might take a long time to return)
} }

View File

@ -1,73 +1,62 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/
#ifndef QTLOCALPEER_H
#define QTLOCALPEER_H
#include <QtNetwork/QLocalServer> #include <QLocalServer>
#include <QtNetwork/QLocalSocket> #include <QLocalSocket>
#include <QtCore/QDir> #include <QDir>
#if defined(Q_OS_HAIKU) || defined(Q_OS_OS2)
#include <unistd.h>
#endif
namespace QtLP_Private
{
#include "qtlockedfile.h" #include "qtlockedfile.h"
}
class QtLocalPeer : public QObject class QtLocalPeer : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
QtLocalPeer(QObject* parent = 0, const QString &appId = QString()); QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
bool isClient(); bool isClient();
bool sendMessage(const QString &message, int timeout); bool sendMessage(const QString &message, int timeout);
QString applicationId() const QString applicationId() const
{ return id; } { return id; }
void removeLockedFile(); void removeLockedFile();
Q_SIGNALS: Q_SIGNALS:
@ -85,3 +74,5 @@ protected:
private: private:
static const char* ack; static const char* ack;
}; };
#endif // QTLOCALPEER_H

View File

@ -1,46 +1,40 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/

View File

@ -1,58 +1,52 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/
#ifndef QTLOCKEDFILE_H #ifndef QTLOCKEDFILE_H
#define QTLOCKEDFILE_H #define QTLOCKEDFILE_H
#include <QtCore/QFile> #include <QFile>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <QtCore/QVector> #include <QVector>
#endif #endif
#if defined(Q_WS_WIN) #if defined(Q_OS_WIN)
# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
# define QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT
# elif defined(QT_QTLOCKEDFILE_IMPORT) # elif defined(QT_QTLOCKEDFILE_IMPORT)
@ -68,6 +62,8 @@
# define QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT
#endif #endif
namespace QtLP_Private {
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
{ {
public: public:
@ -97,5 +93,5 @@ private:
#endif #endif
LockMode m_lock_mode; LockMode m_lock_mode;
}; };
}
#endif #endif

View File

@ -1,46 +1,40 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/
@ -58,17 +52,14 @@ bool QtLockedFile::lock(LockMode mode, bool block)
return false; return false;
} }
if (mode == NoLock) { if (mode == NoLock)
return unlock(); return unlock();
}
if (mode == m_lock_mode) { if (mode == m_lock_mode)
return true; return true;
}
if (m_lock_mode != NoLock) { if (m_lock_mode != NoLock)
unlock(); unlock();
}
struct flock fl; struct flock fl;
fl.l_whence = SEEK_SET; fl.l_whence = SEEK_SET;
@ -79,9 +70,8 @@ bool QtLockedFile::lock(LockMode mode, bool block)
int ret = fcntl(handle(), cmd, &fl); int ret = fcntl(handle(), cmd, &fl);
if (ret == -1) { if (ret == -1) {
if (errno != EINTR && errno != EAGAIN) { if (errno != EINTR && errno != EAGAIN)
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
}
return false; return false;
} }
@ -98,9 +88,8 @@ bool QtLockedFile::unlock()
return false; return false;
} }
if (!isLocked()) { if (!isLocked())
return true; return true;
}
struct flock fl; struct flock fl;
fl.l_whence = SEEK_SET; fl.l_whence = SEEK_SET;
@ -120,8 +109,7 @@ bool QtLockedFile::unlock()
QtLockedFile::~QtLockedFile() QtLockedFile::~QtLockedFile()
{ {
if (isOpen()) { if (isOpen())
unlock(); unlock();
}
} }

View File

@ -1,57 +1,55 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/
#include "qtlockedfile.h" #include "qtlockedfile.h"
#include <qt_windows.h> #include <qt_windows.h>
#include <QtCore/QFileInfo> #include <QFileInfo>
#define MUTEX_PREFIX "QtLockedFile mutex " #define MUTEX_PREFIX "QtLockedFile mutex "
// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS
#define MAX_READERS MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS
#if QT_VERSION >= 0x050000
#define QT_WA(unicode, ansi) unicode
#endif
Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
{ {
if (mutexname.isEmpty()) { if (mutexname.isEmpty()) {
@ -60,24 +58,24 @@ Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
+ fi.absoluteFilePath().toLower(); + fi.absoluteFilePath().toLower();
} }
QString mname(mutexname); QString mname(mutexname);
if (idx >= 0) { if (idx >= 0)
mname += QString::number(idx); mname += QString::number(idx);
}
Qt::HANDLE mutex; Qt::HANDLE mutex;
if (doCreate) { if (doCreate) {
mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); },
{ mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) { if (!mutex) {
qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
return 0; return 0;
} }
} }
else { else {
mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); },
{ mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) { if (!mutex) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) { if (GetLastError() != ERROR_FILE_NOT_FOUND)
qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
}
return 0; return 0;
} }
} }
@ -110,33 +108,27 @@ bool QtLockedFile::lock(LockMode mode, bool block)
return false; return false;
} }
if (mode == NoLock) { if (mode == NoLock)
return unlock(); return unlock();
}
if (mode == m_lock_mode) { if (mode == m_lock_mode)
return true; return true;
}
if (m_lock_mode != NoLock) { if (m_lock_mode != NoLock)
unlock(); unlock();
}
if (!wmutex && !(wmutex = getMutexHandle(-1, true))) { if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
return false; return false;
}
if (!waitMutex(wmutex, block)) { if (!waitMutex(wmutex, block))
return false; return false;
}
if (mode == ReadLock) { if (mode == ReadLock) {
int idx = 0; int idx = 0;
for (; idx < MAX_READERS; idx++) { for (; idx < MAX_READERS; idx++) {
rmutex = getMutexHandle(idx, false); rmutex = getMutexHandle(idx, false);
if (!rmutex || waitMutex(rmutex, false)) { if (!rmutex || waitMutex(rmutex, false))
break; break;
}
CloseHandle(rmutex); CloseHandle(rmutex);
} }
bool ok = true; bool ok = true;
@ -147,34 +139,30 @@ bool QtLockedFile::lock(LockMode mode, bool block)
} }
else if (!rmutex) { else if (!rmutex) {
rmutex = getMutexHandle(idx, true); rmutex = getMutexHandle(idx, true);
if (!rmutex || !waitMutex(rmutex, false)) { if (!rmutex || !waitMutex(rmutex, false))
ok = false; ok = false;
}
} }
if (!ok && rmutex) { if (!ok && rmutex) {
CloseHandle(rmutex); CloseHandle(rmutex);
rmutex = 0; rmutex = 0;
} }
ReleaseMutex(wmutex); ReleaseMutex(wmutex);
if (!ok) { if (!ok)
return false; return false;
}
} }
else { else {
Q_ASSERT(rmutexes.isEmpty()); Q_ASSERT(rmutexes.isEmpty());
for (int i = 0; i < MAX_READERS; i++) { for (int i = 0; i < MAX_READERS; i++) {
Qt::HANDLE mutex = getMutexHandle(i, false); Qt::HANDLE mutex = getMutexHandle(i, false);
if (mutex) { if (mutex)
rmutexes.append(mutex); rmutexes.append(mutex);
}
} }
if (rmutexes.size()) { if (rmutexes.size()) {
DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
TRUE, block ? INFINITE : 0); TRUE, block ? INFINITE : 0);
if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
if (res != WAIT_TIMEOUT) { if (res != WAIT_TIMEOUT)
qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
}
m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
unlock(); unlock();
return false; return false;
@ -193,9 +181,8 @@ bool QtLockedFile::unlock()
return false; return false;
} }
if (!isLocked()) { if (!isLocked())
return true; return true;
}
if (m_lock_mode == ReadLock) { if (m_lock_mode == ReadLock) {
ReleaseMutex(rmutex); ReleaseMutex(rmutex);
@ -203,7 +190,7 @@ bool QtLockedFile::unlock()
rmutex = 0; rmutex = 0;
} }
else { else {
foreach (Qt::HANDLE mutex, rmutexes) { foreach(Qt::HANDLE mutex, rmutexes) {
ReleaseMutex(mutex); ReleaseMutex(mutex);
CloseHandle(mutex); CloseHandle(mutex);
} }
@ -217,10 +204,8 @@ bool QtLockedFile::unlock()
QtLockedFile::~QtLockedFile() QtLockedFile::~QtLockedFile()
{ {
if (isOpen()) { if (isOpen())
unlock(); unlock();
} if (wmutex)
if (wmutex) {
CloseHandle(wmutex); CloseHandle(wmutex);
}
} }

View File

@ -1,46 +1,40 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/
@ -68,28 +62,31 @@
that will be compared instead. that will be compared instead.
The application should create the QtSingleApplication object early The application should create the QtSingleApplication object early
in the startup phase, and call isRunning() or sendMessage() to in the startup phase, and call isRunning() to find out if another
find out if another instance of this application is already instance of this application is already running. If isRunning()
running. Startup parameters (e.g. the name of the file the user returns false, it means that no other instance is running, and
wanted this new instance to open) can be passed to the running this instance has assumed the role as the running instance. In
instance in the sendMessage() function. this case, the application should continue with the initialization
of the application user interface before entering the event loop
with exec(), as normal.
If isRunning() or sendMessage() returns false, it means that no The messageReceived() signal will be emitted when the running
other instance is running, and this instance has assumed the role application receives messages from another instance of the same
as the running instance. The application should continue with the application. When a message is received it might be helpful to the
initialization of the application user interface before entering user to raise the application so that it becomes visible. To
the event loop with exec(), as normal. The messageReceived() facilitate this, QtSingleApplication provides the
signal will be emitted when the application receives messages from setActivationWindow() function and the activateWindow() slot.
another instance of the same application.
If isRunning() or sendMessage() returns true, another instance is If isRunning() returns true, another instance is already
already running, and the application should terminate or enter running. It may be alerted to the fact that another instance has
client mode. started by using the sendMessage() function. Also data such as
startup parameters (e.g. the name of the file the user wanted this
new instance to open) can be passed to the running instance with
this function. Then, the application should terminate (or enter
client mode).
If a message is received it might be helpful to the user to raise If isRunning() returns true, but sendMessage() fails, that is an
the application so that it becomes visible. To facilitate this, indication that the running instance is frozen.
QtSingleApplication provides the setActivationWindow() function
and the activateWindow() slot.
Here's an example that shows how to convert an existing Here's an example that shows how to convert an existing
application to use QtSingleApplication. It is very simple and does application to use QtSingleApplication. It is very simple and does
@ -103,7 +100,6 @@
QApplication app(argc, argv); QApplication app(argc, argv);
MyMainWidget mmw; MyMainWidget mmw;
mmw.show(); mmw.show();
return app.exec(); return app.exec();
} }
@ -114,19 +110,17 @@
QtSingleApplication app(argc, argv); QtSingleApplication app(argc, argv);
if (app.isRunning()) if (app.isRunning())
return 0; return !app.sendMessage(someDataString);
MyMainWidget mmw; MyMainWidget mmw;
app.setActivationWindow(&mmw); app.setActivationWindow(&mmw);
mmw.show(); mmw.show();
return app.exec(); return app.exec();
} }
\endcode \endcode
Once this QtSingleApplication instance is destroyed(for example, Once this QtSingleApplication instance is destroyed (normally when
when the user quits), when the user next attempts to run the the process exits or crashes), when the user next attempts to run the
application this instance will not, of course, be encountered. The application this instance will not, of course, be encountered. The
next instance to call isRunning() or sendMessage() will assume the next instance to call isRunning() or sendMessage() will assume the
role as the new running instance. role as the new running instance.
@ -143,7 +137,7 @@ void QtSingleApplication::sysInit(const QString &appId)
{ {
actWin = 0; actWin = 0;
peer = new QtLocalPeer(this, appId); peer = new QtLocalPeer(this, appId);
connect(peer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString))); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
} }
@ -157,11 +151,10 @@ void QtSingleApplication::sysInit(const QString &appId)
QtSingleCoreApplication instead. QtSingleCoreApplication instead.
*/ */
QtSingleApplication::QtSingleApplication(int &argc, char** argv, bool GUIenabled) QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
: QApplication(argc, argv, GUIenabled) : QApplication(argc, argv, GUIenabled)
, peer(0)
, actWin(0)
{ {
sysInit();
} }
@ -171,14 +164,67 @@ QtSingleApplication::QtSingleApplication(int &argc, char** argv, bool GUIenabled
QAppliation constructor. QAppliation constructor.
*/ */
QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char** argv) QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
: QApplication(argc, argv) : QApplication(argc, argv)
, peer(0)
, actWin(0)
{ {
sysInit(appId); sysInit(appId);
} }
#if QT_VERSION < 0x050000
/*!
Creates a QtSingleApplication object. The application identifier
will be QCoreApplication::applicationFilePath(). \a argc, \a
argv, and \a type are passed on to the QAppliation constructor.
*/
QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
: QApplication(argc, argv, type)
{
}
# if defined(Q_WS_X11)
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
and \a cmap are passed on to the QApplication constructor.
*/
QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, visual, cmap)
{
sysInit();
}
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
argv, \a visual, and \a cmap are passed on to the QApplication
constructor.
*/
QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, argc, argv, visual, cmap)
{
sysInit();
}
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be \a appId. \a dpy, \a argc, \a
argv, \a visual, and \a cmap are passed on to the QApplication
constructor.
*/
QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, argc, argv, visual, cmap)
{
sysInit(appId);
}
# endif // Q_WS_X11
#endif // QT_VERSION < 0x050000
/*! /*!
Returns true if another instance of this application is running; Returns true if another instance of this application is running;
otherwise false. otherwise false.
@ -192,11 +238,7 @@ QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char**
bool QtSingleApplication::isRunning() bool QtSingleApplication::isRunning()
{ {
#ifdef Q_OS_HAIKU return peer->isClient();
return false;
#else
return (peer && peer->isClient());
#endif
} }
void QtSingleApplication::setAppId(const QString &id) void QtSingleApplication::setAppId(const QString &id)
@ -220,11 +262,7 @@ void QtSingleApplication::setAppId(const QString &id)
*/ */
bool QtSingleApplication::sendMessage(const QString &message, int timeout) bool QtSingleApplication::sendMessage(const QString &message, int timeout)
{ {
#ifdef Q_OS_HAIKU return peer->sendMessage(message, timeout);
return false;
#else
return (peer && peer->sendMessage(message, timeout));
#endif
} }
@ -234,7 +272,7 @@ bool QtSingleApplication::sendMessage(const QString &message, int timeout)
*/ */
QString QtSingleApplication::id() const QString QtSingleApplication::id() const
{ {
return (peer ? peer->applicationId() : QString()); return peer->applicationId();
} }
@ -253,16 +291,10 @@ QString QtSingleApplication::id() const
void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
{ {
actWin = aw; actWin = aw;
if (!peer) { if (activateOnMessage)
return; connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
} else
disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
if (activateOnMessage) {
connect(peer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
}
else {
disconnect(peer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
}
} }
@ -303,7 +335,6 @@ void QtSingleApplication::activateWindow()
actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
actWin->raise(); actWin->raise();
actWin->activateWindow(); actWin->activateWindow();
actWin->setFocus();
} }
} }

View File

@ -1,46 +1,40 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** All rights reserved. ** Contact: http://www.qt-project.org/legal
** Contact: Nokia Corporation (qt-info@nokia.com)
** **
** This file is part of a Qt Solutions component. ** This file is part of the Qt Solutions component.
** **
** Commercial Usage ** $QT_BEGIN_LICENSE:BSD$
** Licensees holding valid Qt Commercial licenses may use this file in ** You may use this file under the terms of the BSD license as follows:
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
** **
** GNU Lesser General Public License Usage ** "Redistribution and use in source and binary forms, with or without
** Alternatively, this file may be used under the terms of the GNU Lesser ** modification, are permitted provided that the following conditions are
** General Public License version 2.1 as published by the Free Software ** met:
** Foundation and appearing in the file LICENSE.LGPL included in the ** * Redistributions of source code must retain the above copyright
** packaging of this file. Please review the following information to ** notice, this list of conditions and the following disclaimer.
** ensure the GNU Lesser General Public License version 2.1 requirements ** * Redistributions in binary form must reproduce the above copyright
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
** **
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
** **
** GNU General Public License Usage ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** Alternatively, this file may be used under the terms of the GNU ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** General Public License version 3.0 as published by the Free Software ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** Foundation and appearing in the file LICENSE.GPL included in the ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** packaging of this file. Please review the following information to ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** ensure the GNU General Public License version 3.0 requirements will be ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** met: http://www.gnu.org/copyleft/gpl.html. ** 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."
** **
** Please note Third Party Software included with Qt Solutions may impose ** $QT_END_LICENSE$
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
** **
****************************************************************************/ ****************************************************************************/
@ -58,8 +52,16 @@ class FALKON_EXPORT QtSingleApplication : public QApplication
Q_OBJECT Q_OBJECT
public: public:
QtSingleApplication(int &argc, char** argv, bool GUIenabled = true); QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
QtSingleApplication(const QString &id, int &argc, char** argv); QtSingleApplication(const QString &id, int &argc, char **argv);
#if QT_VERSION < 0x050000
QtSingleApplication(int &argc, char **argv, Type type);
# if defined(Q_WS_X11)
QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
# endif // Q_WS_X11
#endif // QT_VERSION < 0x050000
bool isRunning(); bool isRunning();
void setAppId(const QString &id); void setAppId(const QString &id);
@ -70,7 +72,7 @@ public:
// Obsolete: // Obsolete:
void initialize(bool dummy = true) void initialize(bool dummy = true)
{ isRunning(); Q_UNUSED(dummy) } { isRunning(); Q_UNUSED(dummy) }
void removeLockFile(); void removeLockFile();
@ -85,8 +87,8 @@ Q_SIGNALS:
private: private:
void sysInit(const QString &appId = QString()); void sysInit(const QString &appId = QString());
QtLocalPeer* peer; QtLocalPeer *peer;
QWidget* actWin; QWidget *actWin;
}; };
#endif #endif // QTSINGLEAPPLICATION_H