Use the same logic to configure window during normal resize and interactive resize
X11Window::doInteractiveResizeSync() configures the x windows but it only does a half of the things that should be done. The rest of it is assumed to be performed by X11Window::updateServerGeometry() when XSync request is acked later. The current state is not ideal and error prone. This change makes X11Window::moveResizeInternal() and X11Window::doInteractiveResizeSync() share the same code to configure the x windows to simplify the code. It also drops X11Window::m_last{Frame,Client,Buffer}Geometry to further simplify the code and make X window geometry tracking even more robust.
This commit is contained in:
parent
706d604305
commit
3f7b26cd9a
2 changed files with 28 additions and 52 deletions
|
@ -4315,9 +4315,10 @@ void X11Window::blockGeometryUpdates(bool block)
|
|||
++m_blockGeometryUpdates;
|
||||
} else {
|
||||
if (--m_blockGeometryUpdates == 0) {
|
||||
if (m_lastBufferGeometry != m_bufferGeometry || m_lastFrameGeometry != m_frameGeometry || m_lastClientGeometry != m_clientGeometry) {
|
||||
updateServerGeometry();
|
||||
}
|
||||
const QRect nativeFrameGeometry = Xcb::toXNative(m_bufferGeometry);
|
||||
const QRect nativeWrapperGeometry = Xcb::toXNative(m_clientGeometry.translated(-m_bufferGeometry.topLeft()));
|
||||
const QRect nativeClientGeometry = QRect(0, 0, nativeWrapperGeometry.width(), nativeWrapperGeometry.height());
|
||||
configure(nativeFrameGeometry, nativeWrapperGeometry, nativeClientGeometry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4375,7 +4376,13 @@ void X11Window::moveResizeInternal(const QRectF &rect, MoveResizeMode mode)
|
|||
m_bufferGeometry = bufferGeometry;
|
||||
m_output = workspace()->outputAt(frameGeometry.center());
|
||||
|
||||
updateServerGeometry();
|
||||
if (!areGeometryUpdatesBlocked()) {
|
||||
const QRect nativeFrameGeometry = Xcb::toXNative(m_bufferGeometry);
|
||||
const QRect nativeWrapperGeometry = Xcb::toXNative(m_clientGeometry.translated(-m_bufferGeometry.topLeft()));
|
||||
const QRect nativeClientGeometry = QRect(0, 0, nativeWrapperGeometry.width(), nativeWrapperGeometry.height());
|
||||
configure(nativeFrameGeometry, nativeWrapperGeometry, nativeClientGeometry);
|
||||
}
|
||||
|
||||
updateWindowRules(Rules::Position | Rules::Size);
|
||||
|
||||
if (isActive()) {
|
||||
|
@ -4398,37 +4405,19 @@ void X11Window::moveResizeInternal(const QRectF &rect, MoveResizeMode mode)
|
|||
Q_EMIT shapeChanged();
|
||||
}
|
||||
|
||||
void X11Window::updateServerGeometry()
|
||||
void X11Window::configure(const QRect &nativeFrame, const QRect &nativeWrapper, const QRect &nativeClient)
|
||||
{
|
||||
if (areGeometryUpdatesBlocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QRectF oldBufferGeometry = m_lastBufferGeometry;
|
||||
|
||||
// Compute the old client rect, the client geometry is always inside the buffer geometry.
|
||||
const QRectF oldClientRect = m_lastClientGeometry.translated(-m_lastBufferGeometry.topLeft());
|
||||
const QRectF clientRect = m_clientGeometry.translated(-m_bufferGeometry.topLeft());
|
||||
|
||||
if (oldBufferGeometry.size() != m_bufferGeometry.size() || oldClientRect != clientRect) {
|
||||
// If the client is being interactively resized, then the frame window, the wrapper window,
|
||||
// and the client window have correct geometry at this point, so we don't have to configure
|
||||
// them again.
|
||||
const QRect xFrameGeometry = Xcb::toXNative(m_bufferGeometry);
|
||||
if (m_frame.geometry() != xFrameGeometry) {
|
||||
m_frame.setGeometry(xFrameGeometry);
|
||||
if (m_frame.size() != nativeFrame.size() || m_wrapper.geometry() != nativeWrapper) {
|
||||
if (m_frame.geometry() != nativeFrame) {
|
||||
m_frame.setGeometry(nativeFrame);
|
||||
}
|
||||
if (!isShade()) {
|
||||
const QRect xWrapperGeometry = Xcb::toXNative(clientRect);
|
||||
if (m_wrapper.geometry() != xWrapperGeometry) {
|
||||
m_wrapper.setGeometry(xWrapperGeometry);
|
||||
if (m_wrapper.geometry() != nativeWrapper) {
|
||||
m_wrapper.setGeometry(nativeWrapper);
|
||||
}
|
||||
const QRect xClientGeometry = Xcb::toXNative(QRectF(QPointF(0, 0), clientRect.size()));
|
||||
if (m_client.geometry() != xClientGeometry) {
|
||||
m_client.setGeometry(xClientGeometry);
|
||||
if (m_client.geometry() != nativeClient) {
|
||||
m_client.setGeometry(nativeClient);
|
||||
}
|
||||
// SELI - won't this be too expensive?
|
||||
// THOMAS - yes, but gtk+ clients will not resize without ...
|
||||
sendSyntheticConfigureNotify();
|
||||
}
|
||||
|
||||
|
@ -4442,17 +4431,13 @@ void X11Window::updateServerGeometry()
|
|||
|
||||
updateInputShape();
|
||||
updateInputWindow();
|
||||
} else {
|
||||
m_frame.move(Xcb::toXNative(m_bufferGeometry.topLeft()));
|
||||
sendSyntheticConfigureNotify();
|
||||
} else if (m_frame.position() != nativeFrame.topLeft()) {
|
||||
m_frame.move(nativeFrame.topLeft());
|
||||
if (m_decoInputExtent.isValid()) {
|
||||
m_decoInputExtent.move(m_frame.position() + input_offset);
|
||||
}
|
||||
sendSyntheticConfigureNotify();
|
||||
}
|
||||
|
||||
m_lastBufferGeometry = m_bufferGeometry;
|
||||
m_lastFrameGeometry = m_frameGeometry;
|
||||
m_lastClientGeometry = m_clientGeometry;
|
||||
}
|
||||
|
||||
static bool changeMaximizeRecursion = false;
|
||||
|
@ -4811,11 +4796,11 @@ void X11Window::doInteractiveResizeSync(const QRectF &rect)
|
|||
const QRectF moveResizeClientGeometry = frameRectToClientRect(moveResizeFrameGeometry);
|
||||
const QRectF moveResizeBufferGeometry = frameRectToBufferRect(moveResizeFrameGeometry);
|
||||
|
||||
const QRect xFrameGeometry = Xcb::toXNative(moveResizeBufferGeometry);
|
||||
const QRect xWrapperGeometry = Xcb::toXNative(moveResizeClientGeometry.translated(-moveResizeBufferGeometry.topLeft()));
|
||||
const QRect xClientGeometry = Xcb::toXNative(QRectF(QPointF(0, 0), moveResizeClientGeometry.size()));
|
||||
const QRect nativeFrameGeometry = Xcb::toXNative(moveResizeBufferGeometry);
|
||||
const QRect nativeWrapperGeometry = Xcb::toXNative(moveResizeClientGeometry.translated(-moveResizeBufferGeometry.topLeft()));
|
||||
const QRect nativeClientGeometry = Xcb::toXNative(QRectF(QPointF(0, 0), moveResizeClientGeometry.size()));
|
||||
|
||||
if (m_frame.geometry() == xFrameGeometry && m_wrapper.geometry() == xWrapperGeometry && m_client.geometry() == xClientGeometry) {
|
||||
if (m_frame.geometry() == nativeFrameGeometry && m_wrapper.geometry() == nativeWrapperGeometry && m_client.geometry() == nativeClientGeometry) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4839,13 +4824,7 @@ void X11Window::doInteractiveResizeSync(const QRectF &rect)
|
|||
m_syncRequest.timeout->start(33);
|
||||
}
|
||||
|
||||
// According to the Composite extension spec, a window will get a new pixmap allocated each time
|
||||
// it is mapped or resized. Given that we redirect frame windows and not client windows, we have
|
||||
// to resize the frame window in order to forcefully reallocate offscreen storage. If we don't do
|
||||
// this, then we might render partially updated client window. I know, it sucks.
|
||||
m_frame.setGeometry(xFrameGeometry);
|
||||
m_wrapper.setGeometry(xWrapperGeometry);
|
||||
m_client.setGeometry(xClientGeometry);
|
||||
configure(nativeFrameGeometry, nativeWrapperGeometry, nativeClientGeometry);
|
||||
}
|
||||
|
||||
void X11Window::handleSyncTimeout()
|
||||
|
|
|
@ -409,7 +409,7 @@ private:
|
|||
void updateHiddenPreview();
|
||||
|
||||
void updateInputShape();
|
||||
void updateServerGeometry();
|
||||
void configure(const QRect &nativeFrame, const QRect &nativeWrapper, const QRect &nativeClient);
|
||||
void discardWindowPixmap();
|
||||
void updateWindowPixmap();
|
||||
|
||||
|
@ -521,9 +521,6 @@ private:
|
|||
QMetaObject::Connection m_edgeGeometryTrackingConnection;
|
||||
|
||||
QMarginsF m_clientFrameExtents;
|
||||
QRectF m_lastBufferGeometry;
|
||||
QRectF m_lastFrameGeometry;
|
||||
QRectF m_lastClientGeometry;
|
||||
int m_blockGeometryUpdates = 0; // > 0 = New geometry is remembered, but not actually set
|
||||
|
||||
std::unique_ptr<X11DecorationRenderer> m_decorationRenderer;
|
||||
|
|
Loading…
Reference in a new issue