static void appicon_move_or_detach(WDock *originalDock, WAppIcon *aicon, int x, int y) { virtual_screen *vscr = aicon->icon->vscr; int superfluous = wPreferences.superfluous; if (originalDock == NULL) return; /* 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(vscr, aicon->icon->core->window, x, y); } } wDockDetach(originalDock, aicon); if (originalDock->auto_collapse && !originalDock->collapsed) { originalDock->collapsed = 1; wDockHideIcons(originalDock); } if (originalDock->auto_raise_lower) wDockLower(originalDock); }
static void appicon_move_to_dock(WDock *originalDock, WDock *lastDock, WAppIcon *aicon, WIcon *icon, int x, int y, int oldX, int oldY, int shad_x, int shad_y, int ix, int iy, Bool *docked, Bool *collapsed) { virtual_screen *vscr = aicon->icon->vscr; WScreen *scr = vscr->screen_ptr; slide_window(icon->core->window, x, y, shad_x, shad_y); XUnmapWindow(dpy, scr->dock_shadow); 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 */ if (lastDock->type == WM_DRAWER) /* Also fill the gap left in the drawer */ wDrawerFillTheGap(lastDock, aicon, False); slide_window(icon->core->window, x, y, oldX, oldY); } } 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) { appicon_move_to_nodock(originalDock, lastDock, aicon, icon, x, y, oldX, oldY); } else { if (originalDock->auto_collapse && !originalDock->collapsed) { originalDock->collapsed = 1; wDockHideIcons(originalDock); } if (originalDock->auto_raise_lower) wDockLower(originalDock); } } } /* 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; }
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; if (aicon->editing || WCHECK_STATE(WSTATE_MODAL)) return; if (IsDoubleClick(scr, event)) { iconDblClick(desc, event); return; } if (event->xbutton.button == Button3) { WObjDescriptor *desc; WApplication *wapp = wApplicationOf(aicon->icon->owner->main_window); if (!wapp) return; if (event->xbutton.send_event && XGrabPointer(dpy, aicon->icon->core->window, True, ButtonMotionMask |ButtonReleaseMask|ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime) !=GrabSuccess) { wwarning("pointer grab failed for appicon menu"); return; } openApplicationMenu(wapp, event->xbutton.x_root, event->xbutton.y_root); /* allow drag select of menu */ desc = &scr->icon_menu->menu->descriptor; event->xbutton.send_event = True; (*desc->handle_mousedown)(desc, event); return; } #ifdef DEBUG puts("Moving icon"); #endif if (event->xbutton.state & MOD_MASK) wLowerFrame(icon->core); else wRaiseFrame(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"); } 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); 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); } while (!done) { WMMaskEvent(dpy, PointerMotionMask|ButtonReleaseMask|ButtonPressMask |ButtonMotionMask|ExposureMask, &ev); switch (ev.type) { case Expose: WMHandleEvent(&ev); break; case MotionNotify: hasMoved = True; if (!grabbed) { if (abs(dx-ev.xmotion.x)>=MOVE_THRESHOLD || abs(dy-ev.xmotion.y)>=MOVE_THRESHOLD) { XChangeActivePointerGrab(dpy, ButtonMotionMask |ButtonReleaseMask|ButtonPressMask, wCursor[WCUR_MOVE], CurrentTime); grabbed=1; } else { 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 (scr->last_dock != workspace->clip && collapsed) { scr->last_dock->collapsed = 1; wDockHideIcons(scr->last_dock); collapsed = 0; } if (!collapsed && (collapsed = workspace->clip->collapsed)) { workspace->clip->collapsed = 0; wDockShowIcons(workspace->clip); } 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) { XUnmapWindow(dpy, scr->dock_shadow); docking = 0; } } break; case ButtonPress: break; case ButtonRelease: if (ev.xbutton.button != clickButton) break; XUngrabPointer(dpy, CurrentTime); if (docking) { Bool docked; /* icon is trying to be docked */ SlideWindow(icon->core->window, x, y, shad_x, shad_y); XUnmapWindow(dpy, scr->dock_shadow); docked = wDockAttachIcon(scr->last_dock, aicon, ix, iy); 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); } wSoundPlay(WSOUND_DOCK); } 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; } if (workspace->clip && workspace->clip->auto_raise_lower) wDockLower(workspace->clip); } if (collapsed) { scr->last_dock->collapsed = 1; wDockHideIcons(scr->last_dock); collapsed = 0; } if (superfluous) { if (ghost!=None) XFreePixmap(dpy, ghost); XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel); } if (wPreferences.auto_arrange_icons) wArrangeIcons(scr, True); if (wPreferences.single_click && !hasMoved) iconDblClick(desc, event); done = 1; break; } } #ifdef DEBUG puts("End icon move"); #endif }
static void appicon_move_motion(virtual_screen *vscr, WScreen *scr, XEvent ev, WDock **lastDock, WDock **originalDock, WAppIcon *aicon, WDock **allDocks, Bool *collapsed, Bool *dockable, Bool *ondock, int *x, int *y, int *ix, int *iy, int *shad_x, int *shad_y, int *ofs_x, int *ofs_y, Bool *grabbed, int omnipresent, Bool *showed_all_clips) { WDock *theNewDock = NULL; int i, j; if (!(*grabbed)) { if (abs(*ofs_x - ev.xmotion.x) < MOVE_THRESHOLD && abs(*ofs_y - ev.xmotion.y) < MOVE_THRESHOLD) return; XChangeActivePointerGrab(dpy, ButtonMotionMask | ButtonReleaseMask | ButtonPressMask, wPreferences.cursor[WCUR_MOVE], CurrentTime); *grabbed = True; } if (omnipresent && !(*showed_all_clips)) { for (j = 0; j < vscr->workspace.count; j++) { if (j == vscr->workspace.current) continue; wDockShowIcons(vscr->workspace.array[j]->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; wAppIconMove(aicon, *x, *y); if (!(ev.xmotion.state & MOD_MASK) || aicon->launching || aicon->lock || *originalDock == NULL) { for (i = 0; *dockable && i < vscr->drawer.drawer_count + 2; i++) { WDock *theDock = allDocks[i]; if (theDock == NULL) break; if (wDockSnapIcon(theDock, aicon, *x, *y, ix, iy, (theDock == *originalDock))) { theNewDock = theDock; break; } } /* Stay in lastDock if no dock really wants us */ if (*originalDock != NULL && theNewDock == NULL && (aicon->launching || aicon->lock || aicon->running)) theNewDock = *lastDock; } if (*lastDock != NULL && *lastDock != theNewDock) { /* Leave lastDock in the state we found it */ if ((*lastDock)->type == WM_DRAWER) wDrawerFillTheGap(*lastDock, aicon, (*lastDock == *originalDock)); 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 (theNewDock->auto_raise_lower) { wDockRaise(theNewDock); /* And raise the moving tile above it */ wRaiseFrame(aicon->icon->vscr, aicon->icon->core); } *lastDock = theNewDock; } *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 = NULL; if (*ondock) XUnmapWindow(dpy, scr->dock_shadow); *ondock = 0; } }