[vlc-commits] skins2(x11): fix Drag&Drop issues on X11.
Erwan Tulou
git at videolan.org
Wed Jan 17 00:39:57 CET 2018
vlc/vlc-3.0 | branch: master | Erwan Tulou <erwan10 at videolan.org> | Tue Jan 16 19:02:13 2018 +0100| [715833ba19414b26128098c802a2e2183d4fa673] | committer: 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
(cherry picked from commit c5213920b8fb6d5a5ed5c430356831f14c170a6a)
Signed-off-by: Erwan Tulou <erwan10 at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=715833ba19414b26128098c802a2e2183d4fa673
---
modules/gui/skins2/x11/x11_dragdrop.cpp | 64 +++++++++++++++++++--------------
modules/gui/skins2/x11/x11_window.cpp | 2 +-
2 files changed, 38 insertions(+), 28 deletions(-)
diff --git a/modules/gui/skins2/x11/x11_dragdrop.cpp b/modules/gui/skins2/x11/x11_dragdrop.cpp
index 47587fbfa3..9244a2532e 100644
--- a/modules/gui/skins2/x11/x11_dragdrop.cpp
+++ b/modules/gui/skins2/x11/x11_dragdrop.cpp
@@ -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;
diff --git a/modules/gui/skins2/x11/x11_window.cpp b/modules/gui/skins2/x11/x11_window.cpp
index 57850299c4..e469ed64cb 100644
--- a/modules/gui/skins2/x11/x11_window.cpp
+++ b/modules/gui/skins2/x11/x11_window.cpp
@@ -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 );
More information about the vlc-commits
mailing list