[PATCH 2/3] include/ole32/user32/winemac.drv/winex11.drv: do not allow dropping drags through obscuring native windows
damjan.jov at gmail.com
Tue Mar 3 12:22:48 CST 2015
On Mon, Mar 2, 2015 at 10:09 PM, Ken Thomases <ken at codeweavers.com> wrote:
> On Mar 1, 2015, at 10:32 PM, Damjan Jovanovic <damjan.jov at 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.
More information about the wine-devel