summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2017-12-14 14:15:34 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-01-24 14:39:16 +0000
commitcb142954c54b7a6e391950d9209b5cea9252092b (patch)
tree9fc77260f10bf052af9a00345b99afd61f42a339 /src/plugins/platforms/xcb
parentb68dfa03489fac8518659d062dce903fb0d15799 (diff)
XCB: Implement native window dump for diaglib
Extract a helper function to determine the window title from QXcbConnection and add an invokable function to the native interface that dumps the window tree similar to existing functionality on Windows. Change-Id: I5544d69ea2b801eb16d3b5b8d64021b3e567b0d8 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp56
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp13
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h2
5 files changed, 75 insertions, 10 deletions
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index d989761297..22d90d6ac2 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -673,4 +673,60 @@ void *QXcbNativeInterface::handlerNativeResourceForBackingStore(const QByteArray
return nullptr;
}
+static void dumpNativeWindowsRecursion(const QXcbConnection *connection, xcb_window_t window,
+ int level, QTextStream &str)
+{
+ if (level)
+ str << QByteArray(2 * level, ' ');
+
+ xcb_connection_t *conn = connection->xcb_connection();
+ auto geomReply = Q_XCB_REPLY(xcb_get_geometry, conn, window);
+ if (!geomReply)
+ return;
+ const QRect geom(geomReply->x, geomReply->y, geomReply->width, geomReply->height);
+ if (!geom.isValid() || (geom.width() <= 3 && geom.height() <= 3))
+ return; // Skip helper/dummy windows.
+ str << "0x";
+ const int oldFieldWidth = str.fieldWidth();
+ const QChar oldPadChar =str.padChar();
+ str.setFieldWidth(8);
+ str.setPadChar(QLatin1Char('0'));
+ str << hex << window;
+ str.setFieldWidth(oldFieldWidth);
+ str.setPadChar(oldPadChar);
+ str << dec << " \""
+ << QXcbWindow::windowTitle(connection, window) << "\" "
+ << geom.width() << 'x' << geom.height() << forcesign << geom.x() << geom.y()
+ << noforcesign << '\n';
+
+ auto reply = Q_XCB_REPLY(xcb_query_tree, conn, window);
+ if (reply) {
+ const int count = xcb_query_tree_children_length(reply.get());
+ const xcb_window_t *children = xcb_query_tree_children(reply.get());
+ for (int i = 0; i < count; ++i)
+ dumpNativeWindowsRecursion(connection, children[i], level + 1, str);
+ }
+}
+
+QString QXcbNativeInterface::dumpConnectionNativeWindows(const QXcbConnection *connection, WId root) const
+{
+ QString result;
+ QTextStream str(&result);
+ if (root) {
+ dumpNativeWindowsRecursion(connection, xcb_window_t(root), 0, str);
+ } else {
+ for (const QXcbScreen *screen : connection->screens()) {
+ str << "Screen: \"" << screen->name() << "\"\n";
+ dumpNativeWindowsRecursion(connection, screen->root(), 0, str);
+ str << '\n';
+ }
+ }
+ return result;
+}
+
+QString QXcbNativeInterface::dumpNativeWindows(WId root) const
+{
+ return dumpConnectionNativeWindows(QXcbIntegration::instance()->defaultConnection(), root);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index fb0db727aa..6a752c68ca 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -127,6 +127,8 @@ public:
Q_INVOKABLE bool systrayVisualHasAlphaChannel();
Q_INVOKABLE bool requestSystemTrayWindowDock(const QWindow *window);
Q_INVOKABLE QRect systemTrayWindowGlobalGeometry(const QWindow *window);
+ Q_INVOKABLE QString dumpConnectionNativeWindows(const QXcbConnection *connection, WId root) const;
+ Q_INVOKABLE QString dumpNativeWindows(WId root = 0) const;
void addHandler(QXcbNativeInterfaceHandler *handler);
void removeHandler(QXcbNativeInterfaceHandler *handler);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index e3d9bc7a3d..49bf5181cc 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -91,16 +91,8 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) {
xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply.get()));
- if (windowManager != XCB_WINDOW_NONE) {
- auto windowManagerReply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
- false, windowManager,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING), 0, 1024);
- if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) {
- m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply.get()),
- xcb_get_property_value_length(windowManagerReply.get()));
- }
- }
+ if (windowManager != XCB_WINDOW_NONE)
+ m_windowManagerName = QXcbWindow::windowTitle(connection, windowManager);
}
const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 46698de158..89ace781ae 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -2835,5 +2835,18 @@ QXcbScreen *QXcbWindow::xcbScreen() const
return static_cast<QXcbScreen *>(screen());
}
+QString QXcbWindow::windowTitle(const QXcbConnection *conn, xcb_window_t window)
+{
+ const xcb_atom_t utf8Atom = conn->atom(QXcbAtom::UTF8_STRING);
+ auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, conn->xcb_connection(),
+ false, window, conn->atom(QXcbAtom::_NET_WM_NAME),
+ utf8Atom, 0, 1024);
+ if (reply && reply->format == 8 && reply->type == utf8Atom) {
+ const char *name = reinterpret_cast<const char *>(xcb_get_property_value(reply.get()));
+ return QString::fromUtf8(name);
+ }
+ return QString();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 638ab26cea..65221394ea 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -182,6 +182,8 @@ public:
virtual void create();
virtual void destroy();
+ static QString windowTitle(const QXcbConnection *conn, xcb_window_t window);
+
public Q_SLOTS:
void updateSyncRequestCounter();