diff --git a/src/window.cpp b/src/window.cpp index bf8aee2c2b..6ff6335b18 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1379,39 +1379,117 @@ void Window::updateInteractiveMoveResize(const QPointF ¤tGlobalCursor) void Window::handleInteractiveMoveResize(const QPointF &local, const QPointF &global) { - const QRectF oldGeo = moveResizeGeometry(); - handleInteractiveMoveResize(local.x(), local.y(), global.x(), global.y()); - if (!isRequestedFullScreen() && isInteractiveMove()) { - if (quickTileMode() != QuickTileMode(QuickTileFlag::None) && oldGeo != moveResizeGeometry()) { - GeometryUpdatesBlocker blocker(this); - setQuickTileMode(QuickTileFlag::None); - const QRectF &geom_restore = geometryRestore(); - setInteractiveMoveOffset(QPointF(double(interactiveMoveOffset().x()) / double(oldGeo.width()) * double(geom_restore.width()), - double(interactiveMoveOffset().y()) / double(oldGeo.height()) * double(geom_restore.height()))); - if (rules()->checkMaximize(MaximizeRestore) == MaximizeRestore) { - setMoveResizeGeometry(geom_restore); + if (isWaitingForInteractiveMoveResizeSync()) { + return; // we're still waiting for the client or the timeout + } + + const Gravity gravity = interactiveMoveResizeGravity(); + if ((gravity == Gravity::None && !isMovableAcrossScreens()) + || (gravity != Gravity::None && (isShade() || !isResizable()))) { + return; + } + + if (!isInteractiveMoveResize()) { + QPointF p(local - interactiveMoveOffset()); + if (p.manhattanLength() >= QApplication::startDragDistance()) { + if (!startInteractiveMoveResize()) { + setInteractiveMoveResizePointerButtonDown(false); + updateCursor(); + return; } - handleInteractiveMoveResize(local.x(), local.y(), global.x(), global.y()); // fix position + updateCursor(); + } else { + return; } + } - if (input()->keyboardModifiers() & Qt::ShiftModifier) { - resetQuickTilingMaximizationZones(); - const auto &r = quickTileGeometry(QuickTileFlag::Custom, global); - if (r.isEmpty()) { - workspace()->outline()->hide(); - } else { - if (!workspace()->outline()->isActive() || workspace()->outline()->geometry() != r.toRect()) { - workspace()->outline()->show(r.toRect(), moveResizeGeometry().toRect()); + // ShadeHover or ShadeActive, ShadeNormal was already avoided above + if (gravity != Gravity::None && shadeMode() != ShadeNone) { + setShade(ShadeNone); + } + + if (isInteractiveResize()) { + if (m_tile && m_tile->supportsResizeGravity(gravity)) { + m_tile->resizeFromGravity(gravity, global.x(), global.y()); + return; + } + } + + const QRectF currentMoveResizeGeom = moveResizeGeometry(); + QRectF nextMoveResizeGeom = currentMoveResizeGeom; + + if (isInteractiveResize()) { + nextMoveResizeGeom = nextInteractiveResizeGeometry(global); + if (nextMoveResizeGeom != currentMoveResizeGeom) { + doInteractiveResizeSync(nextMoveResizeGeom); + Q_EMIT interactiveMoveResizeStepped(nextMoveResizeGeom); + } + } else if (isInteractiveMove()) { + auto nextMoveGeometry = [this, &global]() { + if (!isMovable()) { // isMovableAcrossScreens() must have been true to get here + // Special moving of maximized windows on Xinerama screens + Output *output = workspace()->outputAt(global); + QRectF nextMoveResizeGeom; + if (isRequestedFullScreen()) { + nextMoveResizeGeom = workspace()->clientArea(FullScreenArea, this, output); + } else { + nextMoveResizeGeom = workspace()->clientArea(MaximizeArea, this, output); + const QSizeF adjSize = constrainFrameSize(nextMoveResizeGeom.size(), SizeModeMax); + if (adjSize != nextMoveResizeGeom.size()) { + QRectF r(nextMoveResizeGeom); + nextMoveResizeGeom.setSize(adjSize); + nextMoveResizeGeom.moveCenter(r.center()); + } } + + return nextMoveResizeGeom; } - } else { - if (quickTileMode() == QuickTileMode(QuickTileFlag::None) && isResizable()) { - checkQuickTilingMaximizationZones(global.x(), global.y()); + + return nextInteractiveMoveGeometry(global); + }; + + nextMoveResizeGeom = nextMoveGeometry(); + if (nextMoveResizeGeom != currentMoveResizeGeom) { + GeometryUpdatesBlocker blocker(this); + + if (!isRequestedFullScreen() && quickTileMode() != QuickTileMode(QuickTileFlag::None)) { + setQuickTileMode(QuickTileFlag::None); + + const QRectF &geom_restore = geometryRestore(); + setInteractiveMoveOffset(QPointF(double(interactiveMoveOffset().x()) / double(currentMoveResizeGeom.width()) * double(geom_restore.width()), + double(interactiveMoveOffset().y()) / double(currentMoveResizeGeom.height()) * double(geom_restore.height()))); + if (rules()->checkMaximize(MaximizeRestore) == MaximizeRestore) { + setMoveResizeGeometry(geom_restore); + } + nextMoveResizeGeom = nextMoveGeometry(); // fix position } - if (!m_electricMaximizing) { - // Only if we are in an electric maximizing gesture we should keep the outline, - // otherwise we must make sure it's hidden - workspace()->outline()->hide(); + + if (!isWaitingForInteractiveMoveResizeSync()) { + move(nextMoveResizeGeom.topLeft()); + Q_EMIT interactiveMoveResizeStepped(nextMoveResizeGeom); + } + } + + if (!isRequestedFullScreen()) { + if (input()->modifiersRelevantForGlobalShortcuts() & Qt::ShiftModifier) { + resetQuickTilingMaximizationZones(); + const auto &r = quickTileGeometry(QuickTileFlag::Custom, global); + if (r.isEmpty()) { + workspace()->outline()->hide(); + } else { + if (!workspace()->outline()->isActive() || workspace()->outline()->geometry() != r.toRect()) { + workspace()->outline()->show(r.toRect(), moveResizeGeometry().toRect()); + } + } + } else { + if (quickTileMode() == QuickTileMode(QuickTileFlag::None) && isResizable()) { + checkQuickTilingMaximizationZones(global.x(), global.y()); + } + if (!m_electricMaximizing) { + // Only if we are in an electric maximizing gesture we should keep the outline, + // otherwise we must make sure it's hidden + workspace()->outline()->hide(); + } } } } @@ -1714,86 +1792,6 @@ QRectF Window::nextInteractiveMoveGeometry(const QPointF &global) const return nextMoveResizeGeom; } -void Window::handleInteractiveMoveResize(qreal x, qreal y, qreal x_root, qreal y_root) -{ - if (isWaitingForInteractiveMoveResizeSync()) { - return; // we're still waiting for the client or the timeout - } - - const Gravity gravity = interactiveMoveResizeGravity(); - if ((gravity == Gravity::None && !isMovableAcrossScreens()) - || (gravity != Gravity::None && (isShade() || !isResizable()))) { - return; - } - - if (!isInteractiveMoveResize()) { - QPointF p(QPointF(x /* - padding_left*/, y /* - padding_top*/) - interactiveMoveOffset()); - if (p.manhattanLength() >= QApplication::startDragDistance()) { - if (!startInteractiveMoveResize()) { - setInteractiveMoveResizePointerButtonDown(false); - updateCursor(); - return; - } - updateCursor(); - } else { - return; - } - } - - // ShadeHover or ShadeActive, ShadeNormal was already avoided above - if (gravity != Gravity::None && shadeMode() != ShadeNone) { - setShade(ShadeNone); - } - - QPointF globalPos(x_root, y_root); - // these two points limit the geometry rectangle, i.e. if bottomleft resizing is done, - // the bottomleft corner should be at is at (topleft.x(), bottomright().y()) - const QRectF currentMoveResizeGeom = moveResizeGeometry(); - QRectF nextMoveResizeGeom = moveResizeGeometry(); - - // TODO move whole group when moving its leader or when the leader is not mapped? - - if (isInteractiveResize()) { - if (m_tile && m_tile->supportsResizeGravity(gravity)) { - m_tile->resizeFromGravity(gravity, x_root, y_root); - return; - } - - nextMoveResizeGeom = nextInteractiveResizeGeometry(globalPos); - } else if (isInteractiveMove()) { - Q_ASSERT(gravity == Gravity::None); - if (!isMovable()) { // isMovableAcrossScreens() must have been true to get here - // Special moving of maximized windows on Xinerama screens - Output *output = workspace()->outputAt(globalPos); - if (isRequestedFullScreen()) { - nextMoveResizeGeom = workspace()->clientArea(FullScreenArea, this, output); - } else { - nextMoveResizeGeom = workspace()->clientArea(MaximizeArea, this, output); - const QSizeF adjSize = constrainFrameSize(nextMoveResizeGeom.size(), SizeModeMax); - if (adjSize != nextMoveResizeGeom.size()) { - QRectF r(nextMoveResizeGeom); - nextMoveResizeGeom.setSize(adjSize); - nextMoveResizeGeom.moveCenter(r.center()); - } - } - } else { - nextMoveResizeGeom = nextInteractiveMoveGeometry(globalPos); - } - } else { - Q_UNREACHABLE(); - } - - if (nextMoveResizeGeom != currentMoveResizeGeom) { - if (isInteractiveMove()) { - move(nextMoveResizeGeom.topLeft()); - } else { - doInteractiveResizeSync(nextMoveResizeGeom); - } - - Q_EMIT interactiveMoveResizeStepped(nextMoveResizeGeom); - } -} - StrutRect Window::strutRect(StrutArea area) const { return StrutRect(); @@ -2739,7 +2737,7 @@ void Window::layoutDecorationRects(QRectF &left, QRectF &top, QRectF &right, QRe void Window::processDecorationMove(const QPointF &localPos, const QPointF &globalPos) { if (isInteractiveMoveResizePointerButtonDown()) { - handleInteractiveMoveResize(localPos.x(), localPos.y(), globalPos.x(), globalPos.y()); + handleInteractiveMoveResize(localPos, globalPos); return; } // TODO: handle modifiers diff --git a/src/window.h b/src/window.h index 6c69e30bcc..e27b26b5db 100644 --- a/src/window.h +++ b/src/window.h @@ -1676,7 +1676,6 @@ protected: * Default implementation does nothing. */ virtual void doInteractiveResizeSync(const QRectF &rect); - void handleInteractiveMoveResize(qreal x, qreal y, qreal x_root, qreal y_root); void handleInteractiveMoveResize(const QPointF &local, const QPointF &global); QRectF titleBarRect(const QRectF &rect, bool &transposed, int &requiredPixels) const; QRectF nextInteractiveMoveGeometry(const QPointF &global) const;