diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-10 12:40:29 +0200 |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-10 12:40:56 +0200 |
commit | 6b0cd62e5ecad075c4528d3a09ec903ab057680e (patch) | |
tree | daa08ef647df36a774c5ce78738dffb9c2d154bf /src/plugins/platforms | |
parent | f56a905ced02b387f6ac7f482f997629f27bcf89 (diff) |
Added frameMargins() API and support in XCB plugin.
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 92 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 5 |
2 files changed, 97 insertions, 0 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 86a8c75878..d635ee8bcb 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -113,6 +113,7 @@ void QXcbWindow::create() m_windowState = Qt::WindowNoState; m_hasReceivedSyncRequest = false; + m_dirtyFrameMargins = true; Qt::WindowType type = window()->windowType(); @@ -304,6 +305,93 @@ void QXcbWindow::setGeometry(const QRect &rect) Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values)); } +QMargins QXcbWindow::frameMargins() const +{ + if (m_dirtyFrameMargins) { + xcb_window_t window = m_window; + xcb_window_t parent = m_window; + + bool foundRoot = false; + + const QVector<xcb_window_t> &virtualRoots = + connection()->wmSupport()->virtualRoots(); + + while (!foundRoot) { + xcb_query_tree_cookie_t cookie = xcb_query_tree(xcb_connection(), parent); + + xcb_generic_error_t *error; + xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, &error); + if (reply) { + if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1) { + foundRoot = true; + } else { + window = parent; + parent = reply->parent; + } + + free(reply); + } else { + if (error) { + connection()->handleXcbError(error); + free(error); + } + + m_dirtyFrameMargins = false; + m_frameMargins = QMargins(); + return m_frameMargins; + } + } + + QPoint offset; + + xcb_generic_error_t *error; + xcb_translate_coordinates_reply_t *reply = + xcb_translate_coordinates_reply( + xcb_connection(), + xcb_translate_coordinates(xcb_connection(), window, parent, 0, 0), + &error); + + if (reply) { + offset = QPoint(reply->dst_x, reply->dst_y); + free(reply); + } else if (error) { + free(error); + } + + xcb_get_geometry_reply_t *geom = + xcb_get_geometry_reply( + xcb_connection(), + xcb_get_geometry(xcb_connection(), parent), + &error); + + if (geom) { + // -- + // add the border_width for the window managers frame... some window managers + // do not use a border_width of zero for their frames, and if we the left and + // top strut, we ensure that pos() is absolutely correct. frameGeometry() + // will still be incorrect though... perhaps i should have foffset as well, to + // indicate the frame offset (equal to the border_width on X). + // - Brad + // -- copied from qwidget_x11.cpp + + int left = offset.x() + geom->border_width; + int top = offset.y() + geom->border_width; + int right = geom->width + geom->border_width - geometry().width() - offset.x(); + int bottom = geom->height + geom->border_width - geometry().height() - offset.y(); + + m_frameMargins = QMargins(left, top, right, bottom); + + free(geom); + } else if (error) { + free(error); + } + + m_dirtyFrameMargins = false; + } + + return m_frameMargins; +} + void QXcbWindow::setVisible(bool visible) { if (visible) @@ -327,6 +415,8 @@ void QXcbWindow::show() free(error); } + m_dirtyFrameMargins = true; + if (window()->windowState() & Qt::WindowMinimized) xcb_wm_hints_set_iconic(&hints); else @@ -635,6 +725,8 @@ Qt::WindowState QXcbWindow::setWindowState(Qt::WindowState state) if (state == m_windowState) return state; + m_dirtyFrameMargins = true; + // unset old state switch (m_windowState) { case Qt::WindowMinimized: diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index f50a611b4e..501e9a33c4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -61,6 +61,8 @@ public: void setGeometry(const QRect &rect); + QMargins frameMargins() const; + void setVisible(bool visible); Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); Qt::WindowState setWindowState(Qt::WindowState state); @@ -139,6 +141,9 @@ private: bool m_mapped; xcb_window_t m_netWmUserTimeWindow; + + mutable bool m_dirtyFrameMargins; + mutable QMargins m_frameMargins; }; #endif |