Commit c5213920 authored by Erwan Tulou's avatar Erwan Tulou

skins2(x11): fix Drag&Drop issues on X11.

this patch fixes issues that limited the scope of Drag&Drop.
- set the version number to the latest one (version 5 in 2003!)
- ensure the data type is not hardcoded but selected at runtime.
- add a XSync to ascertain full completion of Drag and Drop.
- protect against possible overflow
- add some debugging info
parent ba86cdb1
......@@ -48,7 +48,9 @@ X11DragDrop::X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay,
void X11DragDrop::dndEnter( ldata_t data )
{
Window src = data[0];
int version = data[1]>>24;
m_xPos = m_yPos = -1;
(void)version;
// Retrieve available data types
std::list<std::string> dataTypes;
......@@ -81,16 +83,23 @@ void X11DragDrop::dndEnter( ldata_t data )
}
}
// list all data types available
std::list<std::string>::iterator it;
for( it = dataTypes.begin(); it != dataTypes.end(); ++it )
msg_Dbg( getIntf(), "D&D data type: %s", (*it).c_str() );
// Find the right target
m_target = None;
std::list<std::string>::iterator it;
for( it = dataTypes.begin(); it != dataTypes.end(); ++it )
{
if( *it == "text/uri-list" ||
*it == "text/plain" ||
*it == "STRING" )
*it == "text/plain;charset=utf-8" ||
*it == "STRING" ||
*it == "UTF8_STRING" )
{
m_target = XInternAtom( XDISPLAY, (*it).c_str(), 0 );
msg_Dbg( getIntf(), "D&D data type chosen: %s", (*it).c_str() );
break;
}
}
......@@ -107,22 +116,11 @@ void X11DragDrop::dndPosition( ldata_t data )
m_xPos = data[2] >> 16;
m_yPos = data[2] & 0xffff;
Time time = data[3];
Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 );
//Atom targetAtom = XInternAtom( XDISPLAY, "text/plain", 0 );
Atom targetAtom = XInternAtom( XDISPLAY, "text/uri-list", 0 );
Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 );
Atom action = data[4];
(void)time; (void)action;
Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
Atom typeAtom = XInternAtom( XDISPLAY, "XdndFinished", 0 );
// Convert the selection into the given target
// NEEDED or it doesn't work!
XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src,
time );
actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
typeAtom = XInternAtom( XDISPLAY, "XdndStatus", 0 );
Atom typeAtom = XInternAtom( XDISPLAY, "XdndStatus", 0 );
XEvent event;
event.type = ClientMessage;
......@@ -149,6 +147,8 @@ void X11DragDrop::dndPosition( ldata_t data )
void X11DragDrop::dndLeave( ldata_t data )
{
(void)data;
m_target = None;
// transmit DragLeave event
EvtDragLeave evt( getIntf() );
m_pWin->processEvent( evt );
......@@ -163,26 +163,33 @@ void X11DragDrop::dndDrop( ldata_t data )
Time time = data[2];
Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 );
Atom targetAtom = XInternAtom( XDISPLAY, "text/uri-list", 0 );
Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 );
Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
Atom typeAtom = XInternAtom( XDISPLAY, "XdndFinished", 0 );
// Convert the selection into the given target
XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src,
XConvertSelection( XDISPLAY, selectionAtom, m_target, propAtom, src,
time );
// Needed to ensure XGetWindowProperty returns something
XSync( XDISPLAY, False );
// Read the selection
Atom type;
int format;
unsigned long nitems, nbytes;
unsigned long nitems, nbytes_after_return;
char *buffer;
XGetWindowProperty( XDISPLAY, src, propAtom, 0, 1024, False,
AnyPropertyType, &type, &format, &nitems, &nbytes,
(unsigned char**)&buffer );
long length_max = 1024;
XGetWindowProperty( XDISPLAY, src, propAtom, 0, length_max, False,
AnyPropertyType, &type, &format, &nitems,
&nbytes_after_return, (unsigned char**)&buffer );
if( buffer && nbytes_after_return > 0 )
{
XFree( buffer );
length_max += nbytes_after_return;
XGetWindowProperty( XDISPLAY, src, propAtom, 0, length_max, False,
AnyPropertyType, &type, &format, &nitems,
&nbytes_after_return, (unsigned char**)&buffer );
}
if( buffer != NULL )
{
msg_Dbg( getIntf(), "buffer received: %s", buffer );
char* psz_dup = strdup( buffer );
char* psz_new = psz_dup;
while( psz_new && *psz_new )
......@@ -198,7 +205,7 @@ void X11DragDrop::dndDrop( ldata_t data )
skip = strlen( sep[i] );
break;
}
if( *psz_new )
if( *psz_new && strstr( psz_new, "://" ) )
{
files.push_back( psz_new );
}
......@@ -209,6 +216,9 @@ void X11DragDrop::dndDrop( ldata_t data )
XFree( buffer );
}
Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
Atom typeAtom = XInternAtom( XDISPLAY, "XdndFinished", 0 );
// Tell the source we accepted the drop
XEvent event;
event.type = ClientMessage;
......
......@@ -148,7 +148,7 @@ X11Window::X11Window( intf_thread_t *pIntf, GenericWindow &rWindow,
// Register the window as a drop target
Atom xdndAtom = XInternAtom( XDISPLAY, "XdndAware", False );
char xdndVersion = 4;
char xdndVersion = 5;
XChangeProperty( XDISPLAY, m_wnd, xdndAtom, XA_ATOM, 32,
PropModeReplace, (unsigned char *)&xdndVersion, 1 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment