From: Daniel Déchelotte <[email protected]>

Behaves essentially the same, only a bit more consistently.
Known differences:
1. An AppIcon will now always end up undocked if moved while Mod1 is pressed.
2. Moving a docked AppIcon with Mod1 pressed (undocking it) used to auto-expand 
the clip,
   as clip expansion happened first, while looking for a snapping position,
   and the test on Mod1 being pressed happened only later
---
 src/appicon.c |  342 +++++++++++++++++++++++++++++++++++++--------------------
 src/appicon.h |    1 +
 src/dock.c    |  226 +-------------------------------------
 src/dock.h    |    2 +
 4 files changed, 230 insertions(+), 341 deletions(-)

diff --git a/src/appicon.c b/src/appicon.c
index e969d39..bc02216 100644
--- a/src/appicon.c
+++ b/src/appicon.c
@@ -63,6 +63,7 @@ extern WDDomain *WDWindowAttributes;
 extern XContext wWinContext;
 
 #define MOD_MASK       wPreferences.modifier_mask
+#define ICON_SIZE      wPreferences.icon_size
 
 void appIconMouseDown(WObjDescriptor * desc, XEvent * event);
 static void iconDblClick(WObjDescriptor * desc, XEvent * event);
@@ -667,24 +668,8 @@ static void iconDblClick(WObjDescriptor *desc, XEvent 
*event)
 void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
 {
        WAppIcon *aicon = desc->parent;
-       WIcon *icon = aicon->icon;
-       XEvent ev;
-       int x = aicon->x_pos, y = aicon->y_pos;
-       int dx = event->xbutton.x, dy = event->xbutton.y;
-       int grabbed = 0;
-       int done = 0;
-       int superfluous = wPreferences.superfluous;     /* we catch it to avoid 
problems */
-       WScreen *scr = icon->core->screen_ptr;
-       WWorkspace *workspace = scr->workspaces[scr->current_workspace];
-       int shad_x = 0, shad_y = 0, docking = 0, dockable, collapsed = 0;
-       int ix, iy;
-       int clickButton = event->xbutton.button;
-       Pixmap ghost = None;
-       Window wins[2];
-       Bool movingSingle = False;
-       int oldX = x;
-       int oldY = y;
-       Bool hasMoved = False;
+       WScreen *scr = aicon->icon->core->screen_ptr;
+       Bool hasMoved;
 
        if (aicon->editing || WCHECK_STATE(WSTATE_MODAL))
                return;
@@ -729,24 +714,92 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * 
event)
                return;
        }
 
-       if (event->xbutton.state & MOD_MASK)
-               wLowerFrame(icon->core);
-       else
+       hasMoved = wHandleAppIconMove(aicon, event);
+       if (wPreferences.single_click && !hasMoved && aicon->dock != NULL)
+       {
+               iconDblClick(desc, event);
+       }
+}
+
+Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
+{
+       WDock *originalDock = aicon->dock; /* can be NULL */
+       WDock *lastDock = originalDock;
+       WDock *allDocks[2]; /* clip and dock (order to be determined at 
runtime) */
+       Bool done = False, dockable, ondock;
+       Bool grabbed = False;
+       Bool collapsed = False; /* Stores the collapsed state of lastDock, 
before the moving appicon entered it */
+       int superfluous = wPreferences.superfluous; /* we cache it to avoid 
problems */
+       int omnipresent = aicon->omnipresent; /* this must be cached */
+       Bool showed_all_clips = False;
+
+       WIcon *icon = aicon->icon;
+       WScreen *scr = icon->core->screen_ptr;
+       int clickButton = event->xbutton.button;
+       Pixmap ghost = None;
+       Window wins[2]; /* Managing shadow window */
+       XEvent ev;
+
+       int x = aicon->x_pos, y = aicon->y_pos;
+       int ofs_x = event->xbutton.x, ofs_y = event->xbutton.y;
+       int shad_x = x, shad_y = y;
+       int ix = aicon->xindex, iy = aicon->yindex;
+       int i;
+       int oldX = x;
+       int oldY = y;
+       Bool hasMoved = False;
+
+       if (wPreferences.flags.noupdates && originalDock != NULL)
+               return False;
+
+       if (!(event->xbutton.state & MOD_MASK))
                wRaiseFrame(icon->core);
+       else {
+               /* If Mod is pressed for an docked appicon, assume it is to 
undock it,
+                * so don't lower it */
+               if (originalDock == NULL)
+                       wLowerFrame(icon->core);
+       }
 
        if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
                         | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
-                        GrabModeAsync, None, None, CurrentTime) != GrabSuccess)
-               wwarning("pointer grab failed for appicon move");
+                        GrabModeAsync, None, None, CurrentTime) != 
GrabSuccess) {
+               wwarning("Pointer grab failed in wHandleAppIconMove");
+       }
+
+       if (originalDock != NULL) {
+           dockable = True;
+           ondock = True;
+       }
+       else {
+               ondock = False;
+               if (wPreferences.flags.nodock && wPreferences.flags.noclip)
+                       dockable = 0;
+               else
+                       dockable = canBeDocked(icon->owner);
+       }
+
+       /* We try the various docks in that order:
+        * - First, the dock the appicon comes from, if any
+        * - Then, the "dock" (WM_DOCK)
+        * - Finally, the clip
+        */
+       i = 0;
+       if (originalDock != NULL)
+               allDocks[ i++ ] = originalDock;
+       if (!wPreferences.flags.nodock && scr->dock != originalDock)
+               allDocks[ i++ ] = scr->dock;
+       if (!wPreferences.flags.noclip &&
+           originalDock != scr->workspaces[scr->current_workspace]->clip)
+               allDocks[ i++ ] = scr->workspaces[scr->current_workspace]->clip;
+       for ( ; i < 2; i++) /* In case the clip, the dock, or both, are 
disabled */
+               allDocks[ i ] = NULL;
 
-       if (wPreferences.flags.nodock && wPreferences.flags.noclip)
-               dockable = 0;
-       else
-               dockable = canBeDocked(icon->owner);
 
        wins[0] = icon->core->window;
        wins[1] = scr->dock_shadow;
        XRestackWindows(dpy, wins, 2);
+       XMoveResizeWindow(dpy, scr->dock_shadow, aicon->x_pos, aicon->y_pos, 
ICON_SIZE, ICON_SIZE);
        if (superfluous) {
                if (icon->pixmap != None)
                        ghost = MakeGhostIcon(scr, icon->pixmap);
@@ -755,6 +808,8 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
                XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost);
                XClearWindow(dpy, scr->dock_shadow);
        }
