diff --git a/src/modules/launcher/launcher.cpp b/src/modules/launcher/launcher.cpp index 4a4b065..6f3e757 100644 --- a/src/modules/launcher/launcher.cpp +++ b/src/modules/launcher/launcher.cpp @@ -247,8 +247,8 @@ bool Launcher::requestSendToDesktop(QString appId) // 创建桌面快捷方式文件 DesktopInfo dinfo(itemsMap[appId].info.path.toStdString()); - dinfo.getDesktopFile()->setKey(MainSection, dbusService.toStdString(), "X-Deepin-CreatedBy"); - dinfo.getDesktopFile()->setKey(MainSection, appId.toStdString(), "X-Deepin-AppID"); + dinfo.getDesktopFile()->setKey(MainSection, "X-Deepin-CreatedBy", dbusService.toStdString()); + dinfo.getDesktopFile()->setKey(MainSection, "X-Deepin-AppID", appId.toStdString()); if (!dinfo.getDesktopFile()->saveToFile(filePath.toStdString())) return false; diff --git a/src/modules/startmanager/startmanager.cpp b/src/modules/startmanager/startmanager.cpp index 4b4a2a8..b7790df 100644 --- a/src/modules/startmanager/startmanager.cpp +++ b/src/modules/startmanager/startmanager.cpp @@ -12,6 +12,7 @@ #include "meminfo.h" #include "../../service/impl/application_manager.h" +#include #include #include @@ -37,12 +38,25 @@ StartManager::StartManager(QObject *parent) , m_autostartFiles(getAutostartList()) , m_isDBusCalled(false) { + waitForDeadChild(); loadSysMemLimitConfig(); getDesktopToAutostartMap(); listenAutostartFileEvents(); startAutostartProgram(); } +static void sig_child(int signo) +{ + int stat; + int pid; + while((pid = waitpid(-1, &stat, WNOHANG)) > 0); +} + +void StartManager::waitForDeadChild() +{ + signal(SIGCHLD, sig_child); +} + bool StartManager::addAutostart(const QString &desktop) { setIsDBusCalled(true); @@ -369,24 +383,26 @@ bool StartManager::doLaunchAppWithOptions(QString desktopFile, uint32_t timestam bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp, QStringList files) { - QProcess process; + QProcess process; // NOTE(black_desk): this QProcess not used to start, we + // have to manually fork and exec to set + // GIO_LAUNCHED_DESKTOP_FILE_PID. QStringList cmdPrefixesEnvs; - QStringList envs; + QProcessEnvironment envs = QProcessEnvironment::systemEnvironment(); QString appId(QString::fromStdString(info->getId())); bool useProxy = shouldUseProxy(appId); - for (QString var : QProcess::systemEnvironment()) { - if (useProxy && (var.startsWith("auto_proxy") - || var.startsWith("http_proxy") - || var.startsWith("https_proxy") - || var.startsWith("ftp_proxy") - || var.startsWith("all_proxy") - || var.startsWith("SOCKS_SERVER") - || var.startsWith("no_proxy"))) { - continue; - } - - envs << var; + if (useProxy) { + envs.remove("auto_proxy"); + envs.remove("AUTO_PROXY"); + envs.remove("http_proxy"); + envs.remove("HTTP_PROXY"); + envs.remove("https_proxy"); + envs.remove("HTTPS_PROXY"); + envs.remove("ftp_proxy"); + envs.remove("FTP_PROXY"); + envs.remove("SOCKS_SERVER"); + envs.remove("no_proxy"); + envs.remove("NO_PROXY"); } // FIXME: Don't using env to control the window scale factor, this function @@ -403,12 +419,10 @@ bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp double scale = ret.isValid() ? ret.value() : 1.0; scale = scale > 0 ? scale : 1; const QString scaleStr = QString::number(scale, 'f', -1); - envs << "DEEPIN_WINE_SCALE=" + scaleStr; + envs.insert("DEEPIN_WINE_SCALE", scaleStr); } } - envs << cmdPrefixesEnvs; - QStringList exeArgs; auto stdCmdLine = cmdLine.toStdString(); @@ -438,8 +452,8 @@ bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp QString exec = exeArgs[0]; exeArgs.removeAt(0); - qDebug() << "Launching app, desktop: " << QString::fromStdString(info->getFileName()) << " exec: " << exec - << " args: " << exeArgs << " useProxy:" << useProxy << "appid:" << appId << "envs:" << envs; + qDebug() << "Launching app, desktop:" << QString::fromStdString(info->getFileName()) << "exec:" << exec + << "args:" << exeArgs << "useProxy:" << useProxy << "appid:" << appId << "envs:" << envs.toStringList(); process.setProgram(exec); process.setArguments(exeArgs); @@ -447,17 +461,36 @@ bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp // NOTE(black_desk): This have to be done after load system environment. // Set same env twice in qt make the first one gone. - envs << QString("GIO_LAUNCHED_DESKTOP_FILE=") + - QString::fromStdString(info->getDesktopFile()->getFilePath()); + envs.insert("GIO_LAUNCHED_DESKTOP_FILE", QString::fromStdString(info->getDesktopFile()->getFilePath())); - process.setEnvironment(envs); - qint64 pid = 0; - if (process.startDetached(&pid)) { + qint64 pid = fork(); + if (pid == 0) { + envs.insert("GIO_LAUNCHED_DESKTOP_FILE_PID", QByteArray::number(getpid()).constData()); + auto argList = process.arguments(); + char const * args[argList.length() + 1]; + std::transform(argList.constBegin(), argList.constEnd(), args, [](const QString& str){ + auto byte = new QByteArray; + *byte = str.toUtf8(); + auto tmp_buf = byte->data(); + return tmp_buf; + }); + args[process.arguments().length()] = 0; + auto envStringList = envs.toStringList(); + char const * envs[envStringList.length() + 1]; + std::transform(envStringList.constBegin(), envStringList.constEnd(), envs, [](const QString& str){ + auto byte = new QByteArray; + *byte = str.toUtf8(); + auto tmp_buf = byte->data(); + return tmp_buf; + }); + envs[envStringList.length()] = 0; + execvpe(process.program().toLocal8Bit().constData(), (char**)args, (char**)envs); + exit(-1); + } else { if (useProxy) { qDebug() << "Launch the process[" << pid << "] by app proxy."; dbusHandler->addProxyProc(pid); } - return true; } return false; diff --git a/src/modules/startmanager/startmanager.h b/src/modules/startmanager/startmanager.h index e8b7abe..9770a5d 100644 --- a/src/modules/startmanager/startmanager.h +++ b/src/modules/startmanager/startmanager.h @@ -40,6 +40,7 @@ public Q_SLOTS: void onAutoStartupPathChange(const QString &dirPath); private: + void waitForDeadChild(); bool setAutostart(const QString &fileName, const bool value); bool doLaunchAppWithOptions(const QString &desktopFile); bool doLaunchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QVariantMap options);