[PATCH 3/3] ole32/winex11.drv: implement dragging from Wine and dropping to X11

Damjan Jovanovic damjan.jov at gmail.com
Sun Mar 1 22:32:43 CST 2015


The window used as the drag source on the X11 side is the clipboard's
thread_selection_wnd(), which is fine as XDnD uses XdndSelection
instead of the PRIMARY/CLIPBOARD selections, so both can happily
coexist. Data is converted to X11 formats and cached during
IDropTarget_DragEnter(), then provided to the drop target during
selection requests. The file clipboard.c had to be patched a bit to
export data in a form useful to XDnD, as well as to forward selection
requests received between calls to the IDropTarget methods to xdnd.c.

The complication is that ole32 implements DoDragDrop() using the win32
event loop, and IDropTarget methods block, while the exchange of XDnD
messages over X11 is asynchronous, so winex11.drv's IDropTarget
implementation is forced to selectively pump the event loop itself
while waiting for the reply - for up to 500 milliseconds. However the
clipboard does this too. Even so, X11 apps are slow to send
XdndFinished, sometimes leading Windows apps to believe the drop
failed when it didn't. Ideally the drag loop in ole32 would be broken
up and made event-driven and asynchronous, so XDnD messages would be
interpreted and re-posted to ole32's drag window as they come in while
the drag message loop continues running in between them, that way much
longer waits would be viable. At the moment, at least the 50
millisecond DRAG_TIMER_ID timer in ole32 was changed so it doesn't
create a large backlog of WM_TIMER events - it is now stopped every
time it fires and started again after OLEDD_TrackStateChange()
returns.

There's several other ways this could have been done:
* copy or move the entire drag loop from ole32 to winex11.drv /
winemac.drv and reimplement it using the native windowing functions.
The problem then is that there is duplication of code in 2 display
drivers if not in ole32 as well.
* adopt every native window with create_foreign_window() when the
mouse is first dragged over it, give it an IDropTarget that does
conversion to XDnD, and thus treat all windows as HWND - transparently
to ole32. Has the benefit of fewer changes to the user32 driver API,
keeps the drag loop in ole32 so it's shared between X11 and Mac, but
in my attempts to do this, the z-order of windows got messed up while
dragging (it seems create_foreign_window() is only designed for
XEMBED?).

With this patch all 4 drag-and-drop scenarios on
http://wiki.winehq.org/DragAndDrop become implemented, but the
following still remains:
* better FORMATETC supports, eg. tymeds other than HGLOBAL
* XEMBED support
* XdndProxy support
* Supporting more clipboard formats and conversions between them. Apps
that deal with files often want
CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR which can't be implemented
completely/correctly, as the X Direct Save protocol supports only a
single application/octet-stream unlike the many streams Windows can
have, and can supply a directory name to save files to but then Wine
has to copy the streams from the application into files in that
directory in a background thread, and even a directory name isn't
always possible as the drop target might not be a directory that
actually exists on disk either (eg. directory on remote server, a
window selecting which files to compress, etc.).

Otherwise dragging out of Wine works quite well and behaves just like
native dragging does.

Damjan Jovanovic
---
 dlls/ole32/ole2.c            |   2 +
 dlls/winex11.drv/clipboard.c |  32 +++-
 dlls/winex11.drv/x11drv.h    |   5 +
 dlls/winex11.drv/xdnd.c      | 439 ++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 476 insertions(+), 2 deletions(-)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-ole32-winex11.drv-implement-dragging-from-Wine-and-dro.txt
Type: text/x-patch
Size: 21799 bytes
Desc: not available
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20150302/c4f83d39/attachment-0001.bin>


More information about the wine-patches mailing list