+       if (ondock)
+               XMapWindow(dpy, scr->dock_shadow);
 
        while (!done) {
                WMMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | 
ButtonPressMask
@@ -774,8 +829,8 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
                case MotionNotify:
                        hasMoved = True;
                        if (!grabbed) {
-                               if (abs(dx - ev.xmotion.x) >= MOVE_THRESHOLD
-                                   || abs(dy - ev.xmotion.y) >= 
MOVE_THRESHOLD) {
+                               if (abs(ofs_x - ev.xmotion.x) >= MOVE_THRESHOLD
+                                   || abs(ofs_y - ev.xmotion.y) >= 
MOVE_THRESHOLD) {
                                        XChangeActivePointerGrab(dpy, 
ButtonMotionMask
                                                                 | 
ButtonReleaseMask | ButtonPressMask,
                                                                 
wCursor[WCUR_MOVE], CurrentTime);
@@ -784,68 +839,87 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * 
event)
                                        break;
                                }
                        }
-                       x = ev.xmotion.x_root - dx;
-                       y = ev.xmotion.y_root - dy;
-
-                       if (movingSingle)
-                               XMoveWindow(dpy, icon->core->window, x, y);
-                       else
-                               wAppIconMove(aicon, x, y);
-
-                       if (dockable) {
-                               if (scr->dock && wDockSnapIcon(scr->dock, 
aicon, x, y, &ix, &iy, False)) {
-                                       shad_x = scr->dock->x_pos + ix * 
wPreferences.icon_size;
-                                       shad_y = scr->dock->y_pos + iy * 
wPreferences.icon_size;
-
-                                       if (scr->last_dock != scr->dock && 
collapsed) {
-                                               scr->last_dock->collapsed = 1;
-                                               wDockHideIcons(scr->last_dock);
-                                               collapsed = 0;
-                                       }
-                                       if (!collapsed && (collapsed = 
scr->dock->collapsed)) {
-                                               scr->dock->collapsed = 0;
-                                               wDockShowIcons(scr->dock);
-                                       }
-
-                                       if (scr->dock->auto_raise_lower)
-                                               wDockRaise(scr->dock);
-
-                                       scr->last_dock = scr->dock;
 
-                                       XMoveWindow(dpy, scr->dock_shadow, 
shad_x, shad_y);
-                                       if (!docking)
-                                               XMapWindow(dpy, 
scr->dock_shadow);
-
-                                       docking = 1;
-                               } else if (workspace->clip &&
-                                          wDockSnapIcon(workspace->clip, 
aicon, x, y, &ix, &iy, False)) {
-                                       shad_x = workspace->clip->x_pos + ix * 
wPreferences.icon_size;
-                                       shad_y = workspace->clip->y_pos + iy * 
wPreferences.icon_size;
+                       if (omnipresent && !showed_all_clips) {
+                               int i;
+                               for (i = 0; i < scr->workspace_count; i++) {
+                                       if (i == scr->current_workspace)
+                                               continue;
+                                       
wDockShowIcons(scr->workspaces[i]->clip);
+                                       /* Note: if dock is collapsed (for 
instance, because it
+                                          auto-collapses), its icons still 
won't show up */
+                               }
+                               showed_all_clips = True; /* To prevent 
flickering */
+                       }
 
-                                       if (scr->last_dock != workspace->clip 
&& collapsed) {
-                                               scr->last_dock->collapsed = 1;
-                                               wDockHideIcons(scr->last_dock);
-                                               collapsed = 0;
+                       x = ev.xmotion.x_root - ofs_x;
+                       y = ev.xmotion.y_root - ofs_y;
+                       wAppIconMove(aicon, x, y);
+
+                       /* At a high level, this if-block is about setting 
theNewDock to
+                        * the first dock that could snap the appicon at the 
current
+                        * position, and the next if-block uses that and other 
info to
+                        * determine whether to dock/undock.
+                        */
+                       WDock *theNewDock = NULL;
+                       for (i = 0; dockable && i < 2; i++) {
+                               WDock *theDock = allDocks[i];
+                               if (theDock == NULL)
+                                       break;
+                               if (wDockSnapIcon(theDock, aicon, x, y, &ix, 
&iy, (theDock == originalDock))) {
+                                       theNewDock = theDock;
+                                       break;
+                               }
+                       }
+                       if (originalDock != NULL && theNewDock == NULL &&
+                               (aicon->launching || aicon->lock || 
aicon->running)) {
+                               /* In those cases, stay in lastDock if no dock 
really wants us */
+                               theNewDock = lastDock;
+                       }
+                       if (theNewDock != NULL && !aicon->launching && 
!aicon->lock && ev.xmotion.state & MOD_MASK)
+                               /* Mod is pressed: do not dock */
+                               theNewDock = NULL;
+                       if (lastDock != NULL && lastDock != theNewDock) {
+                               /* Leave lastDock in the state we found it */
+                               if (collapsed) {
+                                       lastDock->collapsed = 1;
+                                       wDockHideIcons(lastDock);
+                                       collapsed = False;
+                               }
+                               if (lastDock->auto_raise_lower) {
+                                       wDockLower(lastDock);
+                               }
+                       }
+                       if (theNewDock != NULL) {
+                               if (lastDock != theNewDock) {
+                                       collapsed = theNewDock->collapsed;
+                                       if (collapsed) {
+                                               theNewDock->collapsed = 0;
+                                               wDockShowIcons(theNewDock);
                                        }
-                                       if (!collapsed && (collapsed = 
workspace->clip->collapsed)) {
-                                               workspace->clip->collapsed = 0;
-                                               wDockShowIcons(workspace->clip);
+                                       if (theNewDock->auto_raise_lower) {
+                                               wDockRaise(theNewDock);
+                                               /* And raise the moving tile 
above it */
+                                               wRaiseFrame(aicon->icon->core);
                                        }
+                                       lastDock = theNewDock;
+                               }
 
-                                       if (workspace->clip->auto_raise_lower)
-                                               wDockRaise(workspace->clip);
-
-                                       scr->last_dock = workspace->clip;
-
-                                       XMoveWindow(dpy, scr->dock_shadow, 
shad_x, shad_y);
-                                       if (!docking)
-                                               XMapWindow(dpy, 
scr->dock_shadow);
-
-                                       docking = 1;
-                               } else if (docking) {
+                               shad_x = lastDock->x_pos + 
ix*wPreferences.icon_size;
+                               shad_y = lastDock->y_pos + 
iy*wPreferences.icon_size;
+                         
+                               XMoveWindow(dpy, scr->dock_shadow, shad_x, 
shad_y);
+                         
+                               if (!ondock) {
+                                       XMapWindow(dpy, scr->dock_shadow);
+                               }
+                               ondock = 1;
+                       } else {
+                               lastDock = theNewDock; // i.e., NULL
+                               if (ondock) {
                                        XUnmapWindow(dpy, scr->dock_shadow);
-                                       docking = 0;
                                }
+                               ondock = 0;
                        }
                        break;
 
@@ -857,41 +931,63 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * 
event)
                                break;
                        XUngrabPointer(dpy, CurrentTime);
 
-                       if (docking) {
-                               Bool docked;
-
-                               /* icon is trying to be docked */
+                       Bool docked = False;
+                       if (ondock) {
                                SlideWindow(icon->core->window, x, y, shad_x, 
shad_y);
                                XUnmapWindow(dpy, scr->dock_shadow);
-                               docked = wDockAttachIcon(scr->last_dock, aicon, 
ix, iy, False);
-                               if (scr->last_dock->auto_collapse)
-                                       collapsed = 0;
-
-                               if (workspace->clip &&
-                                   workspace->clip != scr->last_dock && 
workspace->clip->auto_raise_lower)
-                                       wDockLower(workspace->clip);
-
-                               if (!docked) {
-                                       /* If icon could not be docked, slide 
it back to the old
-                                        * position */
-                                       SlideWindow(icon->core->window, x, y, 
oldX, oldY);
+                               if (originalDock == NULL) { // docking an 
undocked appicon
+                                       docked = wDockAttachIcon(lastDock, 
aicon, ix, iy, False);
+                                       if (!docked) {
+                                               /* AppIcon got rejected 
(happens only when we can't get the
+                                                  command for that appicon, 
and the user cancels the
+                                                  wInputDialog asking for 
one). Make the rejection obvious by
+                                                  sliding the icon to its old 
position */
+                                               SlideWindow(icon->core->window, 
x, y, oldX, oldY);
+                                       }
                                }
-                       } else {
-                               if (movingSingle) {
-                                       /* move back to its place */
-                                       SlideWindow(icon->core->window, x, y, 
oldX, oldY);
-                                       wAppIconMove(aicon, oldX, oldY);
-                               } else {
-                                       XMoveWindow(dpy, icon->core->window, x, 
y);
-                                       aicon->x_pos = x;
-                                       aicon->y_pos = y;
+                               else { // moving a docked appicon to a dock
+                                       if (originalDock == lastDock) {
+                                               docked = True;
+                                               wDockReattachIcon(originalDock, 
aicon, ix, iy);
+                                       }
+                                       else {
+                                               docked = 
wDockMoveIconBetweenDocks(originalDock, lastDock, aicon, ix, iy);
+                                               if (!docked) {
+                                                       /* Possible scenario: 
user moved an auto-attracted appicon
+                                                          from the clip to the 
dock, and cancelled the wInputDialog
+                                                          asking for a command 
*/
+                                                       
SlideWindow(icon->core->window, x, y, oldX, oldY);
+                                                       
wDockReattachIcon(originalDock, aicon, aicon->xindex, aicon->yindex);
+                                               }
+                                       }
+                               }
+                               // No matter what happened above, check to 
lower lastDock
+                               if (lastDock->auto_raise_lower)
+                                       wDockLower(lastDock);
+                               /* If docked (or tried to dock) to a 
auto_collapsing dock, unset
+                                * collapsed, so that wHandleAppIconMove 
doesn't collapse it
+                                * right away (the timer will take care of it) 
*/
+                               if (lastDock->auto_collapse)
+                                       collapsed = 0;
+                       }
+                       else {
+                               if (originalDock != NULL) { /* Detaching a 
docked appicon */
+                                       if (superfluous) {
+                                               if (!aicon->running && 
!wPreferences.no_animations) {
+                                                       /* We need to deselect 
it, even if is deselected in
+                                                        * wDockDetach(), 
because else DoKaboom() will fail.
+                                                        */
+                                                       if 
(aicon->icon->selected)
+                                                               
wIconSelect(aicon->icon);
+                                                       DoKaboom(scr, 
aicon->icon->core->window, x, y);
+                                               }
+                                       }
+                                       wDockDetach(originalDock, aicon);
                                }
-                               if (workspace->clip && 
workspace->clip->auto_raise_lower)
-                                       wDockLower(workspace->clip);
                        }
                        if (collapsed) {
-                               scr->last_dock->collapsed = 1;
-                               wDockHideIcons(scr->last_dock);
+                               lastDock->collapsed = 1;
+                               wDockHideIcons(lastDock);
                                collapsed = 0;
                        }
                        if (superfluous) {
@@ -899,17 +995,21 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * 
event)
                                        XFreePixmap(dpy, ghost);
                                XSetWindowBackground(dpy, scr->dock_shadow, 
scr->white_pixel);
                        }
-
-                       if (wPreferences.auto_arrange_icons)
+                       if (showed_all_clips) {
+                               int i;
+                               for (i = 0; i < scr->workspace_count; i++) {
+                                       if (i == scr->current_workspace)
+                                               continue;
+                                       
wDockHideIcons(scr->workspaces[i]->clip);
+                               }
+                       }
+                       if (wPreferences.auto_arrange_icons && !(originalDock 
!= NULL && docked))
+                               /* Need to rearrange unless moving from dock to 
dock */
                                wArrangeIcons(scr, True);
-
-                       if (wPreferences.single_click && !hasMoved)
-                               iconDblClick(desc, event);
-
-                       done = 1;
-                       break;
+                       return hasMoved;
                }
        }
+       return False; /* Never reached */
 }
 
 /* This function save the application icon and store the path in the 
Dictionary */
diff --git a/src/appicon.h b/src/appicon.h
index d63d9a7..f5aa0d5 100644
--- a/src/appicon.h
+++ b/src/appicon.h
@@ -71,6 +71,7 @@ typedef struct WAppIcon {
 
 WAppIcon *wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance,
                                char *wm_class, int tile);
+Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event);
 
 void wAppIconDestroy(WAppIcon *aicon);
 void wAppIconPaint(WAppIcon *aicon);
diff --git a/src/dock.c b/src/dock.c
index 41c9efb..e2352fd 100644
--- a/src/dock.c
+++ b/src/dock.c
@@ -105,8 +105,6 @@ static void clipLeave(WDock *dock);
 
 static void handleClipChangeWorkspace(WScreen *scr, XEvent *event);
 
-static Bool moveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int 
x, int y);
-
 static void clipEnterNotify(WObjDescriptor *desc, XEvent *event);
 static void clipLeaveNotify(WObjDescriptor *desc, XEvent *event);
 static void clipAutoCollapse(void *cdata);
@@ -115,7 +113,6 @@ static void launchDockedApplication(WAppIcon *btn, Bool 
withSelection);
 
 static void clipAutoLower(void *cdata);
 static void clipAutoRaise(void *cdata);
-static void reattachIcon(WDock *dock, WAppIcon *icon, int x, int y);
 static WAppIcon *mainIconCreate(WScreen *scr, int type);
 
 static int onScreen(WScreen *scr, int x, int y);
@@ -781,13 +778,13 @@ static void switchWSCommand(WMenu *menu, WMenuEntry 
*entry)
 
                WM_ITERATE_ARRAY(selectedIcons, btn, iter) {
                        if (wDockFindFreeSlot(dest, &x, &y)) {
-                               moveIconBetweenDocks(src, dest, btn, x, y);
+                               wDockMoveIconBetweenDocks(src, dest, btn, x, y);
                                XUnmapWindow(dpy, btn->icon->core->window);
                        }
                }
        } else if (icon != scr->clip_icon) {
                if (wDockFindFreeSlot(dest, &x, &y)) {
-                       moveIconBetweenDocks(src, dest, icon, x, y);
+                       wDockMoveIconBetweenDocks(src, dest, icon, x, y);
                        XUnmapWindow(dpy, icon->icon->core->window);
                }
        }
