void WMScreenAbortDrag(W_Screen *screen) { if (!screen || !screen->dragInfo.sourceInfo) return; W_DragSourceInfo *source = screen->dragInfo.sourceInfo; W_DragSourceStopTimer(); // inform the other client if (source->destinationWindow) W_SendDnDClientMessage(screen->display, source->destinationWindow, screen->xdndLeaveAtom, WMViewXID(source->sourceView), 0, 0, 0, 0); WMDeleteSelectionHandler(source->sourceView, screen->xdndSelectionAtom, CurrentTime); wfree(source->selectionProcs); if (source->sourceView->dragSourceProcs->endedDrag) source->sourceView->dragSourceProcs->endedDrag(source->sourceView, &source->imageLocation, False); if (source->icon) XDestroyWindow(screen->display, source->icon); if (source->dragCursor != None) { XDefineCursor(screen->display, screen->rootWin, screen->defaultCursor); XFreeCursor(screen->display, source->dragCursor); } wfree(source); screen->dragInfo.sourceInfo = NULL; }
/* send a DnD message to the destination window */ static Bool sendDnDClientMessage(WMDraggingInfo * info, Atom message, unsigned long data1, unsigned long data2, unsigned long data3, unsigned long data4) { Display *dpy = sourceScreen(info)->display; Window srcWin = WMViewXID(XDND_SOURCE_VIEW(info)); Window destWin = XDND_DEST_WIN(info); if (!W_SendDnDClientMessage(dpy, destWin, message, srcWin, data1, data2, data3, data4)) { /* drop failed */ recolorCursor(info, False); endDragImage(info, True); endDragProcess(info, False); return False; } return True; }