Skip to content

Commit c5f2cce

Browse files
author
Chen Bin
committed
refactor: The Clipboard operations in the Wayland
1. 整理所有信号的连接与创建,避免重复连接和内存泄漏的情况。 2. 通过创建一个统一的线程管理机制[服务流机制],管理所有获取 的拷贝和粘贴操作指令。 其中,用两种不同的服务流来分别管理拷贝和粘贴,拷贝流在 每一次用户操作 Ctrl + c 时都会重新创建,流程执行完毕后自动 退出回收;粘贴流由于执行指令类似,因此将其放在同一个流中进行 后台监听,当用户使用 Ctrl + v 时,不断的向流中放置消息,使 流开始正常工作。 服务流使用责任链模式实现,每一个服务存在不同的指令,每个 指令在子线程中执行不同的任务,并将结果发送给下一个服务中的指 令,直到服务结束。多个服务串行,形成最终的服务流。 3. 由于窗管对信号中指针的接受,没有进行线程安全的操作,因此 最终实现时增加了较多的线程同步机制,以防止出现野指针 Log: Influence: Wayland clipboard
1 parent 1002671 commit c5f2cce

15 files changed

+1287
-150
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ install(TARGETS ${BIN_NAME} DESTINATION bin)
139139
set(BIN_NAME dde-clipboard-daemon)
140140

141141
file(GLOB_RECURSE dde-clipboard-daemon_SCRS
142+
"dde-clipboard-daemon/serviceflow/*.h"
143+
"dde-clipboard-daemon/serviceflow/*.cpp"
142144
"dde-clipboard-daemon/*.h"
143145
"dde-clipboard-daemon/*.cpp"
144146
)

dde-clipboard-daemon/clipboardloader.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ ClipboardLoader::ClipboardLoader(QObject *parent)
9090
if (qEnvironmentVariable("XDG_SESSION_TYPE").contains("wayland")) {
9191
#ifdef USE_DEEPIN_KF5_WAYLAND
9292
m_waylandCopyClient = new WaylandCopyClient(this);
93-
m_waylandCopyClient->init();
9493

9594
connect(m_waylandCopyClient, &WaylandCopyClient::dataChanged, this, [this] {
9695
this->doWork(WAYLAND_PROTOCOL);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#include "command.h"
6+
#include "servicetool.h"
7+
8+
Command::Command(CommandService *service)
9+
: m_service(service)
10+
{
11+
setAutoDelete(true);
12+
}
13+
14+
void Command::exit()
15+
{
16+
m_isExit = true;
17+
}
18+
19+
Command::State Command::state() const
20+
{
21+
return m_state;
22+
}
23+
24+
CommandService *Command::service() const
25+
{
26+
return m_service;
27+
}
28+
29+
void Command::installMessageExtractor(Extractor *extractor)
30+
{
31+
Q_ASSERT(extractor);
32+
switch (extractor->direction()) {
33+
case Extractor::CommandToTransporter: {
34+
if (m_outEx) {
35+
qWarning("This command already has the out direction Extractor.");
36+
return;
37+
}
38+
m_outEx = extractor;
39+
}
40+
break;
41+
case Extractor::TransporterToCommand: {
42+
if (m_inEx) {
43+
qWarning("This command already has the in direction Extractor.");
44+
return;
45+
}
46+
m_inEx = extractor;
47+
}
48+
break;
49+
}
50+
}
51+
52+
void Command::run()
53+
{
54+
Q_ASSERT(m_inEx);
55+
while (true) {
56+
m_state = Preparing;
57+
CommandMessage *msg = m_inEx->takeFromTransporter();
58+
if (m_isExit) {
59+
delete msg;
60+
break;
61+
}
62+
63+
m_state = Running;
64+
QList<CommandMessage *> destMsgs = doExecute(msg);
65+
66+
// 允许复用同一个 msg 的情况
67+
if (!destMsgs.contains(msg))
68+
delete msg;
69+
70+
if (m_outEx) {
71+
for (auto destMsg : destMsgs)
72+
m_outEx->pushToTransporter(destMsg);
73+
}
74+
}
75+
m_state = Preparing;
76+
}
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#ifndef COMMAND
6+
#define COMMAND
7+
8+
#include <QRunnable>
9+
10+
class CommandService;
11+
class CommandMessage;
12+
class Extractor;
13+
class Command : public QRunnable
14+
{
15+
public:
16+
enum State {
17+
Preparing,
18+
Running
19+
};
20+
Command(CommandService *service = nullptr);
21+
22+
virtual QList<CommandMessage *> doExecute(CommandMessage *) = 0;
23+
virtual QString name() const = 0;
24+
25+
void exit();
26+
State state() const;
27+
28+
CommandService *service() const;
29+
void installMessageExtractor(Extractor *extractor);
30+
31+
private:
32+
void run() override;
33+
34+
Extractor * m_inEx = nullptr;
35+
Extractor * m_outEx = nullptr;
36+
bool m_isExit = false;
37+
State m_state = Preparing;
38+
CommandService *m_service = nullptr;
39+
};
40+
41+
#endif // COMMANDMESSAGE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#ifndef COMMANDMESSAGE
6+
#define COMMANDMESSAGE
7+
8+
class CommandMessage
9+
{
10+
public:
11+
enum Error {
12+
NoError,
13+
ExecuteError
14+
};
15+
16+
CommandMessage() = default;
17+
virtual ~CommandMessage() {}
18+
19+
inline Error error() const {
20+
return m_error;
21+
}
22+
23+
inline void setError(Error err) {
24+
m_error = err;
25+
}
26+
27+
protected:
28+
Error m_error = NoError;
29+
};
30+
31+
#endif // COMMANDMESSAGE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#include "commandservice.h"
6+
7+
CommandService::CommandService()
8+
{
9+
10+
}
11+
12+
CommandService::~CommandService()
13+
{
14+
15+
}
16+
17+
CommandService *CommandService::nextService() const
18+
{
19+
return this->m_nextService;
20+
}
21+
22+
void CommandService::setNextService(CommandService *service)
23+
{
24+
this->m_nextService = service;
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#ifndef COMMANDSERVICE
6+
#define COMMANDSERVICE
7+
8+
#include "command.h"
9+
10+
class CommandService
11+
{
12+
public:
13+
CommandService();
14+
virtual ~CommandService();
15+
16+
virtual QList<Command *> commands() = 0;
17+
18+
CommandService *nextService() const;
19+
void setNextService(CommandService* service);
20+
21+
private:
22+
CommandService* m_nextService;
23+
};
24+
25+
#endif // COMMANDSERVICE

0 commit comments

Comments
 (0)