From d54b654b51a32926b285af9d87bde40b1da65b3a Mon Sep 17 00:00:00 2001 From: zhaoyingzhen Date: Fri, 2 Sep 2022 16:58:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B5=8F=E8=A7=88?= =?UTF-8?q?=E5=99=A8=E4=B8=AD=E9=80=89=E4=B8=AD=E6=96=87=E6=9C=AC=E5=90=8E?= =?UTF-8?q?=E9=95=BF=E6=8C=89Ctrl+C=E5=87=BA=E7=8E=B0=E6=A1=8C=E9=9D=A2?= =?UTF-8?q?=E5=B4=A9=E6=BA=83=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此修改为配合窗管一起修改,解决wayland下多实例接收数据导致的问题。已将wayland下剪切板给UI提供数据和管理数据实例合并,去掉插件。 Log: 修复浏览器中选中文本后长按Ctrl+C出现桌面崩溃的问题。 Bug: https://pms.uniontech.com/bug-view-151723.html Influence: 剪切板全量功能。 --- CMakeLists.txt | 83 +---- dde-clipboard-daemon/clipboarddaemon.cpp | 31 ++ dde-clipboard-daemon/clipboarddaemon.h | 17 + ...ipboard_loader.cpp => clipboardloader.cpp} | 26 +- .../clipboard_loader.h => clipboardloader.h} | 5 +- .../dde-clipboard-loader/src => }/constants.h | 0 dde-clipboard-daemon/dbus_manager.cpp | 279 --------------- dde-clipboard-daemon/dbus_manager.h | 51 --- .../dde-clipboard-loader/src => }/iteminfo.h | 0 dde-clipboard-daemon/main.cpp | 24 +- .../clipboard_loader_plugin.cpp | 81 ----- .../clipboard_loader_plugin.h | 17 - .../clipboard_loader_plugin_global.h | 16 - .../src/wayland_copy_client.cpp | 317 ------------------ .../src/wayland_copy_client.h | 82 ----- .../clipboard_manager_plugin.cpp | 74 ---- .../clipboard_manager_plugin.h | 17 - .../clipboard_manager_plugin_global.h | 16 - .../src => }/waylandcopyclient.cpp | 54 +-- .../src => }/waylandcopyclient.h | 10 +- 20 files changed, 116 insertions(+), 1084 deletions(-) create mode 100644 dde-clipboard-daemon/clipboarddaemon.cpp create mode 100644 dde-clipboard-daemon/clipboarddaemon.h rename dde-clipboard-daemon/{plugin/dde-clipboard-loader/src/clipboard_loader.cpp => clipboardloader.cpp} (95%) rename dde-clipboard-daemon/{plugin/dde-clipboard-loader/src/clipboard_loader.h => clipboardloader.h} (92%) rename dde-clipboard-daemon/{plugin/dde-clipboard-loader/src => }/constants.h (100%) delete mode 100644 dde-clipboard-daemon/dbus_manager.cpp delete mode 100644 dde-clipboard-daemon/dbus_manager.h rename dde-clipboard-daemon/{plugin/dde-clipboard-loader/src => }/iteminfo.h (100%) delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.cpp delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.h delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin_global.h delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.cpp delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.h delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.cpp delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.h delete mode 100644 dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin_global.h rename dde-clipboard-daemon/{plugin/dde-clipboard-manager/src => }/waylandcopyclient.cpp (92%) rename dde-clipboard-daemon/{plugin/dde-clipboard-manager/src => }/waylandcopyclient.h (93%) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcac638..ef0b9a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-all") set(CMAKE_EXE_LINKER_FLAGS "-z relro -z now -z noexecstack -pie") if (CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fsanitize=address -O2") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address -O2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fsanitize=address -O0") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address -O0") endif() if (DEFINED ENABLE_MIEEE) @@ -139,9 +139,8 @@ install(TARGETS ${BIN_NAME} DESTINATION bin) set(BIN_NAME dde-clipboard-daemon) file(GLOB_RECURSE dde-clipboard-daemon_SCRS - "dde-clipboard-daemon/main.cpp" - "dde-clipboard-daemon/dbus_manager.cpp" - "dde-clipboard-daemon/dbus_manager.h" + "dde-clipboard-daemon/*.h" + "dde-clipboard-daemon/*.cpp" ) add_executable(${BIN_NAME} @@ -152,13 +151,15 @@ target_include_directories(${BIN_NAME} PUBLIC ${Qt5Widget_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${DtkCore_INCLUDE_DIRS} - ) + KF5::WaylandClient +) target_link_libraries(${BIN_NAME} PRIVATE ${Qt5DBus_LIBRARIES} ${Qt5Core_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${DtkCore_LIBRARIES} + KF5::WaylandClient ) install(TARGETS ${BIN_NAME} DESTINATION bin) @@ -172,76 +173,6 @@ install(FILES misc/dde-clipboard-daemon.desktop DESTINATION /etc/xdg/autostart/ ) -#----------------------------dde-clipboard-loader------------------------------ -set(PLUGIN_NAME "dde-clipboard-loader") - -file(GLOB_RECURSE dde-clipboard-loader_SCRS - "dde-clipboard-daemon/plugin/dde-clipboard-loader/*.h" - "dde-clipboard-daemon/plugin/dde-clipboard-loader/*.cpp" - "dde-clipboard-daemon/plugin/dde-clipboard-loader/src/*.h" - "dde-clipboard-daemon/plugin/dde-clipboard-loader/src/*.cpp" -) - -add_definitions("${QT_DEFINITIONS} -DCLIPBOARD_LIBRARY") - -add_library(${PLUGIN_NAME} SHARED - ${dde-clipboard-loader_SCRS} -) - -set_target_properties(${PLUGIN_NAME} PROPERTIES - LIBRARY_OUTPUT_DIRECTORY - plugins/ -) - -target_include_directories(${PLUGIN_NAME} PUBLIC - ${Qt5Widget_INCLUDE_DIRS} - ${Qt5DBus_INCLUDE_DIRS} - KF5::WaylandClient - "dde-clipboard-daemon/plugin/dde-clipboard-loader/src" - ) - -target_link_libraries(${PLUGIN_NAME} PRIVATE - ${Qt5Widgets_LIBRARIES} - ${Qt5DBus_LIBRARIES} - KF5::WaylandClient -) - -install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-clipboard/) - -#----------------------------dde-clipboard-manager------------------------------ -set(PLUGIN_NAME "dde-clipboard-manager") - -file(GLOB_RECURSE dde-clipboard-manager_SRCS - "dde-clipboard-daemon/plugin/dde-clipboard-manager/*.h" - "dde-clipboard-daemon/plugin/dde-clipboard-manager/*.cpp" - "dde-clipboard-daemon/plugin/dde-clipboard-manager/src/*.h" - "dde-clipboard-daemon/plugin/dde-clipboard-manager/src/*.cpp" -) - -add_definitions("${QT_DEFINITIONS} -DCLIPBOARD_LIBRARY") - -add_library(${PLUGIN_NAME} SHARED ${dde-clipboard-manager_SRCS}) - -set_target_properties(${PLUGIN_NAME} PROPERTIES - LIBRARY_OUTPUT_DIRECTORY - plugins/ -) - -target_include_directories(${PLUGIN_NAME} PUBLIC - ${Qt5Widget_INCLUDE_DIRS} - ${Qt5DBus_INCLUDE_DIRS} - KF5::WaylandServer - "dde-clipboard-daemon/plugin/dde-clipboard-manager/src" - ) - -target_link_libraries(${PLUGIN_NAME} PRIVATE - ${Qt5Widgets_LIBRARIES} - ${Qt5DBus_LIBRARIES} - KF5::WaylandClient -) - -install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-clipboard/) - #----------------------------ut-dde-clipboard------------------------------ set(UT_BIN_NAME ut-dde-clipboard) diff --git a/dde-clipboard-daemon/clipboarddaemon.cpp b/dde-clipboard-daemon/clipboarddaemon.cpp new file mode 100644 index 0000000..48dbfa6 --- /dev/null +++ b/dde-clipboard-daemon/clipboarddaemon.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "clipboarddaemon.h" +#include "clipboardloader.h" + +#include +#include + +ClipboardDaemon::ClipboardDaemon(QObject *parent) + : QObject(parent) +{ + QDBusConnection connection = QDBusConnection::sessionBus(); + if (!connection.registerService("com.deepin.dde.ClipboardLoader")) { + qInfo() << "error:" << connection.lastError().message(); + } + + ClipboardLoader *clipboardLoader = new ClipboardLoader(this); + connection.registerObject("/com/deepin/dde/ClipboardLoader", clipboardLoader, + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals); + + // 剪切板管理和提供UI数据的功能合并,WaylandCopyClient只实例化一次 +#if 0 + // 实例化wayland 剪切板管理器 + if (qEnvironmentVariable("XDG_SESSION_TYPE").contains("wayland")) { + WaylandCopyClient *waylandClipboardManager = new WaylandCopyClient(this); + waylandClipboardManager->init(true); + } +#endif +} diff --git a/dde-clipboard-daemon/clipboarddaemon.h b/dde-clipboard-daemon/clipboarddaemon.h new file mode 100644 index 0000000..b378a79 --- /dev/null +++ b/dde-clipboard-daemon/clipboarddaemon.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef CLIPBOARD_DAEMON_H +#define CLIPBOARD_DAEMON_H + +#include + +class ClipboardDaemon : public QObject +{ + Q_OBJECT +public: + explicit ClipboardDaemon(QObject *parent = nullptr); +}; + +#endif //CLIPBOARD_DAEMON_H diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/clipboard_loader.cpp b/dde-clipboard-daemon/clipboardloader.cpp similarity index 95% rename from dde-clipboard-daemon/plugin/dde-clipboard-loader/src/clipboard_loader.cpp rename to dde-clipboard-daemon/clipboardloader.cpp index 001360a..fadb925 100644 --- a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/clipboard_loader.cpp +++ b/dde-clipboard-daemon/clipboardloader.cpp @@ -2,11 +2,9 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -#include "clipboard_loader.h" +#include "clipboardloader.h" #include -#include -#include #include #include #include @@ -82,15 +80,16 @@ ItemInfo Buf2Info(const QByteArray &buf) QString ClipboardLoader::m_pixPath; -ClipboardLoader::ClipboardLoader() - : m_board(qApp->clipboard()) +ClipboardLoader::ClipboardLoader(QObject *parent) + : QObject(parent) + , m_board(nullptr) #ifdef USE_DEEPIN_KF5_WAYLAND , m_waylandCopyClient(nullptr) #endif { if (qEnvironmentVariable("XDG_SESSION_TYPE").contains("wayland")) { #ifdef USE_DEEPIN_KF5_WAYLAND - m_waylandCopyClient = &WaylandCopyClient::ref(); + m_waylandCopyClient = new WaylandCopyClient(this); m_waylandCopyClient->init(); connect(m_waylandCopyClient, &WaylandCopyClient::dataChanged, this, [this] { @@ -99,15 +98,16 @@ ClipboardLoader::ClipboardLoader() #else qWarning() << "we will not work with wayland"; #endif + } else { + m_board = qApp->clipboard(); + connect(m_board, &QClipboard::dataChanged, this, [this] { + this->doWork(X11_PROTOCOL); + }); } - connect(m_board, &QClipboard::dataChanged, this, [this] { - this->doWork(X11_PROTOCOL); - }); - QDir dir(QDir::homePath() + PixCacheDir); if (dir.exists() && dir.removeRecursively()) { - qDebug() << "ClipboardLoder startup, remove old cache, path:" << dir.path(); + qDebug() << "ClipboardLoader startup, remove old cache, path:" << dir.path(); } } @@ -132,7 +132,9 @@ void ClipboardLoader::dataReborned(const QByteArray &buf) break; } - m_board->setMimeData(mimeData); + if (m_board) + m_board->setMimeData(mimeData); + #ifdef USE_DEEPIN_KF5_WAYLAND if (m_waylandCopyClient) m_waylandCopyClient->setMimeData(mimeData); diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/clipboard_loader.h b/dde-clipboard-daemon/clipboardloader.h similarity index 92% rename from dde-clipboard-daemon/plugin/dde-clipboard-loader/src/clipboard_loader.h rename to dde-clipboard-daemon/clipboardloader.h index 87b2a40..a7327a1 100644 --- a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/clipboard_loader.h +++ b/dde-clipboard-daemon/clipboardloader.h @@ -7,8 +7,9 @@ #include "constants.h" #ifdef USE_DEEPIN_KF5_WAYLAND -#include "wayland_copy_client.h" +#include "waylandcopyclient.h" #endif + #include "iteminfo.h" #include @@ -28,7 +29,7 @@ class ClipboardLoader : public QObject Q_CLASSINFO("D-Bus Interface", "com.deepin.dde.ClipboardLoader") public: - ClipboardLoader(); + explicit ClipboardLoader(QObject *parent = nullptr); bool cachePixmap(const QPixmap &srcPix, ItemInfo &info); void setImageData(const ItemInfo &info, QMimeData *&mimeData); diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/constants.h b/dde-clipboard-daemon/constants.h similarity index 100% rename from dde-clipboard-daemon/plugin/dde-clipboard-loader/src/constants.h rename to dde-clipboard-daemon/constants.h diff --git a/dde-clipboard-daemon/dbus_manager.cpp b/dde-clipboard-daemon/dbus_manager.cpp deleted file mode 100644 index 6d5fa07..0000000 --- a/dde-clipboard-daemon/dbus_manager.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "dbus_manager.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Q_LOGGING_CATEGORY(plugin, "===dde.plugin") - -typedef const char *(*InfoFun)(); -typedef void (*StartFun)(); -typedef void (*StopFun)(); -typedef void (*UnloadFun)(const char *); -typedef void (*UnloadCallBack)(UnloadFun); - -void OnUnload(const char *name) { - qCDebug(plugin) << name << "request unload self"; - DBusManager::instance()->UnLoad(name); -} - -static const QStringList CompatiblePluginApiList { - "1.0", -}; - -DBusManager *DBusManager::m_instance = nullptr; -DBusManager::DBusManager(QObject *parent) - : QObject(parent) -{ - -} - -DBusManager::~DBusManager() -{ - foreach(auto pair, m_map.values()) { - auto lib = pair.second; - if (lib->isLoaded()) - lib->unload(); - lib->deleteLater(); - } - - m_map.clear(); -} - -DBusManager *DBusManager::instance( QObject *parent) -{ - if (!m_instance) - m_instance = new DBusManager(parent); - return m_instance; -} - -void DBusManager::LoadAllPlugins() -{ - // 启动时加载所有插件 - QDir libDir(getPluginPath()); - qInfo() << "plugins dir: " << libDir.absolutePath(); - for (auto name : libDir.entryList(QStringList() << "*")) { - Load(name); - } -} - -/** - * @brief DBusManager::Load 手动加载指定插件 - * @param pluginName 插件的文件名,不需要包含路径 - * @return 是否加载成功 - * @note 插件需要放置在loader进程父目录的lib文件夹下 - */ -void DBusManager::Load(const QString &fileName) -{ - QFileInfo fileInfo(getPluginPath() + QDir::separator() + fileName); - if (!QLibrary::isLibrary(fileInfo.absoluteFilePath())) - return; - - QLibrary *lib = new QLibrary(fileInfo.absoluteFilePath()); - - InfoFun infoFun = InfoFun(lib->resolve("Info")); - if (!infoFun) { - qCDebug(plugin) << "failed to resolve the `Info` method: "<< fileInfo.fileName() ; - if (lib->isLoaded()) - lib->unload(); - lib->deleteLater(); - return; - } - - PluginInfo info; - const char *data = infoFun(); - auto ba = QByteArray(data); - if (data) { - resolveInfo(ba, info); - } - - if (info.name.isEmpty() || !info.enabled) { - qCDebug(plugin) << "unload plugin , name: " << info.name << ", enabled: " << info.enabled; - if (lib->isLoaded()) - lib->unload(); - lib->deleteLater(); - return; - } - - if (info.version.isEmpty() || !CompatiblePluginApiList.contains(info.version)) { - qCDebug(plugin) << "plugin api version not matched! expect versions:" << CompatiblePluginApiList - << ", got version:" << info.version - << ", the plugin file is:" << fileInfo.absoluteFilePath(); - if (lib->isLoaded()) - lib->unload(); - lib->deleteLater(); - return; - } - - /** - * @brief initPlugin 调用插件的Start接口正式启动插件 - * @param fileName 插件的文件名 - * @param name 插件名,通过Info接口解析得到 - * @param lib 解析插件的指针 - */ - auto initPlugin = [ = ] (const QString &fileName, const QString &name, QLibrary *lib) { - if (name.isEmpty() || !lib) - return; - - if (m_map.keys().contains(name)) { - qCDebug(plugin) << name << ": this plugin is already loaded."; - if (lib->isLoaded()) - lib->unload(); - lib->deleteLater(); - return; - } - - StartFun startFun = StartFun(lib->resolve("Start")); - if (!startFun) { - qCDebug(plugin) << fileName << ": failed to resolve the `Start` method"; - if (lib->isLoaded()) - lib->unload(); - lib->deleteLater(); - return; - } - - // 允许插件主动退出 - UnloadCallBack unloadCallBack = UnloadCallBack(lib->resolve("UnloadCallBack")); - if (unloadCallBack) { - unloadCallBack(&OnUnload); - } - - qDebug() << "load: " << name; - startFun(); - qDebug() << "load finished: " << name; - - QPair pair; - pair.first = fileName; - pair.second = lib; - m_map.insert(name, pair); - - QMetaObject::invokeMethod(this, "PluginLoaded", Qt::QueuedConnection, Q_ARG(QString, name)); - }; - - // 存在依赖的服务,等待服务启动后再执行初始化,只会在第一次启动后初始化 - if(!info.service.isEmpty()) { - if (QDBusConnection::sessionBus().interface()->isServiceRegistered(info.service)) { - initPlugin(fileInfo.fileName(), info.name, lib); - } else { - qCDebug(plugin) << "session service " << info.service << " not start, wait..."; - QDBusServiceWatcher *watcher = new QDBusServiceWatcher(info.service, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); - connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, [ = ] { - qCDebug(plugin) << "session service " << info.service << " started"; - initPlugin(fileInfo.fileName(), info.name, lib); - watcher->deleteLater(); - }); - } - } else { - initPlugin(fileInfo.fileName(), info.name, lib); - } -} - -/** - * @brief DBusManager::UnLoad 手动卸载指定插件 - * @param name 插件名,通过解析Info接口中的name字段得到 - * @return 是否卸载成功 - * @note 插件需要放置在loader进程父目录的lib文件夹下 - */ -void DBusManager::UnLoad(const QString &name) -{ - if (!m_map.keys().contains(name)) { - if (calledFromDBus()) - sendErrorReply(QDBusError::Failed, "This plugin is not loaded."); - return; - } - - QLibrary *lib = m_map.value(name).second; - if (!lib) { - if (calledFromDBus()) - sendErrorReply(QDBusError::Failed, "This plugin is not loaded."); - return; - } - - StopFun stopFun = StopFun(lib->resolve("Stop")); - if (!stopFun) { - if (calledFromDBus()) - sendErrorReply(QDBusError::Failed, "Failed to resolve the `Stop` method"); - return; - } - - qCDebug(plugin) << "unload: " << name; - stopFun(); - qCDebug(plugin) << "unload finished: " << name; - - if (lib->isLoaded()) - lib->unload(); - lib->deleteLater(); - - m_map.remove(name); - - Q_EMIT PluginUnLoaded(name); -} - -/** - * @brief DBusManager::IsRunning 判断插件当前是否正在运行 - * @param name 插件名,通过解析Info接口中的name字段得到 - * @return 是否正在运行 - * @note 插件未提供指定接口的会拒绝加载 - */ -bool DBusManager::IsRunning(const QString &name) -{ - return m_map.value(name).second; -} - -/** - * @brief DBusManager::PluginList 所有加载中的插件 - * @return 导出的为插件的name的集合 - */ -QStringList DBusManager::PluginList() -{ - return m_map.keys(); -} - -/** - * @brief DBusManager::getPluginPath 获取插件存放路径 - * @param type 系统级插件还是用户级插件目录 - * @return - */ -const QString DBusManager::getPluginPath() -{ -#ifdef QT_DEBUG - QDir dir = QDir::currentPath(); - dir.cd("plugins"); -#else - QDir dir("/usr/lib/dde-clipboard"); -#endif - return dir.absolutePath(); -} - -/** - * @brief DBusManager::resolveInfo 解析插件的信息 - * @param data 通过插件的Info接口获取的数据 - * @param info 结构体引用,解析后的数据会存放到结构体中 - */ -void DBusManager::resolveInfo(QByteArray data, DBusManager::PluginInfo &info) -{ - QJsonParseError err; - QJsonDocument doc = QJsonDocument::fromJson(data, &err); - if (err.error != QJsonParseError::NoError || !doc.isObject()) { - qCDebug(plugin) << "plugin info parse failed!!!"; - return; - } - - QJsonObject obj = doc.object(); - info.name = obj.value("name").toString(); - info.version = obj.value("version").toString(); - info.service = obj.value("service").toString(); - info.enabled = obj.value("enabled").toBool(); -} diff --git a/dde-clipboard-daemon/dbus_manager.h b/dde-clipboard-daemon/dbus_manager.h deleted file mode 100644 index 9607478..0000000 --- a/dde-clipboard-daemon/dbus_manager.h +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef DBUSMANAGER_H -#define DBUSMANAGER_H - -#include -#include -#include - -class QLibrary; -class DBusManager : public QObject, public QDBusContext -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.deepin.dde.Clipboard") - Q_CLASSINFO("D-Bus Path", "/com/deepin/dde/Clipboard") - -public: - static DBusManager *instance( QObject *parent = nullptr); - -public Q_SLOTS: - void Load(const QString &fileName); - void UnLoad(const QString &name); - bool IsRunning(const QString &name); - QStringList PluginList(); - void LoadAllPlugins(); - -Q_SIGNALS: - void PluginLoaded(const QString &name); - void PluginUnLoaded(const QString &name); - -private: - DBusManager( QObject *parent = nullptr); - ~ DBusManager(); - struct PluginInfo{ - QString name; - QString version; - QString service; - bool enabled = true; - }; - - const QString getPluginPath(); - void resolveInfo(QByteArray data, PluginInfo &info); - -private: - static DBusManager *m_instance; - QMap> m_map; -}; - -#endif // DBUSMANAGER_H diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/iteminfo.h b/dde-clipboard-daemon/iteminfo.h similarity index 100% rename from dde-clipboard-daemon/plugin/dde-clipboard-loader/src/iteminfo.h rename to dde-clipboard-daemon/iteminfo.h diff --git a/dde-clipboard-daemon/main.cpp b/dde-clipboard-daemon/main.cpp index f5a6ddf..593e047 100644 --- a/dde-clipboard-daemon/main.cpp +++ b/dde-clipboard-daemon/main.cpp @@ -3,15 +3,12 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include +#include #include -#include -#include -#include -#include #include -#include "dbus_manager.h" +#include "clipboarddaemon.h" DCORE_USE_NAMESPACE @@ -20,19 +17,20 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); a.setOrganizationName("deepin"); a.setApplicationName("dde-clipboard-daemon"); + DLogManager::registerConsoleAppender(); DLogManager::registerFileAppender(); - DBusManager *manager = DBusManager::instance(); - const QString &interface = "com.deepin.daemon.Clipboard"; - const QString &path = "/com/deepin/daemon/Clipboard"; - + const QString interface = "com.deepin.daemon.Clipboard"; + const QString path = "/com/deepin/daemon/Clipboard"; if (!QDBusConnection::sessionBus().registerService(interface)) { - qDebug() << "DBus register failed, error message:" << QDBusConnection::sessionBus().lastError().message(); + qWarning() << "DBus register failed, error message:" << QDBusConnection::sessionBus().lastError().message(); exit(-1); } - QDBusConnection::sessionBus().registerObject(path, manager, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals); - manager->LoadAllPlugins(); + + ClipboardDaemon daemon; + QDBusConnection::sessionBus().registerObject(path, &daemon, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals); qDebug() << "Everything is ok!"; + return a.exec(); -} +} \ No newline at end of file diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.cpp b/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.cpp deleted file mode 100644 index 776d5ec..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "clipboard_loader_plugin.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "clipboard_loader.h" - -static ClipboardLoader *worker = nullptr; -static UnloadFun unloadFun = nullptr; -static QByteArray info; -bool Start() -{ - QDBusConnection connection = QDBusConnection::sessionBus(); - if (!connection.registerService("com.deepin.dde.ClipboardLoader")) { - qDebug() << "error:" << connection.lastError().message(); - return false; - } - - if (!worker) { - worker = new ClipboardLoader; - } - - connection.registerObject("/com/deepin/dde/ClipboardLoader", worker, - QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals); - return true; -} - -bool Stop() -{ - QDBusConnection connection = QDBusConnection::sessionBus(); - if (!connection.unregisterService("com.deepin.dde.ClipboardLoader")) { - qDebug() << "error:" << connection.lastError().message(); - return false; - } - - if (worker) { - QDeferredDeleteEvent *event = new QDeferredDeleteEvent; - qApp->postEvent(worker, event); - worker = nullptr; - } - - if (unloadFun) { - unloadFun = nullptr; - } - - return true; -} - -const char *Info() -{ - if (info.isEmpty()) { - QVariantHash data; - data.insert("name","clipboard-loader"); - data.insert("version","1.0"); - data.insert("service",""); - data.insert("enabled", true); - QJsonObject rootObj = QJsonObject::fromVariantHash(data); - QJsonDocument document; - document.setObject(rootObj); - info = QString(document.toJson()).toLocal8Bit(); - } - - return info.data(); -} - -void UnloadCallBack(UnloadFun fun) -{ - unloadFun = fun; -} diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.h b/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.h deleted file mode 100644 index 9ad01c2..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin.h +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef CLIPBOARD_LOADER_PLUGIN_H -#define CLIPBOARD_LOADER_PLUGIN_H - -#include "clipboard_loader_plugin_global.h" - -typedef void (*UnloadFun)(const char *); - -extern "C" CLIPBOARDLOADERSHARED_EXPORT bool Start(); -extern "C" CLIPBOARDLOADERSHARED_EXPORT bool Stop(); -extern "C" CLIPBOARDLOADERSHARED_EXPORT const char *Info(); -extern "C" CLIPBOARDLOADERSHARED_EXPORT void UnloadCallBack(UnloadFun fun); - -#endif // CLIPBOARD_LOADER_PLUGIN_H diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin_global.h b/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin_global.h deleted file mode 100644 index c14ab41..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-loader/clipboard_loader_plugin_global.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef CLIPBOARD_LOADER_PLUGIN_GLOBAL_H -#define CLIPBOARD_LOADER_PLUGIN_GLOBAL_H - -#include - -#if defined(CLIPBOARD_LIBRARY) -# define CLIPBOARDLOADERSHARED_EXPORT Q_DECL_EXPORT -#else -# define CLIPBOARDLOADERSHARED_EXPORT Q_DECL_IMPORT -#endif - -#endif // CLIPBOARD_LOADER_PLUGIN_GLOBAL_H diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.cpp b/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.cpp deleted file mode 100644 index da5f67a..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifdef USE_DEEPIN_KF5_WAYLAND -#include "wayland_copy_client.h" - -#include "constants.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static QStringList imageMimeFormats(const QList &imageFormats) -{ - QStringList formats; - formats.reserve(imageFormats.size()); - for (const auto &format : imageFormats) - formats.append(QLatin1String("image/") + QLatin1String(format.toLower())); - - // put png at the front because it is best - int pngIndex = formats.indexOf(QLatin1String("image/png")); - if (pngIndex != -1 && pngIndex != 0) - formats.move(pngIndex, 0); - - return formats; -} - -static inline QStringList imageReadMimeFormats() -{ - return imageMimeFormats(QImageReader::supportedImageFormats()); -} - -static QByteArray getByteArray(QMimeData *mimeData, const QString &mimeType) -{ - QByteArray content; - if (mimeType == QLatin1String("text/plain")) { - content = mimeData->text().toUtf8(); - } else if (mimeData->hasImage() - && (mimeType == QLatin1String("application/x-qt-image") - || mimeType.startsWith(QLatin1String("image/")))) { - QImage image = qvariant_cast(mimeData->imageData()); - if (!image.isNull()) { - QBuffer buf; - buf.open(QIODevice::ReadWrite); - QByteArray fmt = "BMP"; - if (mimeType.startsWith(QLatin1String("image/"))) { - QByteArray imgFmt = mimeType.mid(6).toUpper().toLatin1(); - if (QImageWriter::supportedImageFormats().contains(imgFmt)) - fmt = imgFmt; - } - QImageWriter wr(&buf, fmt); - wr.write(image); - content = buf.buffer(); - } - } else if (mimeType == QLatin1String("application/x-color")) { - content = qvariant_cast(mimeData->colorData()).name().toLatin1(); - } else if (mimeType == QLatin1String("text/uri-list")) { - QList urls = mimeData->urls(); - for (int i = 0; i < urls.count(); ++i) { - content.append(urls.at(i).toEncoded()); - content.append('\n'); - } - } else { - content = mimeData->data(mimeType); - } - return content; -} - -DMimeData::DMimeData() -{ - -} - -DMimeData::~DMimeData() -{ - -} - -QVariant DMimeData::retrieveData(const QString &mimeType, QVariant::Type preferredType) const -{ - QVariant data = QMimeData::retrieveData(mimeType,preferredType); - if (mimeType == QLatin1String("application/x-qt-image")) { - if (data.isNull() || (data.userType() == QMetaType::QByteArray && data.toByteArray().isEmpty())) { - // try to find an image - QStringList imageFormats = imageReadMimeFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - data = QMimeData::retrieveData(imageFormats.at(i), preferredType); - if (data.isNull() || (data.userType() == QMetaType::QByteArray && data.toByteArray().isEmpty())) - continue; - break; - } - } - int typeId = static_cast(preferredType); - // we wanted some image type, but all we got was a byte array. Convert it to an image. - if (data.userType() == QMetaType::QByteArray - && (typeId == QMetaType::QImage || typeId == QMetaType::QPixmap || typeId == QMetaType::QBitmap)) - data = QImage::fromData(data.toByteArray()); - } else if (mimeType == QLatin1String("application/x-color") && data.userType() == QMetaType::QByteArray) { - QColor c; - QByteArray ba = data.toByteArray(); - if (ba.size() == 8) { - ushort * colBuf = (ushort *)ba.data(); - c.setRgbF(qreal(colBuf[0]) / qreal(0xFFFF), - qreal(colBuf[1]) / qreal(0xFFFF), - qreal(colBuf[2]) / qreal(0xFFFF), - qreal(colBuf[3]) / qreal(0xFFFF)); - data = c; - } else { - qWarning() << "Qt: Invalid color format"; - } - } else { - data = QMimeData::retrieveData(mimeType, preferredType); - } - return data; -} - -WaylandCopyClient::WaylandCopyClient(QObject *parent) - : QObject(parent) - , m_connectionThread(new QThread(this)) - , m_connectionThreadObject(new ConnectionThread()) - , m_eventQueue(nullptr) - , m_dataControlDeviceManager(nullptr) - , m_dataControlDevice(nullptr) - , m_copyControlSource(nullptr) - , m_mimeData(new DMimeData) - , m_seat(nullptr) -{ - -} - -WaylandCopyClient::~WaylandCopyClient() -{ - m_connectionThread->quit(); - m_connectionThread->wait(); - m_connectionThreadObject->deleteLater(); - if (m_mimeData) - m_mimeData->deleteLater(); -} - -WaylandCopyClient& WaylandCopyClient::ref() -{ - static WaylandCopyClient instance; - - return instance; -} - -void WaylandCopyClient::init() -{ - connect(m_connectionThreadObject, &ConnectionThread::connected, this, [this] { - m_eventQueue = new EventQueue(this); - m_eventQueue->setup(m_connectionThreadObject); - - Registry *registry = new Registry(this); - setupRegistry(registry); - }, Qt::QueuedConnection ); - m_connectionThreadObject->moveToThread(m_connectionThread); - m_connectionThread->start(); - m_connectionThreadObject->initConnection(); -} - -void WaylandCopyClient::setupRegistry(Registry *registry) -{ - connect(registry, &Registry::seatAnnounced, this, [this, registry] (quint32 name, quint32 version) { - m_seat = registry->createSeat(name, version, this); - }); - - connect(registry, &Registry::dataControlDeviceManagerAnnounced, this, [this, registry] (quint32 name, quint32 version) { - m_dataControlDeviceManager = registry->createDataControlDeviceManager(name, version, this); - m_dataControlDevice = m_dataControlDeviceManager->getDataDevice(m_seat, this); - - connect(m_dataControlDevice, &DataControlDeviceV1::selectionCleared, this, [&] { - m_copyControlSource = nullptr; - sendOffer(); - }); - - connect(m_dataControlDevice, &DataControlDeviceV1::dataOffered, this, &WaylandCopyClient::onDataOffered); - }); - - registry->setEventQueue(m_eventQueue); - registry->create(m_connectionThreadObject); - registry->setup(); -} - -void WaylandCopyClient::onDataOffered(KWayland::Client::DataControlOfferV1* offer) -{ - qDebug() << "data offered"; - if (!offer) - return; - - if (!m_mimeData) - m_mimeData = new DMimeData(); - m_mimeData->clear(); - - QList mimeTypeList = filterMimeType(offer->offeredMimeTypes()); - int mimeTypeCount = mimeTypeList.count(); - - // 将所有的数据插入到mime data中 - static QMutex setMimeDataMutex; - static int mimeTypeIndex = 0; - mimeTypeIndex = 0; - for (const QString &mimeType : mimeTypeList) { - int pipeFds[2]; - if (pipe(pipeFds) != 0) { - qWarning() << "Create pipe failed."; - return; - } - - // 根据mime类取数据,写入pipe中 - offer->receive(mimeType, pipeFds[1]); - close(pipeFds[1]); - // 异步从pipe中读取数据写入mime data中 - QtConcurrent::run([pipeFds, this, mimeType, mimeTypeCount] { - QFile readPipe; - if (readPipe.open(pipeFds[0], QIODevice::ReadOnly)) { - if (readPipe.isReadable()) { - const QByteArray &data = readPipe.readAll(); - if (!data.isEmpty()) { - // 需要加锁进行同步,否则可能会崩溃 - QMutexLocker locker(&setMimeDataMutex); - m_mimeData->setData(mimeType, data); - } else { - qWarning() << "Pipe data is empty, mime type: " << mimeType; - } - } else { - qWarning() << "Pipe is not readable"; - } - } else { - qWarning() << "Open pipe failed!"; - } - close(pipeFds[0]); - if (++mimeTypeIndex >= mimeTypeCount) { - qDebug() << "emit dataChanged"; - mimeTypeIndex = 0; - emit this->dataChanged(); - } - }); - } -} - -const QMimeData* WaylandCopyClient::mimeData() -{ - return m_mimeData; -} - -void WaylandCopyClient::setMimeData(QMimeData *mimeData) -{ - if (m_mimeData) - m_mimeData->deleteLater(); - - m_mimeData = mimeData; - sendOffer(); -} - -void WaylandCopyClient::sendOffer() -{ - m_copyControlSource = m_dataControlDeviceManager->createDataSource(this); - if (!m_copyControlSource) - return; - - connect(m_copyControlSource, &DataControlSourceV1::sendDataRequested, this, &WaylandCopyClient::onSendDataRequest); - for (const QString &format : m_mimeData->formats()) { - // 如果是application/x-qt-image类型则需要提供image的全部类型, 比如image/png - if (ApplicationXQtImageLiteral == format) { - QStringList imageFormats = imageReadMimeFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - m_copyControlSource->offer(imageFormats.at(i)); - } - continue; - } - m_copyControlSource->offer(format); - } - - m_dataControlDevice->setSelection(0, m_copyControlSource); - m_connectionThreadObject->flush(); -} - -void WaylandCopyClient::onSendDataRequest(const QString &mimeType, qint32 fd) const -{ - QFile f; - if (f.open(fd, QFile::WriteOnly, QFile::AutoCloseHandle)) { - const QByteArray &ba = getByteArray(m_mimeData, mimeType); - f.write(ba); - f.close(); - } -} - -QList WaylandCopyClient::filterMimeType(const QList &mimeTypeList) -{ - QList tmpList; - for (const QString &mimeType : mimeTypeList) { - // 根据窗管的要求,不读取纯大写、和不含'/'的字段,因为源窗口可能没有写入这些字段的数据,导致获取数据的线程一直等待。 - if ((mimeType.contains("/") && mimeType.toUpper() != mimeType) - || mimeType == "FROM_DEEPIN_CLIPBOARD_MANAGER" - || mimeType == "TIMESTAMP") { - tmpList.append(mimeType); - } - } - - return tmpList; -} -#endif diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.h b/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.h deleted file mode 100644 index cbd5b9a..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-loader/src/wayland_copy_client.h +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifdef USE_DEEPIN_KF5_WAYLAND -#ifndef WAYLANDCOPYCLIENT_H -#define WAYLANDCOPYCLIENT_H - -#include "iteminfo.h" - -#include -#include - -namespace KWayland -{ -namespace Client -{ -class ConnectionThread; -class EventQueue; -class Registry; -class Seat; -class DataControlDeviceManager; -class DataControlDeviceV1; -class DataControlSourceV1; -class DataControlOfferV1; -} //Client -} //KWayland - -using namespace KWayland::Client; - -class DMimeData : public QMimeData -{ -Q_OBJECT - -public: - DMimeData(); - ~DMimeData(); - virtual QVariant retrieveData(const QString &mimeType, - QVariant::Type preferredType) const; -}; - - -class WaylandCopyClient : public QObject -{ - Q_OBJECT - -public: - virtual ~WaylandCopyClient(); - - void init(); - const QMimeData *mimeData(); - void setMimeData(QMimeData *mimeData); - void sendOffer(); - static WaylandCopyClient& ref(); - -private: - explicit WaylandCopyClient(QObject *parent = nullptr); - - void setupRegistry(Registry *registry); - QList filterMimeType(const QList &mimeTypeList); - -Q_SIGNALS: - void dataChanged(); - -protected slots: - void onSendDataRequest(const QString &mimeType, qint32 fd) const; - void onDataOffered(DataControlOfferV1 *offer); - -private: - QThread *m_connectionThread; - ConnectionThread *m_connectionThreadObject; - EventQueue *m_eventQueue; - DataControlDeviceManager *m_dataControlDeviceManager; - DataControlDeviceV1 *m_dataControlDevice; - DataControlSourceV1 *m_copyControlSource; - QPointer m_mimeData; - Seat *m_seat; - ItemInfo m_itemInfo; -}; - -#endif // WAYLANDCOPYCLIENT_H -#endif diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.cpp b/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.cpp deleted file mode 100644 index a314214..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "clipboard_manager_plugin.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "waylandcopyclient.h" -#ifdef USE_DEEPIN_KF5_WAYLAND -static WaylandCopyClient *manager = nullptr; -#endif -static UnloadFun unloadFun = nullptr; -static QByteArray info; -bool Start() -{ - if (QGuiApplication::platformName().startsWith("wayland", Qt::CaseInsensitive)) { -#ifdef USE_DEEPIN_KF5_WAYLAND - manager = &WaylandCopyClient::ref(); - manager->init(); -#else - qWarning() << "we will not work with wayland"; -#endif - } - return true; -} - -bool Stop() -{ -#ifdef USE_DEEPIN_KF5_WAYLAND - if (manager) { - QDeferredDeleteEvent *event = new QDeferredDeleteEvent; - qApp->postEvent(manager, event); - manager = nullptr; - } -#endif - - if (unloadFun) { - unloadFun = nullptr; - } - - return true; -} - -const char *Info() -{ - if (info.isEmpty()) { - QVariantHash data; - data.insert("name","clipboard-manager"); - data.insert("version","1.0"); - data.insert("service",""); - data.insert("enabled", QGuiApplication::platformName().startsWith("wayland", Qt::CaseInsensitive)); - QJsonObject rootObj = QJsonObject::fromVariantHash(data); - QJsonDocument document; - document.setObject(rootObj); - info = QString(document.toJson()).toLocal8Bit(); - } - - return info.data(); -} - -void UnloadCallBack(UnloadFun fun) -{ - unloadFun = fun; -} diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.h b/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.h deleted file mode 100644 index 9206256..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin.h +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef CLIPBOARD_MANAGER_PLUGIN_H -#define CLIPBOARD_MANAGER_PLUGIN_H - -#include "clipboard_manager_plugin_global.h" - -typedef void (*UnloadFun)(const char *); - -extern "C" CLIPBOARDMANAGERSHARED_EXPORT bool Start(); -extern "C" CLIPBOARDMANAGERSHARED_EXPORT bool Stop(); -extern "C" CLIPBOARDMANAGERSHARED_EXPORT const char *Info(); -extern "C" CLIPBOARDMANAGERSHARED_EXPORT void UnloadCallBack(UnloadFun fun); - -#endif // CLIPBOARD_MANAGER_PLUGIN_H diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin_global.h b/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin_global.h deleted file mode 100644 index 59724e4..0000000 --- a/dde-clipboard-daemon/plugin/dde-clipboard-manager/clipboard_manager_plugin_global.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef CLIPBOARD_MANAGER_PLUGIN_GLOBAL_H -#define CLIPBOARD_MANAGER_PLUGIN_GLOBAL_H - -#include - -#if defined(CLIPBOARDMANAGER_LIBRARY) -# define CLIPBOARDMANAGERSHARED_EXPORT Q_DECL_EXPORT -#else -# define CLIPBOARDMANAGERSHARED_EXPORT Q_DECL_IMPORT -#endif - -#endif // CLIPBOARD_MANAGER_PLUGIN_GLOBAL_H diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-manager/src/waylandcopyclient.cpp b/dde-clipboard-daemon/waylandcopyclient.cpp similarity index 92% rename from dde-clipboard-daemon/plugin/dde-clipboard-manager/src/waylandcopyclient.cpp rename to dde-clipboard-daemon/waylandcopyclient.cpp index 47be8b5..c3c41b1 100644 --- a/dde-clipboard-daemon/plugin/dde-clipboard-manager/src/waylandcopyclient.cpp +++ b/dde-clipboard-daemon/waylandcopyclient.cpp @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later + #ifdef USE_DEEPIN_KF5_WAYLAND #include "waylandcopyclient.h" -//#include "constants.h" #include #include @@ -11,13 +11,11 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include @@ -138,7 +136,7 @@ WaylandCopyClient::WaylandCopyClient(QObject *parent) , m_dataControlDeviceManager(nullptr) , m_dataControlDevice(nullptr) , m_copyControlSource(nullptr) - , m_mimeData(new DMimeData) + , m_mimeData(new DMimeData()) , m_seat(nullptr) { @@ -149,17 +147,11 @@ WaylandCopyClient::~WaylandCopyClient() m_connectionThread->quit(); m_connectionThread->wait(); m_connectionThreadObject->deleteLater(); + if (m_mimeData) m_mimeData->deleteLater(); } -WaylandCopyClient& WaylandCopyClient::ref() -{ - static WaylandCopyClient instance; - - return instance; -} - void WaylandCopyClient::init() { connect(m_connectionThreadObject, &ConnectionThread::connected, this, [this] { @@ -172,6 +164,8 @@ void WaylandCopyClient::init() m_connectionThreadObject->moveToThread(m_connectionThread); m_connectionThread->start(); m_connectionThreadObject->initConnection(); + + // clipboard Manager的功能 connect(this, &WaylandCopyClient::dataChanged, this, &WaylandCopyClient::onDataChanged); } @@ -200,21 +194,23 @@ void WaylandCopyClient::setupRegistry(Registry *registry) void WaylandCopyClient::onDataOffered(KWayland::Client::DataControlOfferV1* offer) { - qDebug() << "data offered"; if (!offer) return; + QList mimeTypeList = filterMimeType(offer->offeredMimeTypes()); + if (mimeTypeList.isEmpty()) + return; + if (!m_mimeData) m_mimeData = new DMimeData(); m_mimeData->clear(); - QList mimeTypeList = filterMimeType(offer->offeredMimeTypes()); - int mimeTypeCount = mimeTypeList.count(); + static int readCount = 0; + static QMutex mimeDataLock; + readCount = 0; // 将所有的数据插入到mime data中 - static QMutex setMimeDataMutex; - static int mimeTypeIndex = 0; - mimeTypeIndex = 0; + int mimeTypeCount = mimeTypeList.count(); for (const QString &mimeType : mimeTypeList) { int pipeFds[2]; if (pipe(pipeFds) != 0) { @@ -225,6 +221,7 @@ void WaylandCopyClient::onDataOffered(KWayland::Client::DataControlOfferV1* offe // 根据mime类取数据,写入pipe中 offer->receive(mimeType, pipeFds[1]); close(pipeFds[1]); + // 异步从pipe中读取数据写入mime data中 QtConcurrent::run([pipeFds, this, mimeType, mimeTypeCount] { QFile readPipe; @@ -233,7 +230,7 @@ void WaylandCopyClient::onDataOffered(KWayland::Client::DataControlOfferV1* offe const QByteArray &data = readPipe.readAll(); if (!data.isEmpty()) { // 需要加锁进行同步,否则可能会崩溃 - QMutexLocker locker(&setMimeDataMutex); + QMutexLocker locker(&mimeDataLock); m_mimeData->setData(mimeType, data); } else { qWarning() << "Pipe data is empty, mime type: " << mimeType; @@ -244,10 +241,10 @@ void WaylandCopyClient::onDataOffered(KWayland::Client::DataControlOfferV1* offe } else { qWarning() << "Open pipe failed!"; } + close(pipeFds[0]); - if (++mimeTypeIndex >= mimeTypeCount) { - qDebug() << "emit dataChanged"; - mimeTypeIndex = 0; + if (++readCount >= mimeTypeCount) { + readCount = 0; emit this->dataChanged(); } }); @@ -264,11 +261,15 @@ const QMimeData* WaylandCopyClient::mimeData() return m_mimeData; } -void WaylandCopyClient::setMimeData(QMimeData *mimeData) { +void WaylandCopyClient::setMimeData(QMimeData *mimeData) +{ if (m_mimeData) m_mimeData->deleteLater(); + m_mimeData = mimeData; sendOffer(); + + Q_EMIT dataChanged(); } void WaylandCopyClient::sendOffer() @@ -296,7 +297,6 @@ void WaylandCopyClient::sendOffer() void WaylandCopyClient::onSendDataRequest(const QString &mimeType, qint32 fd) const { - qDebug() << "SendDataRequest" << endl; QFile f; if (f.open(fd, QFile::WriteOnly, QFile::AutoCloseHandle)) { const QByteArray &ba = getByteArray(m_mimeData, mimeType); @@ -305,14 +305,14 @@ void WaylandCopyClient::onSendDataRequest(const QString &mimeType, qint32 fd) co } } -QList WaylandCopyClient::filterMimeType(const QList &mimeTypeList) +QStringList WaylandCopyClient::filterMimeType(const QStringList &mimeTypeList) { - QList tmpList; + QStringList tmpList; for (const QString &mimeType : mimeTypeList) { // 根据窗管的要求,不读取纯大写、和不含'/'的字段,因为源窗口可能没有写入这些字段的数据,导致获取数据的线程一直等待。 if ((mimeType.contains("/") && mimeType.toUpper() != mimeType) - || mimeType == "FROM_DEEPIN_CLIPBOARD_MANAGER" - || mimeType == "TIMESTAMP") { + || mimeType == "FROM_DEEPIN_CLIPBOARD_MANAGER" + || mimeType == "TIMESTAMP") { tmpList.append(mimeType); } } diff --git a/dde-clipboard-daemon/plugin/dde-clipboard-manager/src/waylandcopyclient.h b/dde-clipboard-daemon/waylandcopyclient.h similarity index 93% rename from dde-clipboard-daemon/plugin/dde-clipboard-manager/src/waylandcopyclient.h rename to dde-clipboard-daemon/waylandcopyclient.h index d16cc47..71265c4 100644 --- a/dde-clipboard-daemon/plugin/dde-clipboard-manager/src/waylandcopyclient.h +++ b/dde-clipboard-daemon/waylandcopyclient.h @@ -1,12 +1,15 @@ // SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later + #ifdef USE_DEEPIN_KF5_WAYLAND #ifndef COPYCLIENT_H #define COPYCLIENT_H +#include #include #include +#include namespace KWayland { @@ -16,8 +19,8 @@ class ConnectionThread; class EventQueue; class Registry; class Seat; -class DataControlDeviceManager; class DataControlDeviceV1; +class DataControlDeviceManager; class DataControlSourceV1; class DataControlOfferV1; } //Client @@ -27,7 +30,7 @@ using namespace KWayland::Client; class DMimeData : public QMimeData { -Q_OBJECT + Q_OBJECT public: DMimeData(); ~DMimeData(); @@ -47,11 +50,10 @@ class WaylandCopyClient : public QObject const QMimeData *mimeData(); void setMimeData(QMimeData *mimeData); void sendOffer(); - static WaylandCopyClient& ref(); private: void setupRegistry(Registry *registry); - QList filterMimeType(const QList &mimeTypeList); + QStringList filterMimeType(const QStringList &mimeTypeList); Q_SIGNALS: void dataChanged();