From 00414eb7799e979a892d1e47555c3023b9ba2742 Mon Sep 17 00:00:00 2001 From: Alexey Kutepov Date: Sat, 25 Jan 2020 03:36:51 +0700 Subject: [PATCH] Synchronize Clipboard with Primary Selection on Linux when copying (#1502) * Introduce crossPlatformCopy() It sets the text of the clipboard and also syncs it with the selection clipboard if it is supported. Such behaviour is pretty common for X11 application on Unix-like Operating Systems. * Fix clang-format remarks * Fix weird clang-format config discrepancy between my machine and CI * Remove clipboard argument from crossPlatformCopy * Fix clang-format remarks --- chatterino.pro | 2 ++ src/util/Clipboard.cpp | 16 ++++++++++++++++ src/util/Clipboard.hpp | 9 +++++++++ src/widgets/helper/ChannelView.cpp | 28 ++++++++++++---------------- src/widgets/splits/Split.cpp | 3 ++- 5 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 src/util/Clipboard.cpp create mode 100644 src/util/Clipboard.hpp diff --git a/chatterino.pro b/chatterino.pro index 79d36ab60..23c6cc5ab 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -210,6 +210,7 @@ SOURCES += \ src/singletons/TooltipPreviewImage.cpp \ src/singletons/Updates.cpp \ src/singletons/WindowManager.cpp \ + src/util/Clipboard.cpp \ src/util/DebugCount.cpp \ src/util/FormatTime.cpp \ src/util/FunctionEventFilter.cpp \ @@ -412,6 +413,7 @@ HEADERS += \ src/singletons/Updates.hpp \ src/singletons/WindowManager.hpp \ src/util/Clamp.hpp \ + src/util/Clipboard.hpp \ src/util/CombinePath.hpp \ src/util/ConcurrentMap.hpp \ src/util/DebugCount.hpp \ diff --git a/src/util/Clipboard.cpp b/src/util/Clipboard.cpp new file mode 100644 index 000000000..c71014476 --- /dev/null +++ b/src/util/Clipboard.cpp @@ -0,0 +1,16 @@ +#include "util/Clipboard.hpp" +#include + +namespace chatterino { + +void crossPlatformCopy(const QString &text) +{ + auto clipboard = QApplication::clipboard(); + clipboard->setText(text); + if (clipboard->supportsSelection()) + { + clipboard->setText(text, QClipboard::Selection); + } +} + +} // namespace chatterino diff --git a/src/util/Clipboard.hpp b/src/util/Clipboard.hpp new file mode 100644 index 000000000..ff23a1f2d --- /dev/null +++ b/src/util/Clipboard.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace chatterino { + +void crossPlatformCopy(const QString &text); + +} // namespace chatterino diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 4ed079fd7..3fe02bfbe 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -28,6 +28,7 @@ #include "singletons/Theme.hpp" #include "singletons/TooltipPreviewImage.hpp" #include "singletons/WindowManager.hpp" +#include "util/Clipboard.hpp" #include "util/DistanceBetweenPoints.hpp" #include "util/IncognitoBrowser.hpp" #include "widgets/Scrollbar.hpp" @@ -64,9 +65,8 @@ namespace { if (!image->isEmpty()) { copyMenu->addAction( - QString(scale) + "x link", [url = image->url()] { - QApplication::clipboard()->setText(url.string); - }); + QString(scale) + "x link", + [url = image->url()] { crossPlatformCopy(url.string); }); openMenu->addAction( QString(scale) + "x link", [url = image->url()] { QDesktopServices::openUrl(QUrl(url.string)); @@ -84,9 +84,8 @@ namespace { openMenu->addSeparator(); copyMenu->addAction( - "Copy " + name + " emote link", [url = emote.homePage] { - QApplication::clipboard()->setText(url.string); // - }); + "Copy " + name + " emote link", + [url = emote.homePage] { crossPlatformCopy(url.string); }); openMenu->addAction( "Open " + name + " emote link", [url = emote.homePage] { QDesktopServices::openUrl(QUrl(url.string)); // @@ -124,9 +123,8 @@ ChannelView::ChannelView(BaseWidget *parent) }); auto shortcut = new QShortcut(QKeySequence("Ctrl+C"), this); - QObject::connect(shortcut, &QShortcut::activated, [this] { - QGuiApplication::clipboard()->setText(this->getSelectedText()); - }); + QObject::connect(shortcut, &QShortcut::activated, + [this] { crossPlatformCopy(this->getSelectedText()); }); this->clickTimer_ = new QTimer(this); this->clickTimer_->setSingleShot(true); @@ -1552,8 +1550,7 @@ void ChannelView::addContextMenuItems( menu->addAction("Open link incognito", [url] { openLinkIncognito(url); }); } - menu->addAction("Copy link", - [url] { QApplication::clipboard()->setText(url); }); + menu->addAction("Copy link", [url] { crossPlatformCopy(url); }); menu->addSeparator(); } @@ -1561,9 +1558,8 @@ void ChannelView::addContextMenuItems( // Copy actions if (!this->selection_.isEmpty()) { - menu->addAction("Copy selection", [this] { - QGuiApplication::clipboard()->setText(this->getSelectedText()); - }); + menu->addAction("Copy selection", + [this] { crossPlatformCopy(this->getSelectedText()); }); } menu->addAction("Copy message", [layout] { @@ -1571,14 +1567,14 @@ void ChannelView::addContextMenuItems( layout->addSelectionText(copyString, 0, INT_MAX, CopyMode::OnlyTextAndEmotes); - QGuiApplication::clipboard()->setText(copyString); + crossPlatformCopy(copyString); }); menu->addAction("Copy full message", [layout] { QString copyString; layout->addSelectionText(copyString); - QGuiApplication::clipboard()->setText(copyString); + crossPlatformCopy(copyString); }); // Open in new split. diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index 0a93b4888..6b285770b 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -10,6 +10,7 @@ #include "singletons/Settings.hpp" #include "singletons/Theme.hpp" #include "singletons/WindowManager.hpp" +#include "util/Clipboard.hpp" #include "util/Shortcut.hpp" #include "util/StreamLink.hpp" #include "widgets/Notebook.hpp" @@ -659,7 +660,7 @@ void Split::openSubPage() void Split::copyToClipboard() { - QApplication::clipboard()->setText(this->view_->getSelectedText()); + crossPlatformCopy(this->view_->getSelectedText()); } void Split::showSearch()