@@ -1961,7 +1958,7 @@ Bool wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, 
int y, Bool update_icon
        return True;
 }
 
-static void reattachIcon(WDock *dock, WAppIcon *icon, int x, int y)
+void wDockReattachIcon(WDock *dock, WAppIcon *icon, int x, int y)
 {
        int index;
 
@@ -1978,7 +1975,7 @@ static void reattachIcon(WDock *dock, WAppIcon *icon, int 
x, int y)
        icon->y_pos = dock->y_pos + y * ICON_SIZE;
 }
 
-static Bool moveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int 
x, int y)
+Bool wDockMoveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, 
int y)
 {
        WWindow *wwin;
        char *command = NULL;
@@ -2941,7 +2938,7 @@ void wClipUpdateForWorkspaceChange(WScreen *scr, int 
workspace)
                        WAppIconChain *chain = scr->global_icons;
 
                        while (chain) {
-                               moveIconBetweenDocks(chain->aicon->dock,
+                               wDockMoveIconBetweenDocks(chain->aicon->dock,
                                                     
scr->workspaces[workspace]->clip,
                                                     chain->aicon, 
chain->aicon->xindex, chain->aicon->yindex);
                                if (scr->workspaces[workspace]->clip->collapsed)
@@ -3400,217 +3397,6 @@ static void handleDockMove(WDock *dock, WAppIcon 
*aicon, XEvent *event)
        }
 }
 
-static Bool handleIconMove(WDock *dock, WAppIcon *aicon, XEvent *event)
-{
-       WScreen *scr = dock->screen_ptr;
-       Window wins[2];
-       WIcon *icon = aicon->icon;
-       WDock *dock2 = NULL, *last_dock = dock, *clip = NULL;
-       int ondock, grabbed = 0, change_dock = 0, collapsed = 0;
-       XEvent ev;
-       int x = aicon->x_pos, y = aicon->y_pos;
-       int ofs_x = event->xbutton.x, ofs_y = event->xbutton.y;
-       int shad_x = x, shad_y = y;
-       int ix = aicon->xindex, iy = aicon->yindex;
-       int tmp;
-       Pixmap ghost = None;
-       Bool docked;
-       int superfluous = wPreferences.superfluous;     /* we catch it to avoid 
problems */
-       int omnipresent = aicon->omnipresent;   /* this must be cached!!! */
-       Bool showed_all_clips = False;
-       Bool hasMoved = False;
-
-       if (wPreferences.flags.noupdates)
-               return hasMoved;
-
-       if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
-                        | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
-                        GrabModeAsync, None, None, CurrentTime) != 
GrabSuccess) {
-       }
-
-       if (!(event->xbutton.state & MOD_MASK))
-               wRaiseFrame(icon->core);
-
-       if (!wPreferences.flags.noclip)
-               clip = scr->workspaces[scr->current_workspace]->clip;
-
-       if (dock == scr->dock && !wPreferences.flags.noclip)
-               dock2 = clip;
-       else if (dock != scr->dock && !wPreferences.flags.nodock)
-               dock2 = scr->dock;
-
-       wins[0] = icon->core->window;
-       wins[1] = scr->dock_shadow;
-       XRestackWindows(dpy, wins, 2);
-       XMoveResizeWindow(dpy, scr->dock_shadow, aicon->x_pos, aicon->y_pos, 
ICON_SIZE, ICON_SIZE);
-       if (superfluous) {
-               if (icon->pixmap != None)
-                       ghost = MakeGhostIcon(scr, icon->pixmap);
-               else
-                       ghost = MakeGhostIcon(scr, icon->core->window);
-
-               XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost);
-               XClearWindow(dpy, scr->dock_shadow);
-       }
-       XMapWindow(dpy, scr->dock_shadow);
-
-       ondock = 1;
-
-       while (1) {
-               XMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | 
ButtonPressMask
-                          | ButtonMotionMask | ExposureMask, &ev);
-               switch (ev.type) {
-               case Expose:
-                       WMHandleEvent(&ev);
-                       break;
-
-               case MotionNotify:
-                       hasMoved = True;
-                       if (!grabbed) {
-                               if (abs(ofs_x - ev.xmotion.x) >= MOVE_THRESHOLD
-                                   || abs(ofs_y - ev.xmotion.y) >= 
MOVE_THRESHOLD) {
-                                       XChangeActivePointerGrab(dpy, 
ButtonMotionMask
-                                                                | 
ButtonReleaseMask | ButtonPressMask,
-                                                                
wCursor[WCUR_MOVE], CurrentTime);
-                                       grabbed = 1;
-                               } else {
-                                       break;
-                               }
-                       }
-
-                       if (omnipresent && !showed_all_clips) {
-                               int i;
-                               for (i = 0; i < scr->workspace_count; i++) {
-                                       if (i == scr->current_workspace)
-                                               continue;
-                                       
wDockShowIcons(scr->workspaces[i]->clip);
-                                       /* Note: if dock is collapsed (for 
instance,
-                                          because it auto-collapses), its icons
-                                          still won't show up */
-                               }
-                               showed_all_clips = True; /* To prevent 
flickering */
-                       }
-
-                       x = ev.xmotion.x_root - ofs_x;
-                       y = ev.xmotion.y_root - ofs_y;
-                       tmp = wDockSnapIcon(dock, aicon, x, y, &ix, &iy, True);
-                       if (tmp && dock2) {
-                               change_dock = 0;
-                               if (last_dock != dock && collapsed) {
-                                       last_dock->collapsed = 1;
-                                       wDockHideIcons(last_dock);
-                                       collapsed = 0;
-                               }
-                               if (!collapsed && (collapsed = 
dock->collapsed)) {
-                                       dock->collapsed = 0;
-                                       wDockShowIcons(dock);
-                               }
-                               if (dock->auto_raise_lower)
-                                       wDockRaise(dock);
-                               last_dock = dock;
-                       } else if (dock2) {
-                               tmp = wDockSnapIcon(dock2, aicon, x, y, &ix, 
&iy, False);
-                               if (tmp) {
-                                       change_dock = 1;
-                                       if (last_dock != dock2 && collapsed) {
-                                               last_dock->collapsed = 1;
-                                               wDockHideIcons(last_dock);
-                                               collapsed = 0;
-                                       }
-                                       if (!collapsed && (collapsed = 
dock2->collapsed)) {
-                                               dock2->collapsed = 0;
-                                               wDockShowIcons(dock2);
-                                       }
-                                       if (dock2->auto_raise_lower)
-                                               wDockRaise(dock2);
-                                       last_dock = dock2;
-                               }
-                       }
-                       if (aicon->launching || aicon->lock || (aicon->running 
&& !(ev.xmotion.state & MOD_MASK))
-                           || (!aicon->running && tmp)) {
-                               shad_x = last_dock->x_pos + ix * 
wPreferences.icon_size;
-                               shad_y = last_dock->y_pos + iy * 
wPreferences.icon_size;
-
-                               XMoveWindow(dpy, scr->dock_shadow, shad_x, 
shad_y);
-
-                               if (!ondock)
-                                       XMapWindow(dpy, scr->dock_shadow);
-
-                               ondock = 1;
-                       } else {
-                               if (ondock)
-                                       XUnmapWindow(dpy, scr->dock_shadow);
-
-                               ondock = 0;
-                       }
-                       XMoveWindow(dpy, icon->core->window, x, y);
-                       break;
-
-               case ButtonPress:
-                       break;
-
-               case ButtonRelease:
-                       if (ev.xbutton.button != event->xbutton.button)
-                               break;
-                       XUngrabPointer(dpy, CurrentTime);
-                       if (ondock) {
-                               SlideWindow(icon->core->window, x, y, shad_x, 
shad_y);
-                               XUnmapWindow(dpy, scr->dock_shadow);
-                               if (!change_dock) {
-                                       reattachIcon(dock, aicon, ix, iy);
-                                       if (clip && dock != clip && 
clip->auto_raise_lower)
-                                               wDockLower(clip);
-                               } else {
-                                       docked = moveIconBetweenDocks(dock, 
dock2, aicon, ix, iy);
-                                       if (!docked) {
-                                               /* Slide it back if dock 
rejected it */
-                                               SlideWindow(icon->core->window, 
x, y, aicon->x_pos, aicon->y_pos);
-                                               reattachIcon(dock, aicon, 
aicon->xindex, aicon->yindex);
-                                       }
-                                       if (last_dock->type == WM_CLIP && 
last_dock->auto_collapse)
-                                               collapsed = 0;
-                               }
-                       } else {
-                               aicon->x_pos = x;
-                               aicon->y_pos = y;
-                               if (superfluous) {
-                                       if (!aicon->running && 
!wPreferences.no_animations) {
-                                               /* We need to deselect it, even 
if is deselected in
-                                                * wDockDetach(), because else 
DoKaboom() will fail.
-                                                */
-                                               if (aicon->icon->selected)
-                                                       
wIconSelect(aicon->icon);
-
-                                               DoKaboom(scr, 
aicon->icon->core->window, x, y);
-                                       }
-                               }
-                               if (clip && clip->auto_raise_lower)
-                                       wDockLower(clip);
-                               wDockDetach(dock, aicon);
-                       }
-                       if (collapsed) {
-                               last_dock->collapsed = 1;
-                               wDockHideIcons(last_dock);
-                               collapsed = 0;
-                       }
-                       if (superfluous) {
-                               if (ghost != None)
-                                       XFreePixmap(dpy, ghost);
-                               XSetWindowBackground(dpy, scr->dock_shadow, 
scr->white_pixel);
-                       }
-                       if (showed_all_clips) {
-                               int i;
-                               for (i = 0; i < scr->workspace_count; i++) {
-                                       if (i == scr->current_workspace)
-                                               continue;
-                                       
wDockHideIcons(scr->workspaces[i]->clip);
-                               }
-                       }
-                       return hasMoved;;
-               }
-       }
-       return False;  /* never reached */
-}
 
 static int getClipButton(int px, int py)
 {
@@ -3730,7 +3516,7 @@ static void iconMouseDown(WObjDescriptor *desc, XEvent 
*event)
                        else
                                handleDockMove(dock, aicon, event);
                } else {
-                       Bool hasMoved = handleIconMove(dock, aicon, event);
+                       Bool hasMoved = wHandleAppIconMove(aicon, event);
                        if (wPreferences.single_click && !hasMoved)
                                iconDblClick(desc, event);
                }
diff --git a/src/dock.h b/src/dock.h
index 47d963d..8cc6842 100644
--- a/src/dock.h
+++ b/src/dock.h
@@ -82,6 +82,8 @@ Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, 
int req_y,
                    int *ret_x, int *ret_y, int redocking);
 Bool wDockFindFreeSlot(WDock *dock, int *req_x, int *req_y);
 void wDockDetach(WDock *dock, WAppIcon *icon);
+Bool wDockMoveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, 
int y);
+void wDockReattachIcon(WDock *dock, WAppIcon *icon, int x, int y);
 
 void wDockFinishLaunch(WDock *dock, WAppIcon *icon);
 void wDockTrackWindowLaunch(WDock *dock, Window window);
-- 
1.7.10.4


-- 
To unsubscribe, send mail to [email protected].

Reply via email to