feat: 修改自启动应用启动方式

*修改自启动应用启动方式, 采用loader进程先校验应用信息,再拉起应用的方式
*修复launcher模块部分接口导出失败的问题
*增加launcher、dock、loader模块代码注释

Log: 修改自启动应用启动方式
Task: https://pms.uniontech.com/task-view-131611.html
Influence: 应用启动方式不同
Change-Id: Ie88027602d1395c6bbad69e610f3639ecc7dfbc1
This commit is contained in:
weizhixiang 2022-05-19 13:13:55 +08:00
parent 68f52fe831
commit 5997b3a2a1
53 changed files with 1618 additions and 693 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
CMakeLists.txt.user
build/
build/

View File

@ -1,16 +1,9 @@
<interface name='org.desktopspec.ApplicationManager'>
<method name='Run'>
<method name='Launch'>
<arg type='s' name='id' direction='in'/>
<arg type='as' name='files' direction='in' />
<arg type='o' name='instance' direction='out'/>
</method>
<method name='GetInformation'>
<arg type='s' name='id' direction='in' />
<arg type='o' name='info' direction='out' />
</method>
<method name='GetInstances'>
<arg type='s' name='id' direction='in' />
<arg type='ao' name='instances' direction='out' />
</method>
<method name='AddAutostart'>
<arg type='s' name='fileNamae' direction='in' />
<arg type='b' name='outArg0' direction='out' />
@ -32,11 +25,6 @@
<method name='IsMemSufficient'>
<arg type='b' name='outArg0' direction='out' />
</method>
<method name='LaunchApp'>
<arg type='s' name='desktopFile' direction='in' />
<arg type='u' name='timestamp' direction='in' />
<arg type='as' name='files' direction='in' />
</method>
<method name='LaunchAppAction'>
<arg type='s' name='desktopFile' direction='in' />
<arg type='s' name='action' direction='in' />

View File

@ -3,7 +3,7 @@ set(DCONFIG_FILES
com.deepin.dde.dock.json
com.deepin.dde.appearance.json
com.deepin.dde.startdde.json
com.deepin.dde.xsettings.json
com.deepin.xsettings.json
)
install(FILES ${DCONFIG_FILES} DESTINATION /usr/share/dsg/configs/dde-application-manager)

View File

@ -22,13 +22,13 @@
bool LauncherItemInfo::operator!=(const LauncherItemInfo &itemInfo)
{
return itemInfo.ID != ID;
return itemInfo.id != id;
}
QDBusArgument &operator<<(QDBusArgument &argument, const LauncherItemInfo &itemInfo)
{
argument.beginStructure();
argument << itemInfo.Path << itemInfo.Name << itemInfo.ID << itemInfo.Icon << itemInfo.CategoryID << itemInfo.TimeInstalled;
argument << itemInfo.path << itemInfo.name << itemInfo.id << itemInfo.icon << itemInfo.categoryId << itemInfo.timeInstalled << itemInfo.keywords;
argument.endStructure();
return argument;
}
@ -36,7 +36,7 @@ QDBusArgument &operator<<(QDBusArgument &argument, const LauncherItemInfo &itemI
const QDBusArgument &operator>>(const QDBusArgument &argument, LauncherItemInfo &itemInfo)
{
argument.beginStructure();
argument >> itemInfo.Path >> itemInfo.Name >> itemInfo.ID >> itemInfo.Icon >> itemInfo.CategoryID >> itemInfo.TimeInstalled;
argument >> itemInfo.path >> itemInfo.name >> itemInfo.id >> itemInfo.icon >> itemInfo.categoryId >> itemInfo.timeInstalled >> itemInfo.keywords;
argument.endStructure();
return argument;
}

View File

@ -26,12 +26,13 @@
#include <QDBusMetaType>
struct LauncherItemInfo {
QString Path;
QString Name;
QString ID;
QString Icon;
qint64 CategoryID;
qint64 TimeInstalled;
QString path;
QString name;
QString id;
QString icon;
qint64 categoryId;
qint64 timeInstalled;
QStringList keywords;
bool operator!=(const LauncherItemInfo &versionInfo);
};

View File

@ -14,7 +14,6 @@ public:
friend const QDBusArgument &operator>>(const QDBusArgument &arg, Rect &rect);
friend QDBusArgument &operator<<(QDBusArgument &arg, const Rect &rect);
private:
qint32 X, Y, Width, Height;
};

View File

@ -0,0 +1,7 @@
#include "unlaunchedappmap.h"
void registerUnLaunchedAppMapMetaType()
{
qRegisterMetaType<UnLaunchedAppMap>("UnLaunchedAppMap");
qDBusRegisterMetaType<UnLaunchedAppMap>();
}

View File

@ -0,0 +1,14 @@
#ifndef TYPES_H
#define TYPES_H
#include <QMap>
#include <QStringList>
#include <QDBusMetaType>
typedef QMap<QString, QStringList> UnLaunchedAppMap;
Q_DECLARE_METATYPE(UnLaunchedAppMap)
void registerUnLaunchedAppMapMetaType();
#endif // TYPES_H

View File

@ -48,7 +48,7 @@ std::string BaseDir::userDataDir()
if (!xdgDataHomePtr)
return defaultDir;
if (!DFile::isAbs(xdgDataHomePtr))
if (!DFile::isDir(xdgDataHomePtr))
return defaultDir;
return std::string(xdgDataHomePtr) + "/";
@ -80,7 +80,7 @@ std::string BaseDir::userConfigDir()
return defaultDir;
std::string xdgConfigHome(xdgConfigHomePtr);
if (!DFile::isAbs(xdgConfigHome))
if (!DFile::isDir(xdgConfigHome))
return defaultDir;
return xdgConfigHome + "/";
@ -112,7 +112,7 @@ std::string BaseDir::userCacheDir()
return defaultDir;
std::string xdgCacheHome(xdgCacheHomePtr);
if (!DFile::isAbs(xdgCacheHome))
if (!DFile::isDir(xdgCacheHome))
return defaultDir;
return xdgCacheHome + "/";
@ -158,7 +158,7 @@ std::string BaseDir::userAutoStartDir()
void BaseDir::filterNotAbs(std::vector<std::string> &dirs)
{
for (auto iter = dirs.begin(); iter != dirs.end();) { // erase element in vector
if (!DFile::isAbs(*iter))
if (!DFile::isDir(*iter))
iter = dirs.erase(iter);
else
iter++;

View File

@ -43,7 +43,7 @@ DesktopInfo::DesktopInfo(const std::string &_fileName)
m_fileName = fileNameWithSuffix;
if (!DFile::isAbs(m_fileName)) {
if (DFile::dir(m_fileName).empty()) {
// fileName是文件名增加目录
bool isExisted = false;
for (const auto &dir : BaseDir::appDirs()) {

View File

@ -21,7 +21,9 @@
#include "dfile.h"
#include "macro.h"
#include "dstring.h"
#include<sys/stat.h>
#include <unistd.h>
#include <cstring>
@ -30,14 +32,39 @@ DFile::DFile()
}
bool DFile::isAbs(std::string file)
// 符号连接
bool DFile::isLink(std::string file)
{
char resolved_path[MAX_FILEPATH_LEN];
if (realpath(file.c_str(), resolved_path)) {
std::string filePath(resolved_path);
if (filePath == file)
return true;
}
if (file.empty())
return false;
struct stat fileStat;
if (!stat(file.c_str(), &fileStat))
return S_ISLNK(fileStat.st_mode);
return false;
}
bool DFile::isRegularFile(std::string file)
{
if (file.empty())
return false;
struct stat fileStat;
if (!stat(file.c_str(), &fileStat))
return S_ISREG(fileStat.st_mode);
return true;
}
bool DFile::isDir(std::string dir)
{
if (dir.empty())
return false;
struct stat fileStat;
if (!stat(dir.c_str(), &fileStat))
return S_ISDIR(fileStat.st_mode);
return false;
}
@ -47,13 +74,15 @@ bool DFile::isExisted(std::string file)
return !access(file.c_str(), F_OK);
}
std::string DFile::dir(std::string file)
std::string DFile::dir(std::string path)
{
std::string ret;
if (isAbs(file)) {
size_t pos = file.find_last_of("/");
if (isDir(path)) {
ret = path;
} else {
size_t pos = path.find_last_of("/");
if (pos != std::string::npos) {
ret.assign(file, 0, pos + 1); // 包含结尾斜杠/
ret.assign(path, 0, pos + 1); // 包含结尾斜杠/
}
}

View File

@ -28,9 +28,11 @@ class DFile
{
public:
explicit DFile();
static bool isAbs(std::string file);
static bool isLink(std::string file);
static bool isRegularFile(std::string file);
static bool isDir(std::string dir);
static bool isExisted(std::string file);
static std::string dir(std::string file);
static std::string dir(std::string path);
static std::string base(std::string file);
};

View File

@ -25,7 +25,11 @@
#define _likely_(x) (__builtin_expect(!!(x), 1))
#define _unlikely_(x) (__builtin_expect(!!(x), 0))
#define MAX(x, y) (x) > (y) ? (x) : (y)
#define MIN(x, y) (x) < (y) ? (x) : (y)
#define MAX_FILEPATH_LEN 256
#define MAX_LINE_LEN 256
#endif // MACRO_H

View File

@ -53,9 +53,11 @@ static App parseApp(const std::string& app)
}
App result;
result.prefix = strings[0];
result.type = strings[1];
result.id = strings[2];
if (strings.size() == 3) {
result.prefix = strings[0];
result.type = strings[1];
result.id = strings[2];
}
return result;
}
@ -80,20 +82,12 @@ int runLinglong(void* _arg)
return 0;
}
int child(void* _arg)
int child(Methods::Task* task, std::string path)
{
Methods::Task* task = (Methods::Task*) _arg;
prctl(PR_SET_PDEATHSIG, SIGKILL);
prctl(PR_SET_PDEATHSIG, SIGTERM);
prctl(PR_SET_PDEATHSIG, SIGHUP);
App app = parseApp(task->runId.toStdString());
std::string path{ "/usr/share/applications/" + app.id + ".desktop" };
if (app.type == "user") {
struct passwd* user = getpwuid(getuid());
path = std::string(user->pw_dir) + "/.local/share/applications/" + app.id + ".desktop";
}
DesktopDeconstruction dd(path);
dd.beginGroup("Desktop Entry");
std::cout << dd.value<std::string>("Exec") << std::endl;
@ -114,8 +108,8 @@ int child(void* _arg)
std::filesystem::path container_root_path(annotations.container_root_path.toStdString());
if (!std::filesystem::exists(container_root_path)) {
if (!std::filesystem::create_directories(container_root_path)) {
std::cout << "[Loader] [Warning] cannot create container root path." << std::endl;
return -1;
std::cout << "[Loader] [Warning] cannot create container root path." << std::endl;
return -1;
}
}
@ -137,10 +131,12 @@ int child(void* _arg)
runtime.process.args.push_back(QString::fromStdString(s));
}
// 应用运行信息
QByteArray runtimeArray;
toJson(runtimeArray, runtime);
qWarning() << "runtimeArray: " << runtimeArray;
// 使用Pipe进行父子进程通信
int pipeEnds[2];
if (pipe(pipeEnds) != 0) {
return EXIT_FAILURE;
@ -153,22 +149,29 @@ int child(void* _arg)
}
if (pid == 0) {
// 子进程
(void) close(pipeEnds[1]);
// 重定向到LINGLONG
if (dup2(pipeEnds[0], LINGLONG) == -1) {
return EXIT_FAILURE;
}
(void) close(pipeEnds[0]);
// 初始化运行命令和参数,并执行
char const* const args[] = { "/usr/bin/ll-box", LL_TOSTRING(LINGLONG), nullptr };
int ret = execvp(args[0], (char**) args);
std::cout << "[Loader] [Fork] " << ret << std::endl;
//std::filesystem::remove(container_root_path);
exit(ret);
}
else {
} else {
// 父进程
QByteArray runtimeArray;
linglong::toJson(runtimeArray, runtime);
const std::string data = runtimeArray.data();
close(pipeEnds[0]);
// 将运行时信息通过pipe传递给子进程
write(pipeEnds[1], data.c_str(), data.size());
close(pipeEnds[1]);
}
@ -190,22 +193,24 @@ int main(int argc, char* argv[])
return -2;
}
// TODO: move to a utils.h
std::string socketPath{ "/run/user/1000/deepin-application-manager.socket" };
char socketPath[50];
sprintf(socketPath, "/run/user/%d/deepin-application-manager.socket", getuid());
// register client and run quitConnect
Socket::Client client;
client.connect(socketPath);
// 初始化应用注册信息
QByteArray registerArray;
Methods::Registe registe;
registe.id = dam_task_type;
registe.hash = dam_task_hash;
Methods::toJson(registerArray, registe);
// 向AM注册应用信息进行校验
Methods::Registe registe_result;
registe_result.state = false;
auto result = client.get(registerArray);
QByteArray result = client.get(registerArray);
if (!result.isEmpty()) {
Methods::fromJson(result, registe_result);
}
@ -213,16 +218,31 @@ int main(int argc, char* argv[])
return -3;
}
// 初始化应用实例信息
Methods::Instance instance;
instance.hash = registe_result.hash;
std::cout << "get task" << std::endl;
QByteArray instanceArray;
Methods::toJson(instanceArray, instance);
// 向AM注册应用实例信息进行校验
result = client.get(instanceArray);
Methods::Task task;
Methods::toJson(result, task);
Methods::fromJson(result, task); // fromJson TODO 数据解析异常
qWarning() << "[result] " << result;
// 校验task内容
App app = parseApp(task.runId.toStdString());
if (task.id.isEmpty() || app.id.empty() || app.type.empty() || app.prefix.empty()) {
std::cout << "get task error" << std::endl;
return -4;
}
std::string path{ "/usr/share/applications/" + app.id + ".desktop" };
if (app.type == "user") {
struct passwd* user = getpwuid(getuid());
path = std::string(user->pw_dir) + "/.local/share/applications/" + app.id + ".desktop";
}
pthread_attr_t attr;
size_t stack_size;
pthread_attr_init(&attr);
@ -237,7 +257,7 @@ int main(int argc, char* argv[])
//char* stack = (char*) malloc(stack_size);
//pid_t pid = clone(child, stack + stack_size, CLONE_NEWPID | SIGCHLD, static_cast<void*>(&task));
pid_t pid = child(&task);
pid_t pid = child(&task, path);
// TODO: 启动线程,创建新的连接去接受服务器的消息
/* 设置捕捉函数 */

View File

