From f14adfe545fe16768876b43587ece7c3eec8ebe3 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 3 Dec 2019 09:33:14 +0200 Subject: [PATCH] [x11] Make geometry updates in X11Client more comprehensible Summary: This change makes geometry updates in the X11Client class simpler and also fixes a bug in the move() method. Test Plan: All tests pass. Reviewers: #kwin Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D25710 --- geometry.cpp | 83 ++++++++++++++++++++++++--------------------------- x11client.cpp | 50 ++----------------------------- x11client.h | 4 +-- 3 files changed, 43 insertions(+), 94 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index a106e93a27..4a4f189271 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -1968,11 +1968,11 @@ void X11Client::setFrameGeometry(int x, int y, int w, int h, ForceGeometry_t for if (!areGeometryUpdatesBlocked() && frameGeometry != rules()->checkGeometry(frameGeometry)) { qCDebug(KWIN_CORE) << "forced geometry fail:" << frameGeometry << ":" << rules()->checkGeometry(frameGeometry); } - if (!canUpdateGeometry(frameGeometry, bufferGeometry, force)) { + geom = frameGeometry; + if (force == NormalGeometrySet && m_bufferGeometry == bufferGeometry && pendingGeometryUpdate() == PendingGeometryNone) { return; } m_bufferGeometry = bufferGeometry; - geom = frameGeometry; if (areGeometryUpdatesBlocked()) { if (pendingGeometryUpdate() == PendingGeometryForced) {} // maximum, nothing needed @@ -1982,35 +1982,7 @@ void X11Client::setFrameGeometry(int x, int y, int w, int h, ForceGeometry_t for setPendingGeometryUpdate(PendingGeometryNormal); return; } - const QRect oldBufferGeometry = bufferGeometryBeforeUpdateBlocking(); - bool resized = (oldBufferGeometry.size() != m_bufferGeometry.size() || pendingGeometryUpdate() == PendingGeometryForced); - if (resized) { - resizeDecoration(); - m_frame.setGeometry(m_bufferGeometry); - if (!isShade()) { - QSize cs = clientSize(); - m_wrapper.setGeometry(QRect(clientPos(), cs)); - if (!isResize() || syncRequest.counter == XCB_NONE) - m_client.setGeometry(0, 0, cs.width(), cs.height()); - // SELI - won't this be too expensive? - // THOMAS - yes, but gtk+ clients will not resize without ... - sendSyntheticConfigureNotify(); - } - updateShape(); - } else { - if (isMoveResize()) { - if (compositing()) // Defer the X update until we leave this mode - needsXWindowMove = true; - else - m_frame.move(m_bufferGeometry.topLeft()); // sendSyntheticConfigureNotify() on finish shall be sufficient - } else { - m_frame.move(m_bufferGeometry.topLeft()); - sendSyntheticConfigureNotify(); - } - - // Unconditionally move the input window: it won't affect rendering - m_decoInputExtent.move(QPoint(x, y) + inputPos()); - } + updateServerGeometry(); updateWindowRules(Rules::Position|Rules::Size); // keep track of old maximize mode @@ -2019,7 +1991,7 @@ void X11Client::setFrameGeometry(int x, int y, int w, int h, ForceGeometry_t for workspace()->updateStackingOrder(); // Need to regenerate decoration pixmaps when the buffer size is changed. - if (oldBufferGeometry.size() != m_bufferGeometry.size()) { + if (bufferGeometryBeforeUpdateBlocking().size() != m_bufferGeometry.size()) { discardWindowPixmap(); } emit geometryShapeChanged(this, frameGeometryBeforeUpdateBlocking()); @@ -2055,13 +2027,13 @@ void X11Client::plainResize(int w, int h, ForceGeometry_t force) if (!areGeometryUpdatesBlocked() && frameSize != rules()->checkSize(frameSize)) { qCDebug(KWIN_CORE) << "forced size fail:" << frameSize << ":" << rules()->checkSize(frameSize); } + geom.setSize(frameSize); // resuming geometry updates is handled only in setGeometry() Q_ASSERT(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked()); - if (!canUpdateSize(frameSize, bufferSize, force)) { + if (force == NormalGeometrySet && m_bufferGeometry.size() == bufferSize) { return; } m_bufferGeometry.setSize(bufferSize); - geom.setSize(frameSize); if (areGeometryUpdatesBlocked()) { if (pendingGeometryUpdate() == PendingGeometryForced) {} // maximum, nothing needed @@ -2071,16 +2043,7 @@ void X11Client::plainResize(int w, int h, ForceGeometry_t force) setPendingGeometryUpdate(PendingGeometryNormal); return; } - resizeDecoration(); - m_frame.resize(m_bufferGeometry.size()); - if (!isShade()) { - QSize cs = clientSize(); - m_wrapper.setGeometry(QRect(clientPos(), cs)); - m_client.setGeometry(0, 0, cs.width(), cs.height()); - } - updateShape(); - - sendSyntheticConfigureNotify(); + updateServerGeometry(); updateWindowRules(Rules::Position|Rules::Size); screens()->setCurrent(this); workspace()->updateStackingOrder(); @@ -2094,6 +2057,38 @@ void X11Client::plainResize(int w, int h, ForceGeometry_t force) emit geometryChanged(); } +void X11Client::updateServerGeometry() +{ + if (m_frame.geometry().size() != m_bufferGeometry.size() || pendingGeometryUpdate() == PendingGeometryForced) { + resizeDecoration(); + m_frame.setGeometry(m_bufferGeometry); + if (!isShade()) { + QSize cs = clientSize(); + m_wrapper.setGeometry(QRect(clientPos(), cs)); + if (!isResize() || syncRequest.counter == XCB_NONE) { + m_client.setGeometry(0, 0, cs.width(), cs.height()); + } + // SELI - won't this be too expensive? + // THOMAS - yes, but gtk+ clients will not resize without ... + sendSyntheticConfigureNotify(); + } + updateShape(); + } else { + if (isMoveResize()) { + if (compositing()) { // Defer the X update until we leave this mode + needsXWindowMove = true; + } else { + m_frame.move(m_bufferGeometry.topLeft()); // sendSyntheticConfigureNotify() on finish shall be sufficient + } + } else { + m_frame.move(m_bufferGeometry.topLeft()); + sendSyntheticConfigureNotify(); + } + // Unconditionally move the input window: it won't affect rendering + m_decoInputExtent.move(pos() + inputPos()); + } +} + /** * Reimplemented to inform the client about the new window position. */ diff --git a/x11client.cpp b/x11client.cpp index fd4d51433e..c9f510c1cc 100644 --- a/x11client.cpp +++ b/x11client.cpp @@ -2864,49 +2864,6 @@ void X11Client::handleSync() addRepaintFull(); } -bool X11Client::canUpdatePosition(const QPoint &frame, const QPoint &buffer, ForceGeometry_t force) const -{ - // Obey forced geometry updates. - if (force != NormalGeometrySet) { - return true; - } - // Server-side geometry and our geometry are out of sync. - if (bufferGeometry().topLeft() != buffer) { - return true; - } - if (frameGeometry().topLeft() != frame) { - return true; - } - return false; -} - -bool X11Client::canUpdateSize(const QSize &frame, const QSize &buffer, ForceGeometry_t force) const -{ - // Obey forced geometry updates. - if (force != NormalGeometrySet) { - return true; - } - // Server-side geometry and our geometry are out of sync. - if (bufferGeometry().size() != buffer) { - return true; - } - if (frameGeometry().size() != frame) { - return true; - } - return false; -} - -bool X11Client::canUpdateGeometry(const QRect &frame, const QRect &buffer, ForceGeometry_t force) const -{ - if (canUpdatePosition(frame.topLeft(), buffer.topLeft(), force)) { - return true; - } - if (canUpdateSize(frame.size(), buffer.size(), force)) { - return true; - } - return pendingGeometryUpdate() != PendingGeometryNone; -} - void X11Client::move(int x, int y, ForceGeometry_t force) { const QPoint framePosition(x, y); @@ -2917,11 +2874,11 @@ void X11Client::move(int x, int y, ForceGeometry_t force) if (!areGeometryUpdatesBlocked() && framePosition != rules()->checkPosition(framePosition)) { qCDebug(KWIN_CORE) << "forced position fail:" << framePosition << ":" << rules()->checkPosition(framePosition); } - if (!canUpdatePosition(framePosition, bufferPosition, force)) { + geom.moveTopLeft(framePosition); + if (force == NormalGeometrySet && m_bufferGeometry.topLeft() == bufferPosition) { return; } m_bufferGeometry.moveTopLeft(bufferPosition); - geom.moveTopLeft(framePosition); if (areGeometryUpdatesBlocked()) { if (pendingGeometryUpdate() == PendingGeometryForced) { // Maximum, nothing needed. @@ -2932,8 +2889,7 @@ void X11Client::move(int x, int y, ForceGeometry_t force) } return; } - m_frame.move(m_bufferGeometry.topLeft()); - sendSyntheticConfigureNotify(); + updateServerGeometry(); updateWindowRules(Rules::Position); screens()->setCurrent(this); workspace()->updateStackingOrder(); diff --git a/x11client.h b/x11client.h index 34bb1371d7..6b3b2c050d 100644 --- a/x11client.h +++ b/x11client.h @@ -446,9 +446,6 @@ private: void destroyDecoration() override; void updateFrameExtents(); void setClientFrameExtents(const NETStrut &strut); - bool canUpdatePosition(const QPoint &frame, const QPoint &buffer, ForceGeometry_t force) const; - bool canUpdateSize(const QSize &frame, const QSize &buffer, ForceGeometry_t force) const; - bool canUpdateGeometry(const QRect &frame, const QRect &buffer, ForceGeometry_t force) const; void internalShow(); void internalHide(); @@ -458,6 +455,7 @@ private: void updateHiddenPreview(); void updateInputShape(); + void updateServerGeometry(); xcb_timestamp_t readUserTimeMapTimestamp(const KStartupInfoId* asn_id, const KStartupInfoData* asn_data, bool session) const;