+ endResize();
+ } else if (re->window == frame.window) {
+ if (re->button == 2 && re->state == Mod1Mask)
+ XUngrabPointer(blackbox->getXDisplay(), CurrentTime);
+ }
+}
+
+
+void BlackboxWindow::beginMove(int x_root, int y_root) {
+ assert(! (flags.resizing || flags.moving));
+
+ /*
+ Only one window can be moved/resized at a time. If another window is already
+ being moved or resized, then stop it before whating to work with this one.
+ */
+ BlackboxWindow *changing = blackbox->getChangingWindow();
+ if (changing && changing != this) {
+ if (changing->flags.moving)
+ changing->endMove();
+ else // if (changing->flags.resizing)
+ changing->endResize();
+ }
+
+ XGrabPointer(blackbox->getXDisplay(), frame.window, False,
+ PointerMotionMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync,
+ None, blackbox->getMoveCursor(), CurrentTime);
+
+ if (windowmenu && windowmenu->isVisible())
+ windowmenu->hide();
+
+ flags.moving = True;
+ blackbox->setChangingWindow(this);
+
+ if (! screen->doOpaqueMove()) {
+ XGrabServer(blackbox->getXDisplay());
+
+ frame.changing = frame.rect;
+ screen->showPosition(frame.changing.x(), frame.changing.y());
+
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(),
+ frame.changing.x(),
+ frame.changing.y(),
+ frame.changing.width() - 1,
+ frame.changing.height() - 1);
+ }
+
+ frame.grab_x = x_root - frame.rect.x() - frame.border_w;
+ frame.grab_y = y_root - frame.rect.y() - frame.border_w;
+}
+
+void BlackboxWindow::doMove(int x_root, int y_root) {
+ assert(flags.moving);
+ assert(blackbox->getChangingWindow() == this);
+
+ int dx = x_root - frame.grab_x, dy = y_root - frame.grab_y;
+ dx -= frame.border_w;
+ dy -= frame.border_w;
+
+ const int snap_distance = screen->getEdgeSnapThreshold();
+
+ if (snap_distance) {
+ Rect srect = screen->availableArea();
+ // window corners
+ const int wleft = dx,
+ wright = dx + frame.rect.width() - 1,
+ wtop = dy,
+ wbottom = dy + frame.rect.height() - 1;
+
+ int dleft = std::abs(wleft - srect.left()),
+ dright = std::abs(wright - srect.right()),
+ dtop = std::abs(wtop - srect.top()),
+ dbottom = std::abs(wbottom - srect.bottom());
+
+ // snap left?
+ if (dleft < snap_distance && dleft < dright)
+ dx = srect.left();
+ // snap right?
+ else if (dright < snap_distance && dright < dleft)
+ dx = srect.right() - frame.rect.width() + 1;
+
+ // snap top?
+ if (dtop < snap_distance && dtop < dbottom)
+ dy = srect.top();
+ // snap bottom?
+ else if (dbottom < snap_distance && dbottom < dtop)
+ dy = srect.bottom() - frame.rect.height() + 1;
+
+ srect = screen->getRect(); // now get the full screen
+
+ dleft = std::abs(wleft - srect.left()),
+ dright = std::abs(wright - srect.right()),
+ dtop = std::abs(wtop - srect.top()),
+ dbottom = std::abs(wbottom - srect.bottom());
+
+ // snap left?
+ if (dleft < snap_distance && dleft < dright)
+ dx = srect.left();
+ // snap right?
+ else if (dright < snap_distance && dright < dleft)
+ dx = srect.right() - frame.rect.width() + 1;
+
+ // snap top?
+ if (dtop < snap_distance && dtop < dbottom)
+ dy = srect.top();
+ // snap bottom?
+ else if (dbottom < snap_distance && dbottom < dtop)
+ dy = srect.bottom() - frame.rect.height() + 1;
+ }
+
+ if (screen->doOpaqueMove()) {
+ configure(dx, dy, frame.rect.width(), frame.rect.height());
+ } else {
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(),
+ frame.changing.x(),
+ frame.changing.y(),
+ frame.changing.width() - 1,
+ frame.changing.height() - 1);
+
+ frame.changing.setPos(dx, dy);
+
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(),
+ frame.changing.x(),
+ frame.changing.y(),
+ frame.changing.width() - 1,
+ frame.changing.height() - 1);
+ }
+
+ screen->showPosition(dx, dy);
+}
+
+
+void BlackboxWindow::endMove(void) {
+ assert(flags.moving);
+ assert(blackbox->getChangingWindow() == this);
+
+ flags.moving = False;
+ blackbox->setChangingWindow(0);
+
+ if (! screen->doOpaqueMove()) {
+ /* when drawing the rubber band, we need to make sure we only draw inside
+ * the frame... frame.changing_* contain the new coords for the window,
+ * so we need to subtract 1 from changing_w/changing_h every where we
+ * draw the rubber band (for both moving and resizing)
+ */