summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-06-10 12:40:29 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-06-10 12:40:56 +0200
commit6b0cd62e5ecad075c4528d3a09ec903ab057680e (patch)
treedaa08ef647df36a774c5ce78738dffb9c2d154bf /src/plugins/platforms
parentf56a905ced02b387f6ac7f482f997629f27bcf89 (diff)
Added frameMargins() API and support in XCB plugin.
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp92
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h5
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