2020-01-17 13:56:30 +08:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
|
|
|
|
|
* 2010-2016 LXQt team
|
|
|
|
|
*
|
|
|
|
|
* 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 2, 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, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
|
|
|
* 02110-1301, USA.
|
|
|
|
|
**/
|
2019-07-04 15:46:12 +08:00
|
|
|
#include "modulemanager.h"
|
|
|
|
|
#include "ukuimodule.h"
|
2019-12-31 09:29:25 +08:00
|
|
|
#include "idlewatcher.h"
|
2019-07-04 15:46:12 +08:00
|
|
|
|
2019-07-27 17:45:54 +08:00
|
|
|
#include <QCoreApplication>
|
2019-12-30 09:49:50 +08:00
|
|
|
#include "xdgautostart.h"
|
|
|
|
|
#include "xdgdesktopfile.h"
|
|
|
|
|
#include "xdgdirs.h"
|
2019-07-04 15:46:12 +08:00
|
|
|
#include <QFileInfo>
|
2019-07-13 17:57:05 +08:00
|
|
|
#include <QStringList>
|
|
|
|
|
#include <QSettings>
|
|
|
|
|
#include <QStandardPaths>
|
2019-07-04 15:46:12 +08:00
|
|
|
#include <QDebug>
|
2019-12-09 11:42:40 +08:00
|
|
|
#include <QTimer>
|
2020-03-24 15:40:52 +08:00
|
|
|
#include <QGSettings/QGSettings>
|
2020-08-18 14:43:21 +08:00
|
|
|
#include <QMediaPlayer>
|
2020-03-24 15:40:52 +08:00
|
|
|
/* qt会将glib里的signals成员识别为宏,所以取消该宏
|
|
|
|
|
* 后面如果用到signals时,使用Q_SIGNALS代替即可
|
|
|
|
|
**/
|
|
|
|
|
#ifdef signals
|
|
|
|
|
#undef signals
|
|
|
|
|
#endif
|
2019-07-04 15:46:12 +08:00
|
|
|
|
2020-03-27 21:19:23 +08:00
|
|
|
#define SESSION_REQUIRED_COMPONENTS "org.ukui.session.required-components"
|
|
|
|
|
#define SESSION_REQUIRED_COMPONENTS_PATH "/org/ukui/desktop/session/required-components/"
|
|
|
|
|
|
2020-08-18 15:18:59 +08:00
|
|
|
void ModuleManager::playBootMusic(){
|
2020-08-18 14:43:21 +08:00
|
|
|
//set default value of whether boot-music is opened
|
|
|
|
|
bool play_music = true;
|
|
|
|
|
if (QGSettings::isSchemaInstalled("org.ukui.session")){
|
|
|
|
|
QGSettings *gset = new QGSettings("org.ukui.session","/org/ukui/desktop/session/",this);
|
|
|
|
|
play_music = gset->get("boot-music").toBool();
|
|
|
|
|
}
|
|
|
|
|
if (play_music) {
|
|
|
|
|
QMediaPlayer *player = new QMediaPlayer;
|
|
|
|
|
player->setMedia(QUrl("qrc:/startup.wav"));
|
|
|
|
|
player->play();
|
|
|
|
|
QObject::connect(player,&QMediaPlayer::stateChanged,[=](QMediaPlayer::State state) {
|
|
|
|
|
player->stop();
|
|
|
|
|
player->deleteLater();
|
|
|
|
|
//delete player;
|
|
|
|
|
qDebug() << "play state is " << state;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 15:40:52 +08:00
|
|
|
ModuleManager::ModuleManager( QObject* parent)
|
|
|
|
|
: QObject(parent)
|
2019-07-04 15:46:12 +08:00
|
|
|
{
|
2020-01-03 21:01:01 +08:00
|
|
|
constructStartupList();
|
2019-07-04 15:46:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ModuleManager::~ModuleManager()
|
|
|
|
|
{
|
|
|
|
|
ModulesMapIterator i(mNameMap);
|
|
|
|
|
while (i.hasNext())
|
|
|
|
|
{
|
|
|
|
|
i.next();
|
|
|
|
|
|
|
|
|
|
auto p = i.value();
|
|
|
|
|
disconnect(p, SIGNAL(finished(int, QProcess::ExitStatus)), nullptr, nullptr);
|
|
|
|
|
|
|
|
|
|
delete p;
|
|
|
|
|
mNameMap[i.key()] = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-03 21:01:01 +08:00
|
|
|
void ModuleManager::constructStartupList()
|
2019-07-04 15:46:12 +08:00
|
|
|
{
|
2020-03-27 21:19:23 +08:00
|
|
|
const QByteArray id(SESSION_REQUIRED_COMPONENTS);
|
|
|
|
|
QString window_manager;
|
|
|
|
|
QString panel;
|
|
|
|
|
QString file_manager;
|
|
|
|
|
QString wm_notfound;
|
2020-04-18 20:36:34 +08:00
|
|
|
if (QGSettings::isSchemaInstalled(id)) {
|
2020-03-27 21:19:23 +08:00
|
|
|
const QGSettings* gs = new QGSettings(SESSION_REQUIRED_COMPONENTS,SESSION_REQUIRED_COMPONENTS_PATH,this);
|
|
|
|
|
window_manager = gs->get("windowmanager").toString() + ".desktop";
|
|
|
|
|
panel = gs->get("panel").toString() + ".desktop";
|
|
|
|
|
file_manager = gs->get("filemanager").toString() + ".desktop";
|
|
|
|
|
wm_notfound = gs->get("windowmanager").toString();
|
2020-04-18 20:36:34 +08:00
|
|
|
} else {
|
2020-03-27 21:19:23 +08:00
|
|
|
//gsetting安装失败,或无法获取,设置默认值
|
|
|
|
|
qDebug() << "从gsettings 中或取值失败,设置默认值";
|
|
|
|
|
window_manager = "ukwm.desktop";
|
|
|
|
|
panel = "ukui-panel.desktop";
|
|
|
|
|
file_manager = "peony-qt-desktop.desktop";
|
|
|
|
|
}
|
2020-01-03 21:01:01 +08:00
|
|
|
|
|
|
|
|
QStringList desktop_paths;
|
|
|
|
|
desktop_paths << "/usr/share/applications";
|
2020-02-29 17:38:11 +08:00
|
|
|
desktop_paths << "/etc/xdg/autostart";
|
2020-01-03 21:01:01 +08:00
|
|
|
bool panel_found = false;
|
|
|
|
|
bool fm_found = false;
|
|
|
|
|
bool wm_found = false;
|
|
|
|
|
|
|
|
|
|
const auto files = XdgAutoStart::desktopFileList(desktop_paths, false);
|
2020-04-18 20:36:34 +08:00
|
|
|
for (const XdgDesktopFile& file : files) {
|
|
|
|
|
if (QFileInfo(file.fileName()).fileName() == panel) {
|
2020-01-03 21:01:01 +08:00
|
|
|
mPanel = file;
|
|
|
|
|
panel_found = true;
|
2020-03-24 15:40:52 +08:00
|
|
|
qDebug() << "panel has been found";
|
2020-01-03 21:01:01 +08:00
|
|
|
}
|
2020-04-18 20:36:34 +08:00
|
|
|
if (QFileInfo(file.fileName()).fileName() == file_manager) {
|
2020-01-03 21:01:01 +08:00
|
|
|
mFileManager = file;
|
|
|
|
|
fm_found = true;
|
2020-03-24 15:40:52 +08:00
|
|
|
qDebug() << "filemanager has been found";
|
2020-01-03 21:01:01 +08:00
|
|
|
}
|
2020-04-18 20:36:34 +08:00
|
|
|
if (QFileInfo(file.fileName()).fileName() == window_manager) {
|
2020-01-03 21:01:01 +08:00
|
|
|
mWindowManager = file;
|
|
|
|
|
wm_found = true;
|
2020-03-24 15:40:52 +08:00
|
|
|
qDebug() << "windowmanager has been found";
|
2020-01-03 21:01:01 +08:00
|
|
|
}
|
|
|
|
|
|
2020-04-18 20:36:34 +08:00
|
|
|
if (fm_found && panel_found && wm_found)
|
2020-01-03 21:01:01 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-18 20:36:34 +08:00
|
|
|
if (wm_found == false) {
|
2020-06-18 13:10:17 +08:00
|
|
|
QFileInfo check_ukwm("/usr/share/applications/ukwm.desktop");
|
|
|
|
|
QFileInfo check_ukuikwin("/usr/share/applications/ukui-kwin.desktop");
|
|
|
|
|
if(check_ukwm.exists()) {
|
|
|
|
|
window_manager = "ukwm.desktop";
|
|
|
|
|
}else if(check_ukuikwin.exists()) {
|
|
|
|
|
window_manager = "ukui-kwin.desktop";
|
|
|
|
|
}
|
2020-03-08 11:39:34 +08:00
|
|
|
}
|
|
|
|
|
|
2020-06-18 13:10:17 +08:00
|
|
|
for (const XdgDesktopFile& file : files) {
|
|
|
|
|
if (QFileInfo(file.fileName()).fileName() == window_manager){
|
|
|
|
|
mWindowManager = file;
|
|
|
|
|
wm_found = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//配置文件所给的窗口管理器找不到.desktop文件时,将所给QString设为可执行命令,创建一个desktop文件赋给mWindowManager
|
|
|
|
|
// if (wm_found == false) {
|
|
|
|
|
// mWindowManager = XdgDesktopFile(XdgDesktopFile::ApplicationType,"window-manager", wm_notfound);
|
|
|
|
|
// qDebug() << "windowmanager has been created";
|
|
|
|
|
// }
|
|
|
|
|
|
2020-01-03 21:01:01 +08:00
|
|
|
QString desktop_phase = "X-UKUI-Autostart-Phase";
|
|
|
|
|
QString desktop_type = "Type";
|
2020-03-07 19:52:28 +08:00
|
|
|
//设置excludeHidden为true,判断所有desktop文件的Hidden值,若为true,则将其从自启列表中去掉
|
|
|
|
|
const XdgDesktopFileList all_file_list = XdgAutoStart::desktopFileList(true);
|
2020-01-03 21:01:01 +08:00
|
|
|
for (XdgDesktopFileList::const_iterator i = all_file_list.constBegin(); i != all_file_list.constEnd(); ++i)
|
|
|
|
|
{
|
2020-07-25 16:01:23 +08:00
|
|
|
QString filename = QFileInfo(i->fileName()).fileName();
|
|
|
|
|
if(filename == panel || filename == file_manager || filename == window_manager){
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-01-03 21:01:01 +08:00
|
|
|
const XdgDesktopFile file = *i;
|
|
|
|
|
if (i->contains(desktop_phase)) {
|
|
|
|
|
QStringList s1 =file.value(desktop_phase).toString().split(QLatin1Char(';'));
|
|
|
|
|
if (s1.contains("Initialization")) {
|
|
|
|
|
mInitialization << file;
|
|
|
|
|
} else if (s1.contains("Desktop")) {
|
|
|
|
|
mDesktop << file;
|
|
|
|
|
} else if (s1.contains("Application")) {
|
|
|
|
|
mApplication << file;
|
|
|
|
|
}
|
|
|
|
|
} else if (i->contains(desktop_type)) {
|
|
|
|
|
QStringList s2 = file.value(desktop_type).toString().split(QLatin1Char(';'));
|
|
|
|
|
if (s2.contains("Application")) {
|
|
|
|
|
mApplication << file;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList force_app_paths;
|
|
|
|
|
force_app_paths << "/usr/share/ukui/applications";
|
|
|
|
|
const XdgDesktopFileList force_file_list = XdgAutoStart::desktopFileList(force_app_paths, true);
|
|
|
|
|
for (XdgDesktopFileList::const_iterator i = force_file_list.constBegin(); i != force_file_list.constEnd(); ++i)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << (*i).fileName();
|
|
|
|
|
mForceApplication << *i;
|
2019-12-31 11:13:26 +08:00
|
|
|
}
|
2019-07-04 15:46:12 +08:00
|
|
|
}
|
|
|
|
|
|
2020-01-03 21:01:01 +08:00
|
|
|
/* Startup Phare:
|
|
|
|
|
* Initialization
|
|
|
|
|
* WindowManager
|
|
|
|
|
* Panel
|
|
|
|
|
* FileManager
|
|
|
|
|
* Desktop
|
|
|
|
|
* Application
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void ModuleManager::startup()
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "Start Initialization app: ";
|
2020-04-18 20:36:34 +08:00
|
|
|
for (XdgDesktopFileList::const_iterator i = mInitialization.constBegin(); i != mInitialization.constEnd(); ++i) {
|
2019-12-31 11:13:26 +08:00
|
|
|
startProcess(*i, true);
|
|
|
|
|
}
|
2020-07-30 13:46:45 +08:00
|
|
|
QTimer::singleShot(1000, this, [&]()
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "Start window manager: " << mWindowManager.name();
|
|
|
|
|
startProcess(mWindowManager, true);
|
2020-03-08 11:39:34 +08:00
|
|
|
|
2020-07-30 13:46:45 +08:00
|
|
|
QTimer::singleShot(1000, this, [&]()
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "Start file manager: " << mFileManager.name();
|
|
|
|
|
startProcess(mFileManager, true);
|
2020-01-03 21:01:01 +08:00
|
|
|
|
2020-07-30 13:46:45 +08:00
|
|
|
qDebug() << "Start panel: " << mPanel.name();
|
|
|
|
|
startProcess(mPanel, true);
|
2020-03-24 15:40:52 +08:00
|
|
|
|
2020-08-18 15:18:59 +08:00
|
|
|
playBootMusic();
|
2020-08-18 14:43:21 +08:00
|
|
|
|
2020-07-30 13:46:45 +08:00
|
|
|
qDebug() << "wait for ukui-settings-daemon start-up";
|
|
|
|
|
timer = new QTimer();
|
|
|
|
|
connect(timer,SIGNAL(timeout()),this,SLOT(timerUpdate()));
|
|
|
|
|
timer->start(3000);
|
|
|
|
|
});
|
|
|
|
|
});
|
2020-01-17 13:56:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleManager::timerUpdate(){
|
|
|
|
|
timer->stop();
|
2020-02-07 18:14:18 +08:00
|
|
|
delete timer;
|
2020-01-17 13:56:30 +08:00
|
|
|
|
2020-01-03 21:01:01 +08:00
|
|
|
qDebug() << "Start desktop: ";
|
2020-04-18 20:36:34 +08:00
|
|
|
for (XdgDesktopFileList::const_iterator i = mDesktop.constBegin(); i != mDesktop.constEnd(); ++i) {
|
2019-12-31 11:13:26 +08:00
|
|
|
startProcess(*i, true);
|
2019-12-09 11:42:40 +08:00
|
|
|
}
|
|
|
|
|
|
2020-01-03 21:01:01 +08:00
|
|
|
qDebug() << "Start application: ";
|
2019-12-09 11:42:40 +08:00
|
|
|
QFile file("/etc/xdg/autostart/kylin-nm.desktop");
|
2020-04-18 20:36:34 +08:00
|
|
|
for (XdgDesktopFileList::const_iterator i = mApplication.constBegin(); i != mApplication.constEnd(); ++i) {
|
2020-03-07 19:52:28 +08:00
|
|
|
qDebug() << i->fileName();
|
2019-12-09 11:42:40 +08:00
|
|
|
if(i->fileName()=="/etc/xdg/autostart/nm-applet.desktop" && file.exists()){
|
2019-12-09 15:22:02 +08:00
|
|
|
qDebug() << "the kylin-nm exist so the nm-applet will not start";
|
2019-12-09 11:42:40 +08:00
|
|
|
continue;
|
|
|
|
|
}
|
2020-01-03 21:01:01 +08:00
|
|
|
startProcess(*i, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qDebug() << "Start force application: ";
|
2020-03-24 15:40:52 +08:00
|
|
|
const QString ws = "ukui-window-switch";
|
|
|
|
|
XdgDesktopFile ukui_ws= XdgDesktopFile(XdgDesktopFile::ApplicationType,"ukui-window-switch", ws);
|
|
|
|
|
startProcess(ukui_ws,true);
|
2020-01-03 21:01:01 +08:00
|
|
|
for (XdgDesktopFileList::const_iterator i = mForceApplication.constBegin(); i != mForceApplication.constEnd(); ++i){
|
2020-02-29 17:38:11 +08:00
|
|
|
startProcess(*i, true);
|
2019-07-04 15:46:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-30 10:53:30 +08:00
|
|
|
void ModuleManager::startProcess(const XdgDesktopFile& file, bool required)
|
2019-07-04 15:46:12 +08:00
|
|
|
{
|
|
|
|
|
QStringList args = file.expandExecString();
|
2020-04-18 20:36:34 +08:00
|
|
|
if (args.isEmpty()) {
|
2019-08-30 10:53:30 +08:00
|
|
|
qWarning() << "Wrong desktop file: " << file.fileName();
|
2019-07-04 15:46:12 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString name = QFileInfo(file.fileName()).fileName();
|
2020-04-18 20:36:34 +08:00
|
|
|
if (!mNameMap.contains(name)) {
|
2019-12-09 11:42:40 +08:00
|
|
|
UkuiModule* proc = new UkuiModule(file, this);
|
2020-03-24 15:40:52 +08:00
|
|
|
connect(proc, &UkuiModule::moduleStateChanged, this, &ModuleManager::moduleStateChanged);
|
2019-12-09 11:42:40 +08:00
|
|
|
proc->start();
|
2019-07-04 15:46:12 +08:00
|
|
|
|
2019-12-09 11:42:40 +08:00
|
|
|
mNameMap[name] = proc;
|
|
|
|
|
|
2020-04-18 20:36:34 +08:00
|
|
|
if (required || autoRestart(file)) {
|
2020-01-03 21:01:01 +08:00
|
|
|
connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
|
2019-12-09 11:42:40 +08:00
|
|
|
this, SLOT(restartModules(int, QProcess::ExitStatus)));
|
2020-01-03 21:01:01 +08:00
|
|
|
}
|
2019-12-09 11:42:40 +08:00
|
|
|
}
|
2019-07-04 15:46:12 +08:00
|
|
|
}
|
|
|
|
|
|
2019-08-30 10:53:30 +08:00
|
|
|
void ModuleManager::startProcess(const QString& name, bool required)
|
2019-07-04 15:46:12 +08:00
|
|
|
{
|
2019-08-16 15:58:44 +08:00
|
|
|
QString desktop_name = name + ".desktop";
|
|
|
|
|
QStringList desktop_paths;
|
|
|
|
|
desktop_paths << "/usr/share/applications";
|
2019-12-09 11:42:40 +08:00
|
|
|
|
|
|
|
|
const auto files = XdgAutoStart::desktopFileList(desktop_paths, false);
|
2020-04-18 20:36:34 +08:00
|
|
|
for (const XdgDesktopFile& file : files) {
|
|
|
|
|
if (QFileInfo(file.fileName()).fileName() == desktop_name) {
|
2019-12-09 11:42:40 +08:00
|
|
|
startProcess(file, required);
|
|
|
|
|
return;
|
2019-07-04 15:46:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleManager::stopProcess(const QString& name)
|
|
|
|
|
{
|
|
|
|
|
if (mNameMap.contains(name))
|
|
|
|
|
mNameMap[name]->terminate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ModuleManager::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
|
|
|
|
|
{
|
|
|
|
|
if (eventType != "xcb_generic_event_t") // We only want to handle XCB events
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-07-13 17:57:05 +08:00
|
|
|
|
2020-01-03 21:01:01 +08:00
|
|
|
bool ModuleManager::autoRestart(const XdgDesktopFile &file)
|
|
|
|
|
{
|
|
|
|
|
QString auto_restart = "X-UKUI-AutoRestart";
|
|
|
|
|
return file.value(auto_restart).toBool();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-13 17:57:05 +08:00
|
|
|
void ModuleManager::restartModules(int /*exitCode*/, QProcess::ExitStatus exitStatus)
|
|
|
|
|
{
|
|
|
|
|
UkuiModule* proc = qobject_cast<UkuiModule*>(sender());
|
2020-04-18 20:36:34 +08:00
|
|
|
if (proc->restartNum > 10) {
|
2019-12-31 11:13:26 +08:00
|
|
|
mNameMap.remove(proc->fileName);
|
|
|
|
|
disconnect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), nullptr, nullptr);
|
|
|
|
|
proc->deleteLater();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-07-13 17:57:05 +08:00
|
|
|
if (nullptr == proc) {
|
|
|
|
|
qWarning() << "Got an invalid (null) module to restart, Ignoring it";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-18 20:36:34 +08:00
|
|
|
if (!proc->isTerminating()) {
|
2019-07-13 17:57:05 +08:00
|
|
|
QString procName = proc->file.name();
|
2020-04-18 20:36:34 +08:00
|
|
|
switch (exitStatus) {
|
|
|
|
|
case QProcess::NormalExit:
|
|
|
|
|
qDebug() << "Process" << procName << "(" << proc << ") exited correctly.";
|
|
|
|
|
break;
|
|
|
|
|
case QProcess::CrashExit:
|
|
|
|
|
qDebug() << "Process" << procName << "(" << proc << ") has to be restarted";
|
|
|
|
|
proc->start();
|
|
|
|
|
proc->restartNum++;
|
|
|
|
|
return;
|
|
|
|
|
default:
|
|
|
|
|
qWarning() << "Unknown exit status: " << procName << "(" << proc << ")";
|
2019-07-13 17:57:05 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mNameMap.remove(proc->fileName);
|
|
|
|
|
proc->deleteLater();
|
|
|
|
|
}
|
2019-07-27 17:45:54 +08:00
|
|
|
|
|
|
|
|
void ModuleManager::logout(bool doExit)
|
|
|
|
|
{
|
|
|
|
|
ModulesMapIterator i(mNameMap);
|
|
|
|
|
while (i.hasNext()) {
|
|
|
|
|
i.next();
|
|
|
|
|
qDebug() << "Module logout" << i.key();
|
|
|
|
|
UkuiModule *p = i.value();
|
|
|
|
|
p->terminate();
|
|
|
|
|
}
|
|
|
|
|
i.toFront();
|
|
|
|
|
while (i.hasNext()) {
|
|
|
|
|
i.next();
|
|
|
|
|
UkuiModule *p = i.value();
|
|
|
|
|
if (p->state() != QProcess::NotRunning && !p->waitForFinished(2000)) {
|
|
|
|
|
qWarning() << "Module " << qPrintable(i.key()) << " won't termiante .. killing.";
|
|
|
|
|
p->kill();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-18 20:36:34 +08:00
|
|
|
if (doExit) {
|
2020-04-18 17:43:12 +08:00
|
|
|
//QCoreApplication::exit(0);
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
2019-07-27 17:45:54 +08:00
|
|
|
}
|
2020-03-27 21:19:23 +08:00
|
|
|
|