Make Window::interactiveMoveOffset() relative

Window::interactiveMoveOffset() stores the move offset in pixels, but it
is somewhat annoying to deal with when the window size changes, for example
when the window is unmaximized.

This change makes Window::interactiveMoveOffset() store a ratio where
the move offset can be found. This simplifies the code a bit and fixes
the cursor jumping to the topleft window corner. Although there are other
glitches.

CCBUG: 449105
This commit is contained in:
Vlad Zahorodnii 2024-03-09 13:37:56 +02:00
parent 656313455b
commit 2c7301b3ee
4 changed files with 16 additions and 36 deletions

View file

@ -1323,8 +1323,7 @@ void X11Window::NETMoveResize(qreal x_root, qreal y_root, NET::Direction directi
finishInteractiveMoveResize(false);
}
setInteractiveMoveResizePointerButtonDown(true);
setInteractiveMoveOffset(QPointF(x_root - x(), y_root - y())); // map from global
setInvertedInteractiveMoveOffset(rect().bottomRight() - interactiveMoveOffset());
setInteractiveMoveOffset(QPointF(qreal(x_root - x()) / width(), qreal(y_root - y())) / height()); // map from global
setUnrestrictedInteractiveMoveResize(false);
setInteractiveMoveResizeGravity(convert[direction]);
if (!startInteractiveMoveResize()) {

View file

@ -1385,7 +1385,8 @@ void Window::handleInteractiveMoveResize(const QPointF &local, const QPointF &gl
}
if (!isInteractiveMoveResize()) {
QPointF p(local - interactiveMoveOffset());
const QPointF offset(interactiveMoveOffset().x() * width(), interactiveMoveOffset().y() * height());
const QPointF p(local - offset);
if (p.manhattanLength() >= QApplication::startDragDistance()) {
if (!startInteractiveMoveResize()) {
setInteractiveMoveResizePointerButtonDown(false);
@ -1453,8 +1454,6 @@ void Window::handleInteractiveMoveResize(const QPointF &local, const QPointF &gl
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);
}
@ -1530,12 +1529,12 @@ QRectF Window::nextInteractiveResizeGeometry(const QPointF &global) const
// 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())
QPointF topleft = global - interactiveMoveOffset();
QPointF bottomright = global + invertedInteractiveMoveOffset();
QRectF orig = initialInteractiveMoveResizeGeometry();
QPointF topleft = global - QPointF(interactiveMoveOffset().x() * orig.width(), interactiveMoveOffset().y() * orig.height());
QPointF bottomright = global + QPointF((1.0 - interactiveMoveOffset().x()) * orig.width(), (1.0 - interactiveMoveOffset().y()) * orig.height());
// TODO move whole group when moving its leader or when the leader is not mapped?
QRectF orig = initialInteractiveMoveResizeGeometry();
SizeMode sizeMode = SizeModeAny;
auto calculateMoveResizeGeom = [&topleft, &bottomright, &orig, &nextMoveResizeGeom, &sizeMode, &gravity]() {
switch (gravity) {
@ -1696,20 +1695,15 @@ QRectF Window::nextInteractiveResizeGeometry(const QPointF &global) const
QRectF Window::nextInteractiveMoveGeometry(const QPointF &global) const
{
const QRectF currentMoveResizeGeom = moveResizeGeometry();
QRectF nextMoveResizeGeom = moveResizeGeometry();
const QRectF currentMoveResizeGeom = frameGeometry();
if (!isMovable()) {
return nextMoveResizeGeom;
return currentMoveResizeGeom;
}
QPointF topleft = global - interactiveMoveOffset();
// first move, then snap, then check bounds
QRectF geometry = nextMoveResizeGeom;
geometry.moveTopLeft(topleft);
geometry.moveTopLeft(workspace()->adjustWindowPosition(this, geometry.topLeft(),
isUnrestrictedInteractiveMoveResize()));
nextMoveResizeGeom = geometry;
QRectF nextMoveResizeGeom = currentMoveResizeGeom;
nextMoveResizeGeom.moveTopLeft(QPointF(global.x() - interactiveMoveOffset().x() * currentMoveResizeGeom.width(),
global.y() - interactiveMoveOffset().y() * currentMoveResizeGeom.height()));
nextMoveResizeGeom.moveTopLeft(workspace()->adjustWindowPosition(this, nextMoveResizeGeom.topLeft(), isUnrestrictedInteractiveMoveResize()));
if (!isUnrestrictedInteractiveMoveResize()) {
const StrutRects strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop());
@ -2177,8 +2171,7 @@ bool Window::performMouseCommand(Options::MouseCommand cmd, const QPointF &globa
}
setInteractiveMoveResizeGravity(Gravity::None);
setInteractiveMoveResizePointerButtonDown(true);
setInteractiveMoveOffset(QPointF(globalPos.x() - x(), globalPos.y() - y())); // map from global
setInvertedInteractiveMoveOffset(rect().bottomRight() - interactiveMoveOffset());
setInteractiveMoveOffset(QPointF(qreal(globalPos.x() - x()) / width(), qreal(globalPos.y() - y()) / height())); // map from global
setUnrestrictedInteractiveMoveResize((cmd == Options::MouseActivateRaiseAndUnrestrictedMove
|| cmd == Options::MouseUnrestrictedMove));
if (!startInteractiveMoveResize()) {
@ -2197,7 +2190,7 @@ bool Window::performMouseCommand(Options::MouseCommand cmd, const QPointF &globa
}
setInteractiveMoveResizePointerButtonDown(true);
const QPointF moveOffset = QPointF(globalPos.x() - x(), globalPos.y() - y()); // map from global
setInteractiveMoveOffset(moveOffset);
setInteractiveMoveOffset(QPointF(moveOffset.x() / width(), moveOffset.y() / height()));
int x = moveOffset.x(), y = moveOffset.y();
bool left = x < width() / 3;
bool right = x >= 2 * width() / 3;
@ -2212,7 +2205,6 @@ bool Window::performMouseCommand(Options::MouseCommand cmd, const QPointF &globa
gravity = (x < width() / 2) ? Gravity::Left : Gravity::Right;
}
setInteractiveMoveResizeGravity(gravity);
setInvertedInteractiveMoveOffset(rect().bottomRight() - moveOffset);
setUnrestrictedInteractiveMoveResize((cmd == Options::MouseUnrestrictedResize));
if (!startInteractiveMoveResize()) {
setInteractiveMoveResizePointerButtonDown(false);
@ -2804,8 +2796,7 @@ bool Window::processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu)
{
setInteractiveMoveResizeGravity(mouseGravity());
setInteractiveMoveResizePointerButtonDown(true);
setInteractiveMoveOffset(event->pos());
setInvertedInteractiveMoveOffset(rect().bottomRight() - interactiveMoveOffset());
setInteractiveMoveOffset(QPointF(qreal(event->pos().x()) / width(), qreal(event->pos().y()) / height()));
setUnrestrictedInteractiveMoveResize(false);
startDelayedInteractiveMoveResize();
updateCursor();

View file

@ -1598,14 +1598,6 @@ protected:
{
m_interactiveMoveResize.offset = offset;
}
QPointF invertedInteractiveMoveOffset() const
{
return m_interactiveMoveResize.invertedOffset;
}
void setInvertedInteractiveMoveOffset(const QPointF &offset)
{
m_interactiveMoveResize.invertedOffset = offset;
}
QRectF initialInteractiveMoveResizeGeometry() const
{
return m_interactiveMoveResize.initialGeometry;
@ -1802,7 +1794,6 @@ protected:
bool enabled = false;
bool unrestricted = false;
QPointF offset;
QPointF invertedOffset;
QRectF initialGeometry;
QRectF initialGeometryRestore;
Gravity gravity = Gravity::None;

View file

@ -959,8 +959,7 @@ void XdgToplevelWindow::handleResizeRequested(SeatInterface *seat, XdgToplevelIn
} else {
cursorPos = input()->tablet()->position();
}
setInteractiveMoveOffset(cursorPos - pos()); // map from global
setInvertedInteractiveMoveOffset(rect().bottomRight() - interactiveMoveOffset());
setInteractiveMoveOffset(QPointF((cursorPos.x() - x()) / width(), (cursorPos.y() - y()) / height())); // map from global
setUnrestrictedInteractiveMoveResize(false);
Gravity gravity;
switch (anchor) {