diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 7f1d5dd..15d014c 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1302,6 +1302,40 @@ QRect QXcbWindow::windowToWmGeometry(QRect r) const r.translate(m_frameMargins.left(), m_frameMargins.top()); } else if (!frameInclusive && m_gravity == XCB_GRAVITY_NORTH_WEST) { r.translate(-m_frameMargins.left(), -m_frameMargins.top()); + } else if (m_gravity == XCB_GRAVITY_CENTER) { + if (frameInclusive) { + // r describes the *position* of the window frame and the *size* of + // our own window. Yes, this is a weird QRect. Blame + // QWindow::setFramePosition(). + // + // The center of the frame is at: + // r.topLeft() + frame_size/2 + // = r.topLeft() + (r.size() + QSize(left+right, top+bottom))/2 + // + // The returned rect should have a position pos whose center will be: + // pos.topLeft() + pos.size()/2 (This is just as below) + // = pos.topLeft() + r.size()/2 + // + // Since those two centers are equal, we can calculate pos.topLeft: + // pos.topLeft() = r.topLeft() + QSize(left+right, top+bottom)/2 + r.translate((m_frameMargins.left() + m_frameMargins.right())/2, + (m_frameMargins.top() + m_frameMargins.bottom())/2); + } else { + // The frame's center will be at: + // frame.topLeft() + frame.size()/2 + // = (r.topLeft() - QSize(left, top)) + frame.size()/2 + // = (r.topLeft() - QSize(left, top)) + (r.size() + QSize(left+right, top+bottom))/2 + // = r.topLeft() + (r.size() + QSize(right-left, bottom-top))/2 + // + // The returned rect should have a position pos whose center will be: + // pos.topLeft() + pos.size()/2 (This is just as above) + // = pos.topLeft() + r.size()/2 + // + // Again, those two centers are equal and we end up with: + // pos.topLeft() = r.topLeft() + QSize(right-left, bottom-top)/2 + r.translate((m_frameMargins.right() - m_frameMargins.left())/2, + (m_frameMargins.bottom() - m_frameMargins.top())/2); + } } return r; }