@ -35,30 +35,19 @@ AlRecorder::AlRecorder(DFWatcher *_watcher, QObject *parent)
, watcher(_watcher)
, mutex(QMutex(QMutex::NonRecursive))
{
QDBusConnection con = QDBusConnection::sessionBus();
if (!con.registerService("org.deepin.daemon.AlRecorder1"))
{
qWarning() << "register service AlRecorder1 error:" << con.lastError().message();
return;
}
if (!con.registerObject("/org/deepin/daemon/AlRecorder1", this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals))
{
qWarning() << "register object AlRecorder1 error:" << con.lastError().message();
return;
}
connect(watcher, &DFWatcher::Event, this, &AlRecorder::onDFChanged, Qt::QueuedConnection);
Q_EMIT ServiceRestarted();
Q_EMIT serviceRestarted();
}
AlRecorder::~AlRecorder()
{
QDBusConnection::sessionBus().unregisterObject("/org/deepin/daemon/AlRecorder1");
}
// 获取未启动应用列表
QMap<QString, QStringList> AlRecorder::GetNew()
/**
* @brief AlRecorder::getNew
* @return
*/
QMap<QString, QStringList> AlRecorder::getNew()
{
QMap<QString, QStringList> ret;
QMutexLocker locker(&mutex);
@ -76,8 +65,11 @@ QMap<QString, QStringList> AlRecorder::GetNew()
return ret;
}
// 标记应用已启动状态
void AlRecorder::MarkLaunched(const QString &filePath)
/**
* @brief AlRecorder::markLaunched
* @param filePath
*/
void AlRecorder::markLaunched(const QString &filePath)
{
if (!filePath.endsWith(".desktop"))
return;
@ -102,12 +94,15 @@ void AlRecorder::MarkLaunched(const QString &filePath)
end:
if (info.isDir()) {
saveStatusFile(info.absolutePath() + "/");
Q_EMIT Launched(filePath);
Q_EMIT launched(filePath);
}
}
// 记录Launcher服务卸载应用信息, 终端卸载不会调用该函数, desktopFiles为绝对路径
void AlRecorder::UninstallHints(const QStringList &desktopFiles)
/**
* @brief AlRecorder::uninstallHints Launcher服务卸载应用信息, desktopFiles为绝对路径
* @param desktopFiles
*/
void AlRecorder::uninstallHints(const QStringList &desktopFiles)
{
QMutexLocker locker(&mutex);
for (auto desktop : desktopFiles) {
@ -121,8 +116,11 @@ void AlRecorder::UninstallHints(const QStringList &desktopFiles)
}
}
// 监控目录
void AlRecorder::WatchDirs(const QStringList &dataDirs)
/**
* @brief AlRecorder::watchDirs
* @param dataDirs
*/
void AlRecorder::watchDirs(const QStringList &dataDirs)
{
for (auto dirPath : dataDirs) {
if (subRecoders.contains(dirPath))
@ -143,7 +141,10 @@ void AlRecorder::WatchDirs(const QStringList &dataDirs)
}
}
// 初始化应用目录记录
/**
* @brief AlRecorder::initSubRecoder
* @param dirPath
*/
void AlRecorder::initSubRecoder(const QString &dirPath)
{
subRecorder sub;
@ -191,6 +192,11 @@ void AlRecorder::initSubRecoder(const QString &dirPath)
subRecoders[dirPath] = sub;
}
/**
* @brief AlRecorder::onDFChanged desktopFile文件改变事件
* @param filePath
* @param op
*/
void AlRecorder::onDFChanged(const QString &filePath, uint32_t op)
{
QFileInfo info(filePath);
@ -232,6 +238,10 @@ void AlRecorder::onDFChanged(const QString &filePath, uint32_t op)
}
}
/**
* @brief AlRecorder::saveStatusFile
* @param dirPath
*/
void AlRecorder::saveStatusFile(const QString &dirPath)
{
subRecorder sub = subRecoders[dirPath];
@ -252,6 +262,6 @@ void AlRecorder::saveStatusFile(const QString &dirPath)
// 覆盖原文件
QFile::remove(sub.statusFile);
QFile::rename(tmpFile, sub.statusFile);
Q_EMIT StatusSaved(dirPath, sub.statusFile, ok);
Q_EMIT statusSaved(dirPath, sub.statusFile, ok);
}

View File

@ -46,18 +46,18 @@ public:
~AlRecorder();
Q_SIGNALS:
void Launched(const QString &file);
void StatusSaved(const QString &root, const QString &file, bool ok);
void ServiceRestarted();
void launched(const QString &file);
void statusSaved(const QString &root, const QString &file, bool ok);
void serviceRestarted();
private Q_SLOTS:
void onDFChanged(const QString &filePath, uint32_t op);
public Q_SLOTS:
QMap<QString, QStringList> GetNew();
void MarkLaunched(const QString &filePath);
void UninstallHints(const QStringList &desktopFiles);
void WatchDirs(const QStringList &dataDirs);
QMap<QString, QStringList> getNew();
void markLaunched(const QString &filePath);
void uninstallHints(const QStringList &desktopFiles);
void watchDirs(const QStringList &dataDirs);
private:
void initSubRecoder(const QString &dirPath);

View File

@ -23,6 +23,7 @@
#include "dfwatcher.h"
#include "alrecorder.h"
#include "basedir.h"
#include "dbusalrecorderadaptor.h"
#include <QDebug>
#include <QDir>
@ -32,12 +33,27 @@ AppManager::AppManager(QObject *parent)
, watcher(new DFWatcher(this))
, recorder(new AlRecorder(watcher, this))
{
new DBusAdaptorRecorder(recorder);
QDBusConnection con = QDBusConnection::sessionBus();
if (!con.registerService("org.deepin.daemon.AlRecorder1"))
{
qWarning() << "register service AlRecorder1 error:" << con.lastError().message();
return;
}
if (!con.registerObject("/org/deepin/daemon/AlRecorder1", recorder))
{
qWarning() << "register object AlRecorder1 error:" << con.lastError().message();
return;
}
QStringList dataDirs;
dataDirs << BaseDir::userAppDir().c_str();
for (auto &dir : BaseDir::sysAppDirs())
dataDirs << dir.c_str();
recorder->WatchDirs(dataDirs); // 监控应用desktop
recorder->watchDirs(dataDirs); // 监控应用desktop
}
AppManager::~AppManager()

View File

@ -0,0 +1,48 @@
#include "dbusalrecorderadaptor.h"
DBusAdaptorRecorder::DBusAdaptorRecorder(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
// constructor
setAutoRelaySignals(true);
if (QMetaType::type("UnlaunchedAppMap") == QMetaType::UnknownType)
registerUnLaunchedAppMapMetaType();
AlRecorder *recorder = static_cast<AlRecorder *>(QObject::parent());
if (recorder) {
connect(recorder, &AlRecorder::launched, this, &DBusAdaptorRecorder::Launched);
connect(recorder, &AlRecorder::serviceRestarted, this, &DBusAdaptorRecorder::ServiceRestarted);
connect(recorder, &AlRecorder::statusSaved, this, &DBusAdaptorRecorder::StatusSaved);
}
}
DBusAdaptorRecorder::~DBusAdaptorRecorder()
{
// destructor
}
AlRecorder *DBusAdaptorRecorder::parent() const
{
return static_cast<AlRecorder *>(QObject::parent());
}
UnLaunchedAppMap DBusAdaptorRecorder::GetNew()
{
return parent()->getNew();
}
void DBusAdaptorRecorder::MarkLaunched(const QString &desktopFile)
{
parent()->markLaunched(desktopFile);
}
void DBusAdaptorRecorder::UninstallHints(const QStringList &desktopFiles)
{
parent()->uninstallHints(desktopFiles);
}
void DBusAdaptorRecorder::WatchDirs(const QStringList &dirs)
{
parent()->watchDirs(dirs);
}

View File

@ -0,0 +1,67 @@
#ifndef DBUSALRECORDERADAPTOR_H
#define DBUSALRECORDERADAPTOR_H
#include "alrecorder.h"
#include "unlaunchedappmap.h"
#include <QtCore/QObject>
#include <QtCore/QMetaObject>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
class DBusAdaptorRecorder: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.deepin.daemon.AlRecorder1")
Q_CLASSINFO("D-Bus Introspection", ""
" <interface name=\"org.deepin.daemon.AlRecorder1\">\n"
" <method name=\"GetNew\">\n"
" <arg direction=\"out\" type=\"a{sas}\" name=\"newApps\"/>\n"
" <annotation value=\"UnLaunchedAppMap\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
" </method>\n"
" <method name=\"MarkLaunched\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" </method>\n"
" <method name=\"UninstallHints\">\n"
" <arg direction=\"in\" type=\"as\" name=\"desktopFiles\"/>\n"
" </method>\n"
" <method name=\"WatchDirs\">\n"
" <arg direction=\"in\" type=\"as\" name=\"dirs\"/>\n"
" </method>\n"
" <signal name=\"Launched\">\n"
" <arg type=\"s\" name=\"file\"/>\n"
" </signal>\n"
" <signal name=\"StatusSaved\">\n"
" <arg type=\"s\" name=\"root\"/>\n"
" <arg type=\"s\" name=\"file\"/>\n"
" <arg type=\"b\" name=\"ok\"/>\n"
" </signal>\n"
" <signal name=\"ServiceRestarted\"/>\n"
" </interface>\n"
"")
AlRecorder *parent() const;
public:
explicit DBusAdaptorRecorder(QObject *parent);
virtual ~DBusAdaptorRecorder();
public: // PROPERTIES
public Q_SLOTS: // METHODS
UnLaunchedAppMap GetNew();
void MarkLaunched(const QString &desktopFile);
void UninstallHints(const QStringList &desktopFiles);
void WatchDirs(const QStringList &dirs);
Q_SIGNALS: // SIGNALS
void Launched(const QString &file);
void ServiceRestarted();
void StatusSaved(const QString &root, const QString &file, bool ok);
};
#endif

View File

@ -212,6 +212,31 @@ QString DBusAdaptorDock::QueryWindowIdentifyMethod(uint win)
return parent()->queryWindowIdentifyMethod(win);
}
QStringList DBusAdaptorDock::GetDockedAppsDesktopFiles()
{
return parent()->getDockedAppsDesktopFiles();
}
QString DBusAdaptorDock::GetPluginSettings()
{
return parent()->getPluginSettings();
}
void DBusAdaptorDock::SetPluginSettings(QString jsonStr)
{
parent()->setPluginSettings(jsonStr);
}
void DBusAdaptorDock::MergePluginSettings(QString jsonStr)
{
parent()->mergePluginSettings(jsonStr);
}
void DBusAdaptorDock::RemovePluginSettings(QString key1, QStringList key2List)
{
parent()->removePluginSettings(key1, key2List);
}
bool DBusAdaptorDock::RequestDock(const QString &desktopFile, int index)
{
return parent()->requestDock(desktopFile, index);

View File

@ -44,67 +44,83 @@ class DBusAdaptorDock: public QDBusAbstractAdaptor
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.deepin.dde.daemon.Dock1")
Q_CLASSINFO("D-Bus Introspection", ""
" <interface name=\"org.deepin.dde.daemon.Dock1\">\n"
" <method name=\"CloseWindow\">\n"
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
" </method>\n"
" <method name=\"GetEntryIDs\">\n"
" <arg direction=\"out\" type=\"as\" name=\"list\"/>\n"
" </method>\n"
" <method name=\"IsDocked\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"IsOnDock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"MoveEntry\">\n"
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"newIndex\"/>\n"
" </method>\n"
" <method name=\"QueryWindowIdentifyMethod\">\n"
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
" <arg direction=\"out\" type=\"s\" name=\"identifyMethod\"/>\n"
" </method>\n"
" <method name=\"RequestDock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"RequestUndock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"SetFrontendWindowRect\">\n"
" <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
" <arg direction=\"in\" type=\"u\" name=\"width\"/>\n"
" <arg direction=\"in\" type=\"u\" name=\"height\"/>\n"
" </method>\n"
" <signal name=\"ServiceRestarted\"/>\n"
" <signal name=\"EntryAdded\">\n"
" <arg type=\"o\" name=\"path\"/>\n"
" <arg type=\"i\" name=\"index\"/>\n"
" </signal>\n"
" <signal name=\"EntryRemoved\">\n"
" <arg type=\"s\" name=\"entryId\"/>\n"
" </signal>\n"
" <property access=\"readwrite\" type=\"u\" name=\"ShowTimeout\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"HideTimeout\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeEfficient\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeFashion\"/>\n"
" <property access=\"read\" type=\"iiii\" name=\"FrontendWindowRect\"/>\n"
" <property access=\"read\" type=\"d\" name=\"Opacity\"/>\n"
" <property access=\"read\" type=\"ao\" name=\"Entries\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"HideMode\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"DisplayMode\"/>\n"
" <property access=\"read\" type=\"i\" name=\"HideState\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"Position\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"IconSize\"/>\n"
" <property access=\"read\" type=\"as\" name=\"DockedApps\"/>\n"
" </interface>\n"
"")
" <interface name=\"org.deepin.dde.daemon.Dock1\">\n"
" <method name=\"CloseWindow\">\n"
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
" </method>\n"
" <method name=\"GetEntryIDs\">\n"
" <arg direction=\"out\" type=\"as\" name=\"list\"/>\n"
" </method>\n"
" <method name=\"IsDocked\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"IsOnDock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"MoveEntry\">\n"
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"newIndex\"/>\n"
" </method>\n"
" <method name=\"QueryWindowIdentifyMethod\">\n"
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
" <arg direction=\"out\" type=\"s\" name=\"identifyMethod\"/>\n"
" </method>\n"
" <method name=\"GetDockedAppsDesktopFiles\">\n"
" <arg direction=\"out\" type=\"as\" name=\"desktopFiles\"/>\n"
" </method>\n"
" <method name=\"GetPluginSettings\">\n"
" <arg direction=\"out\" type=\"s\" name=\"jsonStr\"/>\n"
" </method>\n"
" <method name=\"SetPluginSettings\">\n"
" <arg direction=\"in\" type=\"s\" name=\"jsonStr\"/>\n"
" </method>\n"
" <method name=\"MergePluginSettings\">\n"
" <arg direction=\"in\" type=\"s\" name=\"jsonStr\"/>\n"
" </method>\n"
" <method name=\"RemovePluginSettings\">\n"
" <arg direction=\"in\" type=\"s\" name=\"key1\"/>\n"
" <arg direction=\"in\" type=\"as\" name=\"key2List\"/>\n"
" </method>\n"
" <method name=\"RequestDock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"RequestUndock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"SetFrontendWindowRect\">\n"
" <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
" <arg direction=\"in\" type=\"u\" name=\"width\"/>\n"
" <arg direction=\"in\" type=\"u\" name=\"height\"/>\n"
" </method>\n"
" <signal name=\"ServiceRestarted\"/>\n"
" <signal name=\"EntryAdded\">\n"
" <arg type=\"o\" name=\"path\"/>\n"
" <arg type=\"i\" name=\"index\"/>\n"
" </signal>\n"
" <signal name=\"EntryRemoved\">\n"
" <arg type=\"s\" name=\"entryId\"/>\n"
" </signal>\n"
" <property access=\"readwrite\" type=\"u\" name=\"ShowTimeout\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"HideTimeout\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeEfficient\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeFashion\"/>\n"
" <property access=\"read\" type=\"(iiii)\" name=\"FrontendWindowRect\"/>\n"
" <property access=\"read\" type=\"d\" name=\"Opacity\"/>\n"
" <property access=\"read\" type=\"ao\" name=\"Entries\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"HideMode\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"DisplayMode\"/>\n"
" <property access=\"read\" type=\"i\" name=\"HideState\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"Position\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"IconSize\"/>\n"
" <property access=\"read\" type=\"as\" name=\"DockedApps\"/>\n"
" </interface>\n"
"")
public:
DBusAdaptorDock(QObject *parent);
virtual ~DBusAdaptorDock();
@ -166,6 +182,11 @@ public Q_SLOTS: // METHODS
bool IsOnDock(const QString &desktopFile);
void MoveEntry(int index, int newIndex);
QString QueryWindowIdentifyMethod(uint win);
QStringList GetDockedAppsDesktopFiles();
QString GetPluginSettings();
void SetPluginSettings(QString jsonStr);
void MergePluginSettings(QString jsonStr);
void RemovePluginSettings(QString key1, QStringList key2List);
bool RequestDock(const QString &desktopFile, int index);
bool RequestUndock(const QString &desktopFile);
void SetFrontendWindowRect(int x, int y, uint width, uint height);

