Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/dfm-base/dfm-base.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ find_package(dfm${DTK_VERSION_MAJOR}-burn REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(gio REQUIRED gio-unix-2.0 IMPORTED_TARGET)
pkg_check_modules(mount REQUIRED mount IMPORTED_TARGET)
pkg_check_modules(PC_XCB REQUIRED xcb)

set(XCB_INCLUDE_DIRS ${PC_XCB_INCLUDE_DIRS})
set(XCB_LIBRARIES ${PC_XCB_LIBRARIES})
set(XCB_DEFINITIONS ${PC_XCB_CFLAGS_OTHER})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(XCB DEFAULT_MSG XCB_LIBRARIES XCB_INCLUDE_DIRS)

pkg_search_module(X11 REQUIRED x11 IMPORTED_TARGET)
if(${QT_VERSION_MAJOR} EQUAL "6")
Expand Down Expand Up @@ -107,8 +99,6 @@ target_link_libraries(${BIN_NAME}
PkgConfig::gio
PkgConfig::X11
poppler-cpp
${XCB_LIBRARIES}
xcb-xfixes
${DFM_EXTRA_LIBRARIES}
)

Expand Down
112 changes: 15 additions & 97 deletions src/dfm-base/utils/clipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@
#include <dfm-base/dfm_global_defines.h>
#include <dfm-base/utils/systempathutil.h>
#include <dfm-base/file/local/localfileiconprovider.h>
#include <dfm-base/mimetype/mimetypedisplaymanager.h>

Check warning on line 12 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dfm-base/mimetype/mimetypedisplaymanager.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 12 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <dfm-base/mimetype/mimetypedisplaymanager.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <dfm-base/utils/fileutils.h>

Check warning on line 13 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dfm-base/utils/fileutils.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 13 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <dfm-base/utils/fileutils.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <dfm-base/widgets/filemanagerwindowsmanager.h>

Check warning on line 14 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dfm-base/widgets/filemanagerwindowsmanager.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 14 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <dfm-base/widgets/filemanagerwindowsmanager.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <dfm-base/utils/clipboardmonitor.h>
#include <dfm-base/utils/windowutils.h>

#include <QApplication>

Check warning on line 16 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QApplication> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 16 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QApplication> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QClipboard>

Check warning on line 17 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QClipboard> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 17 in src/dfm-base/utils/clipboard.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QClipboard> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QMimeData>
#include <QMutex>
#include <QDebug>
Expand All @@ -36,54 +34,51 @@
static QAtomicInt remoteCurrentCount = 0;
static ClipBoard::ClipboardAction clipboardAction = ClipBoard::kUnknownAction;
static std::atomic_bool canReadClipboard { true };
static std::atomic_bool hasUosRemote { false };
static ClipboardMonitor *clipMonitor { nullptr };
static std::atomic_bool isX11 { false };

static constexpr char kUserIdKey[] = "userId";
static constexpr char kRemoteCopyKey[] = "uos/remote-copy";
static constexpr char kGnomeCopyKey[] = "x-special/gnome-copied-files";
static constexpr char kRemoteAssistanceCopyKey[] = "uos/remote-copied-files";

void onClipboardDataChanged(const QStringList &formats)
void onClipboardDataChanged()
{
if (!canReadClipboard)
return;

QMutexLocker lk(&clipboardFileUrlsMutex);
clipboardFileUrls.clear();

if (formats.isEmpty()) {
qCWarning(logDFMBase) << "Clipboard data changed with empty mime formats";
const QMimeData *mimeData = qApp->clipboard()->mimeData();
if (!mimeData || mimeData->formats().isEmpty()) {
qCWarning(logDFMBase) << "get null mimeData from QClipBoard or remote formats is null!";
return;
}

if (formats.contains(kRemoteCopyKey) || hasUosRemote) {
qCInfo(logDFMBase) << "Clipboard action set to remote copy mode";
if (mimeData->hasFormat(kRemoteCopyKey)) {
qCWarning(logDFMBase) << "clipboard use other !";
clipboardAction = ClipBoard::kRemoteAction;
remoteCurrentCount++;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Incrementing QAtomicInt with ++ may not convey memory ordering

Prefer using an explicit atomic method such as fetchAndAddRelaxed(1) to make memory ordering intentions clear.

Suggested change
remoteCurrentCount++;
remoteCurrentCount.fetchAndAddRelaxed(1);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert不对原逻辑改动

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这条建议只是从“风格和可读性”角度来提:

QAtomicInt 的 “++” 操作确实会原子加一,但它的内存顺序语义是隐含的。为了让代码读起来更直观,也更明确地表达“这里不需要强制的 acquire/release,仅仅是一个放宽版的原子加一”,我们才推荐把

remoteCurrentCount++;

改成

remoteCurrentCount.fetchAndAddRelaxed(1);

两者在功能上是一致的,不会改变现有逻辑。如果你觉得“++”已经足够且更简洁,也完全可以保留,PR 的 revert 本身也不影响这部分行为。只是为了后续维护时一看就知道“这是个 relax(宽松)模式的原子加一”,才建议显式调用 fetchAndAddRelaxed

return;
}
// 远程协助功能
if (formats.contains(kRemoteAssistanceCopyKey)) {
qCInfo(logDFMBase) << "Remote assistance copy action detected";
if (mimeData->hasFormat(kRemoteAssistanceCopyKey)) {
qCInfo(logDFMBase) << "Remote copy: set remote copy action";
clipboardAction = ClipBoard::kRemoteCopiedAction;
return;
}
if (!formats.contains(kGnomeCopyKey)) {
qCWarning(logDFMBase) << "Missing required gnome copy key in clipboard formats:" << formats;
// 没有文件拷贝
if (!mimeData->hasFormat(kGnomeCopyKey)) {
qCWarning(logDFMBase) << "no kGnomeCopyKey target in mimedata formats!";
clipboardAction = ClipBoard::kUnknownAction;
return;
}
const QMimeData *mimeData = qApp->clipboard()->mimeData();
const QString &data = mimeData->data(kGnomeCopyKey);
const static QRegularExpression regCut("cut\nfile://"), regCopy("copy\nfile://");
if (data.contains(regCut)) {
clipboardAction = ClipBoard::kCutAction;
} else if (data.contains(regCopy)) {
clipboardAction = ClipBoard::kCopyAction;
} else {
qCWarning(logDFMBase) << "Invalid gnome copy key data format:" << data << "available formats:" << mimeData->formats();
qCWarning(logDFMBase) << "wrong kGnomeCopyKey data = " << data;
clipboardAction = ClipBoard::kUnknownAction;
}

Expand All @@ -97,15 +92,8 @@
ClipBoard::ClipBoard(QObject *parent)
: QObject(parent)
{
init();
}

void ClipBoard::init()
{
QLibrary library("libdisplayjack-clipboard.so");
qCDebug(logDFMBase) << "Initializing clipboard with library:" << library.fileName();
connect(qApp->clipboard(), &QClipboard::dataChanged, this, [this]() {
onClipboardDataChanged(qApp->clipboard()->mimeData()->formats());
onClipboardDataChanged();
emit clipboardDataChanged();
});

Expand All @@ -116,20 +104,6 @@
connect(&FileManagerWindowsManager::instance(), &FileManagerWindowsManager::lastWindowClosed, this, [] {
GlobalData::canReadClipboard = false;
});

if (!WindowUtils ::isWayLand() || !library.load())
return;

library.unload();
qCInfo(logDFMBase) << "X11 clipboard monitor initialized successfully";
GlobalData::isX11 = true;
GlobalData::clipMonitor = new ClipboardMonitor;
connect(GlobalData::clipMonitor, &ClipboardMonitor::clipboardChanged, this, [](const QStringList &formats) {
qCDebug(logDFMBase) << "X11 clipboard formats changed:" << formats;
GlobalData::hasUosRemote = formats.contains(GlobalData::kRemoteCopyKey);
});

GlobalData::clipMonitor->start();
}

ClipBoard *ClipBoard::instance()
Expand Down Expand Up @@ -340,21 +314,6 @@
setUrlsToClipboard(clipboardUrls, action);
}

void ClipBoard::readFirstClipboard()
{
QStringList mime;
if (GlobalData::isX11) {
static bool first = false;
if (first)
return;
first = true;
mime = getFirstMimeTypesByX11();
} else {
mime = qApp->clipboard()->mimeData()->formats();
}

onClipboardDataChanged(mime);
}
/*!
* \brief ClipBoard::getUrlsByX11 Use X11 to read URLs downloaded
* remotely from the clipboard
Expand Down Expand Up @@ -492,48 +451,7 @@
return clipboardFileUrls;
}

QStringList ClipBoard::getFirstMimeTypesByX11()
{
// 使用x11创建一个窗口去阻塞获取URl
Display *display = XOpenDisplay(nullptr);
unsigned long color = BlackPixel(display, DefaultScreen(display));
Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, 1, 1, 0, color, color);

char *result = nullptr;
unsigned long ressize = 0, restail = 0;
int resbits;
Atom bufid = XInternAtom(display, "CLIPBOARD", False),
fmtid = XInternAtom(display, "TARGETS", False),
propid = XInternAtom(display, "XSEL_DATA", False);
XEvent event;

QList<QUrl> urls;
QString results;

XSelectInput(display, window, PropertyChangeMask);
XConvertSelection(display, bufid, fmtid, propid, window, CurrentTime);
QList<QUrl> currentClipboardFileUrls;
do {
XNextEvent(display, &event);
} while (event.type != SelectionNotify || event.xselection.selection != bufid);

XGetWindowProperty(display, window, propid, 0, LONG_MAX / 4, True, AnyPropertyType,
&fmtid, &resbits, &ressize, &restail, reinterpret_cast<unsigned char **>(&result));
QStringList formats;
if (resbits == 32 && ressize > 0) {
Atom *atoms = reinterpret_cast<Atom *>(result);
for (int i = 0; i < static_cast<int>(ressize); i++) {
formats.append(XGetAtomName(display, atoms[i]));
}
qCWarning(logDFMBase) << "X11 clipboard first read formats:" << formats;
}
XFree(result);
XDestroyWindow(display, window);
XCloseDisplay(display);
return formats;
}

void ClipBoard::onClipboardDataChanged(const QStringList &mimeTypes)
void ClipBoard::onClipboardDataChanged()
{
GlobalData::onClipboardDataChanged(mimeTypes);
GlobalData::onClipboardDataChanged();
}
6 changes: 1 addition & 5 deletions src/dfm-base/utils/clipboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
class QMimeData;
class QUrl;
namespace dfmbase {
class ClipboardMonitor;
class ClipBoard : public QObject
{
Q_OBJECT
Expand Down Expand Up @@ -41,20 +40,17 @@
ClipboardAction clipboardAction() const;
void removeUrls(const QList<QUrl> &urls);
void replaceClipboardUrl(const QUrl &oldUrl, const QUrl &newUrl);
void readFirstClipboard();

private:
explicit ClipBoard(QObject *parent = nullptr);
void init();
virtual ~ClipBoard() = default;
static QList<QUrl> getUrlsByX11();
QStringList getFirstMimeTypesByX11();

Q_SIGNALS:
void clipboardDataChanged();

public Q_SLOTS:

Check warning on line 52 in src/dfm-base/utils/clipboard.h

View workflow job for this annotation

GitHub Actions / cppcheck

There is an unknown macro here somewhere. Configuration is required. If Q_SLOTS is a macro then please configure it.

Check warning on line 52 in src/dfm-base/utils/clipboard.h

View workflow job for this annotation

GitHub Actions / static-check / static-check

There is an unknown macro here somewhere. Configuration is required. If Q_SLOTS is a macro then please configure it.
void onClipboardDataChanged(const QStringList & mimeTypes);
void onClipboardDataChanged();
};
} // namespace dfmbase
Q_DECLARE_METATYPE(DFMBASE_NAMESPACE::ClipBoard::ClipboardAction)
Expand Down
Loading
Loading