aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHein-Pieter van Braam2018-01-29 00:33:57 +0100
committerHein-Pieter van Braam2018-01-30 20:55:11 +0100
commite69b30b276003966b6b63da21600b9506e20430e (patch)
tree618504fadbcf221e1340c10b86e9f034c45d7e8c
parent99e72894a20a4349d7172be3c2ee3bb7486fa007 (diff)
downloadgodot-e69b30b276003966b6b63da21600b9506e20430e.tar.gz
godot-e69b30b276003966b6b63da21600b9506e20430e.tar.zst
godot-e69b30b276003966b6b63da21600b9506e20430e.zip
Fix Copy/Paste problems on X11
The target of the TARGETS type should be XA_ATOM and not XA_TARGETS when requested. Since we are sending a number of ATOMS the size should be set to the integer size and not the char size. The size field of the atoms is also the number of atoms and not the size of the array. This caused some clients to wrongly interpret the data and read garbage in the X11 packet. I also add the more modern representation for UTF-8 and clarify the error message if a client attempts to request a type we don't know about. This fixes #10431 (cherry picked from commit fb60f2dbe649c03a8357a277eccb6d06dfe07b68)
-rw-r--r--platform/x11/os_x11.cpp40
1 files changed, 29 insertions, 11 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 7a2cbf26b..eaf72d4db 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1862,8 +1862,12 @@ void OS_X11::process_xevents() {
e = event;
req = &(e.xselectionrequest);
- if (req->target == XA_STRING || req->target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) ||
- req->target == XInternAtom(x11_display, "UTF8_STRING", 0)) {
+ if (req->target == XInternAtom(x11_display, "UTF8_STRING", 0) ||
+ req->target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) ||
+ req->target == XInternAtom(x11_display, "TEXT", 0) ||
+ req->target == XA_STRING ||
+ req->target == XInternAtom(x11_display, "text/plain;charset=utf-8", 0) ||
+ req->target == XInternAtom(x11_display, "text/plain", 0)) {
CharString clip = OS::get_clipboard().utf8();
XChangeProperty(x11_display,
req->requestor,
@@ -1876,26 +1880,40 @@ void OS_X11::process_xevents() {
respond.xselection.property = req->property;
} else if (req->target == XInternAtom(x11_display, "TARGETS", 0)) {
- Atom data[2];
- data[0] = XInternAtom(x11_display, "UTF8_STRING", 0);
- data[1] = XA_STRING;
- XChangeProperty(x11_display, req->requestor, req->property, req->target,
- 8, PropModeReplace, (unsigned char *)&data,
- sizeof(data));
+ Atom data[7];
+ data[0] = XInternAtom(x11_display, "TARGETS", 0);
+ data[1] = XInternAtom(x11_display, "UTF8_STRING", 0);
+ data[2] = XInternAtom(x11_display, "COMPOUND_TEXT", 0);
+ data[3] = XInternAtom(x11_display, "TEXT", 0);
+ data[4] = XA_STRING;
+ data[5] = XInternAtom(x11_display, "text/plain;charset=utf-8", 0);
+ data[6] = XInternAtom(x11_display, "text/plain", 0);
+
+ XChangeProperty(x11_display,
+ req->requestor,
+ req->property,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (unsigned char *)&data,
+ sizeof(data) / sizeof(data[0]));
respond.xselection.property = req->property;
} else {
- printf("No String %x\n",
- (int)req->target);
+ char *targetname = XGetAtomName(x11_display, req->target);
+ printf("No Target '%s'\n", targetname);
+ if (targetname)
+ XFree(targetname);
respond.xselection.property = None;
}
+
respond.xselection.type = SelectionNotify;
respond.xselection.display = req->display;
respond.xselection.requestor = req->requestor;
respond.xselection.selection = req->selection;
respond.xselection.target = req->target;
respond.xselection.time = req->time;
- XSendEvent(x11_display, req->requestor, 0, 0, &respond);
+ XSendEvent(x11_display, req->requestor, True, NoEventMask, &respond);
XFlush(x11_display);
} break;