diff --git a/client/displayservers/Wayland/clipboard.c b/client/displayservers/Wayland/clipboard.c index c0bbbed3..7559acda 100644 --- a/client/displayservers/Wayland/clipboard.c +++ b/client/displayservers/Wayland/clipboard.c @@ -41,8 +41,13 @@ struct DataOffer { static const char * textMimetypes[] = { - "text/plain", "text/plain;charset=utf-8", + "text/plain", + NULL, +}; + +static const char * textMimetypeAliases[] = +{ "TEXT", "STRING", "UTF8_STRING", @@ -128,9 +133,15 @@ static bool mimetypeEndswith(const char * mimetype, const char * what) return !strcmp(mimetype + mimetypeLen - whatLen, what); } +static bool isPlainTextMimetype(const char * mimetype) +{ + return containsMimetype(textMimetypes, mimetype) || + containsMimetype(textMimetypeAliases, mimetype); +} + static bool isTextMimetype(const char * mimetype) { - if (containsMimetype(textMimetypes, mimetype)) + if (isPlainTextMimetype(mimetype)) return true; if (!strcmp(mimetype, "text/ico")) @@ -437,7 +448,7 @@ static void dataOfferHandleOffer(void * opaque, struct wl_data_offer * offer, // text/html represents rich text format, which is almost never desirable when // and should not be used when a plain text or image format is available. - if ((isImageCbtype(type) || containsMimetype(textMimetypes, mimetype)) && + if ((isImageCbtype(type) || isPlainTextMimetype(mimetype)) && data->mimetypes[LG_CLIPBOARD_DATA_TEXT] && strstr(data->mimetypes[LG_CLIPBOARD_DATA_TEXT], "html")) { diff --git a/client/displayservers/X11/clipboard.c b/client/displayservers/X11/clipboard.c index 5e2a777b..b39b12d3 100644 --- a/client/displayservers/X11/clipboard.c +++ b/client/displayservers/X11/clipboard.c @@ -93,6 +93,8 @@ struct X11ClipboardState LG_Lock lock; Atom aCurSelection; Atom aTypes[LG_CLIPBOARD_DATA_NONE]; + Atom aTextPlain; + Atom aTextPlainUtf8; Atom aFileGnome; Atom aFileMate; Atom aFileKde; @@ -116,10 +118,12 @@ static const char * atomTypes[] = "text/uri-list", }; -static const char fileGnomeMime[] = "x-special/gnome-copied-files"; -static const char fileMateMime [] = "x-special/mate-copied-files"; -static const char fileKdeMime [] = "application/x-kde-cutselection"; -static const char fileUriMime [] = "text/uri-list"; +static const char textPlainMime [] = "text/plain"; +static const char textPlainUtf8Mime[] = "text/plain;charset=utf-8"; +static const char fileGnomeMime [] = "x-special/gnome-copied-files"; +static const char fileMateMime [] = "x-special/mate-copied-files"; +static const char fileKdeMime [] = "application/x-kde-cutselection"; +static const char fileUriMime [] = "text/uri-list"; static struct X11ClipboardState x11cb; @@ -154,6 +158,15 @@ static const char * fileMimeForAtom(Atom atom) return NULL; } +static bool typeMatchesAtom(LG_ClipboardData type, Atom atom) +{ + if (type != LG_CLIPBOARD_DATA_TEXT) + return atom == x11cb.aTypes[type]; + + return atom == x11cb.aTypes[type] || + atom == x11cb.aTextPlain || atom == x11cb.aTextPlainUtf8; +} + bool x11CBEventThread(const XEvent * xe) { switch(xe->type) @@ -290,15 +303,19 @@ bool x11CBInit(void) } } - x11cb.aFileGnome = XInternAtom(x11.display, fileGnomeMime, False); - x11cb.aFileMate = XInternAtom(x11.display, fileMateMime , False); - x11cb.aFileKde = XInternAtom(x11.display, fileKdeMime , False); + x11cb.aTextPlain = XInternAtom(x11.display, textPlainMime , False); + x11cb.aTextPlainUtf8 = XInternAtom(x11.display, textPlainUtf8Mime, False); + x11cb.aFileGnome = XInternAtom(x11.display, fileGnomeMime , False); + x11cb.aFileMate = XInternAtom(x11.display, fileMateMime , False); + x11cb.aFileKde = XInternAtom(x11.display, fileKdeMime , False); if ( - x11cb.aFileGnome == BadAlloc || x11cb.aFileGnome == BadValue || - x11cb.aFileMate == BadAlloc || x11cb.aFileMate == BadValue || - x11cb.aFileKde == BadAlloc || x11cb.aFileKde == BadValue) + x11cb.aTextPlain == BadAlloc || x11cb.aTextPlain == BadValue || + x11cb.aTextPlainUtf8 == BadAlloc || x11cb.aTextPlainUtf8 == BadValue || + x11cb.aFileGnome == BadAlloc || x11cb.aFileGnome == BadValue || + x11cb.aFileMate == BadAlloc || x11cb.aFileMate == BadValue || + x11cb.aFileKde == BadAlloc || x11cb.aFileKde == BadValue) { - DEBUG_ERROR("failed to get clipboard file atoms"); + DEBUG_ERROR("failed to get clipboard atoms"); return false; } @@ -493,7 +510,12 @@ static void x11CBSelectionRequest(const XSelectionRequestEvent e) targets[0] = x11atoms.TARGETS; targets[1] = x11cb.aTypes[requestType]; int count = 2; - if (requestType == LG_CLIPBOARD_DATA_FILES) + if (requestType == LG_CLIPBOARD_DATA_TEXT) + { + targets[count++] = x11cb.aTextPlain; + targets[count++] = x11cb.aTextPlainUtf8; + } + else if (requestType == LG_CLIPBOARD_DATA_FILES) { targets[count++] = x11cb.aFileGnome; targets[count++] = x11cb.aFileMate; @@ -602,7 +624,7 @@ static void x11CBSelectionRequest(const XSelectionRequestEvent e) // look to see if we can satisfy the data type for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i) - if (x11cb.aTypes[i] == e.target && requestType == i) + if (typeMatchesAtom(i, e.target) && requestType == i) { struct X11ClipboardWrite * write = calloc(1, sizeof(*write)); if (!write)