feat: 实现StartManager功能
实现StartManager功能, 曝露在ApplicationManager服务上 Log: 实现StartManager功能 Task: https://pms.uniontech.com/task-view-130337.html Influence: 无 Change-Id: I8e83a66f8c25b09e0f4be1e4be9defac95b02b80
This commit is contained in:
41
src/lib/applaunchcontext.cpp
Normal file
41
src/lib/applaunchcontext.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "applaunchcontext.h"
|
||||
|
||||
AppLaunchContext::AppLaunchContext()
|
||||
: m_count(0)
|
||||
, m_timestamp(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// TODO
|
||||
std::string AppLaunchContext::getStartupNotifyId(const DesktopInfo *info, std::vector<std::string> files)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// TODO
|
||||
void AppLaunchContext::launchFailed(std::string startupNotifyId)
|
||||
{
|
||||
|
||||
}
|
58
src/lib/applaunchcontext.h
Normal file
58
src/lib/applaunchcontext.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef APPLAUNCHCONTEXT_H
|
||||
#define APPLAUNCHCONTEXT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class DesktopInfo;
|
||||
class AppLaunchContext
|
||||
{
|
||||
public:
|
||||
AppLaunchContext();
|
||||
|
||||
void setEnv(const std::vector<std::string> &value) {m_env = value;}
|
||||
std::vector<std::string> getEnv() {return m_env;}
|
||||
|
||||
void setTimestamp(uint32_t value) {m_timestamp = value;}
|
||||
uint32_t getTimestamp() {return m_timestamp;}
|
||||
|
||||
void setCmdPrefixes(const std::vector<std::string> &value) {m_cmdPrefixes = value;}
|
||||
std::vector<std::string> getCmdPrefixes() {return m_cmdPrefixes;}
|
||||
|
||||
void setCmdSuffixes(const std::vector<std::string> &value) {m_cmdSuffixes = value;}
|
||||
std::vector<std::string> getCmdSuffixes() {return m_cmdSuffixes;}
|
||||
|
||||
std::string getStartupNotifyId(const DesktopInfo *info, std::vector<std::string> files);
|
||||
|
||||
void launchFailed(std::string startupNotifyId);
|
||||
|
||||
private:
|
||||
uint m_count;
|
||||
uint32_t m_timestamp;
|
||||
std::vector<std::string> m_cmdPrefixes;
|
||||
std::vector<std::string> m_cmdSuffixes;
|
||||
std::vector<std::string> m_env;
|
||||
};
|
||||
|
||||
#endif // APPLAUNCHCONTEXT_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -39,11 +39,11 @@ std::string BaseDir::homeDir()
|
||||
return std::string(home) + "/";
|
||||
}
|
||||
|
||||
std::string BaseDir::uerDataDir()
|
||||
std::string BaseDir::userDataDir()
|
||||
{
|
||||
// default $HOME/.local/share
|
||||
std::string home = homeDir();
|
||||
std::string defaultDir = home.size() > 0 ? home + ".local/share/" : "";
|
||||
std::string defaultDir = (home.size() > 0) ? home + ".local/share/" : "";
|
||||
const char *xdgDataHomePtr = getenv("XDG_DATA_HOME");
|
||||
if (!xdgDataHomePtr)
|
||||
return defaultDir;
|
||||
@ -106,7 +106,7 @@ std::vector<std::string> BaseDir::sysConfigDirs()
|
||||
std::string BaseDir::userCacheDir()
|
||||
{
|
||||
std::string home = homeDir();
|
||||
std::string defaultDir = home.size() > 0 ? home + ".cache/" : "";
|
||||
std::string defaultDir = (home.size() > 0) ? home + ".cache/" : "";
|
||||
const char *xdgCacheHomePtr = getenv("XDG_CACHE_HOME");
|
||||
if (!xdgCacheHomePtr)
|
||||
return defaultDir;
|
||||
@ -120,8 +120,8 @@ std::string BaseDir::userCacheDir()
|
||||
|
||||
std::string BaseDir::userAppDir()
|
||||
{
|
||||
std::string dataDir = uerDataDir();
|
||||
return dataDir.size() > 0 ? dataDir + "appliations/" : "";
|
||||
std::string dataDir = userDataDir();
|
||||
return (dataDir.size() > 0) ? dataDir + "appliations/" : "";
|
||||
}
|
||||
|
||||
std::vector<std::string> BaseDir::sysAppDirs()
|
||||
@ -150,6 +150,11 @@ std::vector<std::string> BaseDir::autoStartDirs()
|
||||
return autoStartDirs;
|
||||
}
|
||||
|
||||
std::string BaseDir::userAutoStartDir()
|
||||
{
|
||||
return userConfigDir() + "autostart/";
|
||||
}
|
||||
|
||||
void BaseDir::filterNotAbs(std::vector<std::string> &dirs)
|
||||
{
|
||||
for (auto iter = dirs.begin(); iter != dirs.end();) { // erase element in vector
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -32,7 +32,7 @@ public:
|
||||
BaseDir();
|
||||
|
||||
static std::string homeDir();
|
||||
static std::string uerDataDir();
|
||||
static std::string userDataDir();
|
||||
static std::vector<std::string> sysDataDirs();
|
||||
static std::string userConfigDir();
|
||||
static std::vector<std::string> sysConfigDirs();
|
||||
@ -41,6 +41,7 @@ public:
|
||||
static std::vector<std::string> sysAppDirs();
|
||||
static std::vector<std::string> appDirs();
|
||||
static std::vector<std::string> autoStartDirs();
|
||||
static std::string userAutoStartDir();
|
||||
|
||||
private:
|
||||
static void filterNotAbs(std::vector<std::string> &dirs);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -34,52 +34,51 @@
|
||||
std::vector<std::string> DesktopInfo::currentDesktops;
|
||||
|
||||
DesktopInfo::DesktopInfo(const std::string &_fileName)
|
||||
: kf(KeyFile())
|
||||
, fileName(_fileName)
|
||||
, isValid(true)
|
||||
: m_isValid(true)
|
||||
, m_keyFile(KeyFile())
|
||||
{
|
||||
if (!DString::endWith(fileName, ".desktop"))
|
||||
fileName += ".desktop";
|
||||
std::string fileNameWithSuffix(_fileName);
|
||||
if (!DString::endWith(_fileName, ".desktop"))
|
||||
fileNameWithSuffix += ".desktop";
|
||||
|
||||
if (!DFile::isAbs(fileName)) {
|
||||
m_fileName = fileNameWithSuffix;
|
||||
|
||||
if (!DFile::isAbs(m_fileName)) {
|
||||
// fileName是文件名,增加目录
|
||||
bool isExisted = false;
|
||||
for (const auto &dir : BaseDir::appDirs()) {
|
||||
fileName = dir + fileName;
|
||||
if (DFile::isExisted(fileName)) {
|
||||
m_fileName = dir + fileNameWithSuffix;
|
||||
if (DFile::isExisted(m_fileName)) {
|
||||
isExisted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExisted) {
|
||||
isValid = false;
|
||||
m_isValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
kf.loadFile(fileName);
|
||||
m_keyFile.loadFile(m_fileName);
|
||||
|
||||
// check DesktopInfo valid
|
||||
if (fileName.find(".desktop") == std::string::npos)
|
||||
isValid = false;
|
||||
|
||||
std::vector<std::string> mainKeys = kf.getMainKeys();
|
||||
std::vector<std::string> mainKeys = m_keyFile.getMainKeys();
|
||||
if (mainKeys.size() == 0)
|
||||
isValid = false;
|
||||
m_isValid = false;
|
||||
|
||||
bool found = std::any_of(mainKeys.begin(), mainKeys.end(),
|
||||
[](const auto &key) {return key == MainSection;});
|
||||
|
||||
if (!found)
|
||||
isValid = false;
|
||||
m_isValid = false;
|
||||
|
||||
if (kf.getStr(MainSection, KeyType) != TypeApplication)
|
||||
isValid = false;
|
||||
if (m_keyFile.getStr(MainSection, KeyType) != TypeApplication)
|
||||
m_isValid = false;
|
||||
|
||||
name = kf.getLocaleStr(MainSection, KeyName, "");
|
||||
icon = kf.getStr(MainSection, KeyIcon);
|
||||
id = getId();
|
||||
m_name = m_keyFile.getLocaleStr(MainSection, KeyName, "");
|
||||
m_icon = m_keyFile.getStr(MainSection, KeyIcon);
|
||||
m_id = getId();
|
||||
}
|
||||
|
||||
DesktopInfo::~DesktopInfo()
|
||||
@ -89,12 +88,12 @@ DesktopInfo::~DesktopInfo()
|
||||
|
||||
std::string DesktopInfo::getFileName()
|
||||
{
|
||||
return fileName;
|
||||
return m_fileName;
|
||||
}
|
||||
|
||||
bool DesktopInfo::isValidDesktop()
|
||||
{
|
||||
return isValid;
|
||||
return m_isValid;
|
||||
}
|
||||
|
||||
bool DesktopInfo::shouldShow()
|
||||
@ -108,12 +107,12 @@ bool DesktopInfo::shouldShow()
|
||||
|
||||
bool DesktopInfo::getNoDisplay()
|
||||
{
|
||||
return kf.getBool(MainSection, KeyNoDisplay);
|
||||
return m_keyFile.getBool(MainSection, KeyNoDisplay);
|
||||
}
|
||||
|
||||
bool DesktopInfo::getIsHidden()
|
||||
{
|
||||
return kf.getBool(MainSection, KeyHidden);
|
||||
return m_keyFile.getBool(MainSection, KeyHidden);
|
||||
}
|
||||
|
||||
bool DesktopInfo::getShowIn(std::vector<std::string> desktopEnvs)
|
||||
@ -127,8 +126,8 @@ bool DesktopInfo::getShowIn(std::vector<std::string> desktopEnvs)
|
||||
desktopEnvs.assign(currentDesktops.begin(), currentDesktops.end());
|
||||
}
|
||||
|
||||
std::vector<std::string> onlyShowIn = kf.getStrList(MainSection, KeyOnlyShowIn);
|
||||
std::vector<std::string> notShowIn = kf.getStrList(MainSection, KeyNotShowIn);
|
||||
std::vector<std::string> onlyShowIn = m_keyFile.getStrList(MainSection, KeyOnlyShowIn);
|
||||
std::vector<std::string> notShowIn = m_keyFile.getStrList(MainSection, KeyNotShowIn);
|
||||
|
||||
for (const auto &desktop : desktopEnvs) {
|
||||
bool ret = std::any_of(onlyShowIn.begin(), onlyShowIn.end(),
|
||||
@ -147,7 +146,7 @@ bool DesktopInfo::getShowIn(std::vector<std::string> desktopEnvs)
|
||||
|
||||
std::string DesktopInfo::getExecutable()
|
||||
{
|
||||
return kf.getStr(MainSection, KeyExec);
|
||||
return m_keyFile.getStr(MainSection, KeyExec);
|
||||
}
|
||||
|
||||
bool DesktopInfo::isExecutableOk()
|
||||
@ -182,25 +181,31 @@ bool DesktopInfo::isExecutableOk()
|
||||
|
||||
bool DesktopInfo::isInstalled()
|
||||
{
|
||||
const char *name = fileName.c_str();
|
||||
const char *name = m_fileName.c_str();
|
||||
const char *found = strstr(name, "/applications/");
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
auto appDirs = BaseDir::appDirs();
|
||||
return std::any_of(appDirs.begin(), appDirs.end(),
|
||||
[&name, &found] (std::string dir) -> bool {return strneq(dir.c_str(), name, size_t(found - name));});
|
||||
[&name, &found] (std::string dir) -> bool {return strneq(dir.c_str(), name, size_t(found - name));});
|
||||
}
|
||||
|
||||
// [Desktop Action new-window] or [Full_Screenshot Shortcut Group]
|
||||
bool DesktopInfo::isDesktopAction(std::string name)
|
||||
{
|
||||
return DString::startWith(name.c_str(), "Desktop Action") || DString::endWith(name.c_str(), "Shortcut Group");
|
||||
}
|
||||
|
||||
std::vector<DesktopAction> DesktopInfo::getActions()
|
||||
{
|
||||
std::vector<DesktopAction> actions;
|
||||
for (const auto &mainKey : kf.getMainKeys()) {
|
||||
for (const auto &mainKey : m_keyFile.getMainKeys()) {
|
||||
if (DString::startWith(mainKey, "Desktop Action")
|
||||
|| DString::endWith(mainKey, "Shortcut Group")) {
|
||||
DesktopAction action;
|
||||
action.name = kf.getLocaleStr(mainKey, KeyName, "");
|
||||
action.exec = kf.getStr(mainKey, KeyExec);
|
||||
action.name = m_keyFile.getLocaleStr(mainKey, KeyName, "");
|
||||
action.exec = m_keyFile.getStr(mainKey, KeyExec);
|
||||
actions.push_back(action);
|
||||
}
|
||||
}
|
||||
@ -225,10 +230,15 @@ DesktopInfo DesktopInfo::getDesktopInfoById(std::string appId)
|
||||
return DesktopInfo("");
|
||||
}
|
||||
|
||||
bool DesktopInfo::getTerminal()
|
||||
{
|
||||
return m_keyFile.getBool(MainSection, KeyTerminal);
|
||||
}
|
||||
|
||||
// TryExec is Path to an executable file on disk used to determine if the program is actually installed
|
||||
std::string DesktopInfo::getTryExec()
|
||||
{
|
||||
return kf.getStr(MainSection, KeyTryExec);
|
||||
return m_keyFile.getStr(MainSection, KeyTryExec);
|
||||
}
|
||||
|
||||
// 按$PATH路径查找执行文件
|
||||
@ -239,22 +249,26 @@ bool DesktopInfo::findExecutable(std::string &exec)
|
||||
return std::any_of(paths.begin(), paths.end(), [&exec](std::string path) {return DFile::isExisted(path + "/" +exec);});
|
||||
}
|
||||
|
||||
// filename must has suffix desktopExt
|
||||
// example:
|
||||
// /usr/share/applications/a.desktop -> a
|
||||
// /usr/share/applications/kde4/a.desktop -> kde4/a
|
||||
// /xxxx/dir/a.desktop -> /xxxx/dir/a
|
||||
/**
|
||||
* @brief DesktopInfo::getId
|
||||
* filename must has suffix desktopExt
|
||||
* example:
|
||||
* /usr/share/applications/a.desktop -> a
|
||||
* /usr/share/applications/kde4/a.desktop -> kde4/a
|
||||
* /xxxx/dir/a.desktop -> /xxxx/dir/a
|
||||
* @return
|
||||
*/
|
||||
std::string DesktopInfo::getId()
|
||||
{
|
||||
if (!id.empty())
|
||||
return id;
|
||||
if (!m_id.empty())
|
||||
return m_id;
|
||||
|
||||
std::string idStr;
|
||||
auto const suffixPos = fileName.find(".desktop");
|
||||
auto const suffixPos = m_fileName.find(".desktop");
|
||||
if (suffixPos == std::string::npos)
|
||||
return "";
|
||||
|
||||
idStr = fileName.substr(0, fileName.size() - 8); // trim suffix
|
||||
idStr = m_fileName.substr(0, m_fileName.size() - 8); // trim suffix
|
||||
size_t dirPos = idStr.find("/applications/");
|
||||
if (dirPos == std::string::npos)
|
||||
return "";
|
||||
@ -265,45 +279,55 @@ std::string DesktopInfo::getId()
|
||||
[&baseDir](const auto &dir) {return dir == baseDir;});
|
||||
|
||||
if (installed) {
|
||||
id = idStr.substr(baseDir.size(), idStr.size());
|
||||
m_id = idStr.substr(baseDir.size(), idStr.size());
|
||||
}
|
||||
|
||||
return id;
|
||||
return m_id;
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getGenericName()
|
||||
{
|
||||
return kf.getLocaleStr(MainSection, KeyGenericName, "");
|
||||
return m_keyFile.getLocaleStr(MainSection, KeyGenericName, "");
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getName()
|
||||
{
|
||||
return name;
|
||||
return m_name;
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getIcon()
|
||||
{
|
||||
return icon;
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getCommandLine()
|
||||
{
|
||||
return kf.getStr(MainSection, KeyExec);
|
||||
return m_keyFile.getStr(MainSection, KeyExec);
|
||||
}
|
||||
|
||||
std::vector<std::string> DesktopInfo::getKeywords()
|
||||
{
|
||||
return kf.getLocaleStrList(MainSection, KeyKeywords, "");
|
||||
return m_keyFile.getLocaleStrList(MainSection, KeyKeywords, "");
|
||||
}
|
||||
|
||||
std::vector<std::string> DesktopInfo::getCategories()
|
||||
{
|
||||
return kf.getStrList(MainSection, KeyCategories);
|
||||
return m_keyFile.getStrList(MainSection, KeyCategories);
|
||||
}
|
||||
|
||||
void DesktopInfo::setDesktopOverrideExec(const std::string &execStr)
|
||||
{
|
||||
m_overRideExec = execStr;
|
||||
}
|
||||
|
||||
KeyFile *DesktopInfo::getKeyFile()
|
||||
{
|
||||
return &m_keyFile;
|
||||
}
|
||||
|
||||
// class AppsDir
|
||||
AppsDir::AppsDir(const std::string &dirPath)
|
||||
: path(dirPath)
|
||||
: m_path(dirPath)
|
||||
{
|
||||
|
||||
}
|
||||
@ -315,7 +339,7 @@ AppsDir::~AppsDir()
|
||||
|
||||
std::string AppsDir::getPath()
|
||||
{
|
||||
return path;
|
||||
return m_path;
|
||||
}
|
||||
|
||||
|
||||
@ -325,11 +349,10 @@ std::map<std::string, bool> AppsDir::getAppNames()
|
||||
DIR* dp;
|
||||
struct dirent* ep;
|
||||
|
||||
dp = opendir(path.c_str());
|
||||
if (dp == nullptr)
|
||||
{
|
||||
std::cout << "Couldn't open directory " << path << std::endl;
|
||||
return appNames;
|
||||
dp = opendir(m_path.c_str());
|
||||
if (!dp) {
|
||||
std::cout << "Couldn't open directory " << m_path << std::endl;
|
||||
return m_appNames;
|
||||
}
|
||||
|
||||
while ((ep = readdir(dp))) {
|
||||
@ -339,11 +362,11 @@ std::map<std::string, bool> AppsDir::getAppNames()
|
||||
if (!DString::endWith(ep->d_name, ".desktop"))
|
||||
continue;
|
||||
|
||||
appNames.insert({ep->d_name, true});
|
||||
m_appNames.insert({ep->d_name, true});
|
||||
}
|
||||
closedir(dp);
|
||||
|
||||
return appNames;
|
||||
return m_appNames;
|
||||
}
|
||||
|
||||
// 获取所有应用信息
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -57,7 +57,14 @@ const std::string TypeDirectory = "Directory";
|
||||
|
||||
const std::string envDesktopEnv = "XDG_CURRENT_DESKTOP";
|
||||
|
||||
typedef struct DesktopAction {
|
||||
typedef struct DesktopAction
|
||||
{
|
||||
DesktopAction()
|
||||
: section("")
|
||||
, name("")
|
||||
, exec("")
|
||||
{
|
||||
}
|
||||
std::string section;
|
||||
std::string name;
|
||||
std::string exec;
|
||||
@ -78,8 +85,10 @@ public:
|
||||
bool getShowIn(std::vector<std::string> desktopEnvs);
|
||||
bool isExecutableOk();
|
||||
bool isInstalled();
|
||||
static bool isDesktopAction(std::string name);
|
||||
std::vector<DesktopAction> getActions();
|
||||
static DesktopInfo getDesktopInfoById(std::string appId);
|
||||
bool getTerminal();
|
||||
|
||||
std::string getId();
|
||||
std::string getGenericName();
|
||||
@ -88,19 +97,23 @@ public:
|
||||
std::string getCommandLine();
|
||||
std::vector<std::string> getKeywords();
|
||||
std::vector<std::string> getCategories();
|
||||
void setDesktopOverrideExec(const std::string &execStr);
|
||||
|
||||
KeyFile kf;
|
||||
KeyFile *getKeyFile();
|
||||
|
||||
private:
|
||||
std::string getTryExec();
|
||||
bool findExecutable(std::string &exec);
|
||||
std::string fileName;
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string icon;
|
||||
std::string overRideExec;
|
||||
bool isValid;
|
||||
|
||||
static std::vector<std::string> currentDesktops;
|
||||
|
||||
std::string m_fileName;
|
||||
std::string m_id;
|
||||
std::string m_name;
|
||||
std::string m_icon;
|
||||
std::string m_overRideExec;
|
||||
bool m_isValid;
|
||||
KeyFile m_keyFile;
|
||||
};
|
||||
|
||||
// 应用目录类
|
||||
@ -114,8 +127,8 @@ public:
|
||||
static std::vector<DesktopInfo> getAllDesktopInfos();
|
||||
|
||||
private:
|
||||
std::string path;
|
||||
std::map<std::string, bool> appNames;
|
||||
std::string m_path;
|
||||
std::map<std::string, bool> m_appNames;
|
||||
};
|
||||
|
||||
#endif // DESKTOPINFO_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -38,7 +38,7 @@ const char charAt = '@';
|
||||
|
||||
Locale::Locale()
|
||||
{
|
||||
pthread_mutex_init(&languageNames.mutex, nullptr);
|
||||
pthread_mutex_init(&m_languageNames.mutex, nullptr);
|
||||
|
||||
// init aliases
|
||||
FILE *fp = fopen(aliasFile, "r");
|
||||
@ -74,15 +74,18 @@ Locale::Locale()
|
||||
parts = DString::splitStr(line, '\t');
|
||||
|
||||
if (parts.size() == 2) {
|
||||
aliases[parts[0]] = parts[1];
|
||||
m_aliases[parts[0]] = parts[1];
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// wayland environment is useful?
|
||||
// ExplodeLocale Break an X/Open style locale specification into components
|
||||
/**
|
||||
* @brief Locale::explodeLocale 拆分locale
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
Locale::Components Locale::explodeLocale(std::string locale)
|
||||
{
|
||||
Components cmp;
|
||||
@ -146,19 +149,16 @@ std::string Locale::guessCategoryValue(std::string categoryName)
|
||||
|
||||
std::string Locale::unaliasLang(std::string lang)
|
||||
{
|
||||
if (aliases.find(lang) != aliases.end())
|
||||
return aliases[lang];
|
||||
if (m_aliases.find(lang) != m_aliases.end())
|
||||
return m_aliases[lang];
|
||||
else
|
||||
return lang;
|
||||
}
|
||||
|
||||
// wayland environment is useful?
|
||||
/*
|
||||
* Compute all interesting variants for a given locale name -
|
||||
* by stripping off different components of the value.
|
||||
*
|
||||
* For simplicity, we assume that the locale is in
|
||||
* X/Open format: language[_territory][.codeset][@modifier]
|
||||
/**
|
||||
* @brief Locale::getLocaleVariants
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
std::vector<std::string> Locale::getLocaleVariants(const std::string &locale)
|
||||
{
|
||||
@ -192,19 +192,19 @@ std::vector<std::string> Locale::getLanguageNames()
|
||||
return names;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&languageNames.mutex);
|
||||
if (languageNames.language != value) {
|
||||
languageNames.language = value;
|
||||
languageNames.names.clear();
|
||||
pthread_mutex_lock(&m_languageNames.mutex);
|
||||
if (m_languageNames.language != value) {
|
||||
m_languageNames.language = value;
|
||||
m_languageNames.names.clear();
|
||||
std::vector<std::string> langs = DString::splitStr(value, ':');
|
||||
for (const auto & lang : langs) {
|
||||
std::vector<std::string> localeVariant = getLocaleVariants(unaliasLang(lang));
|
||||
for (const auto & var : localeVariant)
|
||||
languageNames.names.push_back(var);
|
||||
m_languageNames.names.push_back(var);
|
||||
}
|
||||
languageNames.names.push_back("C");
|
||||
m_languageNames.names.push_back("C");
|
||||
}
|
||||
pthread_mutex_unlock(&languageNames.mutex);
|
||||
pthread_mutex_unlock(&m_languageNames.mutex);
|
||||
|
||||
return languageNames.names;
|
||||
return m_languageNames.names;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -59,8 +59,8 @@ private:
|
||||
Components explodeLocale(std::string locale);
|
||||
std::string guessCategoryValue(std::string categoryName);
|
||||
std::string unaliasLang(std::string);
|
||||
std::map<std::string, std::string> aliases;
|
||||
LanguageNameCache languageNames;
|
||||
std::map<std::string, std::string> m_aliases;
|
||||
LanguageNameCache m_languageNames;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
85
src/lib/gsetting.cpp
Normal file
85
src/lib/gsetting.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include "gsetting.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
GSetting::GSetting(std::string settings)
|
||||
: m_gs(nullptr)
|
||||
, m_settings(settings)
|
||||
{
|
||||
m_gs = g_settings_new(m_settings.c_str());
|
||||
if (!m_gs) {
|
||||
std::cout << "GSetting: g_settings_new error" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
GSetting::~GSetting()
|
||||
{
|
||||
if (m_gs) {
|
||||
g_object_unref(m_gs);
|
||||
m_gs = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GSetting::getString(std::string key)
|
||||
{
|
||||
std::string ret;
|
||||
if (m_gs) {
|
||||
ret = g_settings_get_string(m_gs, key.c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GSetting::setString(std::string key, std::string value)
|
||||
{
|
||||
if (m_gs) {
|
||||
g_settings_set_string(m_gs, key.c_str(), value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
int GSetting::getInt(std::string key)
|
||||
{
|
||||
int ret = 0;
|
||||
if (m_gs) {
|
||||
ret = g_settings_get_int(m_gs, key.c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GSetting::setInt(std::string key, int value)
|
||||
{
|
||||
if (m_gs) {
|
||||
g_settings_set_int(m_gs, key.c_str(), value);
|
||||
}
|
||||
}
|
||||
|
||||
double GSetting::getDouble(std::string key)
|
||||
{
|
||||
double ret = 0;
|
||||
if (m_gs) {
|
||||
ret = g_settings_get_double(m_gs, key.c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GSetting::setDouble(std::string key, double value)
|
||||
{
|
||||
if (m_gs) {
|
||||
g_settings_set_double(m_gs, key.c_str(), value);
|
||||
}
|
||||
}
|
||||
|
||||
bool GSetting::getBool(std::string key)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_gs) {
|
||||
ret = g_settings_get_boolean(m_gs, key.c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GSetting::setBool(std::string key, bool value)
|
||||
{
|
||||
if (m_gs) {
|
||||
g_settings_set_double(m_gs, key.c_str(), value);
|
||||
}
|
||||
}
|
30
src/lib/gsetting.h
Normal file
30
src/lib/gsetting.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef GSETTING_H
|
||||
#define GSETTING_H
|
||||
|
||||
#include <string>
|
||||
#include <gio/gio.h>
|
||||
|
||||
class GSetting
|
||||
{
|
||||
public:
|
||||
explicit GSetting(std::string settings);
|
||||
~GSetting();
|
||||
|
||||
std::string getString(std::string key);
|
||||
void setString(std::string key, std::string value);
|
||||
|
||||
int getInt(std::string key);
|
||||
void setInt(std::string key, int value);
|
||||
|
||||
double getDouble(std::string key);
|
||||
void setDouble(std::string key, double value);
|
||||
|
||||
bool getBool(std::string key);
|
||||
void setBool(std::string key, bool value);
|
||||
|
||||
private:
|
||||
GSettings *m_gs;
|
||||
std::string m_settings;
|
||||
};
|
||||
|
||||
#endif // GSETTING_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -29,26 +29,26 @@
|
||||
#include <iostream>
|
||||
|
||||
KeyFile::KeyFile(char separtor)
|
||||
: fp(nullptr)
|
||||
, modified(false)
|
||||
, listSeparator(separtor)
|
||||
: m_fp(nullptr)
|
||||
, m_modified(false)
|
||||
, m_listSeparator(separtor)
|
||||
{
|
||||
}
|
||||
|
||||
KeyFile::~KeyFile()
|
||||
{
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
if (m_fp) {
|
||||
fclose(m_fp);
|
||||
m_fp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyFile::getBool(const std::string §ion, const std::string &key, bool defaultValue)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
if (m_mainKeyMap.find(section) == m_mainKeyMap.end())
|
||||
return false;
|
||||
|
||||
std::string valueStr = mainKeyMap[section][key];
|
||||
std::string valueStr = m_mainKeyMap[section][key];
|
||||
bool value = defaultValue;
|
||||
if (valueStr == "true")
|
||||
value = true;
|
||||
@ -58,6 +58,14 @@ bool KeyFile::getBool(const std::string §ion, const std::string &key, bool d
|
||||
return value;
|
||||
}
|
||||
|
||||
void KeyFile::setBool(const std::string §ion, const std::string &key, const std::string &defaultValue)
|
||||
{
|
||||
if (m_mainKeyMap.find(section) == m_mainKeyMap.end())
|
||||
m_mainKeyMap.insert({section, KeyMap()});
|
||||
|
||||
m_mainKeyMap[section][key] = defaultValue;
|
||||
}
|
||||
|
||||
// TODO
|
||||
std::vector<bool> KeyFile::getBoolList(const std::string §ion, const std::string &key, bool defaultValue)
|
||||
{
|
||||
@ -67,10 +75,10 @@ std::vector<bool> KeyFile::getBoolList(const std::string §ion, const std::st
|
||||
|
||||
int KeyFile::getInt(const std::string §ion, const std::string &key, int defaultValue)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
if (m_mainKeyMap.find(section) == m_mainKeyMap.end())
|
||||
return defaultValue;
|
||||
|
||||
std::string valueStr = mainKeyMap[section][key];
|
||||
std::string valueStr = m_mainKeyMap[section][key];
|
||||
int value;
|
||||
try {
|
||||
value = std::stoi(valueStr);
|
||||
@ -94,6 +102,12 @@ int64_t KeyFile::getInt64(const std::string §ion, const std::string &key, in
|
||||
return int64_t(0);
|
||||
}
|
||||
|
||||
// TODO
|
||||
uint64_t KeyFile::getUint64(const std::string §ion, const std::string &key, int64_t defaultValue)
|
||||
{
|
||||
return uint64_t(0);
|
||||
}
|
||||
|
||||
// TODO
|
||||
float KeyFile::getFloat(const std::string §ion, const std::string &key, float defaultValue)
|
||||
{
|
||||
@ -102,10 +116,10 @@ float KeyFile::getFloat(const std::string §ion, const std::string &key, floa
|
||||
|
||||
std::string KeyFile::getStr(const std::string §ion, const std::string &key, std::string defaultValue)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
if (m_mainKeyMap.find(section) == m_mainKeyMap.end())
|
||||
return defaultValue;
|
||||
|
||||
std::string valueStr = mainKeyMap[section][key];
|
||||
std::string valueStr = m_mainKeyMap[section][key];
|
||||
if (valueStr.empty())
|
||||
valueStr = defaultValue;
|
||||
|
||||
@ -114,10 +128,10 @@ std::string KeyFile::getStr(const std::string §ion, const std::string &key,
|
||||
|
||||
bool KeyFile::containKey(const std::string §ion, const std::string &key)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
if (m_mainKeyMap.find(section) == m_mainKeyMap.end())
|
||||
return false;
|
||||
|
||||
return mainKeyMap[section].find(key) != mainKeyMap[section].end();
|
||||
return m_mainKeyMap[section].find(key) != m_mainKeyMap[section].end();
|
||||
}
|
||||
|
||||
std::string KeyFile::getLocaleStr(const std::string §ion, const std::string &key, std::string defaultLocale)
|
||||
@ -141,7 +155,7 @@ std::string KeyFile::getLocaleStr(const std::string §ion, const std::string
|
||||
std::vector<std::string> KeyFile::getStrList(const std::string §ion, const std::string &key)
|
||||
{
|
||||
std::string value = getStr(section, key);
|
||||
return DString::splitStr(value, listSeparator);
|
||||
return DString::splitStr(value, m_listSeparator);
|
||||
}
|
||||
|
||||
std::vector<std::string> KeyFile::getLocaleStrList(const std::string §ion, const std::string &key, std::string defaultLocale)
|
||||
@ -164,10 +178,10 @@ std::vector<std::string> KeyFile::getLocaleStrList(const std::string §ion, c
|
||||
// 修改keyfile内容
|
||||
void KeyFile::setKey(const std::string §ion, const std::string &key, const std::string &value)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
mainKeyMap.insert({section, KeyMap()});
|
||||
if (m_mainKeyMap.find(section) == m_mainKeyMap.end())
|
||||
m_mainKeyMap.insert({section, KeyMap()});
|
||||
|
||||
mainKeyMap[section].insert({key, value});
|
||||
m_mainKeyMap[section][key] = value;
|
||||
}
|
||||
|
||||
// 写入文件
|
||||
@ -178,7 +192,7 @@ bool KeyFile::saveToFile(const std::string &filePath)
|
||||
return false;
|
||||
|
||||
|
||||
for (const auto &im : mainKeyMap) {
|
||||
for (const auto &im : m_mainKeyMap) {
|
||||
const auto &keyMap = im.second;
|
||||
std::string section = "[" + im.first + "]\n";
|
||||
fputs(section.c_str(), sfp);
|
||||
@ -194,19 +208,19 @@ bool KeyFile::saveToFile(const std::string &filePath)
|
||||
|
||||
bool KeyFile::loadFile(const std::string &filePath)
|
||||
{
|
||||
mainKeyMap.clear();
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
m_mainKeyMap.clear();
|
||||
if (m_fp) {
|
||||
fclose(m_fp);
|
||||
m_fp = nullptr;
|
||||
}
|
||||
|
||||
std::string lastSection;
|
||||
fp = fopen(filePath.data(), "r");
|
||||
if (!fp)
|
||||
m_fp = fopen(filePath.data(), "r");
|
||||
if (!m_fp)
|
||||
return false;
|
||||
|
||||
char line[MAX_LINE_LEN] = {0};
|
||||
while (fgets(line, MAX_LINE_LEN, fp)) {
|
||||
while (fgets(line, MAX_LINE_LEN, m_fp)) {
|
||||
char *start = &line[0];
|
||||
char *end = start;
|
||||
while (!strneq(end, "\0", 1))
|
||||
@ -232,7 +246,7 @@ bool KeyFile::loadFile(const std::string &filePath)
|
||||
if (lPos && rPos && rPos - lPos > 0 && lPos == start && rPos == end) {
|
||||
// 主键
|
||||
std::string section(lPos + 1, size_t(rPos - lPos - 1));
|
||||
mainKeyMap.insert({section, KeyMap()});
|
||||
m_mainKeyMap.insert({section, KeyMap()});
|
||||
lastSection = section;
|
||||
} else {
|
||||
char *equal = strchr(start, '=');
|
||||
@ -248,7 +262,7 @@ bool KeyFile::loadFile(const std::string &filePath)
|
||||
// 子键
|
||||
std::string key(start, size_t(equal - start));
|
||||
std::string value(equal + 1, size_t(end - equal));
|
||||
for (auto &iter : mainKeyMap) {
|
||||
for (auto &iter : m_mainKeyMap) {
|
||||
if (iter.first != lastSection)
|
||||
continue;
|
||||
|
||||
@ -256,8 +270,9 @@ bool KeyFile::loadFile(const std::string &filePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
fclose(m_fp);
|
||||
m_fp = nullptr;
|
||||
m_filePath = filePath;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -265,7 +280,7 @@ bool KeyFile::loadFile(const std::string &filePath)
|
||||
std::vector<std::string> KeyFile::getMainKeys()
|
||||
{
|
||||
std::vector<std::string> mainKeys;
|
||||
for (const auto &iter : mainKeyMap)
|
||||
for (const auto &iter : m_mainKeyMap)
|
||||
mainKeys.push_back(iter.first);
|
||||
|
||||
return mainKeys;
|
||||
@ -274,7 +289,7 @@ std::vector<std::string> KeyFile::getMainKeys()
|
||||
void KeyFile::print()
|
||||
{
|
||||
std::cout << "sectionMap: " << std::endl;
|
||||
for (auto sectionMap : mainKeyMap) {
|
||||
for (auto sectionMap : m_mainKeyMap) {
|
||||
std::cout << "section=" << sectionMap.first << std::endl;
|
||||
KeyMap keyMap = sectionMap.second;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -37,10 +37,12 @@ public:
|
||||
~KeyFile();
|
||||
|
||||
bool getBool(const std::string §ion, const std::string &key, bool defaultValue = false);
|
||||
void setBool(const std::string §ion, const std::string &key, const std::string &defaultValue = "false");
|
||||
std::vector<bool> getBoolList(const std::string §ion, const std::string &key, bool defaultValue = false);
|
||||
int getInt(const std::string §ion, const std::string &key, int defaultValue = 0);
|
||||
std::vector<int> getIntList(const std::string §ion, const std::string &key, int defaultValue = 0);
|
||||
int64_t getInt64(const std::string §ion, const std::string &key, int64_t defaultValue = 0);
|
||||
uint64_t getUint64(const std::string §ion, const std::string &key, int64_t defaultValue = 0);
|
||||
float getFloat(const std::string §ion, const std::string &key, float defaultValue = 0);
|
||||
std::string getStr(const std::string §ion, const std::string &key, std::string defaultValue = "");
|
||||
bool containKey(const std::string §ion, const std::string &key);
|
||||
@ -57,11 +59,11 @@ public:
|
||||
void print();
|
||||
|
||||
private:
|
||||
MainKeyMap mainKeyMap; // section -> key : value
|
||||
std::string filePath;
|
||||
FILE *fp;
|
||||
bool modified;
|
||||
char listSeparator;
|
||||
MainKeyMap m_mainKeyMap; // section -> key : value
|
||||
std::string m_filePath;
|
||||
FILE *m_fp;
|
||||
bool m_modified;
|
||||
char m_listSeparator;
|
||||
};
|
||||
|
||||
#endif // KEYFILE_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
91
src/lib/meminfo.cpp
Normal file
91
src/lib/meminfo.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "meminfo.h"
|
||||
#include "macro.h"
|
||||
#include "dstring.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
MemInfo::MemInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemoryInfo MemInfo::getMemoryInfo()
|
||||
{
|
||||
MemoryInfo ret;
|
||||
FILE *fp = fopen("/proc/meminfo", "r");
|
||||
if (!fp)
|
||||
return ret;
|
||||
|
||||
char line[MAX_LINE_LEN] = {0};
|
||||
while (fgets(line, MAX_LINE_LEN, fp)) {
|
||||
std::string info(line);
|
||||
std::vector<std::string> parts = DString::splitStr(info, ':');
|
||||
if (parts.size() != 2)
|
||||
continue;
|
||||
|
||||
uint64_t num = std::stoll(parts[1]);
|
||||
if (parts[0] == "MemTotal") {
|
||||
ret.memTotal = num;
|
||||
} else if (parts[0] == "MemFree") {
|
||||
ret.memFree = num;
|
||||
} else if (parts[0] == "MemAvailable") {
|
||||
ret.memAvailable = num;
|
||||
} else if (parts[0] == "Buffers") {
|
||||
ret.buffers = num;
|
||||
} else if (parts[0] == "Cached") {
|
||||
ret.cached = num;
|
||||
} else if (parts[0] == "SwapTotal") {
|
||||
ret.swapTotal = num;
|
||||
} else if (parts[0] == "SwapFree") {
|
||||
ret.swapFree = num;
|
||||
} else if (parts[0] == "SwapCached") {
|
||||
ret.swapCached = num;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// IsSufficient check the memory whether reaches the qualified value
|
||||
bool MemInfo::isSufficient(uint64_t minMemAvail, uint64_t maxSwapUsed)
|
||||
{
|
||||
if (minMemAvail == 0)
|
||||
return true;
|
||||
|
||||
MemoryInfo info = getMemoryInfo();
|
||||
uint64_t used = info.swapTotal - info.swapFree - info.swapCached;
|
||||
|
||||
if (info.memAvailable < minMemAvail)
|
||||
return false;
|
||||
|
||||
if (maxSwapUsed == 0 || info.memAvailable > used)
|
||||
return true;
|
||||
|
||||
return used < maxSwapUsed;
|
||||
}
|
||||
|
||||
|
50
src/lib/meminfo.h
Normal file
50
src/lib/meminfo.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MEMINFO_H
|
||||
#define MEMINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// MemoryInfo show the current memory stat, sum by kb
|
||||
struct MemoryInfo
|
||||
{
|
||||
uint64_t memTotal;
|
||||
uint64_t memFree;
|
||||
uint64_t memAvailable;
|
||||
uint64_t buffers;
|
||||
uint64_t cached;
|
||||
uint64_t swapTotal;
|
||||
uint64_t swapFree;
|
||||
uint64_t swapCached;
|
||||
};
|
||||
|
||||
class MemInfo
|
||||
{
|
||||
public:
|
||||
MemInfo();
|
||||
|
||||
static MemoryInfo getMemoryInfo();
|
||||
|
||||
static bool isSufficient(uint64_t minMemAvail, uint64_t maxSwapUsed);
|
||||
};
|
||||
|
||||
#endif // MEMINFO_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -31,80 +31,80 @@
|
||||
#define FILECONTENLEN 2048
|
||||
|
||||
Process::Process()
|
||||
: pid(0)
|
||||
, ppid(0)
|
||||
: m_pid(0)
|
||||
, m_ppid(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Process::Process(int _pid)
|
||||
: pid(_pid)
|
||||
, ppid(0)
|
||||
: m_pid(_pid)
|
||||
, m_ppid(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Process::isExist()
|
||||
{
|
||||
std::string procDir = "/proc/" + std::to_string(pid);
|
||||
std::string procDir = "/proc/" + std::to_string(m_pid);
|
||||
return DFile::isExisted(procDir);
|
||||
}
|
||||
|
||||
std::vector<std::string> Process::getCmdLine()
|
||||
{
|
||||
if (cmdLine.size() == 0) {
|
||||
if (m_cmdLine.size() == 0) {
|
||||
std::string cmdlineFile = getFile("cmdline");
|
||||
cmdLine = readFile(cmdlineFile);
|
||||
m_cmdLine = readFile(cmdlineFile);
|
||||
}
|
||||
|
||||
return cmdLine;
|
||||
return m_cmdLine;
|
||||
}
|
||||
|
||||
std::string Process::getCwd()
|
||||
{
|
||||
if (cwd.empty()) {
|
||||
if (m_cwd.empty()) {
|
||||
std::string cwdFile = getFile("cwd");
|
||||
char path[MAX_FILEPATH_LEN] = {};
|
||||
ssize_t len = readlink(cwdFile.c_str(), path, MAX_FILEPATH_LEN);
|
||||
if (len > 0 && len < MAX_FILEPATH_LEN) {
|
||||
cwd = std::string(path) + "/";
|
||||
m_cwd = std::string(path) + "/";
|
||||
}
|
||||
}
|
||||
|
||||
return cwd;
|
||||
return m_cwd;
|
||||
}
|
||||
|
||||
std::string Process::getExe()
|
||||
{
|
||||
if (exe.empty()) {
|
||||
if (m_exe.empty()) {
|
||||
std::string cmdLineFile = getFile("exe");
|
||||
char path[MAX_FILEPATH_LEN] = {};
|
||||
ssize_t len = readlink(cmdLineFile.c_str(), path, MAX_FILEPATH_LEN);
|
||||
if (len > 0 && len < MAX_FILEPATH_LEN) {
|
||||
exe = std::string(path);
|
||||
m_exe = std::string(path);
|
||||
}
|
||||
}
|
||||
|
||||
return exe;
|
||||
return m_exe;
|
||||
}
|
||||
|
||||
std::vector<std::string> Process::getEnviron()
|
||||
{
|
||||
if (environ.size() == 0) {
|
||||
if (m_environ.size() == 0) {
|
||||
std::string envFile = getFile("environ");
|
||||
environ = readFile(envFile);
|
||||
m_environ = readFile(envFile);
|
||||
}
|
||||
|
||||
return environ;
|
||||
return m_environ;
|
||||
}
|
||||
|
||||
std::string Process::getEnv(const std::string &key)
|
||||
{
|
||||
if (environ.size() == 0)
|
||||
environ = getEnviron();
|
||||
if (m_environ.size() == 0)
|
||||
m_environ = getEnviron();
|
||||
|
||||
std::string keyPrefix = key + "=";
|
||||
for (auto & env : environ) {
|
||||
for (auto & env : m_environ) {
|
||||
if (DString::startWith(env, keyPrefix)) {
|
||||
ulong len = keyPrefix.size();
|
||||
return env.substr(len, env.size() - len);
|
||||
@ -116,59 +116,59 @@ std::string Process::getEnv(const std::string &key)
|
||||
|
||||
Status Process::getStatus()
|
||||
{
|
||||
if (status.size() == 0) {
|
||||
if (m_status.size() == 0) {
|
||||
std::string statusFile = getFile("status");
|
||||
FILE *fp = fopen(statusFile.c_str(), "r");
|
||||
if (!fp)
|
||||
return status;
|
||||
return m_status;
|
||||
|
||||
char line[MAX_LINE_LEN] = {0};
|
||||
while (fgets(line, MAX_LINE_LEN, fp)) {
|
||||
std::string info(line);
|
||||
std::vector<std::string> parts = DString::splitStr(info, ':');
|
||||
if (parts.size() == 2)
|
||||
status[parts[0]] = parts[1];
|
||||
m_status[parts[0]] = parts[1];
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return status;
|
||||
return m_status;
|
||||
}
|
||||
|
||||
std::vector<int> Process::getUids()
|
||||
{
|
||||
if (uids.size() == 0) {
|
||||
if (status.find("Uid") != status.end()) {
|
||||
std::string uidGroup = status["Uid"];
|
||||
if (m_uids.size() == 0) {
|
||||
if (m_status.find("Uid") != m_status.end()) {
|
||||
std::string uidGroup = m_status["Uid"];
|
||||
std::vector<std::string> parts = DString::splitStr(uidGroup, '\t');
|
||||
uids.reserve(parts.size());
|
||||
std::transform(parts.begin(), parts.end(), uids.begin(),
|
||||
m_uids.reserve(parts.size());
|
||||
std::transform(parts.begin(), parts.end(), m_uids.begin(),
|
||||
[](std::string idStr) -> int {return std::stoi(idStr);});
|
||||
}
|
||||
}
|
||||
|
||||
return uids;
|
||||
return m_uids;
|
||||
}
|
||||
|
||||
int Process::getPid()
|
||||
{
|
||||
return pid;
|
||||
return m_pid;
|
||||
}
|
||||
|
||||
int Process::getPpid()
|
||||
{
|
||||
if (ppid == 0) {
|
||||
if (status.find("PPid") != status.end()) {
|
||||
ppid = std::stoi(status["PPid"]);
|
||||
if (m_ppid == 0) {
|
||||
if (m_status.find("PPid") != m_status.end()) {
|
||||
m_ppid = std::stoi(m_status["PPid"]);
|
||||
}
|
||||
}
|
||||
|
||||
return ppid;
|
||||
return m_ppid;
|
||||
}
|
||||
|
||||
std::string Process::getFile(const std::string &name)
|
||||
{
|
||||
return "/proc/" + std::to_string(pid) + "/" + name;
|
||||
return "/proc/" + std::to_string(m_pid) + "/" + name;
|
||||
}
|
||||
|
||||
// /proc is not real file system
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -49,14 +49,14 @@ private:
|
||||
std::string getFile(const std::string &name);
|
||||
std::vector<std::string> readFile(std::string fileName);
|
||||
|
||||
int pid;
|
||||
std::vector<std::string> cmdLine;
|
||||
std::string cwd;
|
||||
std::string exe;
|
||||
std::vector<std::string> environ;
|
||||
Status status;
|
||||
std::vector<int> uids;
|
||||
int ppid;
|
||||
int m_pid;
|
||||
std::vector<std::string> m_cmdLine;
|
||||
std::string m_cwd;
|
||||
std::string m_exe;
|
||||
std::vector<std::string> m_environ;
|
||||
Status m_status;
|
||||
std::vector<int> m_uids;
|
||||
int m_ppid;
|
||||
};
|
||||
|
||||
#endif // PROCESS_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -26,46 +26,46 @@
|
||||
|
||||
XCBUtils::XCBUtils()
|
||||
{
|
||||
connect = xcb_connect(nullptr, &screenNum); // nullptr表示默认使用环境变量$DISPLAY获取屏幕
|
||||
if (xcb_connection_has_error(connect)) {
|
||||
m_connect = xcb_connect(nullptr, &m_screenNum); // nullptr表示默认使用环境变量$DISPLAY获取屏幕
|
||||
if (xcb_connection_has_error(m_connect)) {
|
||||
std::cout << "XCBUtils: init xcb_connect error" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xcb_ewmh_init_atoms_replies(&ewmh,
|
||||
xcb_ewmh_init_atoms(connect, &ewmh), // 初始化Atom
|
||||
if (!xcb_ewmh_init_atoms_replies(&m_ewmh,
|
||||
xcb_ewmh_init_atoms(m_connect, &m_ewmh), // 初始化Atom
|
||||
nullptr))
|
||||
std::cout << "XCBUtils: init ewmh error" << std::endl;
|
||||
}
|
||||
|
||||
XCBUtils::~XCBUtils()
|
||||
{
|
||||
if (connect) {
|
||||
xcb_disconnect(connect); // 关闭连接并释放
|
||||
connect = nullptr;
|
||||
if (m_connect) {
|
||||
xcb_disconnect(m_connect); // 关闭连接并释放
|
||||
m_connect = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
XWindow XCBUtils::allocId()
|
||||
{
|
||||
return xcb_generate_id(connect);
|
||||
return xcb_generate_id(m_connect);
|
||||
}
|
||||
|
||||
void XCBUtils::killClientChecked(XWindow xid)
|
||||
{
|
||||
xcb_kill_client_checked(connect, xid);
|
||||
xcb_kill_client_checked(m_connect, xid);
|
||||
}
|
||||
|
||||
xcb_get_property_reply_t *XCBUtils::getPropertyValueReply(XWindow xid, XCBAtom property, XCBAtom type)
|
||||
{
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property(connect,
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property(m_connect,
|
||||
0,
|
||||
xid,
|
||||
property,
|
||||
type,
|
||||
0,
|
||||
MAXLEN);
|
||||
return xcb_get_property_reply(connect, cookie, nullptr);
|
||||
return xcb_get_property_reply(m_connect, cookie, nullptr);
|
||||
}
|
||||
|
||||
void *XCBUtils::getPropertyValue(XWindow xid, XCBAtom property, XCBAtom type)
|
||||
@ -84,7 +84,7 @@ void *XCBUtils::getPropertyValue(XWindow xid, XCBAtom property, XCBAtom type)
|
||||
std::string XCBUtils::getUTF8PropertyStr(XWindow xid, XCBAtom property)
|
||||
{
|
||||
std::string ret;
|
||||
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, property, ewmh.UTF8_STRING);
|
||||
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, property, m_ewmh.UTF8_STRING);
|
||||
if (reply) {
|
||||
ret = getUTF8StrFromReply(reply);
|
||||
|
||||
@ -95,14 +95,14 @@ std::string XCBUtils::getUTF8PropertyStr(XWindow xid, XCBAtom property)
|
||||
|
||||
XCBAtom XCBUtils::getAtom(const char *name)
|
||||
{
|
||||
XCBAtom ret = atomCache.getVal(name);
|
||||
XCBAtom ret = m_atomCache.getVal(name);
|
||||
if (ret == ATOMNONE) {
|
||||
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connect, false, strlen(name), name);
|
||||
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply (connect,
|
||||
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_connect, false, strlen(name), name);
|
||||
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply (m_connect,
|
||||
cookie,
|
||||
nullptr);
|
||||
if (reply) {
|
||||
atomCache.store(name, reply->atom);
|
||||
m_atomCache.store(name, reply->atom);
|
||||
ret = reply->atom;
|
||||
|
||||
free(reply);
|
||||
@ -114,16 +114,16 @@ XCBAtom XCBUtils::getAtom(const char *name)
|
||||
|
||||
std::string XCBUtils::getAtomName(XCBAtom atom)
|
||||
{
|
||||
std::string ret = atomCache.getName(atom);
|
||||
std::string ret = m_atomCache.getName(atom);
|
||||
if (ret.empty()) {
|
||||
xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(connect, atom);
|
||||
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(connect,
|
||||
xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(m_connect, atom);
|
||||
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(m_connect,
|
||||
cookie,
|
||||
nullptr);
|
||||
if (reply) {
|
||||
char *name = xcb_get_atom_name_name(reply);
|
||||
if (name) {
|
||||
atomCache.store(name, atom);
|
||||
m_atomCache.store(name, atom);
|
||||
ret = name;
|
||||
}
|
||||
|
||||
@ -137,8 +137,8 @@ std::string XCBUtils::getAtomName(XCBAtom atom)
|
||||
Geometry XCBUtils::getWindowGeometry(XWindow xid)
|
||||
{
|
||||
Geometry ret;
|
||||
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connect, xid);
|
||||
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(connect, cookie, nullptr);
|
||||
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(m_connect, xid);
|
||||
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(m_connect, cookie, nullptr);
|
||||
if (reply) {
|
||||
ret.x = reply->x;
|
||||
ret.y = reply->y;
|
||||
@ -156,8 +156,8 @@ Geometry XCBUtils::getWindowGeometry(XWindow xid)
|
||||
XWindow XCBUtils::getActiveWindow()
|
||||
{
|
||||
XWindow ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window(&ewmh, screenNum);
|
||||
if (!xcb_ewmh_get_active_window_reply(&ewmh, cookie, &ret, nullptr))
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window(&m_ewmh, m_screenNum);
|
||||
if (!xcb_ewmh_get_active_window_reply(&m_ewmh, cookie, &ret, nullptr))
|
||||
std::cout << "getActiveWindow error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -165,15 +165,15 @@ XWindow XCBUtils::getActiveWindow()
|
||||
|
||||
void XCBUtils::setActiveWindow(XWindow xid)
|
||||
{
|
||||
xcb_ewmh_set_active_window(&ewmh, screenNum, xid);
|
||||
xcb_ewmh_set_active_window(&m_ewmh, m_screenNum, xid);
|
||||
}
|
||||
|
||||
std::list<XWindow> XCBUtils::getClientList()
|
||||
{
|
||||
std::list<XWindow> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list(&ewmh, screenNum);
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list(&m_ewmh, m_screenNum);
|
||||
xcb_ewmh_get_windows_reply_t reply;
|
||||
if (!xcb_ewmh_get_client_list_reply(&ewmh, cookie, &reply, nullptr))
|
||||
if (!xcb_ewmh_get_client_list_reply(&m_ewmh, cookie, &reply, nullptr))
|
||||
std::cout << "getClientList error" << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < reply.windows_len; i++)
|
||||
@ -185,9 +185,9 @@ std::list<XWindow> XCBUtils::getClientList()
|
||||
std::list<XWindow> XCBUtils::getClientListStacking()
|
||||
{
|
||||
std::list<XWindow> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_stacking(&ewmh, screenNum);
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_stacking(&m_ewmh, m_screenNum);
|
||||
xcb_ewmh_get_windows_reply_t reply;
|
||||
if (!xcb_ewmh_get_client_list_stacking_reply(&ewmh, cookie, &reply, nullptr))
|
||||
if (!xcb_ewmh_get_client_list_stacking_reply(&m_ewmh, cookie, &reply, nullptr))
|
||||
std::cout << "getClientListStacking error" << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < reply.windows_len; i++)
|
||||
@ -199,9 +199,9 @@ std::list<XWindow> XCBUtils::getClientListStacking()
|
||||
std::vector<XCBAtom> XCBUtils::getWMState(XWindow xid)
|
||||
{
|
||||
std::vector<XCBAtom> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state(&ewmh, xid);
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state(&m_ewmh, xid);
|
||||
xcb_ewmh_get_atoms_reply_t reply; // a list of Atom
|
||||
if (xcb_ewmh_get_wm_state_reply(&ewmh, cookie, &reply, nullptr)) {
|
||||
if (xcb_ewmh_get_wm_state_reply(&m_ewmh, cookie, &reply, nullptr)) {
|
||||
for (uint32_t i = 0; i < reply.atoms_len; i++) {
|
||||
ret.push_back(reply.atoms[i]);
|
||||
}
|
||||
@ -215,9 +215,9 @@ std::vector<XCBAtom> XCBUtils::getWMState(XWindow xid)
|
||||
std::vector<XCBAtom> XCBUtils::getWMWindoType(XWindow xid)
|
||||
{
|
||||
std::vector<XCBAtom> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type(&ewmh, xid);
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type(&m_ewmh, xid);
|
||||
xcb_ewmh_get_atoms_reply_t reply; // a list of Atom
|
||||
if (!xcb_ewmh_get_wm_window_type_reply(&ewmh, cookie, &reply, nullptr))
|
||||
if (!xcb_ewmh_get_wm_window_type_reply(&m_ewmh, cookie, &reply, nullptr))
|
||||
std::cout << xid << " getWMWindoType error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -226,9 +226,9 @@ std::vector<XCBAtom> XCBUtils::getWMWindoType(XWindow xid)
|
||||
std::vector<XCBAtom> XCBUtils::getWMAllowedActions(XWindow xid)
|
||||
{
|
||||
std::vector<XCBAtom> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_allowed_actions(&ewmh, xid);
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_allowed_actions(&m_ewmh, xid);
|
||||
xcb_ewmh_get_atoms_reply_t reply; // a list of Atoms
|
||||
if (!xcb_ewmh_get_wm_allowed_actions_reply(&ewmh, cookie, &reply, nullptr))
|
||||
if (!xcb_ewmh_get_wm_allowed_actions_reply(&m_ewmh, cookie, &reply, nullptr))
|
||||
std::cout << xid << " getWMAllowedActions error" << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < reply.atoms_len; i++) {
|
||||
@ -244,15 +244,15 @@ void XCBUtils::setWMAllowedActions(XWindow xid, std::vector<XCBAtom> actions)
|
||||
for (size_t i = 0; i < actions.size(); i++)
|
||||
list[i] = actions[i];
|
||||
|
||||
xcb_ewmh_set_wm_allowed_actions(&ewmh, xid, actions.size(), list);
|
||||
xcb_ewmh_set_wm_allowed_actions(&m_ewmh, xid, actions.size(), list);
|
||||
}
|
||||
|
||||
std::string XCBUtils::getWMName(XWindow xid)
|
||||
{
|
||||
std::string ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name(&ewmh, xid);
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name(&m_ewmh, xid);
|
||||
xcb_ewmh_get_utf8_strings_reply_t reply1;
|
||||
if (!xcb_ewmh_get_wm_name_reply(&ewmh, cookie, &reply1, nullptr))
|
||||
if (!xcb_ewmh_get_wm_name_reply(&m_ewmh, cookie, &reply1, nullptr))
|
||||
std::cout << xid << " getWMName error" << std::endl;
|
||||
|
||||
ret.assign(reply1.strings);
|
||||
@ -263,8 +263,8 @@ std::string XCBUtils::getWMName(XWindow xid)
|
||||
uint32_t XCBUtils::getWMPid(XWindow xid)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_pid(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_pid_reply(&ewmh, cookie, &ret, nullptr))
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_pid(&m_ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_pid_reply(&m_ewmh, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMPid error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -273,9 +273,9 @@ uint32_t XCBUtils::getWMPid(XWindow xid)
|
||||
std::string XCBUtils::getWMIconName(XWindow xid)
|
||||
{
|
||||
std::string ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_name(&ewmh, xid);
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_name(&m_ewmh, xid);
|
||||
xcb_ewmh_get_utf8_strings_reply_t reply;
|
||||
if (!xcb_ewmh_get_wm_icon_name_reply(&ewmh, cookie, &reply, nullptr))
|
||||
if (!xcb_ewmh_get_wm_icon_name_reply(&m_ewmh, cookie, &reply, nullptr))
|
||||
std::cout << xid << " getWMIconName error" << std::endl;
|
||||
|
||||
ret.assign(reply.strings);
|
||||
@ -326,14 +326,14 @@ XWindow XCBUtils::getWMClientLeader(XWindow xid)
|
||||
|
||||
void XCBUtils::requestCloseWindow(XWindow xid, uint32_t timestamp)
|
||||
{
|
||||
xcb_ewmh_request_close_window(&ewmh, screenNum, xid, timestamp, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER);
|
||||
xcb_ewmh_request_close_window(&m_ewmh, m_screenNum, xid, timestamp, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER);
|
||||
}
|
||||
|
||||
uint32_t XCBUtils::getWMDesktop(XWindow xid)
|
||||
{
|
||||
uint32_t ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_desktop_reply(&ewmh, cookie, &ret, nullptr))
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop(&m_ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_desktop_reply(&m_ewmh, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMDesktop error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -341,19 +341,19 @@ uint32_t XCBUtils::getWMDesktop(XWindow xid)
|
||||
|
||||
void XCBUtils::setWMDesktop(XWindow xid, uint32_t desktop)
|
||||
{
|
||||
xcb_ewmh_set_wm_desktop(&ewmh, xid, desktop);
|
||||
xcb_ewmh_set_wm_desktop(&m_ewmh, xid, desktop);
|
||||
}
|
||||
|
||||
void XCBUtils::setCurrentWMDesktop(uint32_t desktop)
|
||||
{
|
||||
xcb_ewmh_set_current_desktop(&ewmh, screenNum, desktop);
|
||||
xcb_ewmh_set_current_desktop(&m_ewmh, m_screenNum, desktop);
|
||||
}
|
||||
|
||||
uint32_t XCBUtils::getCurrentWMDesktop()
|
||||
{
|
||||
uint32_t ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop(&ewmh, screenNum);
|
||||
if (!xcb_ewmh_get_current_desktop_reply(&ewmh, cookie, &ret, nullptr))
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop(&m_ewmh, m_screenNum);
|
||||
if (!xcb_ewmh_get_current_desktop_reply(&m_ewmh, cookie, &ret, nullptr))
|
||||
std::cout << "getCurrentWMDesktop error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -362,9 +362,9 @@ uint32_t XCBUtils::getCurrentWMDesktop()
|
||||
bool XCBUtils::isGoodWindow(XWindow xid)
|
||||
{
|
||||
bool ret = false;
|
||||
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connect, xid);
|
||||
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(m_connect, xid);
|
||||
xcb_generic_error_t **errStore = nullptr;
|
||||
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(connect, cookie, errStore);
|
||||
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(m_connect, cookie, errStore);
|
||||
if (reply) {
|
||||
if (!errStore) // 正常获取窗口geometry则判定为good
|
||||
ret = true;
|
||||
@ -392,8 +392,8 @@ bool XCBUtils::hasXEmbedInfo(XWindow xid)
|
||||
XWindow XCBUtils::getWMTransientFor(XWindow xid)
|
||||
{
|
||||
XWindow ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for(connect, xid);
|
||||
if (!xcb_icccm_get_wm_transient_for_reply(connect, cookie, &ret, nullptr))
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for(m_connect, xid);
|
||||
if (!xcb_icccm_get_wm_transient_for_reply(m_connect, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMTransientFor error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -402,8 +402,8 @@ XWindow XCBUtils::getWMTransientFor(XWindow xid)
|
||||
uint32_t XCBUtils::getWMUserTime(XWindow xid)
|
||||
{
|
||||
uint32_t ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_user_time_reply(&ewmh, cookie, &ret, nullptr))
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time(&m_ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_user_time_reply(&m_ewmh, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMUserTime error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -412,8 +412,8 @@ uint32_t XCBUtils::getWMUserTime(XWindow xid)
|
||||
int XCBUtils::getWMUserTimeWindow(XWindow xid)
|
||||
{
|
||||
XCBAtom ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time_window(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_user_time_window_reply(&ewmh, cookie, &ret, NULL))
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time_window(&m_ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_user_time_window_reply(&m_ewmh, cookie, &ret, NULL))
|
||||
std::cout << xid << " getWMUserTimeWindow error" << std::endl;
|
||||
|
||||
return ret;
|
||||
@ -422,9 +422,9 @@ int XCBUtils::getWMUserTimeWindow(XWindow xid)
|
||||
WMClass XCBUtils::getWMClass(XWindow xid)
|
||||
{
|
||||
WMClass ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class(connect, xid);
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class(m_connect, xid);
|
||||
xcb_icccm_get_wm_class_reply_t reply;
|
||||
if (!xcb_icccm_get_wm_class_reply(connect, cookie, &reply, nullptr)) {
|
||||
if (!xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr)) {
|
||||
if (reply.class_name)
|
||||
ret.className.assign(reply.class_name);
|
||||
|
||||
@ -442,18 +442,18 @@ WMClass XCBUtils::getWMClass(XWindow xid)
|
||||
// TODO
|
||||
void XCBUtils::minimizeWindow(XWindow xid)
|
||||
{
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(connect, xid);
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(m_connect, xid);
|
||||
xcb_icccm_wm_hints_t *hints = new xcb_icccm_wm_hints_t; // 分配堆空间
|
||||
xcb_icccm_get_wm_hints_reply(connect, cookie, hints, nullptr);
|
||||
xcb_icccm_get_wm_hints_reply(m_connect, cookie, hints, nullptr);
|
||||
xcb_icccm_wm_hints_set_iconic(hints);
|
||||
xcb_icccm_set_wm_hints(connect, xid, hints);
|
||||
xcb_icccm_set_wm_hints(m_connect, xid, hints);
|
||||
free(hints);
|
||||
}
|
||||
|
||||
void XCBUtils::maxmizeWindow(XWindow xid)
|
||||
{
|
||||
xcb_ewmh_request_change_wm_state(&ewmh
|
||||
, screenNum
|
||||
xcb_ewmh_request_change_wm_state(&m_ewmh
|
||||
, m_screenNum
|
||||
, xid
|
||||
, XCB_EWMH_WM_STATE_ADD
|
||||
, getAtom("_NET_WM_STATE_MAXIMIZED_VERT")
|
||||
@ -465,7 +465,7 @@ void XCBUtils::maxmizeWindow(XWindow xid)
|
||||
std::vector<std::string> XCBUtils::getWMCommand(XWindow xid)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, XCB_ATOM_WM_COMMAND, ewmh.UTF8_STRING);
|
||||
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, XCB_ATOM_WM_COMMAND, m_ewmh.UTF8_STRING);
|
||||
if (reply) {
|
||||
ret = getUTF8StrsFromReply(reply);
|
||||
free(reply);
|
||||
@ -519,7 +519,7 @@ XWindow XCBUtils::getRootWindow()
|
||||
{
|
||||
XWindow rootWindow = 0;
|
||||
/* Get the first screen */
|
||||
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connect)).data;
|
||||
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(m_connect)).data;
|
||||
if (screen)
|
||||
rootWindow = screen->root;
|
||||
|
||||
@ -530,13 +530,13 @@ XWindow XCBUtils::getRootWindow()
|
||||
void XCBUtils::registerEvents(XWindow xid, uint32_t eventMask)
|
||||
{
|
||||
uint32_t value[1] = {eventMask};
|
||||
xcb_void_cookie_t cookie = xcb_change_window_attributes_checked(connect,
|
||||
xcb_void_cookie_t cookie = xcb_change_window_attributes_checked(m_connect,
|
||||
xid,
|
||||
XCB_CW_EVENT_MASK,
|
||||
&value);
|
||||
xcb_flush(connect);
|
||||
xcb_flush(m_connect);
|
||||
|
||||
xcb_generic_error_t *error = xcb_request_check(connect, cookie);
|
||||
xcb_generic_error_t *error = xcb_request_check(m_connect, cookie);
|
||||
if (error != nullptr) {
|
||||
std::cout << "window " << xid << "registerEvents error" << std::endl;
|
||||
}
|
||||
@ -550,8 +550,8 @@ AtomCache::AtomCache()
|
||||
XCBAtom AtomCache::getVal(std::string name)
|
||||
{
|
||||
XCBAtom atom = ATOMNONE;
|
||||
auto search = atoms.find(name);
|
||||
if (search != atoms.end())
|
||||
auto search = m_atoms.find(name);
|
||||
if (search != m_atoms.end())
|
||||
atom = search->second;
|
||||
|
||||
return atom;
|
||||
@ -560,8 +560,8 @@ XCBAtom AtomCache::getVal(std::string name)
|
||||
std::string AtomCache::getName(XCBAtom atom)
|
||||
{
|
||||
std::string ret;
|
||||
auto search = atomNames.find(atom);
|
||||
if (search != atomNames.end())
|
||||
auto search = m_atomNames.find(atom);
|
||||
if (search != m_atomNames.end())
|
||||
ret = search->second;
|
||||
|
||||
return ret;
|
||||
@ -569,6 +569,6 @@ std::string AtomCache::getName(XCBAtom atom)
|
||||
|
||||
void AtomCache::store(std::string name, XCBAtom value)
|
||||
{
|
||||
atoms[name] = value;
|
||||
atomNames[value] = name;
|
||||
m_atoms[name] = value;
|
||||
m_atomNames[value] = name;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -42,6 +42,7 @@ typedef xcb_map_notify_event_t MapEvent;
|
||||
typedef xcb_configure_notify_event_t ConfigureEvent;
|
||||
typedef xcb_property_notify_event_t PropertyEvent;
|
||||
typedef xcb_event_mask_t EventMask;
|
||||
|
||||
typedef struct {
|
||||
std::string instanceName;
|
||||
std::string className;
|
||||
@ -77,8 +78,8 @@ public:
|
||||
void store(std::string name, XCBAtom value);
|
||||
|
||||
public:
|
||||
std::map<std::string, XCBAtom> atoms;
|
||||
std::map<XCBAtom, std::string> atomNames;
|
||||
std::map<std::string, XCBAtom> m_atoms;
|
||||
std::map<XCBAtom, std::string> m_atomNames;
|
||||
};
|
||||
|
||||
// XCB接口封装, 参考getCurrentWMDesktop
|
||||
@ -95,9 +96,6 @@ public:
|
||||
return &instance;
|
||||
}
|
||||
|
||||
// test
|
||||
xcb_connection_t *getConnect() {return connect;}
|
||||
|
||||
/************************* xcb method ***************************/
|
||||
// 分配XID
|
||||
XWindow allocId();
|
||||
@ -262,11 +260,11 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
xcb_connection_t *connect;
|
||||
int screenNum;
|
||||
xcb_connection_t *m_connect;
|
||||
int m_screenNum;
|
||||
|
||||
xcb_ewmh_connection_t ewmh;
|
||||
AtomCache atomCache; // 和ewmh中Atom类型存在重复部分,扩张了自定义类型
|
||||
xcb_ewmh_connection_t m_ewmh;
|
||||
AtomCache m_atomCache; // 和ewmh中Atom类型存在重复部分,扩张了自定义类型
|
||||
};
|
||||
|
||||
#endif // XCBUTILS_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -46,7 +46,7 @@ void AppInfo::init(DesktopInfo &info)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string xDeepinVendor= info.kf.getStr(MainSection, "X-Deepin-Vendor");
|
||||
std::string xDeepinVendor= info.getKeyFile()->getStr(MainSection, "X-Deepin-Vendor");
|
||||
if (xDeepinVendor == "deepin") {
|
||||
name = info.getGenericName().c_str();
|
||||
if (name.isEmpty())
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -81,7 +81,7 @@ Dock::Dock(QObject *parent)
|
||||
});
|
||||
thread.detach();
|
||||
x11Manager->listenRootWindowXEvent();
|
||||
connect(x11Manager, SIGNAL(X11Manager::needUpdateHideState), this, SLOT(updateHideState));
|
||||
connect(x11Manager, SIGNAL(X11Manager::requestUpdateHideState), this, SLOT(updateHideState));
|
||||
}
|
||||
Q_EMIT serviceRestarted();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -262,7 +262,7 @@ void X11Manager::handleRootWindowPropertyNotifyEvent(XCBAtom atom)
|
||||
else if (atom == XCB->getAtom("_NET_ACTIVE_WINDOW"))
|
||||
handleActiveWindowChangedX();
|
||||
else if (atom == XCB->getAtom("_NET_SHOWING_DESKTOP"))
|
||||
Q_EMIT needUpdateHideState(false);
|
||||
Q_EMIT requestUpdateHideState(false);
|
||||
}
|
||||
|
||||
// destory event
|
||||
@ -302,7 +302,7 @@ void X11Manager::handleConfigureNotifyEvent(XWindow xid, int x, int y, int width
|
||||
if (wmClass.className.c_str() == frontendWindowWmClass)
|
||||
return; // ignore frontend window ConfigureNotify event
|
||||
|
||||
Q_EMIT needUpdateHideState(winInfo->isGeometryChanged(x, y, width, height));
|
||||
Q_EMIT requestUpdateHideState(winInfo->isGeometryChanged(x, y, width, height));
|
||||
}
|
||||
|
||||
// property changed event
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -58,8 +58,8 @@ public:
|
||||
void listenXEventUseXlib();
|
||||
void listenXEventUseXCB();
|
||||
|
||||
signals:
|
||||
void needUpdateHideState(bool delay);
|
||||
Q_SIGNALS:
|
||||
void requestUpdateHideState(bool delay);
|
||||
|
||||
private:
|
||||
void addWindowLastConfigureEvent(XWindow xid, ConfigureEvent* event);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -254,9 +254,9 @@ bool Launcher::requestSendToDesktop(QString appId)
|
||||
|
||||
// 创建桌面快捷方式文件
|
||||
DesktopInfo dinfo(itemsMap[appId].info.path.toStdString());
|
||||
dinfo.kf.setKey(MainSection, dbusService.toStdString(), "X-Deepin-CreatedBy");
|
||||
dinfo.kf.setKey(MainSection, appId.toStdString(), "X-Deepin-AppID");
|
||||
if (!dinfo.kf.saveToFile(filePath.toStdString()))
|
||||
dinfo.getKeyFile()->setKey(MainSection, dbusService.toStdString(), "X-Deepin-CreatedBy");
|
||||
dinfo.getKeyFile()->setKey(MainSection, appId.toStdString(), "X-Deepin-AppID");
|
||||
if (!dinfo.getKeyFile()->saveToFile(filePath.toStdString()))
|
||||
return false;
|
||||
|
||||
std::thread thread([]() {
|
||||
@ -824,7 +824,7 @@ AppType Launcher::getAppType(DesktopInfo &info, const Item &item)
|
||||
QFileInfo fileInfo;
|
||||
// 判断是否为flatpak应用
|
||||
do {
|
||||
if (!info.kf.containKey(MainSection, "X-Flatpak"))
|
||||
if (!info.getKeyFile()->containKey(MainSection, "X-Flatpak"))
|
||||
break;
|
||||
|
||||
std::vector<std::string> parts = DString::splitStr(info.getCommandLine(), ' ');
|
||||
@ -863,7 +863,7 @@ AppType Launcher::getAppType(DesktopInfo &info, const Item &item)
|
||||
|
||||
// 判断是否为wineApp
|
||||
do {
|
||||
std::string createdBy = info.kf.getStr(MainSection, "X-Created-By");
|
||||
std::string createdBy = info.getKeyFile()->getStr(MainSection, "X-Created-By");
|
||||
if (DString::startWith(createdBy, "cxoffice-") || strstr(info.getCommandLine().c_str(), "env WINEPREFIX=")) {
|
||||
ty = AppType::WineApp;
|
||||
goto end;
|
||||
@ -1052,10 +1052,10 @@ bool Launcher::isDeepinCustomDesktopFile(QString fileName)
|
||||
|
||||
Item Launcher:: NewItemWithDesktopInfo(DesktopInfo &info)
|
||||
{
|
||||
QString enName(info.kf.getStr(MainSection, KeyName).c_str());
|
||||
QString enComment(info.kf.getStr(MainSection, KeyComment).c_str());
|
||||
QString xDeepinCategory(info.kf.getStr(MainSection, "X-Deepin-Category").c_str());
|
||||
QString xDeepinVendor(info.kf.getStr(MainSection, "X-Deepin-Vendor").c_str());
|
||||
QString enName(info.getKeyFile()->getStr(MainSection, KeyName).c_str());
|
||||
QString enComment(info.getKeyFile()->getStr(MainSection, KeyComment).c_str());
|
||||
QString xDeepinCategory(info.getKeyFile()->getStr(MainSection, "X-Deepin-Category").c_str());
|
||||
QString xDeepinVendor(info.getKeyFile()->getStr(MainSection, "X-Deepin-Vendor").c_str());
|
||||
|
||||
QString appName;
|
||||
if (xDeepinVendor == "deepin")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
@ -113,7 +113,8 @@ QVector<QString> LauncherSettings::getHiddenApps()
|
||||
return ret;
|
||||
}
|
||||
|
||||
LauncherSettings::LauncherSettings(QObject *parent) : QObject(parent)
|
||||
LauncherSettings::LauncherSettings(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
// 绑定属性
|
||||
connect(dconfig, &DConfig::valueChanged, this, [&] (const QString &key) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
64
src/modules/startmanager/common.h
Normal file
64
src/modules/startmanager/common.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
const QString AMServiceName = "/org/desktopspec/ApplicationManager";
|
||||
const QString autostartDir = "autostart";
|
||||
const QString proxychainsBinary = "proxychains4";
|
||||
|
||||
const QString configLauncher = "com.deepin.dde.launcher";
|
||||
const QString keyAppsUseProxy = "Apps_Use_Proxy";
|
||||
const QString keyAppsDisableScaling = "Apps_Disable_Scaling";
|
||||
|
||||
const QString KeyXGnomeAutostartDelay = "X-GNOME-Autostart-Delay";
|
||||
const QString KeyXGnomeAutoRestart = "X-GNOME-AutoRestart";
|
||||
const QString KeyXDeepinCreatedBy = "X-Deepin-CreatedBy";
|
||||
const QString KeyXDeepinAppID = "X-Deepin-AppID";
|
||||
|
||||
const QString configStartdde = "com.deepin.dde.startdde";
|
||||
const QString keyAutostartDelay = "Autostart_Delay";
|
||||
const QString keyMemCheckerEnabled = "Memchecker_Enabled";
|
||||
const QString keySwapSchedEnabled = "swap-sched-enabled";
|
||||
|
||||
const QString configXsettings = "com.deepin.xsettings";
|
||||
const QString keyScaleFactor = "Scale_Factor";
|
||||
|
||||
const QString uiAppSchedHooksDir = "/usr/lib/UIAppSched.hooks";
|
||||
const QString launchedHookDir = uiAppSchedHooksDir + "/launched";
|
||||
|
||||
const QString cpuFreqAdjustFile = "/usr/share/startdde/app_startup.conf";
|
||||
const QString performanceGovernor = "performance";
|
||||
|
||||
const int restartRateLimitSeconds = 60;
|
||||
|
||||
const QString sysMemLimitConfig = "/usr/share/startdde/memchecker.json";
|
||||
|
||||
const int defaultMinMemAvail = 300; // 300M
|
||||
const int defaultMaxSwapUsed = 1200; // 1200M
|
||||
|
||||
const QString autostartAdded = "added";
|
||||
const QString autostartDeleted = "deleted";
|
||||
|
||||
#endif // COMMON_H
|
470
src/modules/startmanager/startmanager.cpp
Normal file
470
src/modules/startmanager/startmanager.cpp
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "startmanager.h"
|
||||
#include "basedir.h"
|
||||
#include "dfile.h"
|
||||
#include "common.h"
|
||||
#include "desktopinfo.h"
|
||||
#include "startmanagersettings.h"
|
||||
#include "startmanagerdbushandler.h"
|
||||
#include "meminfo.h"
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
|
||||
#define DESKTOPEXT ".desktop"
|
||||
#define SETTING StartManagerSettings::instance()
|
||||
|
||||
StartManager::StartManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, minMemAvail(0)
|
||||
, maxSwapUsed(0)
|
||||
, dbusHandler(new StartManagerDBusHandler(this))
|
||||
, fileWatcher(new QFileSystemWatcher(this))
|
||||
{
|
||||
// load sysMemLimitConfig
|
||||
loadSysMemLimitConfig();
|
||||
|
||||
autostartFiles = getAutostartList();
|
||||
|
||||
// listen autostart files
|
||||
listenAutostartFileEvents();
|
||||
|
||||
// start autostart
|
||||
// TODO only running once when starting system
|
||||
//startAutostartProgram();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief StartManager::addAutostart
|
||||
* @param fileName desktopFile
|
||||
* @return
|
||||
*/
|
||||
bool StartManager::addAutostart(QString fileName)
|
||||
{
|
||||
return setAutostart(fileName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief StartManager::removeAutostart
|
||||
* @param fileName desktopFile
|
||||
* @return
|
||||
*/
|
||||
bool StartManager::removeAutostart(QString fileName)
|
||||
{
|
||||
return setAutostart(fileName, false);
|
||||
}
|
||||
|
||||
QStringList StartManager::autostartList()
|
||||
{
|
||||
if (autostartFiles.size() == 0) {
|
||||
autostartFiles = getAutostartList();
|
||||
}
|
||||
|
||||
return autostartFiles;
|
||||
}
|
||||
|
||||
QString StartManager::dumpMemRecord()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString StartManager::getApps()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief StartManager::isAutostart
|
||||
* @param fileName desktopFile
|
||||
* @return
|
||||
*/
|
||||
bool StartManager::isAutostart(QString fileName)
|
||||
{
|
||||
if (!fileName.endsWith(DESKTOPEXT))
|
||||
return false;
|
||||
|
||||
for (auto autostartDir : BaseDir::autoStartDirs()) {
|
||||
std::string filePath = autostartDir + fileName.toStdString();
|
||||
if (DFile::isExisted(filePath)) {
|
||||
DesktopInfo info(filePath);
|
||||
if (info.isValidDesktop() && !info.getIsHidden()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StartManager::isMemSufficient()
|
||||
{
|
||||
return SETTING->getMemCheckerEnabled() ? MemInfo::isSufficient(minMemAvail, maxSwapUsed) : true;
|
||||
}
|
||||
|
||||
void StartManager::launchApp(QString desktopFile, uint32_t timestamp, QStringList files)
|
||||
{
|
||||
doLaunchAppWithOptions(desktopFile, timestamp, files, QMap<QString, QString>());
|
||||
}
|
||||
|
||||
void StartManager::launchAppAction(QString desktopFile, QString actionSection, uint32_t timestamp)
|
||||
{
|
||||
DesktopInfo info(desktopFile.toStdString());
|
||||
if (!info.isValidDesktop())
|
||||
return;
|
||||
|
||||
DesktopAction targetAction;
|
||||
for (auto action : info.getActions()) {
|
||||
if (!action.section.empty() && action.section.c_str() == actionSection) {
|
||||
targetAction = action;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetAction.section.empty()) {
|
||||
qWarning() << "launchAppAction: targetAction section is empty";
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetAction.exec.empty()) {
|
||||
qInfo() << "launchAppAction: targetAction exe is empty";
|
||||
return;
|
||||
}
|
||||
|
||||
launch(&info, targetAction.exec.c_str(), timestamp, QStringList());
|
||||
|
||||
// mark app launched
|
||||
dbusHandler->markLaunched(desktopFile);
|
||||
}
|
||||
|
||||
void StartManager::launchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QMap<QString, QString> options)
|
||||
{
|
||||
doLaunchAppWithOptions(desktopFile, timestamp, files, options);
|
||||
}
|
||||
|
||||
void StartManager::runCommand(QString exe, QStringList args)
|
||||
{
|
||||
doRunCommandWithOptions(exe, args, QMap<QString, QString>());
|
||||
}
|
||||
|
||||
void StartManager::runCommandWithOptions(QString exe, QStringList args, QMap<QString, QString> options)
|
||||
{
|
||||
doRunCommandWithOptions(exe, args, options);
|
||||
}
|
||||
|
||||
void StartManager::tryAgain(bool launch)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StartManager::onAutoStartupPathChange(const QString &dirPath)
|
||||
{
|
||||
QStringList autostartFilesList = getAutostartList();
|
||||
QSet<QString> newAutostartFiles = QSet<QString>::fromList(autostartFilesList);
|
||||
QSet<QString> oldAutostartFiles = QSet<QString>::fromList(autostartFiles);
|
||||
|
||||
// 添加
|
||||
QSet<QString> newFiles = newAutostartFiles - oldAutostartFiles;
|
||||
QStringList newFile = newFiles.toList();
|
||||
|
||||
// 移除
|
||||
QSet<QString> deletedFiles = oldAutostartFiles - newAutostartFiles;
|
||||
QStringList deleteFile = deletedFiles.toList();
|
||||
|
||||
// 更新autostartFiles记录
|
||||
autostartFiles = autostartFilesList;
|
||||
|
||||
for (auto &file : newFile) {
|
||||
Q_EMIT autostartChanged(autostartAdded, file);
|
||||
}
|
||||
|
||||
for (auto &file : deleteFile) {
|
||||
Q_EMIT autostartChanged(autostartDeleted, file);
|
||||
}
|
||||
}
|
||||
|
||||
bool StartManager::setAutostart(QString fileName, bool value)
|
||||
{
|
||||
if (!fileName.endsWith(DESKTOPEXT))
|
||||
return false;
|
||||
|
||||
if (isAutostart(fileName) == value)
|
||||
return true;
|
||||
|
||||
QFileInfo info(fileName);
|
||||
QString appId = info.baseName();
|
||||
QString autostartDir(BaseDir::userAutoStartDir().c_str());
|
||||
QString autostartFileName = fileName;
|
||||
bool isUserAutostart = false;
|
||||
// if has no user autostart file, create it
|
||||
if (info.isAbsolute()) {
|
||||
if (info.exists() && info.baseName() == autostartDir) {
|
||||
isUserAutostart = true;
|
||||
}
|
||||
} else {
|
||||
autostartFileName = autostartDir + fileName;
|
||||
if (DFile::isExisted(autostartFileName.toStdString())) {
|
||||
isUserAutostart = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isUserAutostart && !DFile::isExisted(autostartFileName.toStdString())) {
|
||||
// get system autostart desktop file
|
||||
for (auto appDir : BaseDir::appDirs()) {
|
||||
QDir dir(appDir.c_str());
|
||||
dir.setFilter(QDir::Files);
|
||||
dir.setNameFilters({ "*.desktop" });
|
||||
bool hiddenStatusChanged = false;
|
||||
for (auto entry : dir.entryInfoList()) {
|
||||
QString desktopFile = entry.absoluteFilePath();
|
||||
if (!desktopFile.contains(fileName))
|
||||
continue;
|
||||
|
||||
if (!QFile::copy(desktopFile, autostartFileName)) // copy origin file
|
||||
return false;
|
||||
|
||||
hiddenStatusChanged = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hiddenStatusChanged)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// change autostart hidden status in file
|
||||
KeyFile kf;
|
||||
kf.loadFile(autostartFileName.toStdString());
|
||||
kf.setKey(MainSection, KeyXDeepinCreatedBy.toStdString(), AMServiceName.toStdString());
|
||||
kf.setKey(MainSection, KeyXDeepinAppID.toStdString(), appId.toStdString());
|
||||
kf.setBool(MainSection, KeyHidden, !value ? "true" : "false");
|
||||
kf.saveToFile(autostartFileName.toStdString());
|
||||
|
||||
if (value && autostartFiles.indexOf(fileName) != -1) {
|
||||
autostartFiles.push_back(fileName);
|
||||
} else if (!value) {
|
||||
autostartFiles.removeAll(fileName);
|
||||
}
|
||||
|
||||
Q_EMIT autostartChanged(value ? autostartAdded : autostartDeleted, fileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StartManager::doLaunchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QMap<QString, QString> options)
|
||||
{
|
||||
// launchApp
|
||||
DesktopInfo info(desktopFile.toStdString());
|
||||
if (!info.isValidDesktop())
|
||||
return false;
|
||||
|
||||
if (options.find("path") != options.end()) {
|
||||
info.getKeyFile()->setKey(MainSection, KeyPath, options["path"].toStdString());
|
||||
}
|
||||
|
||||
if (options.find("desktop-override-exec") != options.end()) {
|
||||
info.setDesktopOverrideExec(options["desktop-override-exec"].toStdString());
|
||||
}
|
||||
|
||||
if (info.getCommandLine().empty()) {
|
||||
qInfo() << "command line is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
launch(&info, info.getCommandLine().c_str(), timestamp, files);
|
||||
|
||||
// mark app launched
|
||||
dbusHandler->markLaunched(desktopFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp, QStringList files)
|
||||
{
|
||||
QProcess process;
|
||||
QStringList cmdPrefixesEnvs;
|
||||
QStringList envs;
|
||||
QString desktopFile(info->getFileName().c_str());
|
||||
QFileInfo fileInfo(desktopFile);
|
||||
QString appId = fileInfo.baseName();
|
||||
|
||||
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 (!appId.isEmpty() && shouldDisableScaling(appId)) {
|
||||
double scale = SETTING->getScaleFactor();
|
||||
scale = scale > 0 ? 1 / scale : 1;
|
||||
QString qtEnv = "QT_SCALE_FACTOR=" + QString::number(scale, 'f', -1);
|
||||
cmdPrefixesEnvs << "/usr/bin/env" << "GDK_DPI_SCALE=1" << "GDK_SCALE=1" << qtEnv;
|
||||
}
|
||||
|
||||
envs << cmdPrefixesEnvs;
|
||||
|
||||
QStringList exeArgs;
|
||||
exeArgs << cmdLine.split(" ") << files;
|
||||
|
||||
if (info->getTerminal()) {
|
||||
exeArgs.insert(0, SETTING->getDefaultTerminalExecArg());
|
||||
exeArgs.insert(0, SETTING->getDefaultTerminalExec());
|
||||
}
|
||||
|
||||
std::string workingDir = info->getKeyFile()->getStr(MainSection, KeyPath);
|
||||
if (workingDir.empty()) {
|
||||
workingDir = BaseDir::homeDir();
|
||||
}
|
||||
|
||||
QString exec = exeArgs[0];
|
||||
exeArgs.removeAt(0);
|
||||
|
||||
qDebug() << "launchApp: " << desktopFile << " exec: " << exec << " args: " << exeArgs;
|
||||
process.setWorkingDirectory(workingDir.c_str());
|
||||
process.setEnvironment(envs);
|
||||
return process.startDetached(exec, exeArgs);
|
||||
}
|
||||
|
||||
bool StartManager::doRunCommandWithOptions(QString exe, QStringList args, QMap<QString, QString> options)
|
||||
{
|
||||
QProcess process;
|
||||
if (options.find("dir") != options.end()) {
|
||||
process.setWorkingDirectory(options["dir"]);
|
||||
}
|
||||
|
||||
return process.startDetached(exe, args);
|
||||
}
|
||||
|
||||
void StartManager::waitCmd(DesktopInfo *info, QProcess *process, QString cmdName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool StartManager::shouldUseProxy(QString appId)
|
||||
{
|
||||
auto useProxyApps = SETTING->getUseProxyApps();
|
||||
if (!useProxyApps.contains(appId))
|
||||
return false;
|
||||
|
||||
if (dbusHandler->getProxyMsg().isEmpty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StartManager::shouldDisableScaling(QString appId)
|
||||
{
|
||||
auto disableScalingApps = SETTING->getDisableScalingApps();
|
||||
return disableScalingApps.contains(appId);
|
||||
}
|
||||
|
||||
void StartManager::loadSysMemLimitConfig()
|
||||
{
|
||||
std::string configPath = BaseDir::userConfigDir() + "deepin/startdde/memchecker.json";
|
||||
QFile file(configPath.c_str());
|
||||
if (!file.exists())
|
||||
file.setFileName(sysMemLimitConfig);
|
||||
|
||||
do {
|
||||
if (!file.exists())
|
||||
break;
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
break;
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
|
||||
file.close();
|
||||
if (!doc.isObject())
|
||||
break;
|
||||
|
||||
minMemAvail = uint64_t(doc.object()["min-mem-available"].toInt());
|
||||
maxSwapUsed = uint64_t(doc.object()["max-swap-used"].toInt());
|
||||
return;
|
||||
} while (0);
|
||||
|
||||
minMemAvail = defaultMinMemAvail;
|
||||
maxSwapUsed = defaultMaxSwapUsed;
|
||||
}
|
||||
|
||||
void StartManager::listenAutostartFileEvents()
|
||||
{
|
||||
for (auto autostartDir : BaseDir::autoStartDirs()) {
|
||||
fileWatcher->addPath(autostartDir.c_str());
|
||||
}
|
||||
connect(fileWatcher, &QFileSystemWatcher::directoryChanged, this, &StartManager::onAutoStartupPathChange, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void StartManager::startAutostartProgram()
|
||||
{
|
||||
auto func = [&] (QString file, uint64_t delayTime) {
|
||||
QThread::sleep(uint64_t(delayTime));
|
||||
this->launchApp(file, 0, QStringList());
|
||||
};
|
||||
|
||||
for (QString desktopFile : autostartList()) {
|
||||
DesktopInfo info(desktopFile.toStdString());
|
||||
if (!info.isValidDesktop())
|
||||
continue;
|
||||
|
||||
int delayTime = info.getKeyFile()->getInt(MainSection, KeyXGnomeAutostartDelay.toStdString());
|
||||
QTimer::singleShot(0, this, [&, desktopFile, delayTime] {
|
||||
QThread::sleep(uint64_t(delayTime));
|
||||
this->launchApp(desktopFile, 0, QStringList());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
QStringList StartManager::getAutostartList()
|
||||
{
|
||||
QStringList ret;
|
||||
for (auto autostartDir : BaseDir::autoStartDirs()) {
|
||||
if (!DFile::isExisted(autostartDir))
|
||||
continue;
|
||||
|
||||
QDir dir(autostartDir.c_str());
|
||||
dir.setFilter(QDir::Files);
|
||||
dir.setNameFilters({ "*.desktop" });
|
||||
for (auto entry : dir.entryInfoList()) {
|
||||
if (ret.contains(entry.absoluteFilePath()))
|
||||
continue;
|
||||
|
||||
ret.push_back(entry.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
81
src/modules/startmanager/startmanager.h
Normal file
81
src/modules/startmanager/startmanager.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef STARTMANAGER_H
|
||||
#define STARTMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
class AppLaunchContext;
|
||||
class StartManagerDBusHandler;
|
||||
class DesktopInfo;
|
||||
class QProcess;
|
||||
class QFileSystemWatcher;
|
||||
|
||||
class StartManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit StartManager(QObject *parent = nullptr);
|
||||
|
||||
bool addAutostart(QString fileName);
|
||||
bool removeAutostart(QString fileName);
|
||||
QStringList autostartList();
|
||||
QString dumpMemRecord();
|
||||
QString getApps();
|
||||
bool isAutostart(QString fileName);
|
||||
bool isMemSufficient();
|
||||
void launchApp(QString desktopFile, uint32_t timestamp, QStringList files);
|
||||
void launchAppAction(QString desktopFile, QString actionSection, uint32_t timestamp);
|
||||
void launchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QMap<QString, QString> options);
|
||||
void runCommand(QString exe, QStringList args);
|
||||
void runCommandWithOptions(QString exe, QStringList args, QMap<QString, QString> options);
|
||||
void tryAgain(bool launch);
|
||||
|
||||
Q_SIGNALS:
|
||||
void autostartChanged(QString status, QString fileName);
|
||||
|
||||
public Q_SLOTS:
|
||||
void onAutoStartupPathChange(const QString &dirPath);
|
||||
|
||||
private:
|
||||
bool setAutostart(QString fileName, bool value);
|
||||
bool doLaunchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QMap<QString, QString> options);
|
||||
bool launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp, QStringList files);
|
||||
bool doRunCommandWithOptions(QString exe, QStringList args, QMap<QString, QString> options);
|
||||
void waitCmd(DesktopInfo *info, QProcess *process, QString cmdName);
|
||||
bool shouldUseProxy(QString appId);
|
||||
bool shouldDisableScaling(QString appId);
|
||||
void loadSysMemLimitConfig();
|
||||
QStringList getDefaultTerminal();
|
||||
void listenAutostartFileEvents();
|
||||
void startAutostartProgram();
|
||||
QStringList getAutostartList();
|
||||
|
||||
uint64_t minMemAvail;
|
||||
uint64_t maxSwapUsed;
|
||||
StartManagerDBusHandler *dbusHandler;
|
||||
QStringList autostartFiles;
|
||||
QFileSystemWatcher *fileWatcher;
|
||||
};
|
||||
|
||||
#endif // STARTMANAGER_H
|
56
src/modules/startmanager/startmanagerdbushandler.cpp
Normal file
56
src/modules/startmanager/startmanagerdbushandler.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "startmanagerdbushandler.h"
|
||||
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
|
||||
StartManagerDBusHandler::StartManagerDBusHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StartManagerDBusHandler::markLaunched(QString desktopFile)
|
||||
{
|
||||
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecoder1", "/org/deepin/daemon/AlRecoder1", "org.deepin.daemon.AlRecoder1");
|
||||
interface.call("MarkLaunched", desktopFile);
|
||||
}
|
||||
|
||||
QString StartManagerDBusHandler::getProxyMsg()
|
||||
{
|
||||
QString ret;
|
||||
QDBusInterface interface = QDBusInterface("com.deepin.system.proxy", "/com/deepin/system/proxy", "com.deepin.system.proxy.App");
|
||||
QDBusReply<QString> reply = interface.call("GetProxy");
|
||||
if (reply.isValid())
|
||||
ret = reply.value();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void StartManagerDBusHandler::addProxyProc(int32_t pid)
|
||||
{
|
||||
QDBusInterface interface = QDBusInterface("com.deepin.system.proxy", "/com/deepin/system/proxy", "com.deepin.system.proxy.App");
|
||||
interface.call("AddProc");
|
||||
}
|
||||
|
||||
|
43
src/modules/startmanager/startmanagerdbushandler.h
Normal file
43
src/modules/startmanager/startmanagerdbushandler.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef STARTMANAGERDBUSHANDLER_H
|
||||
#define STARTMANAGERDBUSHANDLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class StartManagerDBusHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit StartManagerDBusHandler(QObject *parent = nullptr);
|
||||
|
||||
void markLaunched(QString desktopFile);
|
||||
|
||||
QString getProxyMsg();
|
||||
void addProxyProc(int32_t pid);
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // STARTMANAGERDBUSHANDLER_H
|
108
src/modules/startmanager/startmanagersettings.cpp
Normal file
108
src/modules/startmanager/startmanagersettings.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "startmanagersettings.h"
|
||||
#include "settings.h"
|
||||
#include "gsetting.h"
|
||||
|
||||
#include <DConfig>
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
DCORE_USE_NAMESPACE
|
||||
|
||||
static DConfig *launchConfig = Settings::ConfigPtr(configLauncher);
|
||||
static DConfig *startConfig = Settings::ConfigPtr(configStartdde);
|
||||
static DConfig *xsettingsConfig = Settings::ConfigPtr(configXsettings);
|
||||
|
||||
QVector<QString> StartManagerSettings::getUseProxyApps()
|
||||
{
|
||||
QVector<QString> ret;
|
||||
if (!launchConfig)
|
||||
return ret;
|
||||
|
||||
QList<QVariant> apps = launchConfig->value(keyAppsUseProxy).toList();
|
||||
for (auto app : apps) {
|
||||
ret.push_back(app.toString());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVector<QString> StartManagerSettings::getDisableScalingApps()
|
||||
{
|
||||
QVector<QString> ret;
|
||||
if (!launchConfig)
|
||||
return ret;
|
||||
|
||||
QList<QVariant> apps = launchConfig->value(keyAppsDisableScaling).toList();
|
||||
for (auto app : apps) {
|
||||
ret.push_back(app.toString());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool StartManagerSettings::getMemCheckerEnabled()
|
||||
{
|
||||
bool ret = false;
|
||||
if (startConfig) {
|
||||
ret = startConfig->value(keyMemCheckerEnabled).toBool();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
double StartManagerSettings::getScaleFactor()
|
||||
{
|
||||
double ret = 0;
|
||||
if (xsettingsConfig) {
|
||||
xsettingsConfig->value(keyScaleFactor).toDouble();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString StartManagerSettings::getDefaultTerminalExec()
|
||||
{
|
||||
QString ret;
|
||||
GSetting settings("com.deepin.desktop.default-applications.terminal");
|
||||
auto exec = settings.getString("exec");
|
||||
if (!exec.empty()) {
|
||||
ret = exec.c_str();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString StartManagerSettings::getDefaultTerminalExecArg()
|
||||
{
|
||||
QString ret;
|
||||
GSetting settings("com.deepin.desktop.default-applications.terminal");
|
||||
auto execArg = settings.getString("exec-arg");
|
||||
if (!execArg.empty()) {
|
||||
ret = execArg.c_str();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
StartManagerSettings::StartManagerSettings(QObject *paret)
|
||||
{
|
||||
|
||||
}
|
62
src/modules/startmanager/startmanagersettings.h
Normal file
62
src/modules/startmanager/startmanagersettings.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* 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 of the License, or
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef STARTMANAGERSETTINGS_H
|
||||
#define STARTMANAGERSETTINGS_H
|
||||
#ifdef signals
|
||||
#undef signals
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "gsetting.h"
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
class StartManagerSettings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline StartManagerSettings *instance() {
|
||||
static StartManagerSettings instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
QVector<QString> getUseProxyApps();
|
||||
QVector<QString> getDisableScalingApps();
|
||||
|
||||
bool getMemCheckerEnabled();
|
||||
|
||||
double getScaleFactor();
|
||||
|
||||
QString getDefaultTerminalExec();
|
||||
QString getDefaultTerminalExecArg();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
private:
|
||||
StartManagerSettings(QObject *paret = nullptr);
|
||||
StartManagerSettings(const StartManagerSettings &);
|
||||
StartManagerSettings& operator= (const StartManagerSettings &);
|
||||
};
|
||||
|
||||
#endif // STARTMANAGERSETTINGS_H
|
@ -7,6 +7,7 @@ find_package(DtkCore REQUIRED)
|
||||
|
||||
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb-icccm xcb-ewmh xcb)
|
||||
pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11)
|
||||
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
|
||||
|
||||
qt5_add_dbus_adaptor(ADAPTER_SOURCES
|
||||
../../DBus/org.desktopspec.ApplicationManager.xml
|
||||
@ -63,6 +64,12 @@ set(SRCS
|
||||
../lib/basedir.cpp
|
||||
../lib/xcbutils.h
|
||||
../lib/xcbutils.cpp
|
||||
../lib/applaunchcontext.h
|
||||
../lib/applaunchcontext.cpp
|
||||
../lib/meminfo.h
|
||||
../lib/meminfo.cpp
|
||||
../lib/gsetting.h
|
||||
../lib/gsetting.cpp
|
||||
../utils/settings.h
|
||||
../utils/settings.cpp
|
||||
../utils/synmodulebase.h
|
||||
@ -122,6 +129,13 @@ set(SRCS
|
||||
../modules/dock/dbusadaptordock.cpp
|
||||
../modules/dock/dbusadaptorentry.h
|
||||
../modules/dock/dbusadaptorentry.cpp
|
||||
../modules/startmanager/common.h
|
||||
../modules/startmanager/startmanager.h
|
||||
../modules/startmanager/startmanager.cpp
|
||||
../modules/startmanager/startmanagersettings.h
|
||||
../modules/startmanager/startmanagersettings.cpp
|
||||
../modules/startmanager/startmanagerdbushandler.h
|
||||
../modules/startmanager/startmanagerdbushandler.cpp
|
||||
../frameworkdbus/types/launcheriteminfo.h
|
||||
../frameworkdbus/types/launcheriteminfo.cpp
|
||||
../frameworkdbus/types/launcheriteminfolist.h
|
||||
@ -168,10 +182,12 @@ target_link_libraries(deepin-application-manager
|
||||
pthread
|
||||
PkgConfig::XCB
|
||||
PkgConfig::X11
|
||||
PkgConfig::GIO
|
||||
)
|
||||
|
||||
target_include_directories(deepin-application-manager PUBLIC
|
||||
PkgConfig::XCB
|
||||
PkgConfig::GIO
|
||||
../lib
|
||||
../utils
|
||||
../frameworkdbus
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusConnection>
|
||||
#include <QDebug>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
@ -105,7 +110,13 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
ApplicationManager::ApplicationManager(QObject *parent) : QObject(parent), dd_ptr(new ApplicationManagerPrivate(this)) {}
|
||||
ApplicationManager::ApplicationManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, dd_ptr(new ApplicationManagerPrivate(this))
|
||||
, startManager(new StartManager(this))
|
||||
{
|
||||
connect(startManager, &StartManager::autostartChanged, this, &ApplicationManager::AutostartChanged);
|
||||
}
|
||||
|
||||
ApplicationManager::~ApplicationManager() {}
|
||||
|
||||
@ -116,15 +127,13 @@ void ApplicationManager::addApplication(const QList<QSharedPointer<Application>>
|
||||
d->applications = list;
|
||||
}
|
||||
|
||||
QDBusObjectPath ApplicationManager::GetId(int pid)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QDBusObjectPath ApplicationManager::GetInformation(const QString &id)
|
||||
{
|
||||
Q_D(ApplicationManager);
|
||||
|
||||
if (!checkDMsgUid())
|
||||
return {};
|
||||
|
||||
for (const QSharedPointer<Application> &app : d->applications) {
|
||||
if (app->id() == id) {
|
||||
return app->path();
|
||||
@ -136,6 +145,8 @@ QDBusObjectPath ApplicationManager::GetInformation(const QString &id)
|
||||
QList<QDBusObjectPath> ApplicationManager::GetInstances(const QString &id)
|
||||
{
|
||||
Q_D(const ApplicationManager);
|
||||
if (!checkDMsgUid())
|
||||
return {};
|
||||
|
||||
for (const auto &app : d->applications) {
|
||||
if (app->id() == id) {
|
||||
@ -149,6 +160,8 @@ QList<QDBusObjectPath> ApplicationManager::GetInstances(const QString &id)
|
||||
QDBusObjectPath ApplicationManager::Run(const QString &id)
|
||||
{
|
||||
Q_D(ApplicationManager);
|
||||
if (!checkDMsgUid())
|
||||
return {};
|
||||
|
||||
// 创建一个实例
|
||||
for (const QSharedPointer<Application> &app : d->applications) {
|
||||
@ -171,6 +184,102 @@ QDBusObjectPath ApplicationManager::Run(const QString &id)
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ApplicationManager::AddAutostart(QString fileName)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return false;
|
||||
|
||||
return startManager->addAutostart(fileName);
|
||||
}
|
||||
|
||||
bool ApplicationManager::RemoveAutostart(QString fileName)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return false;
|
||||
|
||||
return startManager->removeAutostart(fileName);
|
||||
}
|
||||
|
||||
QStringList ApplicationManager::AutostartList()
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return {};
|
||||
|
||||
return startManager->autostartList();
|
||||
}
|
||||
|
||||
QString ApplicationManager::DumpMemRecord()
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return {};
|
||||
|
||||
return startManager->dumpMemRecord();
|
||||
}
|
||||
|
||||
bool ApplicationManager::IsAutostart(QString fileName)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return false;
|
||||
|
||||
return startManager->isAutostart(fileName);
|
||||
}
|
||||
|
||||
bool ApplicationManager::IsMemSufficient()
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return true;
|
||||
|
||||
return startManager->isMemSufficient();
|
||||
}
|
||||
|
||||
void ApplicationManager::LaunchApp(QString desktopFile, uint32_t timestamp, QStringList files)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return;
|
||||
|
||||
startManager->launchApp(desktopFile, timestamp, files);
|
||||
}
|
||||
|
||||
void ApplicationManager::LaunchAppAction(QString desktopFile, QString action, uint32_t timestamp)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return;
|
||||
|
||||
startManager->launchAppAction(desktopFile, action, timestamp);
|
||||
}
|
||||
|
||||
void ApplicationManager::LaunchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QMap<QString, QString> options)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return;
|
||||
|
||||
startManager->launchAppWithOptions(desktopFile, timestamp, files, options);
|
||||
}
|
||||
|
||||
void ApplicationManager::RunCommand(QString exe, QStringList args)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return;
|
||||
|
||||
startManager->runCommand(exe, args);
|
||||
}
|
||||
|
||||
void ApplicationManager::RunCommandWithOptions(QString exe, QStringList args, QMap<QString, QString> options)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return;
|
||||
|
||||
startManager->runCommandWithOptions(exe, args, options);
|
||||
}
|
||||
|
||||
void ApplicationManager::TryAgain(bool launch)
|
||||
{
|
||||
if (!checkDMsgUid())
|
||||
return;
|
||||
|
||||
startManager->tryAgain(launch);
|
||||
}
|
||||
|
||||
QList<QDBusObjectPath> ApplicationManager::instances() const
|
||||
{
|
||||
Q_D(const ApplicationManager);
|
||||
@ -196,4 +305,10 @@ QList<QDBusObjectPath> ApplicationManager::list() const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ApplicationManager::checkDMsgUid()
|
||||
{
|
||||
QDBusReply<uint> reply = connection().interface()->serviceUid(message().service());
|
||||
return reply.isValid() && (reply.value() == getuid());
|
||||
}
|
||||
|
||||
#include "application_manager.moc"
|
||||
|
@ -1,14 +1,19 @@
|
||||
#ifndef A2862DC7_5DA3_4129_9796_671D88015BED
|
||||
#define A2862DC7_5DA3_4129_9796_671D88015BED
|
||||
|
||||
#include "../../modules/startmanager/startmanager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QDBusObjectPath>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QDBusContext>
|
||||
|
||||
class Application;
|
||||
class ApplicationInstance;
|
||||
class ApplicationManagerPrivate;
|
||||
class ApplicationManager : public QObject {
|
||||
class ApplicationManager : public QObject, public QDBusContext
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QList<QDBusObjectPath> instances READ instances)
|
||||
Q_PROPERTY(QList<QDBusObjectPath> list READ list)
|
||||
@ -16,6 +21,9 @@ class ApplicationManager : public QObject {
|
||||
Q_DECLARE_PRIVATE_D(qGetPtrHelper(dd_ptr), ApplicationManager)
|
||||
|
||||
ApplicationManager(QObject *parent = nullptr);
|
||||
bool checkDMsgUid();
|
||||
|
||||
StartManager *startManager;
|
||||
|
||||
public:
|
||||
~ApplicationManager() override;
|
||||
@ -26,18 +34,34 @@ public:
|
||||
|
||||
void addApplication(const QList<QSharedPointer<Application>> &list);
|
||||
|
||||
signals:
|
||||
void requestCreateInstance(const QSharedPointer<ApplicationInstance> instance);
|
||||
Q_SIGNALS:
|
||||
void AutostartChanged(QString status, QString filePath);
|
||||
|
||||
public: // PROPERTIES
|
||||
QList<QDBusObjectPath> instances() const;
|
||||
QList<QDBusObjectPath> list() const;
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
QDBusObjectPath GetId(int pid);
|
||||
QDBusObjectPath GetInformation(const QString &id);
|
||||
QList<QDBusObjectPath> GetInstances(const QString &id);
|
||||
QDBusObjectPath Run(const QString &id);
|
||||
|
||||
// com.deepin.StartManager
|
||||
bool AddAutostart(QString fileName);
|
||||
bool RemoveAutostart(QString fileName);
|
||||
QStringList AutostartList();
|
||||
QString DumpMemRecord();
|
||||
//QString GetApps();
|
||||
bool IsAutostart(QString fileName);
|
||||
bool IsMemSufficient();
|
||||
//bool Launch(QString desktopFile); deprecated
|
||||
void LaunchApp(QString desktopFile, uint32_t timestamp, QStringList files);
|
||||
void LaunchAppAction(QString desktopFile, QString action, uint32_t timestamp);
|
||||
void LaunchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QMap<QString, QString> options);
|
||||
//bool LaunchWithTimestamp(QString desktopFile, uint32_t timestamp); deprecated
|
||||
void RunCommand(QString exe, QStringList args);
|
||||
void RunCommandWithOptions(QString exe, QStringList args, QMap<QString, QString> options);
|
||||
void TryAgain(bool launch);
|
||||
};
|
||||
|
||||
#endif /* A2862DC7_5DA3_4129_9796_671D88015BED */
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "../modules/apps/appmanager.h"
|
||||
#include "../modules/launcher/launchermanager.h"
|
||||
#include "../modules/dock/dockmanager.h"
|
||||
#include "../modules/startmanager/startmanager.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <DLog>
|
||||
@ -74,6 +75,7 @@ int main(int argc, char *argv[])
|
||||
new AppManager(ApplicationManager::Instance());
|
||||
new LauncherManager(ApplicationManager::Instance());
|
||||
new DockManager(ApplicationManager::Instance());
|
||||
new StartManager(ApplicationManager::Instance());
|
||||
new ApplicationManagerAdaptor(ApplicationManager::Instance());
|
||||
|
||||
QDBusConnection::sessionBus().registerService("org.desktopspec.Application");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
|
Reference in New Issue
Block a user