View File

@ -67,13 +67,13 @@ void DBusHandler::listenWaylandWMSignals()
void DBusHandler::handleLauncherItemChanged(const QString &status, LauncherItemInfo itemInfo, qlonglong categoryID)
{
qInfo() << "handleLauncherItemChanged status:" << status << " Name:" << itemInfo.Name << " ID:" << itemInfo.ID;
qInfo() << "handleLauncherItemChanged status:" << status << " Name:" << itemInfo.name << " ID:" << itemInfo.id;
if (status == "deleted") {
dock->handleLauncherItemDeleted(itemInfo.Path);
dock->handleLauncherItemDeleted(itemInfo.path);
} else if (status == "created") {
// don't need to download to dock when app reinstall
} else if (status == "updated") {
dock->handleLauncherItemUpdated(itemInfo.Path);
dock->handleLauncherItemUpdated(itemInfo.path);
}
}
@ -186,7 +186,10 @@ PlasmaWindow *DBusHandler::createPlasmaWindow(QString objPath)
return new PlasmaWindow("com.deepin.daemon.KWayland.PlasmaWindow", objPath, session, this);
}
// 取消关联信号
/**
* @brief DBusHandler::removePlasmaWindowHandler TODO
* @param window
*/
void DBusHandler::removePlasmaWindowHandler(PlasmaWindow *window)
{

View File

@ -31,6 +31,8 @@
#include "windowinfobase.h"
#include "dbusplasmawindow.h"
#include "macro.h"
#include <QDir>
#include <QMap>
#include <QTimer>
@ -40,6 +42,7 @@
Dock::Dock(QObject *parent)
: SynModule(parent)
, entriesSum(0)
, windowIdentify(new WindowIdentify(this))
, entries(new Entries(this))
, ddeLauncherVisible(true)
@ -91,7 +94,11 @@ Dock::~Dock()
}
// 驻留
/**
* @brief Dock::dockEntry
* @param entry
* @return
*/
bool Dock::dockEntry(Entry *entry)
{
if (entry->getIsDocked())
@ -176,7 +183,10 @@ bool Dock::dockEntry(Entry *entry)
return true;
}
// 取消驻留
/**
* @brief Dock::undockEntry
* @param entry
*/
void Dock::undockEntry(Entry *entry)
{
if (!entry->getIsDocked()) {
@ -232,12 +242,20 @@ void Dock::undockEntry(Entry *entry)
saveDockedApps();
}
/**
* @brief Dock::allocEntryId id
* @return
*/
QString Dock::allocEntryId()
{
int num = entriesSum++;
return QString::number(num);
return QString("e%1T%2").arg(++entriesSum).arg(QString::number(QDateTime::currentMSecsSinceEpoch(), 16));
}
/**
* @brief Dock::shouldShowOnDock
* @param info
* @return
*/
bool Dock::shouldShowOnDock(WindowInfoBase *info)
{
if (info->getWindowType() == "X11") {
@ -256,56 +274,101 @@ bool Dock::shouldShowOnDock(WindowInfoBase *info)
return false;
}
/**
* @brief Dock::setDdeLauncherVisible
* @param visible
*/
void Dock::setDdeLauncherVisible(bool visible)
{
ddeLauncherVisible = visible;
}
/**
* @brief Dock::getWMName
* @return
*/
QString Dock::getWMName()
{
return wmName;
}
/**
* @brief Dock::setWMName
* @param name
*/
void Dock::setWMName(QString name)
{
wmName = name;
}
/**
* @brief Dock::setSynConfig TODO
* @param ba
*/
void Dock::setSynConfig(QByteArray ba)
{
}
/**
* @brief Dock::getSyncConfig TODO
* @return
*/
QByteArray Dock::getSyncConfig()
{
return QByteArray();
}
/**
* @brief Dock::createPlasmaWindow wayland下窗口
* @param objPath
* @return
*/
PlasmaWindow *Dock::createPlasmaWindow(QString objPath)
{
return dbusHandler->createPlasmaWindow(objPath);
}
/**
* @brief Dock::listenKWindowSignals
* @param windowInfo
*/
void Dock::listenKWindowSignals(WindowInfoK *windowInfo)
{
dbusHandler->listenKWindowSignals(windowInfo);
}
/**
* @brief Dock::removePlasmaWindowHandler connect
* @param window
*/
void Dock::removePlasmaWindowHandler(PlasmaWindow *window)
{
dbusHandler->removePlasmaWindowHandler(window);
}
/**
* @brief Dock::presentWindows
* @param windows id
*/
void Dock::presentWindows(QList<uint> windows)
{
dbusHandler->presentWindows(windows);
}
/**
* @brief Dock::getDockHideMode //
* @return
*/
HideMode Dock::getDockHideMode()
{
return SETTING->getHideMode();
}
/**
* @brief Dock::getActiveWindow
* @return
*/
WindowInfoBase *Dock::getActiveWindow()
{
WindowInfoBase *ret = nullptr;
@ -317,12 +380,19 @@ WindowInfoBase *Dock::getActiveWindow()
return ret;
}
/**
* @brief Dock::getClientList client列表
* @return
*/
QList<XWindow> Dock::getClientList()
{
return QList<XWindow>(clientList);
}
// 关闭窗口
/**
* @brief Dock::closeWindow
* @param windowId id
*/
void Dock::closeWindow(uint32_t windowId)
{
qInfo() << "Close Window " << windowId;
@ -335,13 +405,22 @@ void Dock::closeWindow(uint32_t windowId)
}
}
// 获取所有应用Id for debug
/**
* @brief Dock::getEntryIDs Id
* @return
*/
QStringList Dock::getEntryIDs()
{
return entries->getEntryIDs();
}
// 设置任务栏Rect
/**
* @brief Dock::setFrontendWindowRect Rect
* @param x
* @param y
* @param width
* @param height
*/
void Dock::setFrontendWindowRect(int32_t x, int32_t y, uint width, uint height)
{
if (frontendWindowRect == QRect(x, y, width, height)) {
@ -358,14 +437,23 @@ void Dock::setFrontendWindowRect(int32_t x, int32_t y, uint width, uint height)
Q_EMIT frontendWindowRectChanged();
}
// 应用是否驻留
/**
* @brief Dock::isDocked
* @param desktopFile
* @return
*/
bool Dock::isDocked(const QString desktopFile)
{
auto entry = getDockedEntryByDesktopFile(desktopFile);
return !!entry;
}
// 驻留应用
/**
* @brief Dock::requestDock
* @param desktopFile desktopFile全路径
* @param index
* @return
*/
bool Dock::requestDock(QString desktopFile, int index)
{
qInfo() << "RequestDock: " << desktopFile;
@ -394,6 +482,11 @@ bool Dock::requestDock(QString desktopFile, int index)
return true;
}
/**
* @brief Dock::requestUndock
* @param desktopFile desktopFile文件全路径
* @return
*/
bool Dock::requestUndock(QString desktopFile)
{
auto entry = getDockedEntryByDesktopFile(desktopFile);
@ -404,26 +497,41 @@ bool Dock::requestUndock(QString desktopFile)
return true;
}
// 移动驻留程序顺序
/**
* @brief Dock::moveEntry
* @param oldIndex
* @param newIndex
*/
void Dock::moveEntry(int oldIndex, int newIndex)
{
entries->move(oldIndex, newIndex);
saveDockedApps();
}
// 是否在任务栏
/**
* @brief Dock::isOnDock
* @param desktopFile desktopFile文件全路径
* @return
*/
bool Dock::isOnDock(QString desktopFile)
{
return !!getDockedEntryByDesktopFile(desktopFile);
return !!entries->getByDesktopFilePath(desktopFile);
}
// 查询窗口识别方式
/**
* @brief Dock::queryWindowIdentifyMethod
* @param windowId id
* @return
*/
QString Dock::queryWindowIdentifyMethod(XWindow windowId)
{
return entries->queryWindowIdentifyMethod(windowId);
}
// 获取驻留应用desktop文件
/**
* @brief Dock::getDockedAppsDesktopFiles desktop文件
* @return
*/
QStringList Dock::getDockedAppsDesktopFiles()
{
QStringList ret;
@ -434,31 +542,46 @@ QStringList Dock::getDockedAppsDesktopFiles()
return ret;
}
// 获取任务栏插件配置
/**
* @brief Dock::getPluginSettings
* @return
*/
QString Dock::getPluginSettings()
{
return SETTING->getPluginSettings();
}
// 设置任务栏插件配置
/**
* @brief Dock::setPluginSettings
* @param jsonStr
*/
void Dock::setPluginSettings(QString jsonStr)
{
SETTING->setPluginSettings(jsonStr);
}
// 合并任务栏插件配置
/**
* @brief Dock::mergePluginSettings
* @param jsonStr
*/
void Dock::mergePluginSettings(QString jsonStr)
{
SETTING->mergePluginSettings(jsonStr);
}
// 移除任务栏插件配置
/**
* @brief Dock::removePluginSettings
* @param pluginName
* @param settingkeys
*/
void Dock::removePluginSettings(QString pluginName, QStringList settingkeys)
{
SETTING->removePluginSettings(pluginName, settingkeys);
}
// 智能隐藏
/**
* @brief Dock::smartHideModeTimerExpired
*/
void Dock::smartHideModeTimerExpired()
{
HideState state = shouldHideOnSmartHideMode() ? HideState::Hide : HideState::Show;
@ -466,31 +589,40 @@ void Dock::smartHideModeTimerExpired()
setPropHideMode(state);
}
/**
* @brief Dock::initSettings
*/
void Dock::initSettings()
{
SETTING->init();
forceQuitAppStatus = SETTING->getForceQuitAppMode();
connect(SETTING, &DockSettings::hideModeChanged, this, [&](HideMode mode) {
this->updateHideState(false);
});
connect(SETTING, &DockSettings::displayModeChanged, this, [](DisplayMode mode) {
qInfo() << "display mode change to " << static_cast<int>(mode);
});
connect(SETTING, &DockSettings::positionModeChanged, this, [](PositonMode mode) {
connect(SETTING, &DockSettings::positionModeChanged, this, [](PositionMode mode) {
qInfo() << "position mode change to " << static_cast<int>(mode);
});
connect(SETTING, &DockSettings::forceQuitAppChanged, this, [&](bool mode) {
qInfo() << "forceQuitApp change to " << mode;
connect(SETTING, &DockSettings::forceQuitAppChanged, this, [&](ForceQuitAppMode mode) {
qInfo() << "forceQuitApp change to " << int(mode);
forceQuitAppStatus = mode;
entries->updateEntriesMenu();
});
}
// 更新所有应用菜单
/**
* @brief Dock::updateMenu TODO
*/
void Dock::updateMenu()
{
}
// 初始化应用
/**
* @brief Dock::initEntries
*/
void Dock::initEntries()
{
initDockedApps();
@ -498,6 +630,9 @@ void Dock::initEntries()
initClientList();
}
/**
* @brief Dock::initDockedApps
*/
void Dock::initDockedApps()
{
// 初始化驻留应用信息
@ -526,7 +661,9 @@ void Dock::initDockedApps()
saveDockedApps();
}
#include "processinfo.h"
/**
* @brief Dock::initClientList
*/
void Dock::initClientList()
{
QList<XWindow> clients;
@ -542,40 +679,103 @@ void Dock::initClientList()
}
}
/**
* @brief Dock::findWindowByXidX id获取窗口信息
* @param xid
* @return
*/
WindowInfoX *Dock::findWindowByXidX(XWindow xid)
{
return x11Manager->findWindowByXid(xid);
}
/**
* @brief Dock::findWindowByXidK xid获取窗口 TODO wayland和x11下窗口尽量完全剥离 xid查询wayland窗口的情况
* @param xid
* @return
*/
WindowInfoK *Dock::findWindowByXidK(XWindow xid)
{
return waylandManager->findWindowByXid(xid);
}
/**
* @brief Dock::isWindowDockOverlapX X环境下窗口和任务栏是否重叠 TODO
* @param xid
* @return
*/
bool Dock::isWindowDockOverlapX(XWindow xid)
{
return false;
}
// 判断窗口和任务栏是否重叠
/**
* @brief Dock::isWindowDockOverlapK Wayland环境下窗口和任务栏是否重叠
* @param info
* @return
*/
bool Dock::isWindowDockOverlapK(WindowInfoBase *info)
{
if (!info) {
qInfo() << "isWindowDockOverlapK: info is nullptr";
WindowInfoK *infoK = static_cast<WindowInfoK *>(info);
if (!infoK) {
qInfo() << "isWindowDockOverlapK: infoK is nullptr";
return false;
}
//TODO check
Rect rect = infoK->getGeometry();
bool isActiveWin = infoK->getPlasmaWindow()->IsActive();
QString appId = infoK->getAppId();
if (!isActiveWin) {
qInfo() << "isWindowDockOverlapK: check window " << appId << " is not active";
return false;
}
return false;
QStringList appList = {"dde-desktop", "dde-lock", "dde-shutdown"};
if (appList.contains(appId)) {
qInfo() << "isWindowDockOverlapK: appId in white list";
return false;
}
return hasInterSectionK(rect, frontendWindowRect);
}
/**
* @brief Dock::hasInterSectionK Wayland环境下判断活动窗口和任务栏区域是否重叠
* @param windowRect rect
* @param dockRect rect
* @return
*/
bool Dock::hasInterSectionK(const Rect &windowRect, QRect dockRect)
{
int position = getPosition();
int ltX = MAX(windowRect.X, dockRect.x());
int ltY = MAX(windowRect.Y, dockRect.y());
int rbX = MIN(windowRect.X + windowRect.Width, dockRect.x() + dockRect.width());
int rbY = MIN(windowRect.Y + windowRect.Height, dockRect.y() + dockRect.height());
if (position == int(PositionMode::Left) || position == int(PositionMode::Right)) {
return ltX <= rbX && ltY < rbY;
} else if (position == int(PositionMode::TOP) || position == int(PositionMode::Bottom)) {
return ltX < rbX && ltY <= rbY;
} else {
return ltX < rbX && ltY < rbY;
}
}
/**
* @brief Dock::getDockedEntryByDesktopFile
* @param desktopFile desktopFile文件全路径
* @return
*/
Entry *Dock::getDockedEntryByDesktopFile(const QString &desktopFile)
{
return entries->getDockedEntryByDesktopFile(desktopFile);
}
/**
* @brief Dock::shouldHideOnSmartHideMode
* @return
*/
bool Dock::shouldHideOnSmartHideMode()
{
if (!activeWindow || ddeLauncherVisible)
@ -602,6 +802,11 @@ bool Dock::shouldHideOnSmartHideMode()
}
}
/**
* @brief Dock::getActiveWinGroup
* @param xid
* @return
*/
QVector<XWindow> Dock::getActiveWinGroup(XWindow xid)
{
QVector<XWindow> ret;
@ -665,7 +870,10 @@ QVector<XWindow> Dock::getActiveWinGroup(XWindow xid)
return ret;
}
// 更新任务栏隐藏状态
/**
* @brief Dock::updateHideState
* @param delay
*/
void Dock::updateHideState(bool delay)
{
if (ddeLauncherVisible) {
@ -691,6 +899,10 @@ void Dock::updateHideState(bool delay)
}
}
/**
* @brief Dock::setPropHideMode
* @param state
*/
void Dock::setPropHideMode(HideState state)
{
if (state == HideState::Unknown) {
@ -704,6 +916,10 @@ void Dock::setPropHideMode(HideState state)
}
}
/**
* @brief Dock::attachOrDetachWindow
* @param info
*/
void Dock::attachOrDetachWindow(WindowInfoBase *info)
{
if (!info)
@ -742,9 +958,13 @@ void Dock::attachOrDetachWindow(WindowInfoBase *info)
}
}
/**
* @brief Dock::attachWindow
* @param info
*/
void Dock::attachWindow(WindowInfoBase *info)
{
Entry *entry = entries->getByInnerId(info->getEntryInnerId());
Entry *entry = entries->getByInnerId(info->getEntryInnerId()); // entries中存在innerid为空的entry 导致后续新应用通过innerid获取应用一直能获取到
if (entry) {
// entry existed
entry->attachWindow(info);
@ -757,6 +977,10 @@ void Dock::attachWindow(WindowInfoBase *info)
}
}
/**
* @brief Dock::detachWindow
* @param info
*/
void Dock::detachWindow(WindowInfoBase *info)
{
auto entry = entries->getByWindowId(info->getXid());
@ -768,21 +992,31 @@ void Dock::detachWindow(WindowInfoBase *info)
removeAppEntry(entry);
}
void Dock::markAppLaunched(const QString &filePath)
{
dbusHandler->markAppLaunched(filePath);
}
/**
* @brief Dock::launchApp
* @param timestamp
* @param files
*/
void Dock::launchApp(uint32_t timestamp, QStringList files)
{
dbusHandler->launchApp(timestamp, files);
}
/**
* @brief Dock::launchAppAction
* @param timestamp
* @param file
* @param section
*/
void Dock::launchAppAction(uint32_t timestamp, QString file, QString section)
{
dbusHandler->launchAppAction(timestamp, file, section);
}
/**
* @brief Dock::is3DWM 2D/3D
* @return
*/
bool Dock::is3DWM()
{
bool ret = false;
@ -795,16 +1029,29 @@ bool Dock::is3DWM()
return ret;
}
/**
* @brief Dock::isWaylandEnv
* @return
*/
bool Dock::isWaylandEnv()
{
return isWayland;
}
/**
* @brief Dock::handleActiveWindowChangedK wayland环境
* @param activeWin
* @return
*/
WindowInfoK *Dock::handleActiveWindowChangedK(uint activeWin)
{
return waylandManager->handleActiveWindowChangedK(activeWin);
}
/**
* @brief Dock::handleActiveWindowChanged X11环境
* @param info
*/
void Dock::handleActiveWindowChanged(WindowInfoBase *info)
{
qInfo() << "handleActiveWindowChanged";
@ -820,9 +1067,11 @@ void Dock::handleActiveWindowChanged(WindowInfoBase *info)
updateHideState(true);
}
/**
* @brief Dock::saveDockedApps
*/
void Dock::saveDockedApps()
{
// 保存驻留应用信息
QList<QString> dockedApps;
for (auto entry : entries->filterDockedEntries()) {
QString path = entry->getApp()->getFileName();
@ -838,6 +1087,10 @@ void Dock::saveDockedApps()
SETTING->setDockedApps(dockedApps);
}
/** 移除应用实例
* @brief Dock::removeAppEntry
* @param entry
*/
void Dock::removeAppEntry(Entry *entry)
{
if (entry) {
@ -845,6 +1098,9 @@ void Dock::removeAppEntry(Entry *entry)
}
}
/**
* @brief Dock::handleWindowGeometryChanged
*/
void Dock::handleWindowGeometryChanged()
{
if (SETTING->getHideMode() == HideMode::SmartHide)
@ -853,31 +1109,59 @@ void Dock::handleWindowGeometryChanged()
updateHideState(false);
}
/**
* @brief Dock::getEntryByWindowId id获取应用实例
* @param windowId
* @return
*/
Entry *Dock::getEntryByWindowId(XWindow windowId)
{
return entries->getByWindowId(windowId);
}
/**
* @brief Dock::getDesktopFromWindowByBamf bamf软件服务获取指定窗口的desktop文件
* @param windowId
* @return
*/
QString Dock::getDesktopFromWindowByBamf(XWindow windowId)
{
return dbusHandler->getDesktopFromWindowByBamf(windowId);
}
/**
* @brief Dock::registerWindowWayland wayland窗口
* @param objPath
*/
void Dock::registerWindowWayland(const QString &objPath)
{
return waylandManager->registerWindow(objPath);
}
/**
* @brief Dock::unRegisterWindowWayland wayland窗口
* @param objPath
*/
void Dock::unRegisterWindowWayland(const QString &objPath)
{
return waylandManager->unRegisterWindow(objPath);
}
/**
* @brief Dock::identifyWindow
* @param winInfo
* @param innerId
* @return
*/
AppInfo *Dock::identifyWindow(WindowInfoBase *winInfo, QString &innerId)
{
return windowIdentify->identifyWindow(winInfo, innerId);
}
/**
* @brief Dock::markAppLaunched
* @param appInfo
*/
void Dock::markAppLaunched(AppInfo *appInfo)
{
if (!appInfo || !appInfo->isValidApp())
@ -888,21 +1172,37 @@ void Dock::markAppLaunched(AppInfo *appInfo)
dbusHandler->markAppLaunched(desktopFile);
}
/**
* @brief Dock::deleteWindow TODO
* @param xid
*/
void Dock::deleteWindow(XWindow xid)
{
entries->deleteWindow(xid);
}
/**
* @brief Dock::getForceQuitAppStatus
* @return
*/
ForceQuitAppMode Dock::getForceQuitAppStatus()
{
return forceQuitAppStatus;
}
/**
* @brief Dock::getWinIconPreferredApps
* @return
*/
QVector<QString> Dock::getWinIconPreferredApps()
{
return SETTING->getWinIconPreferredApps();
}
/**
* @brief Dock::handleLauncherItemDeleted launcher item被删除信号
* @param itemPath
*/
void Dock::handleLauncherItemDeleted(QString itemPath)
{
for (auto entry : entries->filterDockedEntries()) {
@ -913,7 +1213,10 @@ void Dock::handleLauncherItemDeleted(QString itemPath)
}
}
// 在收到 launcher item 更新的信号后,需要更新相关信息,包括 appInfo、innerId、名称、图标、菜单。
/**
* @brief Dock::handleLauncherItemUpdated launcher item appInfoinnerId
* @param itemPath
*/
void Dock::handleLauncherItemUpdated(QString itemPath)
{
Entry * entry = entries->getByDesktopFilePath(itemPath);
@ -928,31 +1231,55 @@ void Dock::handleLauncherItemUpdated(QString itemPath)
entry->forceUpdateIcon(); // 可能存在Icon图片改变,但Icon名称未改变的情况,因此强制发Icon的属性改变信号
}
/**
* @brief Dock::getOpacity
* @return
*/
double Dock::getOpacity()
{
return SETTING->getOpacity();
}
/**
* @brief Dock::getFrontendWindowRect rect
* @return
*/
QRect Dock::getFrontendWindowRect()
{
return frontendWindowRect;
}
/**
* @brief Dock::getDisplayMode
* @return
*/
int Dock::getDisplayMode()
{
return int(SETTING->getDisplayMode());
}
/**
* @brief Dock::setDisplayMode
* @param mode
*/
void Dock::setDisplayMode(int mode)
{
SETTING->setDisplayMode(DisplayMode(mode));
}
/**
* @brief Dock::getDockedApps
* @return
*/
QStringList Dock::getDockedApps()
{
return SETTING->getDockedApps();
}
/**
* @brief Dock::getEntryPaths
* @return
*/
QStringList Dock::getEntryPaths()
{
QStringList ret;
@ -963,81 +1290,145 @@ QStringList Dock::getEntryPaths()
return ret;
}
/**
* @brief Dock::getHideMode
* @return
*/
HideMode Dock::getHideMode()
{
return SETTING->getHideMode();
}
/**
* @brief Dock::setHideMode
* @param mode
*/
void Dock::setHideMode(HideMode mode)
{
SETTING->setHideMode(mode);
}
/**
* @brief Dock::getHideState
* @return
*/
Dock::HideState Dock::getHideState()
{
return hideState;
}
/**
* @brief Dock::setHideState
* @param state
*/
void Dock::setHideState(Dock::HideState state)
{
hideState = state;
}
/**
* @brief Dock::getHideTimeout
* @return
*/
uint Dock::getHideTimeout()
{
return SETTING->getHideTimeout();
}
/**
* @brief Dock::setHideTimeout
* @param timeout
*/
void Dock::setHideTimeout(uint timeout)
{
SETTING->setHideTimeout(timeout);
}
/**
* @brief Dock::getIconSize
* @return
*/
uint Dock::getIconSize()
{
return SETTING->getIconSize();
}
/**
* @brief Dock::setIconSize
* @param size
*/
void Dock::setIconSize(uint size)
{
SETTING->setIconSize(size);
}
/**
* @brief Dock::getPosition
* @return
*/
int Dock::getPosition()
{
return int(SETTING->getPositionMode());
}
/**
* @brief Dock::setPosition
* @param position
*/
void Dock::setPosition(int position)
{
SETTING->setPositionMode(PositonMode(position));
SETTING->setPositionMode(PositionMode(position));
}
/**
* @brief Dock::getShowTimeout
* @return
*/
uint Dock::getShowTimeout()
{
return SETTING->getShowTimeout();
}
/**
* @brief Dock::setShowTimeout
* @param timeout
*/
void Dock::setShowTimeout(uint timeout)
{
return SETTING->setShowTimeout(timeout);
}
/**
* @brief Dock::getWindowSizeEfficient
* @return
*/
uint Dock::getWindowSizeEfficient()
{
return SETTING->getWindowSizeEfficient();
}
/**
* @brief Dock::setWindowSizeEfficient
* @param size
*/
void Dock::setWindowSizeEfficient(uint size)
{
SETTING->setWindowSizeEfficient(size);
}
/**
* @brief Dock::getWindowSizeFashion
* @return
*/
uint Dock::getWindowSizeFashion()
{
return SETTING->getWindowSizeFashion();
}
/**
* @brief Dock::setWindowSizeFashion
* @param size
*/
void Dock::setWindowSizeFashion(uint size)
{
SETTING->setWindowSizeFashion(size);

View File

@ -65,7 +65,6 @@ public:
void attachOrDetachWindow(WindowInfoBase *info);
void attachWindow(WindowInfoBase *info);
void detachWindow(WindowInfoBase *info);
void markAppLaunched(const QString &filePath);
void launchApp(uint32_t timestamp, QStringList files);
void launchAppAction(uint32_t timestamp, QString file, QString section);
bool is3DWM();
@ -164,6 +163,7 @@ private:
WindowInfoK *findWindowByXidK(XWindow xid);
bool isWindowDockOverlapX(XWindow xid);
bool isWindowDockOverlapK(WindowInfoBase *info);
bool hasInterSectionK(const Rect &windowRect, QRect dockRect);
Entry *getDockedEntryByDesktopFile(const QString &desktopFile);
bool shouldHideOnSmartHideMode();
QVector<XWindow> getActiveWinGroup(XWindow xid);

View File

@ -48,9 +48,10 @@ void DockSettings::init()
} else if(key == keyDisplayMode) {
Q_EMIT displayModeChanged(DisplayMode(dockSettings->value(key).toInt()));
} else if (key == keyPosition) {
Q_EMIT positionModeChanged(PositonMode(dockSettings->value(key).toInt()));
Q_EMIT positionModeChanged(PositionMode(dockSettings->value(key).toInt()));
} else if (key == keyForceQuitApp){
Q_EMIT forceQuitAppChanged(dockSettings->value(key).toBool());
QString mode = dockSettings->value(key).toString();
Q_EMIT forceQuitAppChanged(ForceQuitAppModeHandler(mode).toEnum());
}
});
}
@ -92,21 +93,21 @@ void DockSettings::setDisplayMode(DisplayMode mode)
}
}
PositonMode DockSettings::getPositionMode()
PositionMode DockSettings::getPositionMode()
{
PositonMode ret = PositonMode::Unknown;
PositionMode ret = PositionMode::Unknown;
if (dockSettings) {
QString mode = dockSettings->value(keyPosition).toString();
PositonModeHandler handler(mode);
PositionModeHandler handler(mode);
ret = handler.toEnum();
}
return ret;
}
void DockSettings::setPositionMode(PositonMode mode)
void DockSettings::setPositionMode(PositionMode mode)
{
if (dockSettings) {
dockSettings->setValue(keyPosition, PositonModeHandler(mode).toString());
dockSettings->setValue(keyPosition, PositionModeHandler(mode).toString());
}
}

