[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
This commit is contained in:
parent
d3da912d72
commit
f14adfe545
3 changed files with 43 additions and 94 deletions
83
geometry.cpp
83
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.
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue