fix: 修复设置开机自启动应用重启后失效问题
1. 修复获取自启动列表为空的问题 2. 修复重启后自启动应用没有启动问题 Log: Influence: 设置自启动后重启应用也会保持生效 Bug: https://pms.uniontech.com/bug-view-172263.html Change-Id: Id95f4248fe2d29b3a6d03e9b44bee54671e9c5f6
This commit is contained in:
parent
8be1b299e6
commit
885ad9b07a
@ -217,8 +217,10 @@ bool KeyFile::loadFile(const std::string &filePath)
|
|||||||
|
|
||||||
std::string lastSection;
|
std::string lastSection;
|
||||||
m_fp = fopen(filePath.data(), "r");
|
m_fp = fopen(filePath.data(), "r");
|
||||||
if (!m_fp)
|
if (!m_fp) {
|
||||||
|
perror("open file failed: ");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char line[MAX_LINE_LEN] = {0};
|
char line[MAX_LINE_LEN] = {0};
|
||||||
while (fgets(line, MAX_LINE_LEN, m_fp)) {
|
while (fgets(line, MAX_LINE_LEN, m_fp)) {
|
||||||
|
@ -46,33 +46,25 @@ StartManager::StartManager(QObject *parent)
|
|||||||
, minMemAvail(0)
|
, minMemAvail(0)
|
||||||
, maxSwapUsed(0)
|
, maxSwapUsed(0)
|
||||||
, dbusHandler(new StartManagerDBusHandler(this))
|
, dbusHandler(new StartManagerDBusHandler(this))
|
||||||
, fileWatcher(new QFileSystemWatcher(this))
|
, m_autostartFileWatcher(new QFileSystemWatcher(this))
|
||||||
|
, m_autostartFiles(getAutostartList())
|
||||||
|
, m_isDBusCalled(false)
|
||||||
{
|
{
|
||||||
am = static_cast<ApplicationManager *>(parent);
|
|
||||||
if (!am) {
|
|
||||||
qWarning() << "StartManager init error";
|
|
||||||
}
|
|
||||||
|
|
||||||
// load sysMemLimitConfig
|
|
||||||
loadSysMemLimitConfig();
|
loadSysMemLimitConfig();
|
||||||
|
getDesktopToAutostartMap();
|
||||||
m_autostartFiles = getAutostartList();
|
|
||||||
|
|
||||||
// listen autostart files
|
|
||||||
listenAutostartFileEvents();
|
listenAutostartFileEvents();
|
||||||
|
startAutostartProgram();
|
||||||
// start autostart
|
|
||||||
// TODO only running once when starting system
|
|
||||||
//startAutostartProgram();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartManager::addAutostart(const QString &desktop)
|
bool StartManager::addAutostart(const QString &desktop)
|
||||||
{
|
{
|
||||||
|
setIsDBusCalled(true);
|
||||||
return setAutostart(desktop, true);
|
return setAutostart(desktop, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartManager::removeAutostart(const QString &desktop)
|
bool StartManager::removeAutostart(const QString &desktop)
|
||||||
{
|
{
|
||||||
|
setIsDBusCalled(true);
|
||||||
return setAutostart(desktop, false);
|
return setAutostart(desktop, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,30 +163,90 @@ void StartManager::runCommandWithOptions(QString exe, QStringList args, QMap<QSt
|
|||||||
doRunCommandWithOptions(exe, args, options);
|
doRunCommandWithOptions(exe, args, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartManager::onAutoStartupPathChange(const QString &dirPath)
|
void StartManager::onAutoStartupPathChange(const QString &path)
|
||||||
{
|
{
|
||||||
QStringList autostartFilesList = getAutostartList();
|
const QStringList &autostartFilesList = getAutostartList();
|
||||||
QSet<QString> newAutostartFiles = QSet<QString>::fromList(autostartFilesList);
|
const QSet<QString> newAutostartFiles = QSet<QString>(autostartFilesList.begin(), autostartFilesList.end());
|
||||||
QSet<QString> oldAutostartFiles = QSet<QString>::fromList(m_autostartFiles);
|
const QSet<QString> oldAutostartFiles = QSet<QString>(m_autostartFiles.begin(), m_autostartFiles.end());
|
||||||
|
|
||||||
// 添加
|
const QSet<QString> newFiles = newAutostartFiles - oldAutostartFiles;
|
||||||
QSet<QString> newFiles = newAutostartFiles - oldAutostartFiles;
|
const QSet<QString> deletedFiles = oldAutostartFiles - newAutostartFiles;
|
||||||
QStringList newFile = newFiles.toList();
|
|
||||||
|
|
||||||
// 移除
|
QString desktopFullPath;
|
||||||
QSet<QString> deletedFiles = oldAutostartFiles - newAutostartFiles;
|
QDir autostartDir(BaseDir::userAutoStartDir().c_str());
|
||||||
QStringList deleteFile = deletedFiles.toList();
|
if (deletedFiles.size() && !isDBusCalled()) {
|
||||||
|
for (const QString &path : deletedFiles) {
|
||||||
|
QFileInfo info(path);
|
||||||
|
const QString &autostartDesktopPath = autostartDir.path() + QString("/") + info.fileName();
|
||||||
|
|
||||||
// 更新autostartFiles记录
|
for (const std::string &appDir : BaseDir::appDirs()) {
|
||||||
|
QDir dir(appDir.c_str());
|
||||||
|
dir.setFilter(QDir::Files);
|
||||||
|
dir.setNameFilters({ "*.desktop" });
|
||||||
|
for (const auto &entry : dir.entryInfoList()) {
|
||||||
|
const QString &desktopPath = entry.absoluteFilePath();
|
||||||
|
if (desktopPath.contains(info.baseName())) {
|
||||||
|
desktopFullPath = desktopPath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!desktopFullPath.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_autostartFiles.removeAll(autostartDesktopPath);
|
||||||
|
autostartDir.remove(info.fileName());
|
||||||
|
|
||||||
|
if (m_desktopDirToAutostartDirMap.keys().contains(desktopFullPath)) {
|
||||||
|
m_desktopDirToAutostartDirMap.remove(desktopFullPath);
|
||||||
|
Q_EMIT autostartChanged(autostartDeleted, desktopFullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (newFiles.size() && !isDBusCalled()) {
|
||||||
|
for (const QString &path : newFiles) {
|
||||||
|
QFileInfo info(path);
|
||||||
|
const QString &autostartDesktopPath = autostartDir.path() + QString("/") + info.fileName();
|
||||||
|
m_autostartFiles.push_back(autostartDesktopPath);
|
||||||
|
const bool ret = QFile::copy(info.filePath(), autostartDesktopPath);
|
||||||
|
if (!ret)
|
||||||
|
qWarning() << "add to autostart list failed...";
|
||||||
|
|
||||||
|
/* 设置为自启动时,手动将Hidden字段写入到自启动目录的desktop文件中,并设置为false,只有这样,
|
||||||
|
* 安全中心才不会弹出自启动确认窗口, 这种操作是沿用V20阶段的约定规范,这块已经与安全中心研发对接过 */
|
||||||
|
KeyFile kf;
|
||||||
|
kf.loadFile(autostartDesktopPath.toStdString());
|
||||||
|
kf.setKey(MainSection, KeyXDeepinCreatedBy.toStdString(), AMServiceName.toStdString());
|
||||||
|
kf.setKey(MainSection, KeyXDeepinAppID.toStdString(), info.baseName().toStdString());
|
||||||
|
kf.setBool(MainSection, KeyHidden, "false");
|
||||||
|
kf.saveToFile(autostartDesktopPath.toStdString());
|
||||||
|
|
||||||
|
for (const std::string &appDir : BaseDir::appDirs()) {
|
||||||
|
QDir dir(appDir.c_str());
|
||||||
|
dir.setFilter(QDir::Files);
|
||||||
|
dir.setNameFilters({ "*.desktop" });
|
||||||
|
for (const auto &entry : dir.entryInfoList()) {
|
||||||
|
const QString &desktopPath = entry.absoluteFilePath();
|
||||||
|
if (desktopPath.contains(info.baseName())) {
|
||||||
|
desktopFullPath = desktopPath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!desktopFullPath.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_desktopDirToAutostartDirMap.keys().contains(desktopFullPath)) {
|
||||||
|
m_desktopDirToAutostartDirMap[desktopFullPath] = autostartDesktopPath;
|
||||||
|
Q_EMIT autostartChanged(autostartAdded, desktopFullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是用户通过启动器或者使用dbus接口调用方式添加或者删除自启动,则文件监控的不发送信号
|
||||||
|
// 如果是用户直接删除自启动目录下的文件就发送信号
|
||||||
m_autostartFiles = autostartFilesList;
|
m_autostartFiles = autostartFilesList;
|
||||||
|
|
||||||
for (auto &file : newFile) {
|
|
||||||
Q_EMIT autostartChanged(autostartAdded, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &file : deleteFile) {
|
|
||||||
Q_EMIT autostartChanged(autostartDeleted, file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartManager::setAutostart(const QString &desktop, const bool value)
|
bool StartManager::setAutostart(const QString &desktop, const bool value)
|
||||||
@ -232,8 +284,13 @@ bool StartManager::setAutostart(const QString &desktop, const bool value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QString &autostartDesktopPath = autostartDir.path() + QString("/") + info.fileName();
|
const QString &autostartDesktopPath = autostartDir.path() + QString("/") + info.fileName();
|
||||||
if (value && !m_autostartFiles.contains(desktopFullPath)) {
|
if (value && !m_autostartFiles.contains(autostartDesktopPath)) {
|
||||||
m_autostartFiles.push_back(desktopFullPath);
|
m_autostartFiles.push_back(autostartDesktopPath);
|
||||||
|
|
||||||
|
// 建立映射关系
|
||||||
|
if (!m_desktopDirToAutostartDirMap.keys().contains(desktopFullPath))
|
||||||
|
m_desktopDirToAutostartDirMap[desktopFullPath] = autostartDesktopPath;
|
||||||
|
|
||||||
const bool ret = QFile::copy(info.filePath(), autostartDesktopPath);
|
const bool ret = QFile::copy(info.filePath(), autostartDesktopPath);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
qWarning() << "add to autostart list failed...";
|
qWarning() << "add to autostart list failed...";
|
||||||
@ -246,8 +303,12 @@ bool StartManager::setAutostart(const QString &desktop, const bool value)
|
|||||||
kf.setKey(MainSection, KeyXDeepinAppID.toStdString(), appId.toStdString());
|
kf.setKey(MainSection, KeyXDeepinAppID.toStdString(), appId.toStdString());
|
||||||
kf.setBool(MainSection, KeyHidden, "false");
|
kf.setBool(MainSection, KeyHidden, "false");
|
||||||
kf.saveToFile(autostartDesktopPath.toStdString());
|
kf.saveToFile(autostartDesktopPath.toStdString());
|
||||||
} else if (!value && m_autostartFiles.contains(desktopFullPath)) {
|
} else if (!value && m_autostartFiles.contains(autostartDesktopPath)) {
|
||||||
m_autostartFiles.removeAll(desktopFullPath);
|
// 删除映射关系
|
||||||
|
if (m_desktopDirToAutostartDirMap.keys().contains(desktopFullPath))
|
||||||
|
m_desktopDirToAutostartDirMap.remove(desktopFullPath);
|
||||||
|
|
||||||
|
m_autostartFiles.removeAll(autostartDesktopPath);
|
||||||
autostartDir.remove(info.fileName());
|
autostartDir.remove(info.fileName());
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "error happen...";
|
qWarning() << "error happen...";
|
||||||
@ -255,6 +316,7 @@ bool StartManager::setAutostart(const QString &desktop, const bool value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Q_EMIT autostartChanged(value ? autostartAdded : autostartDeleted, desktopFullPath);
|
Q_EMIT autostartChanged(value ? autostartAdded : autostartDeleted, desktopFullPath);
|
||||||
|
setIsDBusCalled(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,33 +493,73 @@ void StartManager::loadSysMemLimitConfig()
|
|||||||
|
|
||||||
void StartManager::listenAutostartFileEvents()
|
void StartManager::listenAutostartFileEvents()
|
||||||
{
|
{
|
||||||
for (auto autostartDir : BaseDir::autoStartDirs()) {
|
m_autostartFileWatcher->addPath(BaseDir::userAutoStartDir().c_str());
|
||||||
fileWatcher->addPath(autostartDir.c_str());
|
connect(m_autostartFileWatcher, &QFileSystemWatcher::directoryChanged, this, &StartManager::onAutoStartupPathChange, Qt::QueuedConnection);
|
||||||
}
|
|
||||||
connect(fileWatcher, &QFileSystemWatcher::directoryChanged, this, &StartManager::onAutoStartupPathChange, Qt::QueuedConnection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartManager::startAutostartProgram()
|
void StartManager::startAutostartProgram()
|
||||||
{
|
{
|
||||||
auto func = [&] (QString file, uint64_t delayTime) {
|
for (const QString &desktopFile : autostartList()) {
|
||||||
QThread::sleep(uint64_t(delayTime));
|
|
||||||
this->launchApp(file, 0, QStringList());
|
|
||||||
};
|
|
||||||
|
|
||||||
for (QString desktopFile : autostartList()) {
|
|
||||||
DesktopInfo info(desktopFile.toStdString());
|
DesktopInfo info(desktopFile.toStdString());
|
||||||
if (!info.isValidDesktop())
|
if (!info.isValidDesktop())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int delayTime = info.getKeyFile()->getInt(MainSection, KeyXGnomeAutostartDelay.toStdString());
|
launchApp(desktopFile);
|
||||||
QTimer::singleShot(0, this, [&, desktopFile, delayTime] {
|
|
||||||
QThread::sleep(uint64_t(delayTime));
|
|
||||||
this->launchApp(desktopFile, 0, QStringList());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList StartManager::getAutostartList()
|
QStringList StartManager::getAutostartList()
|
||||||
{
|
{
|
||||||
return m_autostartFiles;
|
QStringList autostartList;
|
||||||
|
for (const std::string &autostartDir : BaseDir::autoStartDirs()) {
|
||||||
|
QDir dir(autostartDir.c_str());
|
||||||
|
if (!dir.exists())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dir.setFilter(QDir::Files);
|
||||||
|
dir.setNameFilters({ "*.desktop" });
|
||||||
|
for (const auto &entry : dir.entryInfoList()) {
|
||||||
|
if (autostartList.contains(entry.absoluteFilePath()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
autostartList.push_back(entry.absoluteFilePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return autostartList;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QString> StartManager::getDesktopToAutostartMap()
|
||||||
|
{
|
||||||
|
// 获取已加入到自启动列表应用的desktop全路径
|
||||||
|
QDir autostartDir(BaseDir::userAutoStartDir().c_str());
|
||||||
|
autostartDir.setFilter(QDir::Files);
|
||||||
|
autostartDir.setNameFilters({ "*.desktop" });
|
||||||
|
for (const auto &entry : autostartDir.entryInfoList()) {
|
||||||
|
const QFileInfo &fileInfo(entry.absoluteFilePath());
|
||||||
|
for (const std::string &appDir : BaseDir::appDirs()) {
|
||||||
|
QDir dir(appDir.c_str());
|
||||||
|
dir.setFilter(QDir::Files);
|
||||||
|
dir.setNameFilters({ "*.desktop" });
|
||||||
|
for (const auto &entry : dir.entryInfoList()) {
|
||||||
|
const QString &desktopPath = entry.absoluteFilePath();
|
||||||
|
if (desktopPath.contains(fileInfo.baseName()) &&
|
||||||
|
m_desktopDirToAutostartDirMap.find(desktopPath) == m_desktopDirToAutostartDirMap.end()) {
|
||||||
|
m_desktopDirToAutostartDirMap.insert(desktopPath, entry.absoluteFilePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_desktopDirToAutostartDirMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartManager::setIsDBusCalled(const bool state)
|
||||||
|
{
|
||||||
|
m_isDBusCalled = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartManager::isDBusCalled() const
|
||||||
|
{
|
||||||
|
return m_isDBusCalled;
|
||||||
}
|
}
|
||||||
|
@ -70,13 +70,17 @@ private:
|
|||||||
void listenAutostartFileEvents();
|
void listenAutostartFileEvents();
|
||||||
void startAutostartProgram();
|
void startAutostartProgram();
|
||||||
QStringList getAutostartList();
|
QStringList getAutostartList();
|
||||||
|
QMap<QString, QString> getDesktopToAutostartMap();
|
||||||
|
void setIsDBusCalled(const bool state);
|
||||||
|
bool isDBusCalled() const;
|
||||||
|
|
||||||
uint64_t minMemAvail;
|
uint64_t minMemAvail;
|
||||||
uint64_t maxSwapUsed;
|
uint64_t maxSwapUsed;
|
||||||
StartManagerDBusHandler *dbusHandler;
|
StartManagerDBusHandler *dbusHandler;
|
||||||
QStringList m_autostartFiles;
|
QStringList m_autostartFiles;
|
||||||
QFileSystemWatcher *fileWatcher;
|
QMap<QString, QString> m_desktopDirToAutostartDirMap; // Desktop全路径和自启动目录
|
||||||
ApplicationManager *am;
|
QFileSystemWatcher *m_autostartFileWatcher;
|
||||||
|
bool m_isDBusCalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STARTMANAGER_H
|
#endif // STARTMANAGER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user