View File

@ -114,7 +114,7 @@ public:
};
// 显示位置
enum class PositonMode {
enum class PositionMode {
TOP,
Right,
Bottom,
@ -122,45 +122,45 @@ enum class PositonMode {
Unknown,
};
class PositonModeHandler {
PositonMode modeEnum;
class PositionModeHandler {
PositionMode modeEnum;
QString modeStr;
public:
PositonModeHandler(PositonMode mode) : modeEnum(mode), modeStr("") {}
PositonModeHandler(QString mode) : modeEnum(PositonMode::Unknown), modeStr(mode) {}
PositionModeHandler(PositionMode mode) : modeEnum(mode), modeStr("") {}
PositionModeHandler(QString mode) : modeEnum(PositionMode::Unknown), modeStr(mode) {}
bool equal(PositonModeHandler displayMode) {
bool equal(PositionModeHandler displayMode) {
return toString() == displayMode.toString() || toEnum() == displayMode.toEnum();
}
QString toString() {
switch (modeEnum) {
case PositonMode::TOP:
case PositionMode::TOP:
return "top";
case PositonMode::Right:
case PositionMode::Right:
return "right";
case PositonMode::Bottom:
case PositionMode::Bottom:
return "bottom";
case PositonMode::Left:
case PositionMode::Left:
return "left";
case PositonMode::Unknown:
case PositionMode::Unknown:
default:
return "unknown";
}
}
PositonMode toEnum() {
PositionMode toEnum() {
if (modeStr == "top")
return PositonMode::TOP;
return PositionMode::TOP;
else if (modeStr == "right")
return PositonMode::Right;
return PositionMode::Right;
else if (modeStr == "bottom")
return PositonMode::Bottom;
return PositionMode::Bottom;
else if (modeStr == "left")
return PositonMode::Left;
return PositionMode::Left;
else
return PositonMode::Unknown;
return PositionMode::Unknown;
}
};
@ -228,8 +228,8 @@ public:
void setHideMode(HideMode mode);
DisplayMode getDisplayMode();
void setDisplayMode(DisplayMode mode);
PositonMode getPositionMode();
void setPositionMode(PositonMode mode);
PositionMode getPositionMode();
void setPositionMode(PositionMode mode);
ForceQuitAppMode getForceQuitAppMode();
void setForceQuitAppMode(ForceQuitAppMode mode);
uint getIconSize();
@ -261,9 +261,9 @@ Q_SIGNALS:
// 显示样式改变
void displayModeChanged(DisplayMode mode);
// 显示位置改变
void positionModeChanged(PositonMode mode);
void positionModeChanged(PositionMode mode);
// 强制退出应用开关改变
void forceQuitAppChanged(bool forced);
void forceQuitAppChanged(ForceQuitAppMode mode);
private:

View File

@ -21,7 +21,9 @@
#include "processinfo.h"
#include "dstring.h"
#include "dfile.h"
#include <QFileInfo>
#include <QDir>
ProcessInfo::ProcessInfo(int pid)
: hasPid(true)
@ -43,10 +45,14 @@ ProcessInfo::ProcessInfo(int pid)
}
// args
auto verifyExe = [](std::string exe, std::string cwd, std::string firstArg){
if (DFile::base(firstArg) == firstArg)
if (firstArg.size() == 0)
return false;
QFileInfo info(firstArg.c_str());
if (info.baseName() == firstArg.c_str())
return true;
if (!DFile::isAbs(firstArg))
if (!QDir::isAbsolutePath(firstArg.c_str()))
firstArg = cwd + firstArg;
return exe == firstArg;

View File

@ -34,7 +34,10 @@ WaylandManager::WaylandManager(Dock *_dock, QObject *parent)
}
// 注册窗口
/**
* @brief WaylandManager::registerWindow
* @param objPath
*/
void WaylandManager::registerWindow(const QString &objPath)
{
qInfo() << "registerWindow: " << objPath;

View File

@ -176,6 +176,15 @@ void WindowInfoK::updateProcessInfo()
processInfo = new ProcessInfo(pid);
}
/**
* @brief WindowInfoK::getGeometry
* @return
*/
Rect WindowInfoK::getGeometry()
{
return geometry;
}
int64_t WindowInfoK::getCreatedTime()
{
return createdTime;

View File

@ -64,6 +64,7 @@ public:
void updateInternalId();
void updateCloseable();
void updateProcessInfo();
Rect getGeometry();
private:
bool updateCalled;

View File

@ -8,6 +8,10 @@ DBusAdaptorLauncher::DBusAdaptorLauncher(QObject *parent)
Launcher *launcher = static_cast<Launcher *>(QObject::parent());
if (launcher) {
connect(launcher, &Launcher::itemChanged, this, &DBusAdaptorLauncher::ItemChanged);
connect(launcher, &Launcher::newAppLaunched, this, &DBusAdaptorLauncher::NewAppLaunched);
connect(launcher, &Launcher::uninstallFailed, this, &DBusAdaptorLauncher::UninstallFailed);
connect(launcher, &Launcher::uninstallSuccess, this, &DBusAdaptorLauncher::UninstallSuccess);
connect(launcher, &Launcher::displayModeChanged, this, &DBusAdaptorLauncher::DisplayModeChanged);
connect(launcher, &Launcher::fullScreenChanged, this, &DBusAdaptorLauncher::FullScreenChanged);
}
@ -40,21 +44,19 @@ bool DBusAdaptorLauncher::fullscreen() const
void DBusAdaptorLauncher::setFullscreen(bool value)
{
parent()->setFullScreen(value);
parent()->setFullscreen(value);
}
bool DBusAdaptorLauncher::AddAutostart(const QString &desktopFile)
{
QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager");
QDBusInterface interface = QDBusInterface("com.deepin.SessionManager", "/com/deepin/StartManager", "com.deepin.StartManager");
QDBusReply<bool> reply = interface.call("AddAutostart", desktopFile);
return reply.isValid() ? reply.value() : false;
}
// TODO
QString DBusAdaptorLauncher::GetAllItemInfos()
LauncherItemInfoList DBusAdaptorLauncher::GetAllItemInfos()
{
// return parent()->getAllItemInfos();
return "";
return parent()->getAllItemInfos();
}
QStringList DBusAdaptorLauncher::GetAllNewInstalledApps()
@ -67,11 +69,9 @@ bool DBusAdaptorLauncher::GetDisableScaling(const QString &id)
return parent()->getDisableScaling(id);
}
// TODO
QString DBusAdaptorLauncher::GetItemInfo(const QString &id)
LauncherItemInfo DBusAdaptorLauncher::GetItemInfo(const QString &id)
{
//return parent()->getItemInfo();
return "";
return parent()->getItemInfo(id);
}
bool DBusAdaptorLauncher::GetUseProxy(const QString &id)
@ -85,16 +85,16 @@ bool DBusAdaptorLauncher::IsItemOnDesktop(const QString &id)
}
bool DBusAdaptorLauncher::LaunchWithTimestamp(const QString &desktopFile, int time)
{
{
QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager");
QDBusInterface interface = QDBusInterface("com.deepin.SessionManager", "/com/deepin/StartManager", "com.deepin.StartManager");
QDBusReply<bool> reply = interface.call("LaunchWithTimestamp", desktopFile, time);
return reply.isValid() ? reply.value() : false;
}
bool DBusAdaptorLauncher::RemoveAutostart(const QString &desktopFile)
{
QDBusInterface interface = QDBusInterface("com.deepin.daemon.Display", "/com/deepin/StartManager", "com.deepin.StartManager");
QDBusInterface interface = QDBusInterface("com.deepin.SessionManager", "/com/deepin/StartManager", "com.deepin.StartManager");
QDBusReply<bool> reply = interface.call("RemoveAutostart", desktopFile);
return reply.isValid() ? reply.value() : false;
}

View File

@ -2,6 +2,7 @@
#define DBUSADAPTORLAUNCHER_H
#include "launcher.h"
#include "launcheriteminfolist.h"
#include <QtCore/QObject>
#include <QtCore/QMetaObject>
@ -22,80 +23,83 @@ class DBusAdaptorLauncher: public QDBusAbstractAdaptor
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.deepin.dde.daemon.Launcher1")
Q_CLASSINFO("D-Bus Introspection", ""
" <interface name=\"org.deepin.dde.daemon.Launcher1\">\n"
" <method name=\"GetAllItemInfos\">\n"
" <arg direction=\"out\" type=\"s\" name=\"itemInfoList\"/>\n"
" </method>\n"
" <method name=\"GetAllNewInstalledApps\">\n"
" <arg direction=\"out\" type=\"as\" name=\"apps\"/>\n"
" </method>\n"
" <method name=\"GetDisableScaling\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"GetItemInfo\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"s\" name=\"itemInfo\"/>\n"
" </method>\n"
" <method name=\"GetUseProxy\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"IsItemOnDesktop\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"result\"/>\n"
" </method>\n"
" <method name=\"RequestRemoveFromDesktop\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"RequestSendToDesktop\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"RequestUninstall\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" </method>\n"
" <method name=\"SetDisableScaling\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"in\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"SetUseProxy\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"in\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"LaunchWithTimestamp\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"time\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"RemoveAutostart\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"AddAutostart\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <signal name=\"ItemChanged\">\n"
" <arg type=\"s\" name=\"status\"/>\n"
" <arg type=\"s\" name=\"itemInfo\"/>\n"
" <arg type=\"x\" name=\"categoryID\"/>\n"
" </signal>\n"
" <signal name=\"NewAppLaunched\">\n"
" <arg type=\"s\" name=\"appID\"/>\n"
" </signal>\n"
" <signal name=\"UninstallSuccess\">\n"
" <arg type=\"s\" name=\"appID\"/>\n"
" </signal>\n"
" <signal name=\"UninstallFailed\">\n"
" <arg type=\"s\" name=\"appId\"/>\n"
" <arg type=\"s\" name=\"errMsg\"/>\n"
" </signal>\n"
" <property access=\"readwrite\" type=\"b\" name=\"Fullscreen\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"DisplayMode\"/>\n"
" </interface>\n"
"")
" <interface name=\"org.deepin.dde.daemon.Launcher1\">\n"
" <method name=\"GetAllItemInfos\">\n"
" <arg direction=\"out\" type=\"a(ssssxxas)\" name=\"itemInfoList\"/>\n"
" <annotation value=\"LauncherItemInfoList\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
" </method>\n"
" <method name=\"GetAllNewInstalledApps\">\n"
" <arg direction=\"out\" type=\"as\" name=\"apps\"/>\n"
" </method>\n"
" <method name=\"GetDisableScaling\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"GetItemInfo\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"(ssssxxas)\" name=\"itemInfo\"/>\n"
" <annotation value=\"LauncherItemInfo\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
" </method>\n"
" <method name=\"GetUseProxy\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"IsItemOnDesktop\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"result\"/>\n"
" </method>\n"
" <method name=\"RequestRemoveFromDesktop\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"RequestSendToDesktop\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"RequestUninstall\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" </method>\n"
" <method name=\"SetDisableScaling\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"in\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"SetUseProxy\">\n"
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
" <arg direction=\"in\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"LaunchWithTimestamp\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"time\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"RemoveAutostart\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"AddAutostart\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <signal name=\"ItemChanged\">\n"
" <arg type=\"s\" name=\"status\"/>\n"
" <arg type=\"(ssssxxas)\" name=\"itemInfo\"/>\n"
" <annotation value=\"LauncherItemInfo\" name=\"org.qtproject.QtDBus.QtTypeName.Out1\"/>\n"
" <arg type=\"x\" name=\"categoryID\"/>\n"
" </signal>\n"
" <signal name=\"NewAppLaunched\">\n"
" <arg type=\"s\" name=\"appID\"/>\n"
" </signal>\n"
" <signal name=\"UninstallSuccess\">\n"
" <arg type=\"s\" name=\"appID\"/>\n"
" </signal>\n"
" <signal name=\"UninstallFailed\">\n"
" <arg type=\"s\" name=\"appId\"/>\n"
" <arg type=\"s\" name=\"errMsg\"/>\n"
" </signal>\n"
" <property access=\"readwrite\" type=\"b\" name=\"Fullscreen\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"DisplayMode\"/>\n"
" </interface>\n"
"")
public:
DBusAdaptorLauncher(QObject *parent);
virtual ~DBusAdaptorLauncher();
@ -113,10 +117,10 @@ public: // PROPERTIES
public Q_SLOTS: // METHODS
bool AddAutostart(const QString &desktopFile);
QString GetAllItemInfos();
LauncherItemInfoList GetAllItemInfos();
QStringList GetAllNewInstalledApps();
bool GetDisableScaling(const QString &id);
QString GetItemInfo(const QString &id);
LauncherItemInfo GetItemInfo(const QString &id);
bool GetUseProxy(const QString &id);
bool IsItemOnDesktop(const QString &id);
bool LaunchWithTimestamp(const QString &desktopFile, int time);
@ -127,7 +131,7 @@ public Q_SLOTS: // METHODS
void SetDisableScaling(const QString &id, bool value);
void SetUseProxy(const QString &id, bool value);
Q_SIGNALS: // SIGNALS
void ItemChanged(const QString &status, const QString &itemInfo, qlonglong categoryID);
void ItemChanged(const QString &status, const LauncherItemInfo &itemInfo, qlonglong categoryID);
void NewAppLaunched(const QString &appID);
void UninstallFailed(const QString &appId, const QString &errMsg);
void UninstallSuccess(const QString &appID);

View File

@ -69,11 +69,12 @@ Launcher::Launcher(QObject *parent)
"Event", "", // TODO 修正事件参数
this, SLOT(handleFSWatcherEvents(QDBusMessage)));
// 监控应用目录
watchDataDirs();
// 关联org.deepin.daemon.LRecorder1接口事件ServiceRestarted
watchDataDirs(); // 监控应用目录
QDBusConnection::sessionBus().connect("org.deepin.daemon.AlRecoder1",
"/org/deepin/daemon/AlRecoder1",
"org.deepin.daemon.AlRecoder1",
QDBusConnection::sessionBus().connect("org.deepin.daemon.AlRecorder1",
"/org/deepin/daemon/AlRecorder1",
"org.deepin.daemon.AlRecorder1",
"ServiceRestarted",
this, SLOT(handleLRecoderRestart(QDBusMessage)));
@ -87,15 +88,15 @@ Launcher::Launcher(QObject *parent)
});
// 关联org.deepin.daemon.LRecorder1接口事件Launched
QDBusConnection::sessionBus().connect("org.deepin.daemon.AlRecoder1",
"/org/deepin/daemon/AlRecoder1",
"org.deepin.daemon.AlRecoder1",
QDBusConnection::sessionBus().connect("org.deepin.daemon.AlRecorder1",
"/org/deepin/daemon/AlRecorder1",
"org.deepin.daemon.AlRecorder1",
"Launched", "sa",
this, SLOT([&](QDBusMessage msg) {
QString path = msg.arguments().at(0).toString();
Item item = getItemByPath(path);
if (item.isValid())
Q_EMIT NewAppLaunched(item.id);
Q_EMIT newAppLaunched(item.id);
}));
}
@ -145,27 +146,33 @@ void Launcher::setDisplayMode(int value)
SETTING->setDisplayMode(value == 1 ? "category" : "free");
}
void Launcher::setFullScreen(bool isFull)
void Launcher::setFullscreen(bool isFull)
{
SETTING->setFullscreenMode(isFull);
}
// 获取所有应用信息
QVector<ItemInfo> Launcher::getAllItemInfos()
/**
* @brief Launcher::getAllItemInfos
* @return
*/
LauncherItemInfoList Launcher::getAllItemInfos()
{
QVector<ItemInfo> ret;
LauncherItemInfoList ret;
for (auto item : itemsMap) {
ret.push_back(item.info);
}
return ret;
}
// 获取未打开的应用
/**
* @brief Launcher::getAllNewInstalledApps
* @return
*/
QStringList Launcher::getAllNewInstalledApps()
{
QStringList ret;
QMap<QString, QStringList> newApps;
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecoder1", "/org/deepin/daemon/AlRecoder1", "org.deepin.daemon.AlRecoder1");
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecorder1", "/org/deepin/daemon/AlRecorder1", "org.deepin.daemon.AlRecorder1");
QDBusReply<QMap<QString, QStringList>> reply = interface.call("GetNew");
if (reply.isValid())
newApps = reply;
@ -178,7 +185,11 @@ QVector<ItemInfo> Launcher::getAllItemInfos()
return ret;
}
// 获取应用是否缩放
/**
* @brief Launcher::getDisableScaling
* @param appId
* @return
*/
bool Launcher::getDisableScaling(QString appId)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -191,10 +202,14 @@ bool Launcher::getDisableScaling(QString appId)
return false;
}
// 获取应用信息
ItemInfo Launcher::getItemInfo(QString appId)
/**
* @brief Launcher::getItemInfo
* @param appId
* @return
*/
LauncherItemInfo Launcher::getItemInfo(QString appId)
{
ItemInfo info;
LauncherItemInfo info;
if (itemsMap.find(appId) == itemsMap.end())
return info;
@ -202,7 +217,11 @@ ItemInfo Launcher::getItemInfo(QString appId)
return info;
}
// 获取应用是否代理
/**
* @brief Launcher::getUseProxy
* @param appId
* @return
*/
bool Launcher::getUseProxy(QString appId)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -215,7 +234,11 @@ bool Launcher::getUseProxy(QString appId)
return false;
}
// 桌面是否存在应用desktop文件
/**
* @brief Launcher::isItemOnDesktop desktop文件
* @param appId
* @return
*/
bool Launcher::isItemOnDesktop(QString appId)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -226,7 +249,11 @@ bool Launcher::isItemOnDesktop(QString appId)
return info.exists();
}
// 移除桌面快捷方式
/**
* @brief Launcher::requestRemoveFromDesktop
* @param appId
* @return
*/
bool Launcher::requestRemoveFromDesktop(QString appId)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -241,7 +268,11 @@ bool Launcher::requestRemoveFromDesktop(QString appId)
return file.remove();
}
// 发送应用到桌面
/**
* @brief Launcher::requestSendToDesktop
* @param appId
* @return
*/
bool Launcher::requestSendToDesktop(QString appId)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -268,7 +299,10 @@ bool Launcher::requestSendToDesktop(QString appId)
return true;
}
// 卸载应用
/**
* @brief Launcher::requestUninstall
* @param appId
*/
void Launcher::requestUninstall(QString appId)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -283,7 +317,7 @@ void Launcher::requestUninstall(QString appId)
QString result = QString::fromUtf8(process.readAllStandardOutput());
qInfo() << "RequestUninstall fucntion called by :" << result;
process.close();
if (result == launcherExe) {
if (result != launcherExe) {
qWarning() << result << " has no right to uninstall " << appId;
return;
}
@ -296,13 +330,13 @@ void Launcher::requestUninstall(QString appId)
return;
// 即将卸载appId
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecoder1", "/org/deepin/daemon/AlRecoder1", "org.deepin.daemon.AlRecoder1");
interface.call("UninstallHints", item.info.path);
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecorder1", "/org/deepin/daemon/AlRecorder1", "org.deepin.daemon.AlRecorder1");
interface.call("UninstallHints", QStringList() << item.info.path);
bool ret = doUninstall(info, item); // 阻塞等待
if (!ret) {
QString msg = QString("uninstall %1 result %2").arg(info.getName().c_str()).arg(ret);
Q_EMIT UninstallFailed(appId, msg);
Q_EMIT uninstallFailed(appId, msg);
qInfo() << msg;
return;
}
@ -311,12 +345,16 @@ void Launcher::requestUninstall(QString appId)
QString filePath(QDir::homePath() + "/.config/autostart/" + appId + ".desktop");
QFile file(filePath);
file.remove();
Q_EMIT UninstallSuccess(appId);
Q_EMIT uninstallSuccess(appId);
}, appId);
thread.detach();
}
// 设置应用禁用缩放
/**
* @brief Launcher::setDisableScaling
* @param appId
* @param value
*/
void Launcher::setDisableScaling(QString appId, bool value)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -346,7 +384,11 @@ void Launcher::setDisableScaling(QString appId, bool value)
SETTING->setDisableScalingApps(apps);
}
// 设置用户代理
/**
* @brief Launcher::setUseProxy
* @param appId
* @param value
*/
void Launcher::setUseProxy(QString appId, bool value)
{
if (itemsMap.find(appId) == itemsMap.end())
@ -376,6 +418,10 @@ void Launcher::setUseProxy(QString appId, bool value)
SETTING->setUseProxy(apps);
}
/**
* @brief Launcher::handleFSWatcherEvents
* @param msg
*/
void Launcher::handleFSWatcherEvents(QDBusMessage msg)
{
QList<QVariant> ret = msg.arguments();
@ -398,8 +444,8 @@ void Launcher::handleFSWatcherEvents(QDBusMessage msg)
Item &item = itemsMap[id];
Categorytype ty = queryCategoryId(&item);
if (ty != item.info.categoryId) {
item.info.categoryId = ty;
if (qint64(ty) != item.info.categoryId) {
item.info.categoryId = qint64(ty);
emitItemChanged(&item, appStatusModified);
}
noPkgItemIds.remove(id);
@ -417,6 +463,9 @@ void Launcher:: handleLRecoderRestart(QDBusMessage msg)
watchDataDirs();
}
/**
* @brief Launcher::initSettings
*/
void Launcher::initSettings()
{
connect(SETTING, &LauncherSettings::displayModeChanged, this, [&](QString mode) {
@ -428,7 +477,9 @@ void Launcher::initSettings()
appsHidden = SETTING->getHiddenApps();
}
// 加载应用包信息
/**
* @brief Launcher::loadDesktopPkgMap
*/
void Launcher::loadDesktopPkgMap()
{
QFile file(desktopPkgMapFile);
@ -455,7 +506,9 @@ void Launcher::loadDesktopPkgMap()
}
}
// 加载应用类型信息
/**
* @brief Launcher::loadPkgCategoryMap
*/
void Launcher::loadPkgCategoryMap()
{
QFile file(applicationsFile);
@ -523,7 +576,9 @@ void Launcher::checkDesktopFile(QString filePath)
}
}
// 响应DConfig中隐藏应用配置变化
/**
* @brief Launcher::handleAppHiddenChanged DConfig中隐藏应用配置变化
*/
void Launcher::handleAppHiddenChanged()
{
auto hiddenApps = SETTING->getHiddenApps();
@ -569,7 +624,9 @@ void Launcher::handleAppHiddenChanged()
}
}
// 加载翻译应用信息
/**
* @brief Launcher::loadNameMap
*/
void Launcher::loadNameMap()
{
QFile file(appNameTranslationsFile);
@ -607,7 +664,9 @@ void Launcher::loadNameMap()
}
}
// 初始化应用信息
/**
* @brief Launcher::initItems
*/
void Launcher::initItems()
{
std::vector<DesktopInfo> infos = AppsDir::getAllDesktopInfos();
@ -638,7 +697,7 @@ void Launcher::addItem(Item item)
item.info.name = name;
}
item.info.categoryId = queryCategoryId(&item);
item.info.categoryId = qint64(queryCategoryId(&item));
itemsMap[item.info.id] = item;
}
@ -660,7 +719,11 @@ Categorytype Launcher::queryCategoryId(const Item *item)
return getXCategory(item);
}
// 获取应用类型
/**
* @brief Launcher::getXCategory
* @param item
* @return
*/
Categorytype Launcher::getXCategory(const Item *item)
{
// 统计应用类型
@ -720,7 +783,11 @@ Categorytype Launcher::getXCategory(const Item *item)
return maxCatogories[0];
}
// 使用dpkg -S通过文件路径查包
/**
* @brief Launcher::queryPkgNameWithDpkg 使dpkg -S
* @param itemPath
* @return
*/
QString Launcher::queryPkgNameWithDpkg(const QString &itemPath)
{
QProcess process;
@ -741,7 +808,12 @@ QString Launcher::queryPkgNameWithDpkg(const QString &itemPath)
return "";
}
// 通过id、path查询包名
/**
* @brief Launcher::queryPkgName idpath查询包名
* @param itemID
* @param itemPath
* @return
*/
QString Launcher::queryPkgName(const QString &itemID, const QString &itemPath)
{
if (!itemPath.isEmpty()) {
@ -789,7 +861,11 @@ QString Launcher::queryPkgName(const QString &itemID, const QString &itemPath)
return "";
}
// 根据desktop路径获取Item信息
/**
* @brief Launcher::getItemByPath desktop路径获取Item信息
* @param itemPath
* @return
*/
Item Launcher::getItemByPath(QString itemPath)
{
QString appId = getAppIdByFilePath(itemPath, appDirs);
@ -802,20 +878,22 @@ Item Launcher::getItemByPath(QString itemPath)
return Item();
}
// 监控应用数据目录
/**
* @brief Launcher::watchDataDirs
*/
void Launcher::watchDataDirs()
{
QStringList dataDirs;
dataDirs << QDir::homePath() + ".local/share";
dataDirs << "/usr/local/share" << "/usr/share";
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecoder1", "/org/deepin/daemon/AlRecoder1", "org.deepin.daemon.AlRecoder1");
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecorder1", "/org/deepin/daemon/AlRecorder1", "org.deepin.daemon.AlRecorder1");
interface.call("WatchDirs", dataDirs);
}
void Launcher::emitItemChanged(const Item *item, QString status)
{
ItemInfo info(item->info);
Q_EMIT ItemChanged(status, info, info.categoryId);
LauncherItemInfo info(item->info);
Q_EMIT itemChanged(status, info, info.categoryId);
}
AppType Launcher::getAppType(DesktopInfo &info, const Item &item)
@ -875,6 +953,12 @@ end:
return ty;
}
/**
* @brief Launcher::doUninstall
* @param info
* @param item
* @return
*/
bool Launcher::doUninstall(DesktopInfo &info, const Item &item)
{
bool ret = false;
@ -916,7 +1000,12 @@ bool Launcher::doUninstall(DesktopInfo &info, const Item &item)
return ret;
}
// 卸载flatpak应用
/**
* @brief Launcher::uninstallFlatpak flatpak应用
* @param info
* @param item
* @return
*/
bool Launcher::uninstallFlatpak(DesktopInfo &info, const Item &item)
{
struct FlatpakApp {
@ -971,7 +1060,11 @@ bool Launcher::uninstallFlatpak(DesktopInfo &info, const Item &item)
return true;
}
// 卸载wine应用
/**
* @brief Launcher::uninstallWineApp wine应用
* @param item
* @return
*/
bool Launcher::uninstallWineApp(const Item &item)
{
QProcess process;
@ -983,19 +1076,27 @@ bool Launcher::uninstallWineApp(const Item &item)
return res;
}
// 卸载
/**
* @brief Launcher::uninstallSysApp App
* @param name
* @param pkg
* @return
*/
bool Launcher::uninstallSysApp(const QString &name, const QString &pkg)
{
QDBusInterface lastoreDbus = QDBusInterface("com.deepin.lastore", "/com/deepin/lastore", "com.deepin.lastore.Manager", QDBusConnection::systemBus());
QDBusReply<QString> reply = lastoreDbus.call("RemovePackage", name, pkg); // TODO replay为空?
QString jobPath = reply.isValid() ? reply.value() : "";
if (jobPath.isEmpty())
QDBusReply<QDBusObjectPath> reply = lastoreDbus.call("RemovePackage", name, pkg);
QDBusObjectPath jobPath;
if (reply.isValid())
reply.value();
if (jobPath.path().isEmpty())
return false;
QEventLoop loop;
bool ret = false;
QDBusConnection::sessionBus().connect("com.deepin.lastore",
jobPath,
jobPath.path(),
"com.deepin.lastore.Job",
"Status",
"sa",
@ -1015,7 +1116,11 @@ bool Launcher::uninstallSysApp(const QString &name, const QString &pkg)
return ret;
}
// 移除desktop文件
/**
* @brief Launcher::removeDesktop desktop文件
* @param item
* @return
*/
bool Launcher::removeDesktop(const Item &item)
{
// 移除desktop文件
@ -1029,7 +1134,11 @@ bool Launcher::removeDesktop(const Item &item)
return ret;
}
// 发送卸载结果
/**
* @brief Launcher::notifyUninstallDone
* @param item
* @param result
*/
void Launcher::notifyUninstallDone(const Item &item, bool result)
{
QString msg;
@ -1042,7 +1151,11 @@ void Launcher::notifyUninstallDone(const Item &item, bool result)
interface.call("Notify", "deepin-app-store", 0, "deepin-appstore", msg, "", QVariant(), QVariant(), -1);
}
// deepin custom app
/**
* @brief Launcher::isDeepinCustomDesktopFile Deepin定制应用
* @param fileName
* @return
*/
bool Launcher::isDeepinCustomDesktopFile(QString fileName)
{
QFileInfo fileInfo(fileName);
@ -1074,7 +1187,7 @@ Item Launcher:: NewItemWithDesktopInfo(DesktopInfo &info)
Item item;
item.info.path = appFileName;
item.info.name = appName;
item.info.enName = enName;
//item.info.keywords << enName << appName;
item.info.id = getAppIdByFilePath(item.info.path, appDirs);
item.info.timeInstalled = ctime;
item.exec = info.getCommandLine().c_str();
@ -1083,7 +1196,7 @@ Item Launcher:: NewItemWithDesktopInfo(DesktopInfo &info)
xDeepinCategory = xDeepinCategory.toLower();
for (auto &keyWord : info.getKeywords()) {
item.keywords.push_back(QString(keyWord.c_str()).toLower());
item.desktopKeywords.push_back(QString(keyWord.c_str()).toLower());
}
for (auto &category : info.getCategories()) {

View File

@ -25,6 +25,7 @@
#include "common.h"
#include "synmodule.h"
#include "category.h"
#include "launcheriteminfolist.h"
#include <QObject>
#include <QMap>
@ -53,19 +54,19 @@ struct ItemInfo
{
QString path;
QString name;
QString enName;
QString id;
QString icon;
Categorytype categoryId;
int64_t timeInstalled;
//QStringList keywords; // 存放前端搜索关键字 name enName
};
// 应用信息类
struct Item {
inline bool isValid() {return !info.path.isEmpty();}
ItemInfo info;
QStringList keywords;
LauncherItemInfo info;
QStringList desktopKeywords; //desktop file keywords
QStringList categories;
QString xDeepinCategory;
QString exec;
@ -91,12 +92,12 @@ public:
int getDisplayMode();
bool getFullScreen();
void setDisplayMode(int value);
void setFullScreen(bool isFull);
void setFullscreen(bool isFull);
QVector<ItemInfo> getAllItemInfos();
LauncherItemInfoList getAllItemInfos();
QStringList getAllNewInstalledApps();
bool getDisableScaling(QString appId);
ItemInfo getItemInfo(QString appId);
LauncherItemInfo getItemInfo(QString appId);
bool getUseProxy(QString appId);
bool isItemOnDesktop(QString appId);
bool requestRemoveFromDesktop(QString appId);
@ -106,10 +107,10 @@ public:
void setUseProxy(QString appId, bool value);
Q_SIGNALS:
void ItemChanged(QString status, ItemInfo itemInfo, Categorytype ty);
void NewAppLaunched(QString appId);
void UninstallSuccess(QString appId);
void UninstallFailed(QString appId, QString errMsg);
void itemChanged(QString status, LauncherItemInfo itemInfo, qint64 ty);
void newAppLaunched(QString appId);
void uninstallSuccess(QString appId);
void uninstallFailed(QString appId, QString errMsg);
void displayModeChanged(int mode);
void fullScreenChanged(bool isFull);

View File

@ -31,88 +31,6 @@ DCORE_USE_NAMESPACE
static DConfig *dconfig = Settings::ConfigPtr(configLauncher);
QString LauncherSettings::getDisplayMode()
{
return dconfig ? dconfig->value(keyDisplayMode).toString() : "";
}
void LauncherSettings::setDisplayMode(QString value)
{
if (dconfig) {
dconfig->setValue(keyDisplayMode, value);
}
}
int LauncherSettings::getFullscreenMode()
{
return dconfig ? dconfig->value(keyFullscreen).toBool() : false;
}
void LauncherSettings::setFullscreenMode(int value)
{
if (dconfig) {
dconfig->setValue(keyFullscreen, value);
}
}
QVector<QString> LauncherSettings::getDisableScalingApps()
{
QVector<QString> ret;
if (dconfig) {
QList<QVariant> apps = dconfig->value(keyAppsDisableScaling).toList();
for (auto app : apps) {
ret.push_back(app.toString());
}
}
return ret;
}
void LauncherSettings::setDisableScalingApps(const QVector<QString> &value)
{
if (dconfig) {
QList<QVariant> apps;
for (const auto &app : value)
apps.push_back(app);
dconfig->setValue(keyAppsDisableScaling, apps);
}
}
QVector<QString> LauncherSettings::getUseProxyApps()
{
QVector<QString> ret;
if (dconfig) {
QList<QVariant> apps = dconfig->value(keyAppsUseProxy).toList();
for (auto app : apps) {
ret.push_back(app.toString());
}
}
return ret;
}
void LauncherSettings::setUseProxy(const QVector<QString> &value)
{
if (dconfig) {
QList<QVariant> apps;
for (const auto &app : value)
apps.push_back(app);
dconfig->setValue(keyAppsUseProxy, apps);
}
}
QVector<QString> LauncherSettings::getHiddenApps()
{
QVector<QString> ret;
if (dconfig) {
QList<QVariant> hiddenApps = dconfig->value(keyAppsHidden).toList();
for (auto app : hiddenApps) {
ret.push_back(app.toString());
}
}
return ret;
}
LauncherSettings::LauncherSettings(QObject *parent)
: QObject(parent)
{
@ -127,3 +45,121 @@ LauncherSettings::LauncherSettings(QObject *parent)
}
});
}
/**
* @brief LauncherSettings::getDisplayMode
* @return
*/
QString LauncherSettings::getDisplayMode()
{
return dconfig ? dconfig->value(keyDisplayMode).toString() : "";
}
/**
* @brief LauncherSettings::setDisplayMode
* @param value
*/
void LauncherSettings::setDisplayMode(QString value)
{
if (dconfig) {
dconfig->setValue(keyDisplayMode, value);
}
}
/**
* @brief LauncherSettings::getFullscreenMode
* @return
*/
int LauncherSettings::getFullscreenMode()
{
return dconfig ? dconfig->value(keyFullscreen).toBool() : false;
}
/**
* @brief LauncherSettings::setFullscreenMode
* @param value
*/
void LauncherSettings::setFullscreenMode(int value)
{
if (dconfig) {
dconfig->setValue(keyFullscreen, value);
}
}
/**
* @brief LauncherSettings::getDisableScalingApps
* @return
*/
QVector<QString> LauncherSettings::getDisableScalingApps()
{
QVector<QString> ret;
if (dconfig) {
QList<QVariant> apps = dconfig->value(keyAppsDisableScaling).toList();
for (auto app : apps) {
ret.push_back(app.toString());
}
}
return ret;
}
/**
* @brief LauncherSettings::setDisableScalingApps
* @param value
*/
void LauncherSettings::setDisableScalingApps(const QVector<QString> &value)
{
if (dconfig) {
QList<QVariant> apps;
for (const auto &app : value)
apps.push_back(app);
dconfig->setValue(keyAppsDisableScaling, apps);
}
}
/**
* @brief LauncherSettings::getUseProxyApps
* @return
*/
QVector<QString> LauncherSettings::getUseProxyApps()
{
QVector<QString> ret;
if (dconfig) {
QList<QVariant> apps = dconfig->value(keyAppsUseProxy).toList();
for (auto app : apps) {
ret.push_back(app.toString());
}
}
return ret;
}
/**
* @brief LauncherSettings::setUseProxy
* @param value
*/
void LauncherSettings::setUseProxy(const QVector<QString> &value)
{
if (dconfig) {
QList<QVariant> apps;
for (const auto &app : value)
apps.push_back(app);
dconfig->setValue(keyAppsUseProxy, apps);
}
}
/**
* @brief LauncherSettings::getHiddenApps
* @return
*/
QVector<QString> LauncherSettings::getHiddenApps()
{
QVector<QString> ret;
if (dconfig) {
QList<QVariant> hiddenApps = dconfig->value(keyAppsHidden).toList();
for (auto app : hiddenApps) {
ret.push_back(app.toString());
}
}
return ret;
}

View File

@ -27,9 +27,14 @@
#include <QObject>
#include <QVector>
// 启动器相关配置
class LauncherSettings : public QObject
{
Q_OBJECT
LauncherSettings(QObject *paret = nullptr);
LauncherSettings(const LauncherSettings &);
LauncherSettings& operator= (const LauncherSettings &);
public:
static inline LauncherSettings *instance() {
static LauncherSettings instance;
@ -54,11 +59,6 @@ Q_SIGNALS:
void displayModeChanged(QString mode);
void fullscreenChanged(bool isFull);
void hiddenAppsChanged();
private:
LauncherSettings(QObject *paret = nullptr);
LauncherSettings(const LauncherSettings &);
LauncherSettings& operator= (const LauncherSettings &);
};
#endif // LAUNCHERSETTINGS_H

View File

@ -44,6 +44,7 @@ struct ClientPrivate {
return false;
}
// TODO readFunc function?
if (readFunc) {
readThread = new std::thread([=] {
char buf[512];
@ -72,11 +73,11 @@ struct ClientPrivate {
send(call);
char buf[512];
std::string result;
std::vector<char> data;
int bytesRead;
while ((bytesRead = recv(socket_fd, buf, 512, 0)) > 0) {
for (int i = 0; i < bytesRead; ++i) {
result += buf[i];
data.push_back(buf[i]);
}
if (buf[bytesRead - 1] == '\0') {
@ -84,12 +85,12 @@ struct ClientPrivate {
}
}
QJsonDocument doc = QJsonDocument::fromRawData(result.data(), result.size());
return doc.toJson();
return data.data();
}
size_t send(const QByteArray &call) {
std::string data = call.data();
// \0 作为结尾标记
data += '\0';
return write(socket_fd, data.c_str(), data.length());
}

View File

@ -12,109 +12,119 @@
#include <iostream>
namespace Socket {
class ServerPrivate : public QObject {
Q_OBJECT
public:
Server *q_ptr;
int socket_fd;
QThread *workThread;
Q_SIGNALS:
void requestStart();
ServerPrivate::ServerPrivate(Server *server)
: QObject()
, q_ptr(server)
, socket_fd(-1)
, workThread(nullptr)
{
if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
std::cout << "socket() failed" << std::endl;
return;
}
public:
ServerPrivate(Server *server) : QObject(), q_ptr(server), socket_fd(-1)
{
if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
std::cout << "socket() failed" << std::endl;
connect(this, &ServerPrivate::requestStart, this, &ServerPrivate::work, Qt::QueuedConnection);
}
ServerPrivate::~ServerPrivate()
{
}
void ServerPrivate::work()
{
// 处理客户端数据
while (true) {
// 阻塞等待客户端连接
int socket = accept(socket_fd, nullptr, nullptr);
if (socket == -1) {
std::cout << "accept() failed" << std::endl;
return;
}
connect(this, &ServerPrivate::requestStart, this, &ServerPrivate::work, Qt::QueuedConnection);
}
~ServerPrivate() {}
void work()
{
// start a thread to listen client read
while (true) {
int socket = accept(socket_fd, nullptr, nullptr);
if (socket == -1) {
std::cout << "accept() failed" << std::endl;
return;
}
QtConcurrent::run([=] {
int readBytes = 0;
char buffer[1024];
std::vector<char> data;
while (true) {
readBytes = recv(socket, buffer, 1024, 0);
if (readBytes == -1) {
std::cout << "client connect closed" << std::endl;
break;
}
if (readBytes == 0) {
break;
}
for (int i = 0; i != readBytes; i++) {
data.push_back(buffer[i]);
}
if (buffer[readBytes - 1] == '\0') {
emit q_ptr->onReadyRead(socket, data);
data.clear();
}
QtConcurrent::run([=] {
int readBytes = 0;
char buffer[1024];
std::vector<char> data;
while (true) {
readBytes = recv(socket, buffer, 1024, 0);
if (readBytes == -1) {
std::cout << "client connect closed" << std::endl;
break;
}
});
}
if (readBytes == 0) {
break;
}
for (int i = 0; i != readBytes; i++) {
data.push_back(buffer[i]);
}
if (buffer[readBytes - 1] == '\0') {
emit q_ptr->onReadyRead(socket, data);
data.clear();
}
}
});
}
}
bool ServerPrivate::listen(const std::string &host)
{
if (socket_fd < 0) {
return false;
}
bool listen(const std::string &host)
{
if (socket_fd < 0) {
return false;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, host.size() + 1, "%s", host.c_str());
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, host.size() + 1, "%s", host.c_str());
if (remove(host.c_str()) == -1 && errno != ENOENT) {
std::cout << "remove() failed" << std::endl;
return false;
}
if (bind(socket_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
std::cout << "bind() failed" << std::endl;
return false;
}
if (::listen(socket_fd, sizeof(uint)) < 0) {
std::cout << "listen() failed" << std::endl;
return false;
}
return true;
// 移除原有套接字文件
if (remove(host.c_str()) == -1 && errno != ENOENT) {
std::cout << "remove() failed" << std::endl;
return false;
}
void write(int socket, const std::vector<char> &data)
{
::write(socket, data.data(), data.size());
// 绑定套接字文件
if (bind(socket_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
std::cout << "bind() failed" << std::endl;
return false;
}
void closeClient(int socket)
{
::close(socket);
// 监听客户端连接
if (::listen(socket_fd, 20) < 0) {
std::cout << "listen() failed" << std::endl;
return false;
}
};
Server::Server() : QObject(nullptr), d_ptr(new ServerPrivate(this))
return true;
}
void ServerPrivate::write(int socket, const std::vector<char> &data)
{
::write(socket, data.data(), data.size());
}
void ServerPrivate::closeClient(int socket)
{
::close(socket);
}
Server::Server()
: QObject(nullptr)
, d_ptr(new ServerPrivate(this))
{
qRegisterMetaType<std::vector<char>>("VectorChar");
}
Server::~Server() {}
Server::~Server()
{
}
bool Server::listen(const std::string &host)
{
if (d_ptr->workThread) {
@ -142,6 +152,7 @@ void Server::close(int socket)
{
d_ptr->closeClient(socket);
}
} // namespace Socket
#include "server.moc"

View File

@ -8,7 +8,29 @@
#include <QObject>
namespace Socket {
class ServerPrivate;
class Server;
class ServerPrivate : public QObject {
Q_OBJECT
public:
Server *q_ptr;
int socket_fd;
QThread *workThread;
Q_SIGNALS:
void requestStart();
public:
ServerPrivate(Server *server);
~ServerPrivate();
void work();
bool listen(const std::string &host);
void write(int socket, const std::vector<char> &data);
void closeClient(int socket);
};
class Server : public QObject {
Q_OBJECT
std::unique_ptr<ServerPrivate> d_ptr;

View File

@ -27,6 +27,7 @@
#include "startmanagersettings.h"
#include "startmanagerdbushandler.h"
#include "meminfo.h"
#include "../../service/impl/application_manager.h"
#include <QFileSystemWatcher>
#include <QDebug>
@ -47,6 +48,11 @@ StartManager::StartManager(QObject *parent)
, dbusHandler(new StartManagerDBusHandler(this))
, fileWatcher(new QFileSystemWatcher(this))
{
am = static_cast<ApplicationManager *>(parent);
if (!am) {
qWarning() << "StartManager init error";
}
// load sysMemLimitConfig
loadSysMemLimitConfig();

View File

@ -30,6 +30,7 @@ class StartManagerDBusHandler;
class DesktopInfo;
class QProcess;
class QFileSystemWatcher;
class ApplicationManager;
class StartManager : public QObject
{
@ -76,6 +77,7 @@ private:
StartManagerDBusHandler *dbusHandler;
QStringList autostartFiles;
QFileSystemWatcher *fileWatcher;
ApplicationManager *am;
};
#endif // STARTMANAGER_H

View File

@ -32,7 +32,7 @@ StartManagerDBusHandler::StartManagerDBusHandler(QObject *parent)
void StartManagerDBusHandler::markLaunched(QString desktopFile)
{
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecoder1", "/org/deepin/daemon/AlRecoder1", "org.deepin.daemon.AlRecoder1");
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecorder1", "/org/deepin/daemon/AlRecorder1", "org.deepin.daemon.AlRecorder1");
interface.call("MarkLaunched", desktopFile);
}

View File

@ -19,6 +19,7 @@
#include <iostream>
#include <iterator>
namespace linglong {
namespace util {

View File

@ -29,6 +29,7 @@ add_definitions(-DUSE_QT)
set(SRCS ${PROJECT_BINARY_DIR}/src/define.h)
set(SRCS
./applicationhelper.h
./main.cpp
./impl/application_manager.h
./impl/application_manager.cpp
@ -36,7 +37,6 @@ set(SRCS
./impl/application.cpp
./impl/application_instance.h
./impl/application_instance.cpp
../modules/applicationhelper/helper.h
../modules/tools/desktop_deconstruction.hpp
../modules/socket/server.h
../modules/socket/server.cpp
@ -45,7 +45,6 @@ set(SRCS
../modules/methods/instance.hpp
../modules/methods/quit.hpp
../modules/methods/registe.hpp
../lib/desktopinfo.h
../lib/desktopinfo.cpp
../lib/dlocale.h
@ -82,6 +81,8 @@ set(SRCS
../modules/apps/appmanager.cpp
../modules/apps/dfwatcher.h
../modules/apps/dfwatcher.cpp
../modules/apps/dbusalrecorderadaptor.h
../modules/apps/dbusalrecorderadaptor.cpp
../modules/launcher/common.h
../modules/launcher/launcher.h
../modules/launcher/launcher.cpp
@ -142,6 +143,8 @@ set(SRCS
../frameworkdbus/types/launcheriteminfolist.cpp
../frameworkdbus/types/rect.h
../frameworkdbus/types/rect.cpp
../frameworkdbus/types/unlaunchedappmap.h
../frameworkdbus/types/unlaunchedappmap.cpp
../frameworkdbus/dbuslauncherfront.h
../frameworkdbus/dbuslauncherfront.cpp
../frameworkdbus/dbuslauncher.h
@ -192,6 +195,7 @@ target_include_directories(deepin-application-manager PUBLIC
../utils
../frameworkdbus
../frameworkdbus/qtdbusextended
../frameworkdbus/types
)
install(TARGETS deepin-application-manager DESTINATION bin)

View File

@ -1,7 +1,4 @@
#ifndef A7B4B7B1_0422_4EC9_8441_778273A85F9C
#define A7B4B7B1_0422_4EC9_8441_778273A85F9C
#include "../tools/desktop_deconstruction.hpp"
#include "../modules/tools/desktop_deconstruction.hpp"
#include <QString>
@ -45,6 +42,7 @@ public:
return value<QString>("Icon");
}
// appId
QString id() const
{
return m_file.split("/").last().split(".").first();
@ -76,4 +74,3 @@ public:
} // namespace ApplicationHelper
} // namespace modules
#endif /* A7B4B7B1_0422_4EC9_8441_778273A85F9C */

View File

@ -6,7 +6,7 @@
#include <QThread>
#include <algorithm>
#include "../modules/applicationhelper/helper.h"
#include "../applicationhelper.h"
#include "../modules/tools/desktop_deconstruction.hpp"
#include "application_instance.h"
@ -141,11 +141,11 @@ QString Application::filePath() const
return d->helper->desktop();
}
QSharedPointer<ApplicationInstance> Application::createInstance()
QSharedPointer<ApplicationInstance> Application::createInstance(QStringList files)
{
Q_D(Application);
d->instances << QSharedPointer<ApplicationInstance>(new ApplicationInstance(this, d->helper));
d->instances << QSharedPointer<ApplicationInstance>(new ApplicationInstance(this, d->helper, files));
connect(d->instances.last().get(), &ApplicationInstance::taskFinished, this, [=] {
for (auto it = d->instances.begin(); it != d->instances.end(); ++it) {

View File

@ -50,7 +50,7 @@ public: // PROPERTIES
QString filePath() const;
QSharedPointer<ApplicationInstance> createInstance();
QSharedPointer<ApplicationInstance> createInstance(QStringList files);
public Q_SLOTS: // METHODS
QString Comment(const QString &locale);

View File

@ -9,7 +9,7 @@
#include <QUuid>
#include <QtConcurrent/QtConcurrent>
#include "../../modules/applicationhelper/helper.h"
#include "../applicationhelper.h"
#include "application.h"
#include "applicationinstanceadaptor.h"
@ -46,6 +46,7 @@ public:
void run()
{
#ifdef DEFINE_LOADER_PATH
const QString task_hash{ QString("DAM_TASK_HASH=%1").arg(m_id) };
const QString task_type{ "DAM_TASK_TYPE=freedesktop " };
QProcess* p = new QProcess(q_ptr);
@ -88,7 +89,10 @@ public:
void _kill() {}
};
ApplicationInstance::ApplicationInstance(Application* parent, QSharedPointer<modules::ApplicationHelper::Helper> helper) : QObject(nullptr), dd_ptr(new ApplicationInstancePrivate(this))
ApplicationInstance::ApplicationInstance(Application* parent, QSharedPointer<modules::ApplicationHelper::Helper> helper, QStringList files)
: QObject(nullptr)
, dd_ptr(new ApplicationInstancePrivate(this))
, m_files(files)
{
Q_D(ApplicationInstance);
@ -143,6 +147,7 @@ Methods::Task ApplicationInstance::taskInfo() const
task.id = d->m_id;
task.runId = d->application->id();
task.date = QString::number(startuptime());
task.arguments = m_files;
// TODO: debug to display environment
task.environments.insert( "DISPLAY", ":0" );

View File

@ -18,8 +18,10 @@ class ApplicationInstance : public QObject {
Q_OBJECT
QScopedPointer<ApplicationInstancePrivate> dd_ptr;
Q_DECLARE_PRIVATE_D(qGetPtrHelper(dd_ptr), ApplicationInstance)
QStringList m_files; // 实例打开的文件
public:
ApplicationInstance(Application* parent, QSharedPointer<modules::ApplicationHelper::Helper> helper);
ApplicationInstance(Application* parent, QSharedPointer<modules::ApplicationHelper::Helper> helper, QStringList files);
~ApplicationInstance() override;
public: // PROPERTIES

View File

@ -17,112 +17,111 @@
#include "../../modules/methods/quit.hpp"
#include "../../modules/methods/registe.hpp"
#include "../../modules/methods/task.hpp"
#include "../../modules/socket/server.h"
#include "../../modules/startmanager/startmanager.h"
#include "application.h"
#include "application_instance.h"
#include "applicationinstanceadaptor.h"
class ApplicationManagerPrivate : public QObject
{
Q_OBJECT
ApplicationManager *q_ptr = nullptr;
Q_DECLARE_PUBLIC(ApplicationManager);
QList<QSharedPointer<Application>> applications;
Socket::Server server;
std::multimap<std::string, QSharedPointer<ApplicationInstance>> tasks;
StartManager *startManager;
public:
ApplicationManagerPrivate(ApplicationManager *parent)
ApplicationManagerPrivate::ApplicationManagerPrivate(ApplicationManager *parent)
: QObject(parent)
, q_ptr(parent)
, startManager(new StartManager(this))
{
{
const QString socketPath{QString("/run/user/%1/deepin-application-manager.socket").arg(getuid())};
connect(&server, &Socket::Server::onReadyRead, this, &ApplicationManagerPrivate::recvClientData, Qt::QueuedConnection);
server.listen(socketPath.toStdString());
}
~ApplicationManagerPrivate() {}
}
bool checkDMsgUid()
{
QDBusReply<uint> reply = q_ptr->connection().interface()->serviceUid(q_ptr->message().service());
return reply.isValid() && (reply.value() == getuid());
}
ApplicationManagerPrivate::~ApplicationManagerPrivate()
{
private:
void recvClientData(int socket, const std::vector<char> &data)
{
std::string tmp;
for (char c : data) {
tmp += c;
}
bool ApplicationManagerPrivate::checkDMsgUid()
{
QDBusReply<uint> reply = q_ptr->connection().interface()->serviceUid(q_ptr->message().service());
return reply.isValid() && (reply.value() == getuid());
}
/**
* @brief ApplicationManagerPrivate::recvClientData
* @param socket
* @param data
*/
void ApplicationManagerPrivate::recvClientData(int socket, const std::vector<char> &data)
{
QByteArray jsonArray = data.data();
Methods::Basic basic;
Methods::fromJson(jsonArray, basic);
QByteArray tmpArray;
do {
// 运行实例
if (basic.type == "instance") {
Methods::Instance instance;
Methods::fromJson(jsonArray, instance);
// 校验实例信息
auto find = tasks.find(instance.hash.toStdString());
if (find != tasks.end()) {
Methods::Task task = find->second->taskInfo();
Methods::toJson(tmpArray, task);
// 通过校验,传入应用启动信息
write(socket, tmpArray.toStdString());
tasks.erase(find);
break;
}
}
QByteArray jsonArray = data.data();
Methods::Basic basic;
Methods::fromJson(jsonArray, basic);
QByteArray tmpArray;
do {
if (basic.type == "instance") {
Methods::Instance instance;
Methods::fromJson(jsonArray, instance);
auto find = tasks.find(instance.hash.toStdString());
if (find != tasks.end())
{
Methods::Task task = find->second->taskInfo();
Methods::toJson(tmpArray, task);
write(socket, tmpArray.toStdString());
tasks.erase(find);
break;
}
}
if (basic.type == "quit") {
Methods::Quit quit;
Methods::fromJson(jsonArray, quit);
server.close(socket);
std::cout << "client quit" << std::endl;
break;
}
if (basic.type == "registe") {
Methods::Registe registe;
Methods::fromJson(jsonArray, registe);
Methods::Registe result;
result.state = false;
// std::lock_guard<std::mutex> lock(task_mutex);
for (auto it = tasks.begin(); it != tasks.end(); ++it) {
result.state = true;
result.hash = QString::fromStdString(it->first);
}
Methods::toJson(tmpArray, result);
write(socket, tmpArray.toStdString());
break;
}
write(socket, jsonArray.toStdString());
} while (false);
}
// 退出
if (basic.type == "quit") {
Methods::Quit quit;
Methods::fromJson(jsonArray, quit);
server.close(socket);
std::cout << "client quit" << std::endl;
break;
}
void write(int socket, const std::vector<char> &data)
{
std::vector<char> tmp = data;
tmp.push_back('\0');
server.write(socket, tmp);
}
void write(int socket, const std::string &data)
{
std::vector<char> result;
std::copy(data.cbegin(), data.cend(), std::back_inserter(result));
return write(socket, result);
}
void write(int socket, const char c)
{
return write(socket, std::vector<char>(c));
}
};
// 注册应用
if (basic.type == "registe") {
Methods::Registe registe;
Methods::fromJson(jsonArray, registe);
Methods::Registe result;
result.state = false;
// std::lock_guard<std::mutex> lock(task_mutex);
for (auto it = tasks.begin(); it != tasks.end(); ++it) {
result.state = true;
result.hash = QString::fromStdString(it->first);
}
Methods::toJson(tmpArray, result);
write(socket, tmpArray.toStdString());
break;
}
write(socket, jsonArray.toStdString());
} while (false);
}
ApplicationManager* ApplicationManager::Instance() {
void ApplicationManagerPrivate::write(int socket, const std::vector<char> &data)
{
std::vector<char> tmp = data;
tmp.push_back('\0');
server.write(socket, tmp);
}
void ApplicationManagerPrivate::write(int socket, const std::string &data)
{
std::vector<char> result;
std::copy(data.cbegin(), data.cend(), std::back_inserter(result));
return write(socket, result);
}
void ApplicationManagerPrivate::write(int socket, const char c)
{
return write(socket, std::vector<char>(c));
}
ApplicationManager* ApplicationManager::instance() {
static ApplicationManager manager;
return &manager;
}
@ -145,6 +144,23 @@ void ApplicationManager::addApplication(const QList<QSharedPointer<Application>>
d->applications = list;
}
/**
* @brief ApplicationManager::launchAutostartApps
* TODO loader使用同一个套接字通信
*/
void ApplicationManager::launchAutostartApps()
{
/*
Launch("/freedesktop/system/seahorse", QStringList());
QTimer::singleShot(1000, [&] {
for (auto app : startManager->autostartList()) {
QString id = app.split("/").last().split(".").first();
Launch(id, QStringList());
}
});
*/
}
QDBusObjectPath ApplicationManager::GetInformation(const QString &id)
{
Q_D(ApplicationManager);
@ -175,7 +191,13 @@ QList<QDBusObjectPath> ApplicationManager::GetInstances(const QString &id)
return {};
}
QDBusObjectPath ApplicationManager::Run(const QString &id)
/**
* @brief ApplicationManager::Launch
* @param id QString("/%1/%2/%3").arg(Apptype).arg(d->m_type == Application::Type::System ? "system" : "user").arg(appId)
* @param files
* @return
*/
QDBusObjectPath ApplicationManager::Launch(const QString &id, QStringList files)
{
Q_D(ApplicationManager);
if (!d->checkDMsgUid())
@ -183,9 +205,10 @@ QDBusObjectPath ApplicationManager::Run(const QString &id)
// 创建一个实例
for (const QSharedPointer<Application> &app : d->applications) {
QString appId = app->id();
if (app->id() == id) {
// 创建任务所需的数据,并记录到任务队列,等待 loader 消耗
QSharedPointer<ApplicationInstance> instance{app->createInstance()};
QSharedPointer<ApplicationInstance> instance{app->createInstance(files)};
const std::string hash{instance->hash().toStdString()};
connect(instance.get(), &ApplicationInstance::taskFinished, this, [=] {
for (auto it = d->tasks.begin(); it != d->tasks.end(); ++it) {

View File

@ -1,6 +1,9 @@
#ifndef A2862DC7_5DA3_4129_9796_671D88015BED
#define A2862DC7_5DA3_4129_9796_671D88015BED
#include "../../modules/startmanager/startmanager.h"
#include "../../modules/socket/server.h"
#include <QObject>
#include <QDBusObjectPath>
#include <QList>
@ -9,7 +12,34 @@
class Application;
class ApplicationInstance;
class ApplicationManagerPrivate;
class ApplicationManagerPrivate : public QObject
{
Q_OBJECT
ApplicationManager *q_ptr = nullptr;
Q_DECLARE_PUBLIC(ApplicationManager);
QList<QSharedPointer<Application>> applications;
Socket::Server server;
std::multimap<std::string, QSharedPointer<ApplicationInstance>> tasks;
StartManager *startManager;
public:
ApplicationManagerPrivate(ApplicationManager *parent);
~ApplicationManagerPrivate();
// 检测调用方身份
bool checkDMsgUid();
private:
void recvClientData(int socket, const std::vector<char> &data);
void write(int socket, const std::vector<char> &data);
void write(int socket, const std::string &data);
void write(int socket, const char c);
};
class ApplicationManager : public QObject, public QDBusContext
{
Q_OBJECT
@ -21,9 +51,10 @@ class ApplicationManager : public QObject, public QDBusContext
public:
ApplicationManager(QObject *parent = nullptr);
~ApplicationManager() override;
static ApplicationManager* Instance();
static ApplicationManager* instance();
void addApplication(const QList<QSharedPointer<Application>> &list);
void launchAutostartApps();
Q_SIGNALS:
void AutostartChanged(QString status, QString filePath);
@ -35,7 +66,7 @@ public: // PROPERTIES
public Q_SLOTS: // METHODS
QDBusObjectPath GetInformation(const QString &id);
QList<QDBusObjectPath> GetInstances(const QString &id);
QDBusObjectPath Run(const QString &id);
QDBusObjectPath Launch(const QString &id, QStringList files);
// com.deepin.StartManager
bool AddAutostart(QString fileName);
@ -53,7 +84,6 @@ public Q_SLOTS: // METHODS
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 */

View File

@ -4,7 +4,7 @@
#include "impl/application.h"
#include "applicationmanageradaptor.h"
#include "applicationadaptor.h"
#include "../modules/applicationhelper/helper.h"
#include "applicationhelper.h"
#include "../modules/apps/appmanager.h"
#include "../modules/launcher/launchermanager.h"
#include "../modules/dock/dockmanager.h"
@ -72,15 +72,15 @@ int main(int argc, char *argv[])
DLogManager::registerConsoleAppender();
DLogManager::registerFileAppender();
new AppManager(ApplicationManager::Instance());
new LauncherManager(ApplicationManager::Instance());
new DockManager(ApplicationManager::Instance());
new StartManager(ApplicationManager::Instance());
new ApplicationManagerAdaptor(ApplicationManager::Instance());
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");
QDBusConnection::sessionBus().registerService("org.desktopspec.ApplicationManager");
QDBusConnection::sessionBus().registerObject("/org/desktopspec/ApplicationManager", "org.desktopspec.ApplicationManager", ApplicationManager::Instance());
QDBusConnection::sessionBus().registerObject("/org/desktopspec/ApplicationManager", "org.desktopspec.ApplicationManager", ApplicationManager::instance());
QList<QSharedPointer<Application>> apps{ scanFiles() };
QList<QSharedPointer<ApplicationAdaptor>> appAdapters;
@ -90,7 +90,9 @@ int main(int argc, char *argv[])
QDBusConnection::sessionBus().registerObject(app->path().path(), "org.desktopspec.Application", app.get());
}
ApplicationManager::Instance()->addApplication(apps);
ApplicationManager::instance()->addApplication(apps);
ApplicationManager::instance()->launchAutostartApps();
return app.exec();
}