---------------------- Summary of the problem ---------------------- On the source side: - the source doesn't send the protocol version (it is not set). - the source may receive a status message from a GDK target after having closed the DnD dialog with the leave message. On the destination side: - GDK widgets start the dialog as soon as they enter the XDND aware widget, even if this one was not registered for dnd; - GDK widgets only deal with messages comming from the XDND aware widget, not the messages comming from the subwidgets that were registered to handle dnd. - WINGs doesn't reply to position messages once the drop is allowed or rejected. This stall dnd dialog on GDK side, because the source send position messages on every move (until the drop occurs or the source leaves the target), waiting for target's reply, wich is never sent. Note: this patch does not change the current dnd interface. --------------- List of changes --------------- WINGs/WINGsP.h - set XDND_VERSION 3 (was 4, WINGs is not XDND v4 compliant yet) - add xdndAwareView to W_DragDestinationInfo. GDK can only deals with the (xdnd aware) toplevel window. Store it, to avoid to retrieve it each time we send a message to the source. - add boolean sourceActionChanged to W_DragDestinationInfo struct As source may send position message with a different action until drop, the destination must check if the drop is allowed each time the action changes. - add comment on protocolVersion of W_DraggingInfo struct. dragcommon.c - rename VERSION_INFO macro as XDND_SOURCE_VERSION - remove XDND_DEST_VIEW_STORED macro (not relevant now that we store even unregistered views). - W_SendDnDClientMessage: Debug code added. - handleLeaveMessage: Add condition in case of unregistered (XDND unaware) destination. - W_HandleDNDClientMessage: Fix version checking (XDND v3 and up are not v1 or v2 compliant, whereas v4 and v5 are backward compatible with v3). dragsource.c - rename VERSION_INFO macro as XDND_DEST_VERSION. - W_DragSourceStateHandler: Check if the message comes from the current target, because the source may receive a message from the previous GDK target, even if the dialog is over. - sendEnterMessage: Send correct version (from xdndAware definition in XDND doc). - sendPositionMessage: Return always something (thanks for the comment, Dan). Return True if no message had to be sent, considering it's always a success. Also correct mouse position checking (size.height replace the wrong size.width when checking y coordinate) - storeDestinationProtocolVersion (new): Used in processMotion, if the source enters a new XDND aware destination. - processMotion: To handle status message sent from a GDK target after a closed DnD dialog, set source state to NULL if it enters a non XDND window. See W_DragSourceStateHandler change below for more info. Set XDND_DEST_VERSION when source enters a new XDND aware destination. - W_DragSourceStateHandler: As in processMotion, to handle post-dialog status messages, check if source state is not NULL before processing the message. note: checking if the message's window is the same as the stored destination doesn't work with KDE (for example in Konqueror, window id depends on the position of the cursor inside the xdnd aware widget). dragdestination.c: - rename VERSION_INFO macro as XDND_SOURCE_VERSION - add XDND_SOURCE_ACTION_CHANGED macro (refers to sourceActionChanged, see WINGsP.h changes) - add XDND_AWARE_VIEW macro (refers to xdndAwareView, see WINGsP.h changes) - replace XDND_DEST_VIEW_STORED with XDND_DEST_VIEW_IS_REGISTERED (since findXdndViewInToplevel change implies that XDND_DEST_VIEW is never NULL, but can be an unregistered (XDND unaware) view. - W_DragDestinationStoreEnterMsgInfo: Use initDestinationDragInfo with toplevel as destView parameter (see initDestinationDragInfo and findXdndViewInToplevel changes for more infos on this). Store the toplevel (xdnd aware) window. This is the only one that can be used to send messages to GDK. - W_DragDestinationStorePositionMsgInfo: Store the toplevel (xdnd aware) window. Doesn't need to handle the "new destination is NULL" case anymore. Set the newly added sourceActionChanged - W_DragDestinationCancelDropOnEnter: Handle unregistered destination case. - sendDnDClientMessage: When calling W_SendDnDClientMessage, use the toplevel (xdnd aware) view, instead of the destination one. This allow to change sendDnDClientMessage, replacing the WMView* parameter with a WMDraggingInfo* one, to conform to the sendDnDClientMessage signature defined in dragsource, and hide a little more the datas. This implies minor changes on dragdestination.c static function signatures. - sendStatusMessage (new): This function is used wherever a status message needs to be sent. It manage the coordinates part of the message, to reduce XDND dialog. if the destination has no subwidget, it send the widget position and size, otherwise it request a position message on every move. - sendAllowedAction: Removed (it's reduced to one line with use of sendStatusMessage. Call directly this one in checkActionAllowed). - findXdndViewInToplevel (renamed as findDestinationViewInToplevel): To work with GDK, findXdndViewInToplevel return the view directly under the drag icon (not the registered view or NULL if none). This function is renamed findDestinationViewInToplevel, and never return NULL. Now, the destination view stored in WMDraggingInfo may not be registered. - findChildInWindow (renamed as findChildInView) Following findXdndViewInToplevel changes (may be it was also possible before), use WINGs view's childrenList to find the view under the pointer instead of X functions. This speeds the things quite a lot (approx. x5 according to a quick profiling). With the increase of position/status messages, this is really needed. - initDestinationDragInfo: Following findXdndViewInToplevel change, we can set destView to toplevel on "enter" message". Now destView is always defined. Set newly added sourceActionChanged to False. - W_DragDestinationStartTimer: Remove (XDND_DEST_VIEW(info) == NULL) test (always false, see initDestinationDragInfo change). - idleState: Handle the case where the destination is not registered. - dropAllowedState and dropNotAllowedState: Reply to xdndPosition messages. Recheck if drop is allowed if the action has changed. - W_DragDestinationStateHandler: remove now useless XDND_DEST_VIEW_STORED test (see initDestinationDragInfo), replaced with assertions. - storeRequiredTypeList: Retrieve the type list (if needed) only once and store it.