mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-31 07:52:06 +00:00
Revert "Use gtk clipboard when available to avoid https://bugreports.qt.io/browse/QTBUG-56595"
Fixed in Qt by https://codereview.qt-project.org/c/qt/qtbase/+/306771
This reverts commit 3a91003eea
.
This commit is contained in:
parent
ea3191badf
commit
414456d003
Telegram
@ -1298,8 +1298,6 @@ else()
|
||||
if (NOT DESKTOP_APP_DISABLE_X11_INTEGRATION)
|
||||
target_link_libraries(Telegram PRIVATE X11)
|
||||
endif()
|
||||
|
||||
target_link_libraries(Telegram PRIVATE rt)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -67,10 +67,7 @@ auto ListFromMimeData(not_null<const QMimeData*> data) {
|
||||
if (result.error == Error::None) {
|
||||
return result;
|
||||
} else if (data->hasImage()) {
|
||||
auto image = Platform::GetImageFromClipboard();
|
||||
if (image.isNull()) {
|
||||
image = qvariant_cast<QImage>(data->imageData());
|
||||
}
|
||||
auto image = qvariant_cast<QImage>(data->imageData());
|
||||
if (!image.isNull()) {
|
||||
return Storage::PrepareMediaFromImage(
|
||||
std::move(image),
|
||||
|
@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/send_files_box.h"
|
||||
|
||||
#include "platform/platform_specific.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
@ -799,10 +798,7 @@ bool SendFilesBox::addFiles(not_null<const QMimeData*> data) {
|
||||
if (result.error == Ui::PreparedList::Error::None) {
|
||||
return result;
|
||||
} else if (data->hasImage()) {
|
||||
auto image = Platform::GetImageFromClipboard();
|
||||
if (image.isNull()) {
|
||||
image = qvariant_cast<QImage>(data->imageData());
|
||||
}
|
||||
auto image = qvariant_cast<QImage>(data->imageData());
|
||||
if (!image.isNull()) {
|
||||
return Storage::PrepareMediaFromImage(
|
||||
std::move(image),
|
||||
|
@ -88,7 +88,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "chat_helpers/bot_keyboard.h"
|
||||
#include "chat_helpers/message_field.h"
|
||||
#include "chat_helpers/send_context_menu.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "mtproto/mtproto_config.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwidget.h"
|
||||
@ -4491,10 +4490,7 @@ bool HistoryWidget::confirmSendingFiles(
|
||||
}
|
||||
|
||||
if (hasImage) {
|
||||
auto image = Platform::GetImageFromClipboard();
|
||||
if (image.isNull()) {
|
||||
image = qvariant_cast<QImage>(data->imageData());
|
||||
}
|
||||
auto image = qvariant_cast<QImage>(data->imageData());
|
||||
if (!image.isNull()) {
|
||||
confirmSendingFiles(
|
||||
std::move(image),
|
||||
|
@ -55,7 +55,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "storage/storage_media_prepare.h"
|
||||
#include "storage/storage_account.h"
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "facades.h"
|
||||
#include "styles/style_chat.h"
|
||||
@ -598,10 +597,7 @@ bool RepliesWidget::confirmSendingFiles(
|
||||
}
|
||||
|
||||
if (hasImage) {
|
||||
auto image = Platform::GetImageFromClipboard();
|
||||
if (image.isNull()) {
|
||||
image = qvariant_cast<QImage>(data->imageData());
|
||||
}
|
||||
auto image = qvariant_cast<QImage>(data->imageData());
|
||||
if (!image.isNull()) {
|
||||
confirmSendingFiles(
|
||||
std::move(image),
|
||||
|
@ -48,7 +48,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "storage/storage_media_prepare.h"
|
||||
#include "storage/storage_account.h"
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "facades.h"
|
||||
#include "styles/style_chat.h"
|
||||
@ -338,10 +337,7 @@ bool ScheduledWidget::confirmSendingFiles(
|
||||
}
|
||||
|
||||
if (hasImage) {
|
||||
auto image = Platform::GetImageFromClipboard();
|
||||
if (image.isNull()) {
|
||||
image = qvariant_cast<QImage>(data->imageData());
|
||||
}
|
||||
auto image = qvariant_cast<QImage>(data->imageData());
|
||||
if (!image.isNull()) {
|
||||
confirmSendingFiles(
|
||||
std::move(image),
|
||||
|
@ -32,10 +32,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <giomm.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace Platform {
|
||||
namespace internal {
|
||||
|
||||
@ -49,7 +45,6 @@ constexpr auto kBaseService = "org.telegram.desktop.BaseGtkIntegration-%1"_cs;
|
||||
constexpr auto kWebviewService = "org.telegram.desktop.GtkIntegration.WebviewHelper-%1-%2"_cs;
|
||||
constexpr auto kObjectPath = "/org/telegram/desktop/GtkIntegration"_cs;
|
||||
constexpr auto kInterface = "org.telegram.desktop.GtkIntegration"_cs;
|
||||
constexpr auto kGifcShmId = "tdesktop-gtk-gifc"_cs;
|
||||
|
||||
constexpr auto kIntrospectionXML = R"INTROSPECTION(<node>
|
||||
<interface name='org.telegram.desktop.GtkIntegration'>
|
||||
@ -60,74 +55,14 @@ constexpr auto kIntrospectionXML = R"INTROSPECTION(<node>
|
||||
<arg type='s' name='parent' direction='in'/>
|
||||
<arg type='s' name='filepath' direction='in'/>
|
||||
</method>
|
||||
<method name='GetImageFromClipboard'>
|
||||
<arg type='h' name='shm-descriptor' direction='out'/>
|
||||
<arg type='i' name='shm-size' direction='out'/>
|
||||
</method>
|
||||
<signal name='OpenWithDialogResponse'>
|
||||
<arg type='b' name='result' direction='out'/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>)INTROSPECTION"_cs;
|
||||
|
||||
struct GtkSelectionDataDeleter {
|
||||
void operator()(GtkSelectionData *gsel) {
|
||||
if (gsel) {
|
||||
gtk_selection_data_free(gsel);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using GtkSelectionDataPointer = std::unique_ptr<GtkSelectionData, GtkSelectionDataDeleter>;
|
||||
|
||||
Glib::ustring ServiceName;
|
||||
|
||||
bool GetImageFromClipboardSupported() {
|
||||
return (gtk_clipboard_get != nullptr)
|
||||
&& (gtk_clipboard_wait_for_contents != nullptr)
|
||||
&& (gtk_selection_data_get_data != nullptr)
|
||||
&& (gtk_selection_data_get_length != nullptr)
|
||||
&& (gtk_selection_data_free != nullptr)
|
||||
&& (gdk_atom_intern != nullptr);
|
||||
}
|
||||
|
||||
std::vector<uchar> GetImageFromClipboard() {
|
||||
if (!GetImageFromClipboardSupported()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
if (!clipboard) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static const auto supportedFormats = {
|
||||
gdk_atom_intern("image/png", true),
|
||||
gdk_atom_intern("image/jpeg", true),
|
||||
gdk_atom_intern("image/gif", true),
|
||||
gdk_atom_intern("image/bmp", true),
|
||||
};
|
||||
|
||||
const auto gsel = [&]() -> GtkSelectionDataPointer {
|
||||
for (const auto &format : supportedFormats) {
|
||||
if (auto result = GtkSelectionDataPointer(
|
||||
gtk_clipboard_wait_for_contents(clipboard, format))
|
||||
; result && gtk_selection_data_get_length(result.get()) > 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}();
|
||||
|
||||
if (!gsel) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto data = gtk_selection_data_get_data(gsel.get());
|
||||
const auto length = gtk_selection_data_get_length(gsel.get());
|
||||
return std::vector<uchar>(data, data + length);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class GtkIntegration::Private {
|
||||
@ -226,57 +161,6 @@ void GtkIntegration::Private::handleMethodCall(
|
||||
invocation->return_value({});
|
||||
return;
|
||||
}
|
||||
} else if (method_name == "GetImageFromClipboard") {
|
||||
const auto image = GetImageFromClipboard();
|
||||
if (!image.empty()) {
|
||||
const auto fd = shm_open(
|
||||
kGifcShmId.utf8().constData(),
|
||||
O_RDWR | O_CREAT,
|
||||
S_IRUSR | S_IWUSR);
|
||||
|
||||
if (fd == -1) {
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
const auto fdGuard = gsl::finally([&] {
|
||||
close(fd);
|
||||
shm_unlink(kGifcShmId.utf8().constData());
|
||||
});
|
||||
|
||||
if (ftruncate(fd, image.size())) {
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
const auto mapped = mmap(
|
||||
nullptr,
|
||||
image.size(),
|
||||
PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
0);
|
||||
|
||||
if (mapped == MAP_FAILED) {
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
const auto mappedGuard = gsl::finally([&] {
|
||||
munmap(mapped, image.size());
|
||||
});
|
||||
|
||||
memcpy(mapped, image.data(), image.size());
|
||||
|
||||
const auto fdList = Gio::UnixFDList::create();
|
||||
fdList->append(fd);
|
||||
|
||||
invocation->return_value(
|
||||
Glib::VariantContainerBase::create_tuple({
|
||||
Glib::wrap(g_variant_new_handle(0)),
|
||||
Glib::Variant<int>::create(image.size()),
|
||||
}),
|
||||
fdList);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
@ -350,18 +234,11 @@ void GtkIntegration::load(const QString &allowedBackends) {
|
||||
LOAD_GTK_SYMBOL(lib, gtk_widget_get_window);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_widget_realize);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_widget_destroy);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_clipboard_get);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_clipboard_wait_for_contents);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_selection_data_get_data);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_selection_data_get_length);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_selection_data_free);
|
||||
|
||||
LOAD_GTK_SYMBOL(lib, gtk_app_chooser_dialog_new);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_app_chooser_get_app_info);
|
||||
LOAD_GTK_SYMBOL(lib, gtk_app_chooser_get_type);
|
||||
|
||||
LOAD_GTK_SYMBOL(lib, gdk_atom_intern);
|
||||
|
||||
GdkHelperLoad(lib);
|
||||
Loaded = true;
|
||||
}
|
||||
@ -508,69 +385,6 @@ bool GtkIntegration::showOpenWithDialog(const QString &filepath) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
QImage GtkIntegration::getImageFromClipboard() const {
|
||||
if (_private->remoting) {
|
||||
if (!_private->dbusConnection) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
Glib::RefPtr<Gio::UnixFDList> outFdList;
|
||||
|
||||
const auto loop = Glib::MainLoop::create();
|
||||
Glib::VariantContainerBase reply;
|
||||
_private->dbusConnection->call(
|
||||
std::string(kObjectPath),
|
||||
std::string(kInterface),
|
||||
"GetImageFromClipboard",
|
||||
{},
|
||||
[&](const Glib::RefPtr<Gio::AsyncResult> &result) {
|
||||
try {
|
||||
reply = _private->dbusConnection->call_finish(
|
||||
result,
|
||||
outFdList);
|
||||
} catch (...) {
|
||||
}
|
||||
loop->quit();
|
||||
},
|
||||
ServiceName);
|
||||
|
||||
loop->run();
|
||||
|
||||
if (!reply) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto dataSize = base::Platform::GlibVariantCast<int>(
|
||||
reply.get_child(1));
|
||||
|
||||
const auto mapped = mmap(
|
||||
nullptr,
|
||||
dataSize,
|
||||
PROT_READ,
|
||||
MAP_SHARED,
|
||||
outFdList->get(0),
|
||||
0);
|
||||
|
||||
if (mapped == MAP_FAILED) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uchar> result(dataSize);
|
||||
memcpy(result.data(), mapped, result.size());
|
||||
munmap(mapped, result.size());
|
||||
|
||||
return QImage::fromData(result.data(), result.size());
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto result = GetImageFromClipboard();
|
||||
return QImage::fromData(result.data(), result.size());
|
||||
}
|
||||
|
||||
QString GtkIntegration::AllowedBackends() {
|
||||
return Platform::IsWayland()
|
||||
? qsl("wayland,x11")
|
||||
|
@ -25,8 +25,6 @@ public:
|
||||
|
||||
[[nodiscard]] bool showOpenWithDialog(const QString &filepath) const;
|
||||
|
||||
[[nodiscard]] QImage getImageFromClipboard() const;
|
||||
|
||||
static QString AllowedBackends();
|
||||
|
||||
static int Exec(
|
||||
|
@ -33,10 +33,6 @@ bool GtkIntegration::showOpenWithDialog(const QString &filepath) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
QImage GtkIntegration::getImageFromClipboard() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString GtkIntegration::AllowedBackends() {
|
||||
return {};
|
||||
}
|
||||
|
@ -19,15 +19,9 @@ inline void (*gtk_widget_show)(GtkWidget *widget) = nullptr;
|
||||
inline GdkWindow* (*gtk_widget_get_window)(GtkWidget *widget) = nullptr;
|
||||
inline void (*gtk_widget_realize)(GtkWidget *widget) = nullptr;
|
||||
inline void (*gtk_widget_destroy)(GtkWidget *widget) = nullptr;
|
||||
inline GtkClipboard* (*gtk_clipboard_get)(GdkAtom selection) = nullptr;
|
||||
inline GtkSelectionData* (*gtk_clipboard_wait_for_contents)(GtkClipboard *clipboard, GdkAtom target) = nullptr;
|
||||
inline const guchar* (*gtk_selection_data_get_data)(const GtkSelectionData *selection_data) = nullptr;
|
||||
inline gint (*gtk_selection_data_get_length)(const GtkSelectionData *selection_data) = nullptr;
|
||||
inline void (*gtk_selection_data_free)(GtkSelectionData *data) = nullptr;
|
||||
inline GType (*gtk_app_chooser_get_type)(void) G_GNUC_CONST = nullptr;
|
||||
inline GtkWidget* (*gtk_app_chooser_dialog_new)(GtkWindow *parent, GtkDialogFlags flags, GFile *file) = nullptr;
|
||||
inline GAppInfo* (*gtk_app_chooser_get_app_info)(GtkAppChooser *self) = nullptr;
|
||||
inline GdkAtom (*gdk_atom_intern)(const gchar *atom_name, gboolean only_if_exists) = nullptr;
|
||||
|
||||
} // namespace Gtk
|
||||
} // namespace Platform
|
||||
|
@ -513,14 +513,6 @@ QString GetIconName() {
|
||||
return Result;
|
||||
}
|
||||
|
||||
QImage GetImageFromClipboard() {
|
||||
if (const auto integration = GtkIntegration::Instance()) {
|
||||
return integration->getImageFromClipboard();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<bool> IsDarkMode() {
|
||||
return Core::App().settings().systemDarkMode();
|
||||
}
|
||||
|
@ -18,10 +18,6 @@ namespace Platform {
|
||||
|
||||
[[nodiscard]] bool IsDarkMenuBar();
|
||||
|
||||
inline QImage GetImageFromClipboard() {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline bool AutostartSupported() {
|
||||
return false;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ void IgnoreApplicationActivationRightNow();
|
||||
bool AutostartSupported();
|
||||
bool TrayIconSupported();
|
||||
bool SkipTaskbarSupported();
|
||||
[[nodiscard]] QImage GetImageFromClipboard();
|
||||
void WriteCrashDumpDetails();
|
||||
|
||||
[[nodiscard]] std::optional<bool> IsDarkMode();
|
||||
|
@ -19,10 +19,6 @@ namespace Platform {
|
||||
inline void IgnoreApplicationActivationRightNow() {
|
||||
}
|
||||
|
||||
inline QImage GetImageFromClipboard() {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline bool TrayIconSupported() {
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user