xdnd: can handle more than 3 different target types
Now dropping also works with Nemo and PCManFM(gtk)
This commit is contained in:
parent
ae0a59731e
commit
2c9b28df13
|
@ -1180,6 +1180,57 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
|
||||||
input->parse_input_event( event);
|
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 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";
|
static const char* target_type = "text/uri-list";
|
||||||
|
@ -1489,28 +1540,9 @@ void OS_X11::process_xevents() {
|
||||||
|
|
||||||
if (event.xselection.target == requested) {
|
if (event.xselection.target == requested) {
|
||||||
|
|
||||||
Atom actual_type;
|
Property p = read_property(x11_display, x11_window, XInternAtom(x11_display, "PRIMARY", 0));
|
||||||
int actual_format;
|
|
||||||
unsigned long nitems;
|
|
||||||
unsigned long bytes_after;
|
|
||||||
unsigned char *ret=0;
|
|
||||||
|
|
||||||
int read_bytes = 1024;
|
Vector<String> files = String((char *)p.data).split("\n", false);
|
||||||
|
|
||||||
//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);
|
|
||||||
for (int i = 0; i < files.size(); i++) {
|
for (int i = 0; i < files.size(); i++) {
|
||||||
files[i] = files[i].replace("file://", "").replace("%20", " ").strip_escapes();
|
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)
|
//File(s) have been dragged over the window, check for supported target (text/uri-list)
|
||||||
xdnd_version = ( event.xclient.data.l[1] >> 24);
|
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) {
|
else if ((unsigned int)event.xclient.message_type == (unsigned int )xdnd_position) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue