summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Volkov <a.volkov@rusbitech.ru>2015-05-04 22:41:01 +0300
committerAlexander Volkov <a.volkov@rusbitech.ru>2015-07-08 13:35:26 +0000
commit27bf6df294b30d0335c6e63ca84461f09ea32ac6 (patch)
tree73464a8f73024f89419634c9d43b2bfa78df89be
parent8db7bad6e1901718f5ababc7849a8fb6c4415370 (diff)
xcb: Use _NET_FRAME_EXTENTS to get frame margins
Some window managers don't reparent the client window into the frame, so the old method of calculating frame margins by the geometries of the window and it's frame window is not suitable for them. Use it only as a fallback. Change-Id: Ie4d62370425effef4dd91bf27d98e3746e8a375e Task-number: QTBUG-2280 Reviewed-by: Gatis Paeglis <gatis.paeglis@digia.com> Reviewed-by: Uli Schlachter <psychon@znc.in>
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp18
3 files changed, 20 insertions, 0 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index b8b665157b..4e558f9447 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1578,6 +1578,7 @@ static const char * xcb_atomnames = {
"_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
"_KDE_NET_WM_FRAME_STRUT\0"
+ "_NET_FRAME_EXTENTS\0"
"_NET_STARTUP_INFO\0"
"_NET_STARTUP_INFO_BEGIN\0"
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 291193612c..348af5f155 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -194,6 +194,7 @@ namespace QXcbAtom {
_KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
_KDE_NET_WM_FRAME_STRUT,
+ _NET_FRAME_EXTENTS,
_NET_STARTUP_INFO,
_NET_STARTUP_INFO_BEGIN,
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 6e021ced23..9c5609bb8d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -745,6 +745,22 @@ void QXcbWindow::setGeometry(const QRect &rect)
QMargins QXcbWindow::frameMargins() const
{
if (m_dirtyFrameMargins) {
+ if (connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_FRAME_EXTENTS))) {
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, m_window,
+ atom(QXcbAtom::_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4);
+ QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply(
+ xcb_get_property_reply(xcb_connection(), cookie, NULL));
+ if (reply && reply->type == XCB_ATOM_CARDINAL && reply->format == 32 && reply->value_len == 4) {
+ quint32 *data = (quint32 *)xcb_get_property_value(reply.data());
+ // _NET_FRAME_EXTENTS format is left, right, top, bottom
+ m_frameMargins = QMargins(data[0], data[2], data[1], data[3]);
+ m_dirtyFrameMargins = false;
+ return m_frameMargins;
+ }
+ }
+
+ // _NET_FRAME_EXTENTS property is not available, so
+ // walk up the window tree to get the frame parent
xcb_window_t window = m_window;
xcb_window_t parent = m_window;
@@ -2385,6 +2401,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
m_windowState = newState;
}
return;
+ } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
+ m_dirtyFrameMargins = true;
} else if (event->atom == atom(QXcbAtom::_NET_WORKAREA) && xcbScreen() && event->window == xcbScreen()->root()) {
xcbScreen()->updateGeometry(event->time);
}