diff --git a/src/wine-host/xdnd-proxy.cpp b/src/wine-host/xdnd-proxy.cpp index f30f9cc2..f82be539 100644 --- a/src/wine-host/xdnd-proxy.cpp +++ b/src/wine-host/xdnd-proxy.cpp @@ -46,14 +46,18 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/, LONG /*idChild*/, DWORD /*idEventThread*/, DWORD /*dwmsEventTime*/) { - // FIXME: Prevent this from being run by multiple processes at the same time - - // XXX: `EVENT_OBJECT_DESTROY` doesn't seem to be implemented by Wine, so we - // can't rely on that. if (!(event == EVENT_OBJECT_CREATE && idObject == OBJID_WINDOW)) { return; } + // Don't handle windows that weren't created in this process, because + // otherwise we obviously cannot access the `IDataObject` object + uint32_t process_id = 0; + GetWindowThreadProcessId(hwnd, &process_id); + if (process_id != GetCurrentProcessId()) { + return; + } + // Wine's drag-and-drop tracker windows always have the same window // class name, so we can easily identify them { @@ -68,7 +72,7 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/, // data auto tracker_info = reinterpret_cast(GetWindowLongPtr(hwnd, 0)); - if (!tracker_info) { + if (!tracker_info || !tracker_info->dataObject) { return; } @@ -122,9 +126,9 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/, } break; } - // We won't release the storage, because we're not actually doing - // the Windows drag and drop. We're just snooping in on the data - // that's being dragged. + if (storage.pUnkForRelease) { + storage.pUnkForRelease->Release(); + } } } } diff --git a/src/wine-host/xdnd-proxy.h b/src/wine-host/xdnd-proxy.h index db822a68..de19fe31 100644 --- a/src/wine-host/xdnd-proxy.h +++ b/src/wine-host/xdnd-proxy.h @@ -35,9 +35,10 @@ class WineXdndProxy { * is started, we will initiate the XDND protocol with the same file. This * will allow us to drag files from Wine windows to X11 applications, * something that's normally not possible. Calling this function more than - * once doesn't have any effect, but this will still be called from every - * plugin host instance. Because of that we'll use a global Win32 mutex to - * ensure that this is done from only one thread at a time. + * once doesn't have any effect, but this should still be called at least + * once from every plugin host instance. Because the actual data is stored + * in a COM object, we can only handle drag-and-drop coming form this + * process. */ static WineXdndProxy& init_proxy();