/** Move a client window. */ char MoveClient(ClientNode *np, int startx, int starty) { XEvent event; int oldx, oldy; int doMove; int north, south, east, west; int height; MaxFlags maxFlags; Assert(np); if(!(np->state.border & BORDER_MOVE)) { return 0; } if(np->state.status & STAT_FULLSCREEN) { return 0; } GrabMouseForMove(); RegisterCallback(0, SignalMove, NULL); np->controller = MoveController; shouldStopMove = 0; oldx = np->x; oldy = np->y; maxFlags = np->state.maxFlags; if(!(GetMouseMask() & (Button1Mask | Button2Mask))) { StopMove(np, 0, oldx, oldy, maxFlags); return 0; } GetBorderSize(&np->state, &north, &south, &east, &west); startx -= west; starty -= north; currentClient = np; atTop = atBottom = atLeft = atRight = 0; doMove = 0; for(;;) { WaitForEvent(&event); if(shouldStopMove) { np->controller = NULL; SetDefaultCursor(np->parent); UnregisterCallback(SignalMove, NULL); return doMove; } switch(event.type) { case ButtonRelease: if(event.xbutton.button == Button1 || event.xbutton.button == Button2) { StopMove(np, doMove, oldx, oldy, maxFlags); return doMove; } break; case MotionNotify: DiscardMotionEvents(&event, np->window); np->x = event.xmotion.x_root - startx; np->y = event.xmotion.y_root - starty; /* Get the move time used for desktop switching. */ if(!(atLeft | atTop | atRight | atBottom)) { if(event.xmotion.state & Mod1Mask) { moveTime.seconds = 0; moveTime.ms = 0; } else { GetCurrentTime(&moveTime); } } /* Determine if we are at a border for desktop switching. */ atLeft = atTop = atRight = atBottom = 0; if(event.xmotion.x_root == 0) { atLeft = 1; } else if(event.xmotion.x_root == rootWidth - 1) { atRight = 1; } if(event.xmotion.y_root == 0) { atTop = 1; } else if(event.xmotion.y_root == rootHeight - 1) { atBottom = 1; } if(event.xmotion.state & Mod1Mask) { /* Switch desktops immediately if alt is pressed. */ if(atLeft | atRight | atTop | atBottom) { TimeType now; GetCurrentTime(&now); UpdateDesktop(&now); } } else { /* If alt is not pressed, snap to borders. */ DoSnap(np); } if(!doMove && (abs(np->x - oldx) > MOVE_DELTA || abs(np->y - oldy) > MOVE_DELTA)) { if(np->state.maxFlags) { MaximizeClient(np, MAX_NONE); startx = np->width / 2; starty = -north / 2; MoveMouse(np->parent, startx, starty); } CreateMoveWindow(np); doMove = 1; } if(doMove) { if(settings.moveMode == MOVE_OUTLINE) { ClearOutline(); height = north + south; if(!(np->state.status & STAT_SHADED)) { height += np->height; } DrawOutline(np->x - west, np->y - north, np->width + west + east, height); } else { JXMoveWindow(display, np->parent, np->x - west, np->y - north); SendConfigureEvent(np); } UpdateMoveWindow(np); RequirePagerUpdate(); } break; default: break; } } }
/** Move a client window. */ char MoveClient(ClientNode *np, int startx, int starty, int snap) { XEvent event; int oldx, oldy; int doMove; int north, south, east, west; int height; int hmax, vmax; Assert(np); if(!(np->state.border & BORDER_MOVE)) { return 0; } if(np->state.status & STAT_FULLSCREEN) { return 0; } GrabMouseForMove(); RegisterCallback(0, SignalMove, NULL); np->controller = MoveController; shouldStopMove = 0; oldx = np->x; oldy = np->y; vmax = 0; hmax = 0; if(!(GetMouseMask() & (Button1Mask | Button2Mask))) { StopMove(np, 0, oldx, oldy, 0, 0); return 0; } GetBorderSize(&np->state, &north, &south, &east, &west); startx -= west; starty -= north; currentClient = np; atTop = 0; atBottom = 0; atLeft = 0; atRight = 0; doMove = 0; for(;;) { WaitForEvent(&event); if(shouldStopMove) { np->controller = NULL; SetDefaultCursor(np->parent); UnregisterCallback(SignalMove, NULL); return doMove; } switch(event.type) { case ButtonRelease: if(event.xbutton.button == Button1 || event.xbutton.button == Button2) { StopMove(np, doMove, oldx, oldy, hmax, vmax); return doMove; } break; case MotionNotify: DiscardMotionEvents(&event, np->window); np->x = event.xmotion.x_root - startx; np->y = event.xmotion.y_root - starty; GetCurrentTime(&moveTime); atLeft = 0; atTop = 0; atRight = 0; atBottom = 0; if(event.xmotion.x_root == 0) { atLeft = 1; } else if(event.xmotion.x_root == rootWidth - 1) { atRight = 1; } if(event.xmotion.y_root == 0) { atTop = 1; } else if(event.xmotion.y_root == rootHeight - 1) { atBottom = 1; } if(snap) { DoSnap(np); } if(!doMove && (abs(np->x - oldx) > MOVE_DELTA || abs(np->y - oldy) > MOVE_DELTA)) { if(np->state.status & (STAT_HMAX | STAT_VMAX)) { if(np->state.status & STAT_HMAX) { hmax = 1; } if(np->state.status & STAT_VMAX) { vmax = 1; } MaximizeClient(np, 0, 0); startx = np->width / 2; starty = -north / 2; MoveMouse(np->parent, startx, starty); } CreateMoveWindow(np); doMove = 1; } if(doMove) { if(settings.moveMode == MOVE_OUTLINE) { ClearOutline(); height = north + south; if(!(np->state.status & STAT_SHADED)) { height += np->height; } DrawOutline(np->x - west, np->y - north, np->width + west + east, height); } else { JXMoveWindow(display, np->parent, np->x - west, np->y - north); SendConfigureEvent(np); } UpdateMoveWindow(np); UpdatePager(); } break; default: break; } } }