summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/x11/os_x11.cpp83
1 files changed, 61 insertions, 22 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 802d84b65b..66723c0295 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1180,6 +1180,57 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
input->parse_input_event( event);
}
+struct Property
+{
+ unsigned char *data;
+ int format, nitems;
+ Atom type;
+};
+
+static Property read_property(Display* p_display, Window p_window, Atom p_property) {
+
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ unsigned char *ret=0;
+
+ int read_bytes = 1024;
+
+ //Keep trying to read the property until there are no
+ //bytes unread.
+ do
+ {
+ if(ret != 0)
+ XFree(ret);
+
+ XGetWindowProperty(p_display, p_window, p_property, 0, read_bytes, False, AnyPropertyType,
+ &actual_type, &actual_format, &nitems, &bytes_after,
+ &ret);
+
+ read_bytes *= 2;
+
+ }while(bytes_after != 0);
+
+ Property p = {ret, actual_format, nitems, actual_type};
+
+ return p;
+}
+
+static Atom pick_target_from_list(Display* p_display, Atom *p_list, int p_count) {
+
+ static const char* target_type = "text/uri-list";
+
+ for (int i = 0; i < p_count; i++) {
+
+ Atom atom = p_list[i];
+
+ if (atom != None && String(XGetAtomName(p_display, atom)) == target_type)
+ return atom;
+ }
+ return None;
+}
+
static Atom pick_target_from_atoms(Display* p_disp, Atom p_t1, Atom p_t2, Atom p_t3) {
static const char* target_type = "text/uri-list";
@@ -1489,28 +1540,9 @@ void OS_X11::process_xevents() {
if (event.xselection.target == requested) {
- Atom actual_type;
- int actual_format;
- unsigned long nitems;
- unsigned long bytes_after;
- unsigned char *ret=0;
-
- int read_bytes = 1024;
+ Property p = read_property(x11_display, x11_window, XInternAtom(x11_display, "PRIMARY", 0));
- //Keep trying to read the property until there are no
- //bytes unread.
- do
- {
- if(ret != 0)
- XFree(ret);
- XGetWindowProperty(x11_display, x11_window, XInternAtom(x11_display, "PRIMARY", 0), 0, read_bytes, False, AnyPropertyType,
- &actual_type, &actual_format, &nitems, &bytes_after,
- &ret);
-
- read_bytes *= 2;
- }while(bytes_after != 0);
-
- Vector<String> files = String((char *)ret).split("\n", false);
+ Vector<String> files = String((char *)p.data).split("\n", false);
for (int i = 0; i < files.size(); i++) {
files[i] = files[i].replace("file://", "").replace("%20", " ").strip_escapes();
}
@@ -1541,7 +1573,14 @@ void OS_X11::process_xevents() {
//File(s) have been dragged over the window, check for supported target (text/uri-list)
xdnd_version = ( event.xclient.data.l[1] >> 24);
- requested = pick_target_from_atoms(x11_display, event.xclient.data.l[2],event.xclient.data.l[3], event.xclient.data.l[4]);
+ Window source = event.xclient.data.l[0];
+ bool more_than_3 = event.xclient.data.l[1] & 1;
+ if (more_than_3) {
+ Property p = read_property(x11_display, source, XInternAtom(x11_display, "XdndTypeList", False));
+ requested = pick_target_from_list(x11_display, (Atom*)p.data, p.nitems);
+ }
+ else
+ requested = pick_target_from_atoms(x11_display, event.xclient.data.l[2],event.xclient.data.l[3], event.xclient.data.l[4]);
}
else if ((unsigned int)event.xclient.message_type == (unsigned int )xdnd_position) {