ukui-clock/singleApplication.cpp

117 lines
4.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/
#include "singleApplication.h"
#include <QtNetwork/QLocalSocket>
#include <QFileInfo>
#define TIME_OUT (500) // 500ms
SingleApplication::SingleApplication(int &argc, char **argv)
: QApplication(argc, argv)
, w(NULL)
, _isRunning(false)
, _localServer(NULL) {
// 取应用程序名作为LocalServer的名字
// Take the application name as the name of localserver
_serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName() + QLatin1String(getenv("DISPLAY"));
_initLocalConnection();
}
// 检查是否已經有一个实例在运行, true - 有实例运行, false - 没有实例运行
// Check whether there is an instance running, true - there is an instance running, false - there is no instance running
bool SingleApplication::isRunning() {
return _isRunning;
}
// 通过socket通讯实现程序单实例运行监听到新的连接时触发该函数
// The single instance of the program is run through socket communication, which is triggered when listening to a new connection
void SingleApplication::_newLocalConnection()
{
//返回下一个挂起的连接作为连接的QLocalSocket对象。
QLocalSocket *socket = _localServer->nextPendingConnection();
if (socket) {
//该函数将阻塞直到可以读取数据并且发出readyRead信号为止。 该函数将在毫秒毫秒后超时; 默认超时为30000毫秒。
// 如果有可供读取的数据则该函数返回true否则返回false 否则返回false如果发生错误或操作超时
socket->waitForReadyRead(2*TIME_OUT);
//关闭socket
delete socket;
// 其他处理,如:读取启动参数
// Other processing, such as reading start parameters
_activateWindow();
}
}
// 通过socket通讯实现程序单实例运行
// Through socket communication, the single instance of program can be run,
// 初始化本地连接如果连接不上server则创建否则退出
// Initialize the local connection. If the server cannot be connected, create it. Otherwise, exit
void SingleApplication::_initLocalConnection()
{
_isRunning = false;
QLocalSocket socket;
socket.connectToServer(_serverName);
//建立链接超时时间500ms
if (socket.waitForConnected(TIME_OUT)) {
fprintf(stderr, "%s already running.\n",
_serverName.toLocal8Bit().constData());
//有连接,改状态,直接返回
_isRunning = true;
// 其他处理,如:将启动参数发送到服务端
// Other processing, such as sending startup parameters to the server
return;
}
//连接不上服务器,就创建一个
// If you can't connect to the server, create a
_newLocalServer();
}
// 创建LocalServer
// Create localserver
void SingleApplication::_newLocalServer()
{
_localServer = new QLocalServer(this);
//信号:每当有新的连接
connect(_localServer, SIGNAL(newConnection()), this, SLOT(_newLocalConnection()));
if (!_localServer->listen(_serverName)) {
// 此时监听失败,可能是程序崩溃时,残留进程服务导致的,移除之
// At this time, listening fails. It may be caused by the residual process service when the program crashes. Remove it
if (_localServer->serverError() == QAbstractSocket::AddressInUseError) {
QLocalServer::removeServer(_serverName); // <-- 重点 a key
_localServer->listen(_serverName); // 再次监听
// Monitor again
}
}
}
// 激活主窗口
// Activate main window
void SingleApplication::_activateWindow() {
if (w) {
w->show();
w->raise();
w->activateWindow(); // 激活窗口
// Activate window
}
}