summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Persch <chpe@src.gnome.org>2022-09-01 18:34:03 +0200
committerChristian Persch <chpe@src.gnome.org>2022-09-01 18:34:03 +0200
commite4d500a302db008063f11fd95a984ed28b9d61f3 (patch)
tree9482016eec5decd52aa8aea75b969e4bb9f8a2b5
parentb72b397be45045bc5464ba8ed889f6fb2b39989a (diff)
downloadvte-e4d500a302db008063f11fd95a984ed28b9d61f3.tar.gz
widget: Offer text/html also in UTF-8 format
Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/2527
-rw-r--r--src/clipboard-gtk.cc63
1 files changed, 42 insertions, 21 deletions
diff --git a/src/clipboard-gtk.cc b/src/clipboard-gtk.cc
index 17597485..2d5a22b4 100644
--- a/src/clipboard-gtk.cc
+++ b/src/clipboard-gtk.cc
@@ -28,6 +28,7 @@
#include <utility>
#define MIME_TYPE_TEXT_PLAIN_UTF8 "text/plain;charset=utf-8"
+#define MIME_TYPE_TEXT_HTML_UTF8 "text/html;charset=utf-8"
#define MIME_TYPE_TEXT_HTML_UTF16 "text/html"
namespace vte::platform {
@@ -112,16 +113,23 @@ private:
break;
case ClipboardFormat::HTML: {
- auto [html, len] = text_to_utf16_mozilla(*str);
-
- // This makes yet another copy of the data... :(
- if (html) {
- gtk_selection_data_set(data,
- gtk_selection_data_get_target(data),
- // or gdk_atom_intern_static_string("text/html"),
- 16,
- reinterpret_cast<guchar const*>(html.get()),
- len);
+ auto const type = gtk_selection_data_get_data_type(data);
+
+ if (type == gdk_atom_intern_static_string(MIME_TYPE_TEXT_HTML_UTF8)) {
+ // This makes yet another copy of the data... :(
+ gtk_selection_data_set_text(data, str->data(), str->size());
+ } if (type == gdk_atom_intern_static_string(MIME_TYPE_TEXT_HTML_UTF16)) {
+ auto [html, len] = text_to_utf16_mozilla(*str);
+
+ // This makes yet another copy of the data... :(
+ if (html) {
+ gtk_selection_data_set(data,
+ gtk_selection_data_get_target(data),
+ // or gdk_atom_intern_static_string("text/html"),
+ 16,
+ reinterpret_cast<guchar const*>(html.get()),
+ len);
+ }
}
break;
}
@@ -195,7 +203,11 @@ private:
gtk_target_list_add_text_targets(list.get(),
vte::to_integral(ClipboardFormat::TEXT));
gtk_target_list_add(list.get(),
- gdk_atom_intern_static_string("text/html"),
+ gdk_atom_intern_static_string(MIME_TYPE_TEXT_HTML_UTF8),
+ 0,
+ vte::to_integral(ClipboardFormat::HTML));
+ gtk_target_list_add(list.get(),
+ gdk_atom_intern_static_string(MIME_TYPE_TEXT_HTML_UTF16),
0,
vte::to_integral(ClipboardFormat::HTML));
@@ -324,15 +336,21 @@ public:
}
case ClipboardFormat::HTML: {
- auto [html, len] = m_offer->text_to_utf16_mozilla(*str);
-
- // This makes yet another copy of the data... :(
- if (html) {
- bytes = vte::take_freeable(g_bytes_new_with_free_func(html.release(), len, g_free, nullptr));
- break;
- } else {
- return g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
- "Invalid data");
+ auto const type = std::string_view{mime_type};
+ if (type == MIME_TYPE_TEXT_HTML_UTF8) {
+ bytes = vte::take_freeable(g_bytes_new_with_free_func(g_strndup(str->data(), str->size()),
+ str->size(),
+ g_free, nullptr));
+ } else if (type == MIME_TYPE_TEXT_HTML_UTF16) {
+ auto [html, len] = m_offer->text_to_utf16_mozilla(*str);
+
+ if (html) {
+ bytes = vte::take_freeable(g_bytes_new_with_free_func(html.release(), len, g_free, nullptr));
+ break;
+ } else {
+ return g_task_return_new_error(task.get(), G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+ "Invalid data");
+ }
}
break;
@@ -404,6 +422,8 @@ private:
break;
case ClipboardFormat::HTML:
gdk_content_formats_builder_add_mime_type(builder.get(),
+ MIME_TYPE_TEXT_HTML_UTF8);
+ gdk_content_formats_builder_add_mime_type(builder.get(),
MIME_TYPE_TEXT_HTML_UTF16);
break;
case ClipboardFormat::INVALID:
@@ -419,7 +439,8 @@ private:
{
if (mime_type == MIME_TYPE_TEXT_PLAIN_UTF8)
return ClipboardFormat::TEXT;
- else if (mime_type == MIME_TYPE_TEXT_HTML_UTF16)
+ else if (mime_type == MIME_TYPE_TEXT_HTML_UTF8 ||
+ mime_type == MIME_TYPE_TEXT_HTML_UTF16)
return ClipboardFormat::HTML;
else
return ClipboardFormat::INVALID;