Switch to Xcb::Window geometry where it makes sense
There are a couple of reasons why it's worthwhile doing: The first is that it makes the logic in the updateServerGeometry() function reusable for the interactive code path. As of now, when the window is being interactively resized, doInteractiveResizeSync() will issue some xcb_configure_window() calls but then it also implicitly assumes that updateServerGeometry() will call updateShape() and updateInputWindow() but skip m_frame.setGeometry() later. That is confusing, and error prone. For example, if somebody drops m_lastFrameGeometry in favor of m_frame.geometry() (which is an absolutely reasonable thing to do btw!!), a regression will be introduced: things would appear to work at first, but then eventually bug reports about input working weirdly would start piling up. The second is hidpi scaling of wayland clients. toXNative(a + b + c) is not the same as toXNative(a) + toXNative(b) + toXNative(c). By switching to the device geometry, we leave less space for making an error. The third is that lets us clean up some geometry manipulation code. When dealing with window hierarchies, it's more convenient to have m_window.position() rather than a dedicated property in the X11Window class such as wrapperPos().
This commit is contained in:
parent
02d43147b5
commit
a41fac2d75
2 changed files with 20 additions and 34 deletions
|
@ -1269,9 +1269,9 @@ void X11Window::updateInputWindow()
|
|||
if (left != 0 || top != 0 || right != 0 || bottom != 0) {
|
||||
region = QRegion(-left,
|
||||
-top,
|
||||
decoration()->size().width() + left + right,
|
||||
decoration()->size().height() + top + bottom);
|
||||
region = region.subtracted(decoration()->rect());
|
||||
m_frame.width() + left + right,
|
||||
m_frame.height() + top + bottom);
|
||||
region = region.subtracted(QRect(0, 0, m_frame.width(), m_frame.height()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1284,10 +1284,10 @@ void X11Window::updateInputWindow()
|
|||
input_offset = bounds.topLeft();
|
||||
|
||||
// Move the bounding rect to screen coordinates
|
||||
bounds.translate(frameGeometry().topLeft().toPoint());
|
||||
bounds.translate(m_frame.position());
|
||||
|
||||
// Move the region to input window coordinates
|
||||
region.translate(-input_offset.toPoint());
|
||||
region.translate(-input_offset);
|
||||
|
||||
if (!m_decoInputExtent.isValid()) {
|
||||
const uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
|
||||
|
@ -1542,8 +1542,8 @@ void X11Window::updateShape()
|
|||
XCB_SHAPE_SK_BOUNDING,
|
||||
XCB_SHAPE_SK_BOUNDING,
|
||||
frameId(),
|
||||
Xcb::toXNative(wrapperPos().x()),
|
||||
Xcb::toXNative(wrapperPos().y()),
|
||||
m_wrapper.x(),
|
||||
m_wrapper.y(),
|
||||
window());
|
||||
}
|
||||
} else if (app_noborder) {
|
||||
|
@ -1586,8 +1586,7 @@ void X11Window::updateInputShape()
|
|||
if (!shape_helper_window.isValid()) {
|
||||
shape_helper_window.create(QRect(0, 0, 1, 1));
|
||||
}
|
||||
const QSize bufferSize = Xcb::toXNative(m_bufferGeometry.size());
|
||||
shape_helper_window.resize(bufferSize);
|
||||
shape_helper_window.resize(m_frame.size());
|
||||
xcb_connection_t *c = kwinApp()->x11Connection();
|
||||
xcb_shape_combine(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_BOUNDING,
|
||||
shape_helper_window, 0, 0, frameId());
|
||||
|
@ -1596,16 +1595,16 @@ void X11Window::updateInputShape()
|
|||
XCB_SHAPE_SK_INPUT,
|
||||
XCB_SHAPE_SK_BOUNDING,
|
||||
shape_helper_window,
|
||||
Xcb::toXNative(wrapperPos().x()),
|
||||
Xcb::toXNative(wrapperPos().y()),
|
||||
m_wrapper.x(),
|
||||
m_wrapper.y(),
|
||||
window());
|
||||
xcb_shape_combine(c,
|
||||
XCB_SHAPE_SO_UNION,
|
||||
XCB_SHAPE_SK_INPUT,
|
||||
XCB_SHAPE_SK_INPUT,
|
||||
shape_helper_window,
|
||||
Xcb::toXNative(wrapperPos().x()),
|
||||
Xcb::toXNative(wrapperPos().y()),
|
||||
m_wrapper.x(),
|
||||
m_wrapper.y(),
|
||||
window());
|
||||
xcb_shape_combine(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_INPUT,
|
||||
frameId(), 0, 0, shape_helper_window);
|
||||
|
@ -2912,15 +2911,6 @@ QRectF X11Window::frameRectToBufferRect(const QRectF &rect) const
|
|||
return frameRectToClientRect(rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the wrapper window relative to the frame window. On X11, it
|
||||
* is the same as QPoint(borderLeft(), borderTop()). On Wayland, it's QPoint(0, 0).
|
||||
*/
|
||||
QPointF X11Window::wrapperPos() const
|
||||
{
|
||||
return m_clientGeometry.topLeft() - m_bufferGeometry.topLeft();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the natural size of the window, if the window is not shaded it's the same
|
||||
* as size().
|
||||
|
@ -3926,10 +3916,10 @@ void X11Window::sendSyntheticConfigureNotify()
|
|||
u.event.response_type = XCB_CONFIGURE_NOTIFY;
|
||||
u.event.event = window();
|
||||
u.event.window = window();
|
||||
u.event.x = Xcb::toXNative(m_clientGeometry.x());
|
||||
u.event.y = Xcb::toXNative(m_clientGeometry.y());
|
||||
u.event.width = Xcb::toXNative(m_clientGeometry.width());
|
||||
u.event.height = Xcb::toXNative(m_clientGeometry.height());
|
||||
u.event.x = m_frame.x() + m_wrapper.x() + m_client.x();
|
||||
u.event.y = m_frame.y() + m_wrapper.y() + m_client.y();
|
||||
u.event.width = m_client.width();
|
||||
u.event.height = m_client.height();
|
||||
u.event.border_width = 0;
|
||||
u.event.above_sibling = XCB_WINDOW_NONE;
|
||||
u.event.override_redirect = 0;
|
||||
|
@ -4446,8 +4436,9 @@ void X11Window::updateServerGeometry()
|
|||
} else {
|
||||
m_frame.move(Xcb::toXNative(m_bufferGeometry.topLeft()));
|
||||
sendSyntheticConfigureNotify();
|
||||
// Unconditionally move the input window: it won't affect rendering
|
||||
m_decoInputExtent.move(Xcb::toXNative(pos() + inputPos()));
|
||||
if (m_decoInputExtent.isValid()) {
|
||||
m_decoInputExtent.move(m_frame.position() + input_offset);
|
||||
}
|
||||
}
|
||||
|
||||
m_lastBufferGeometry = m_bufferGeometry;
|
||||
|
|
|
@ -100,7 +100,6 @@ public:
|
|||
QSizeF frameSizeToClientSize(const QSizeF &size) const override;
|
||||
QSizeF clientSizeToFrameSize(const QSizeF &size) const override;
|
||||
QRectF frameRectToBufferRect(const QRectF &rect) const;
|
||||
QPointF wrapperPos() const;
|
||||
QSizeF implicitSize() const;
|
||||
|
||||
void blockGeometryUpdates(bool block);
|
||||
|
@ -136,10 +135,6 @@ public:
|
|||
QSizeF minSize() const override;
|
||||
QSizeF maxSize() const override;
|
||||
QSizeF basicUnit() const;
|
||||
QPointF inputPos() const
|
||||
{
|
||||
return input_offset;
|
||||
} // Inside of geometry()
|
||||
|
||||
bool windowEvent(xcb_generic_event_t *e);
|
||||
WindowType windowType() const override;
|
||||
|
@ -518,7 +513,7 @@ private:
|
|||
bool sessionActivityOverride;
|
||||
|
||||
Xcb::Window m_decoInputExtent;
|
||||
QPointF input_offset;
|
||||
QPoint input_offset; // in device pixels, valid only on X11
|
||||
|
||||
QTimer *m_focusOutTimer;
|
||||
QTimer m_releaseTimer;
|
||||
|
|
Loading…
Reference in a new issue