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>
This commit is contained in:
parent
b68dfa0348
commit
cb142954c5
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -28,10 +28,25 @@
|
||||
|
||||
#include "nativewindowdump.h"
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtGui/QGuiApplication>
|
||||
# include <qpa/qplatformnativeinterface.h>
|
||||
#endif
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
void dumpNativeWindows(WId)
|
||||
void dumpNativeWindows(WId wid)
|
||||
{
|
||||
#if QT_VERSION >= 0x050000
|
||||
QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
|
||||
QString result;
|
||||
QMetaObject::invokeMethod(ni, "dumpNativeWindows", Qt::DirectConnection,
|
||||
Q_RETURN_ARG(QString, result),
|
||||
Q_ARG(WId, wid));
|
||||
qDebug().noquote() << result;
|
||||
#endif // Qt 5
|
||||
}
|
||||
|
||||
void dumpNativeQtTopLevels()
|
||||
|
Loading…
x
Reference in New Issue
Block a user