Skip to content

Commit e7c6814

Browse files
committed
apprt/gtk: (clipboard) add X11 atoms, extra MIME types for text content
This adds the UTF8_STRING atom and explicit UTF-8 character set MIME type (text/plain;charset=utf-8) to text content when being sent to the clipboard under the new multipart support. This fixes clipboard support under X11 particularly, which generally looks for the UTF8_STRING atom when looking for text content. This can be verified with xclip -out -verbose, or trying to do things like paste in Firefox. I've noted that there's a number of other older atoms that exist, but I've refrained from adding them for now. Kitty only seems to set UTF8_STRING and I've had a hard time finding consensus on what exactly is the correct set otherwise.
1 parent 765ee68 commit e7c6814

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

‎src/apprt/gtk/class/surface.zig‎

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3364,8 +3364,42 @@ const Clipboard = struct {
33643364
for (contents, 0..) |content, i| {
33653365
const bytes = glib.Bytes.new(content.data.ptr, content.data.len);
33663366
defer bytes.unref();
3367-
const provider = gdk.ContentProvider.newForBytes(content.mime, bytes);
3368-
providers[i] = provider;
3367+
if (std.mem.eql(u8, content.mime, "text/plain")) {
3368+
// Add some extra MIME types (and X11 atoms) for
3369+
// text/plain. This can be expanded on if certain
3370+
// applications are expecting text in a particular type
3371+
// or atom that is not currently here; UTF8_STRING
3372+
// seems to be the most common one for modern X11, but
3373+
// there are some older ones, e.g., XA_STRING or just
3374+
// plain STRING. Kitty seems to get by with just
3375+
// UTF8_STRING, but I'm also adding the explicit utf-8
3376+
// MIME parameter for correctness; technically, for
3377+
// MIME, when the charset is missing, the default
3378+
// charset is ASCII.
3379+
const text_provider_atoms = [_][:0]const u8{
3380+
"text/plain",
3381+
"text/plain;charset=utf-8",
3382+
"UTF8_STRING",
3383+
};
3384+
// Following on the same logic as our outer union,
3385+
// looks like we only need this memory during union
3386+
// construction, so it's okay if this is just a
3387+
// static-length array and goes out of scope when we're
3388+
// done. Similarly, we don't unref these providers.
3389+
var text_providers: [text_provider_atoms.len]*gdk.ContentProvider = undefined;
3390+
for (text_provider_atoms, 0..) |atom, j| {
3391+
const provider = gdk.ContentProvider.newForBytes(atom, bytes);
3392+
text_providers[j] = provider;
3393+
}
3394+
const text_union = gdk.ContentProvider.newUnion(
3395+
&text_providers,
3396+
text_providers.len,
3397+
);
3398+
providers[i] = text_union;
3399+
} else {
3400+
const provider = gdk.ContentProvider.newForBytes(content.mime, bytes);
3401+
providers[i] = provider;
3402+
}
33693403
}
33703404

33713405
const all = gdk.ContentProvider.newUnion(providers.ptr, providers.len);

0 commit comments

Comments
 (0)