On Mon, Mar 2, 2015 at 10:09 PM, Ken Thomases ken@codeweavers.com wrote:
Hi,
On Mar 1, 2015, at 10:32 PM, Damjan Jovanovic damjan.jov@gmail.com wrote:
Currently Wine does not support dragging from a Wine window to a native Window, but does from a Wine window to another Wine window. What is a big surprise though, is that if a Wine window is obscured by a native window that's on top of it in the z-order, it looks like you are dropping onto the native window, but you are actually dropping THROUGH the native window into the Wine window - in other words, the wrong application gets the drop!
This patch fixes that problem by giving ole32 awareness of native windows (represented by a ULONG_PTR) via new Wine-specific functions in user32 that are implemented by the display drivers winex11.drv and winemac.drv (of which only the former is implemented by this patch). The ole32 drag loop can thus tell whether the window under the mouse is a Wine window or a native window, and obtain IDropTarget from either window type, something that is used by the next patch to implement dragging from Wine to native windows.
I appreciate your work on this, but I think this isn't the right approach. I think if you solve the other problem (dragging from Wine to other apps) by having the driver take over drags and translating them into a native drag operation, then this problem gets solved automatically. The native drag operation will target the proper window under the cursor, eliminating the problem of dropping through non-Wine windows. If the drag goes over a Wine window, then the native drag will get translated back into Win32 by the existing code in the drivers for receiving drops.
Thank you. So in other words you want only native drag and drop to exist, and Wine's drag and drop to be implemented on top of native in all cases. It's doable, we can use native drag and drop for window selection, and nothing forces us to use native APIs for the data transfer when both the source and destination are Wine windows, so potentially lossy data conversions to and from native data formats can still be avoided. Does Alexandre agree with this approach though?
I understand your point from the next patch email that this may result in code duplication between the drivers, but I think that's largely inevitable because of the requirements of driving a native drag operation.
Also, I don't believe your design where the driver implements IDropTarget and ole32 calls its methods can be made to work on the Mac. As is often the case, Cocoa has a much more closed API for drag and drop than X11. We can't really arbitrarily do pieces of the drag operation in isolation and effectively start and stop the drag (as the cursor moves from Wine window to native window and back to a Wine window). We can only start the drag and then Cocoa takes it from there. It calls relevant methods on the drag source object along the way, of course, but we don't have a lot of control over the drag operation other than that.
Yes I see Cocoa's dragImage:at:offset:event:pasteboard:source:slideBack: is analogous to Windows's closed and drag source blocking DoDragDrop() API, rather than XDnD's flexible event-driven protocol. But the worst problem with it isn't that it's closed, but rather its different and incompatible semantics: AFAICT, unlike in Windows where the drag source is an active participant in the drag with its QueryContinueDrag() method allowing cancelling the drop or dropping at the chosen time, the drag source callback methods in Cocoa are just passive observers with no possibility of cancelling the drop or choosing when to drop. It does not seem possible to implement DoDragDrop() correctly on top of that: the source will be forced to drop even if it doesn't want to, and can't willingly drop when it does want to.
-Ken
Damjan