summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2014-11-07 15:57:25 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2014-11-13 12:14:51 +0100
commit034ff4deaf3e4c998f4572705a1c7624c8499c92 (patch)
tree199d5f2624975093e1ff68c58f70ed961ee7abe5
parent63ae74f36533d92c5b38df1eb2a7fcf4c586bf11 (diff)
Add diaglib under manual tests.
Add a set of helper functions and classes providing functionality for dumping widget/window hierarchies and logging events. They can be used by including a .pri file for diagnosing bugs and comparing Qt 5 to Qt 4. Change-Id: I0206f8e57b02540cd80a3e9446c894023d442ddc Reviewed-by: Andy Shaw <andy.shaw@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
-rw-r--r--tests/manual/diaglib/README.txt34
-rw-r--r--tests/manual/diaglib/diaglib.pri43
-rw-r--r--tests/manual/diaglib/eventfilter.cpp113
-rw-r--r--tests/manual/diaglib/eventfilter.h77
-rw-r--r--tests/manual/diaglib/glinfo.cpp112
-rw-r--r--tests/manual/diaglib/glinfo.h48
-rw-r--r--tests/manual/diaglib/nativewindowdump.cpp46
-rw-r--r--tests/manual/diaglib/nativewindowdump.h46
-rw-r--r--tests/manual/diaglib/nativewindowdump_win.cpp207
-rw-r--r--tests/manual/diaglib/qwidgetdump.cpp94
-rw-r--r--tests/manual/diaglib/qwidgetdump.h45
-rw-r--r--tests/manual/diaglib/qwindowdump.cpp176
-rw-r--r--tests/manual/diaglib/qwindowdump.h63
13 files changed, 1104 insertions, 0 deletions
diff --git a/tests/manual/diaglib/README.txt b/tests/manual/diaglib/README.txt
new file mode 100644
index 0000000000..13387f5a2a
--- /dev/null
+++ b/tests/manual/diaglib/README.txt
@@ -0,0 +1,34 @@
+This is a collection of functions and classes helpful for diagnosing bugs
+in Qt 4 and Qt 5. It can be included in the application's .pro file by
+adding:
+
+include([path to Qt sources]/tests/manual/diaglib/diaglib.pri)
+
+For Qt 4, the environment variable QTDIR may be used:
+include($$(QTDIR)/tests/manual/diaglib/diaglib.pri)
+
+The .pri file adds the define QT_DIAG_LIB, so, diagnostic
+code can be enlosed within #ifdef to work without it as well.
+
+All functions and classes are in the QtDiag namespace.
+
+class EventFilter (eventfilter.h):
+ An event filter that logs Qt events to qDebug() depending on
+ configured categories (for example mouse, keyboard, etc).
+
+function glInfo() (glinfo.h):
+ Returns a string describing the Open GL configuration (obtained
+ by querying GL_VENDOR and GL_RENDERER). Available only
+ when the QT qmake variable contains opengl.
+
+functions dumpNativeWindows(), dumpNativeQtTopLevels():
+ These functions du,p out the hierarchy of native Windows. Currently
+ implemented for Windows only.
+
+function dumpAllWidgets() (qwidgetdump.h):
+ Dumps the hierarchy of QWidgets including information about flags,
+ visibility, geometry, etc.
+
+function dumpAllWindows() (qwindowdump.h):
+ Dumps the hierarchy of QWindows including information about flags,
+ visibility, geometry, etc.
diff --git a/tests/manual/diaglib/diaglib.pri b/tests/manual/diaglib/diaglib.pri
new file mode 100644
index 0000000000..138660f85e
--- /dev/null
+++ b/tests/manual/diaglib/diaglib.pri
@@ -0,0 +1,43 @@
+INCLUDEPATH += $$PWD
+SOURCES += \
+ $$PWD/eventfilter.cpp \
+ $$PWD/qwindowdump.cpp \
+
+HEADERS += \
+ $$PWD/eventfilter.h \
+ $$PWD/qwindowdump.h \
+ $$PWD/nativewindowdump.h
+
+win32 {
+ SOURCES += $$PWD/nativewindowdump_win.cpp
+ LIBS *= -luser32
+} else {
+ SOURCES += $$PWD/nativewindowdump.cpp
+}
+
+greaterThan(QT_MAJOR_VERSION, 4) {
+ QT += gui-private core-private
+ contains(QT, widgets) {
+ HEADERS += \
+ $$PWD/$$PWD/qwidgetdump.h
+
+ SOURCES += \
+ $$PWD/qwidgetdump.cpp
+ }
+} else {
+ HEADERS += \
+ $$PWD/$$PWD/qwidgetdump.h
+
+ SOURCES += \
+ $$PWD/qwidgetdump.cpp
+}
+
+contains(QT, opengl) {
+HEADERS += \
+ $$PWD/glinfo.h
+
+SOURCES += \
+ $$PWD/glinfo.cpp
+}
+
+DEFINES += QT_DIAG_LIB
diff --git a/tests/manual/diaglib/eventfilter.cpp b/tests/manual/diaglib/eventfilter.cpp
new file mode 100644
index 0000000000..f0573975f6
--- /dev/null
+++ b/tests/manual/diaglib/eventfilter.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "eventfilter.h"
+#include <QtGui/QMouseEvent>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+namespace QtDiag {
+
+EventFilter::EventFilter(EventCategories eventCategories, QObject *p)
+ : QObject(p)
+{
+ init(eventCategories);
+}
+
+EventFilter::EventFilter(QObject *p)
+ : QObject(p)
+{
+ init(EventCategories(0xFFFFFFF));
+}
+
+void EventFilter::init(EventCategories eventCategories)
+{
+ if (eventCategories & MouseEvents) {
+ m_eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease
+ << QEvent::MouseButtonDblClick << QEvent::NonClientAreaMouseButtonPress
+ << QEvent::NonClientAreaMouseButtonRelease
+ << QEvent::NonClientAreaMouseButtonDblClick
+ << QEvent::Enter << QEvent::Leave;
+ }
+ if (eventCategories & MouseMoveEvents)
+ m_eventTypes << QEvent::MouseMove << QEvent::NonClientAreaMouseMove;
+ if (eventCategories & TouchEvents) {
+ m_eventTypes << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd;
+#if QT_VERSION >= 0x050000
+ m_eventTypes << QEvent::TouchCancel;
+#endif
+ }
+ if (eventCategories & TabletEvents) {
+ m_eventTypes << QEvent::TabletEnterProximity << QEvent::TabletLeaveProximity
+ << QEvent::TabletMove << QEvent::TabletPress << QEvent::TabletRelease;
+ }
+ if (eventCategories & DragAndDropEvents) {
+ m_eventTypes << QEvent::DragEnter << QEvent::DragMove << QEvent::DragLeave
+ << QEvent::Drop << QEvent::DragResponse;
+ }
+ if (eventCategories & KeyEvents) {
+ m_eventTypes << QEvent::KeyPress << QEvent::KeyRelease << QEvent::ShortcutOverride
+ << QEvent::Shortcut;
+ }
+ if (eventCategories & GeometryEvents)
+ m_eventTypes << QEvent::Move << QEvent::Resize;
+ if (eventCategories & PaintEvents) {
+ m_eventTypes << QEvent::UpdateRequest << QEvent::Paint
+ << QEvent::Show << QEvent::Hide;
+#if QT_VERSION >= 0x050000
+ m_eventTypes << QEvent::Expose;
+#endif
+ }
+ if (eventCategories & TimerEvents)
+ m_eventTypes << QEvent::Timer << QEvent::ZeroTimerEvent;
+ if (eventCategories & ObjectEvents) {
+ m_eventTypes << QEvent::ChildAdded << QEvent::ChildPolished
+ << QEvent::ChildRemoved << QEvent::Create << QEvent::Destroy;
+ }
+}
+
+bool EventFilter::eventFilter(QObject *o, QEvent *e)
+{
+ static int n = 0;
+ if (m_eventTypes.contains(e->type())) {
+ QDebug debug = qDebug().nospace();
+ const QString on = o->objectName();
+ debug << '#' << n++ << ' ' << o->metaObject()->className();
+ if (!on.isEmpty())
+ debug << '/' << on;
+ debug << ' ' << e;
+ }
+ return false;
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/eventfilter.h b/tests/manual/diaglib/eventfilter.h
new file mode 100644
index 0000000000..d87ac68b07
--- /dev/null
+++ b/tests/manual/diaglib/eventfilter.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _EVENTFILTER_
+#define _EVENTFILTER_
+
+#include <QtCore/QObject>
+#include <QtCore/QEvent>
+#include <QtCore/QList>
+
+namespace QtDiag {
+
+// Event filter that can for example be installed on QApplication
+// to log relevant events.
+
+class EventFilter : public QObject {
+public:
+ enum EventCategory {
+ MouseEvents = 0x00001,
+ MouseMoveEvents = 0x00002,
+ TouchEvents = 0x00004,
+ TabletEvents = 0x00008,
+ DragAndDropEvents = 0x00010,
+ KeyEvents = 0x00020,
+ GeometryEvents = 0x00040,
+ PaintEvents = 0x00080,
+ TimerEvents = 0x00100,
+ ObjectEvents = 0x00200
+ };
+ Q_DECLARE_FLAGS(EventCategories, EventCategory)
+
+ explicit EventFilter(EventCategories eventCategories, QObject *p = 0);
+ explicit EventFilter(QObject *p = 0);
+
+ bool eventFilter(QObject *, QEvent *);
+
+private:
+ void init(EventCategories eventCategories);
+
+ QList<QEvent::Type> m_eventTypes;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(EventFilter::EventCategories)
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/glinfo.cpp b/tests/manual/diaglib/glinfo.cpp
new file mode 100644
index 0000000000..cd30e46b45
--- /dev/null
+++ b/tests/manual/diaglib/glinfo.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "glinfo.h"
+
+#include <QtOpenGL/QGLFunctions>
+#include <QtOpenGL/QGLWidget>
+#if QT_VERSION > 0x050000
+# if QT_VERSION >= 0x050400
+# include <QtWidgets/QOpenGLWidget>
+# include <QtGui/QOpenGLWindow>
+# else // 5.4
+# include <QtGui/QWindow>
+# endif // 5.0..5.4
+# include <QtGui/QOpenGLContext>
+# include <QtGui/QOpenGLFunctions>
+# include <QtGui/QWindow>
+#endif
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtCore/QTimer>
+
+namespace QtDiag {
+
+#if QT_VERSION > 0x050000
+
+static QString getGlString(const QOpenGLContext *ctx, GLenum name)
+{
+ if (const GLubyte *p = ctx->functions()->glGetString(name))
+ return QString::fromLatin1(reinterpret_cast<const char *>(p));
+ return QString();
+}
+
+static QString glInfo(const QOpenGLContext *ctx)
+{
+ return getGlString(ctx, GL_VENDOR)
+ + QLatin1Char('\n')
+ + getGlString(ctx, GL_RENDERER);
+}
+
+static QString glInfo(const QGLContext *ctx)
+{
+ return glInfo(ctx->contextHandle());
+}
+
+QString glInfo(const QObject *o)
+{
+# if QT_VERSION >= 0x050400
+ if (o->isWindowType()) {
+ if (const QOpenGLWindow *oglw = qobject_cast<const QOpenGLWindow *>(o))
+ return glInfo(oglw->context());
+ return QString();
+ }
+# endif // 5.4
+ if (o->isWidgetType()) {
+ if (const QGLWidget *g = qobject_cast<const QGLWidget *>(o))
+ return glInfo(g->context());
+# if QT_VERSION >= 0x050400
+ if (const QOpenGLWidget *g = qobject_cast<const QOpenGLWidget *>(o))
+ return glInfo(g->context());
+# endif // 5.4
+ }
+ return QString();
+}
+
+#else // Qt4:
+
+static QString getGlString(GLenum name)
+{
+ if (const GLubyte *p = glGetString(name))
+ return QString::fromLatin1(reinterpret_cast<const char *>(p));
+ return QString();
+}
+
+QString glInfo(const QWidget *)
+{
+ return getGlString(GL_VENDOR) + QLatin1Char('\n') + getGlString(GL_RENDERER);
+}
+
+#endif
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/glinfo.h b/tests/manual/diaglib/glinfo.h
new file mode 100644
index 0000000000..1f515267f2
--- /dev/null
+++ b/tests/manual/diaglib/glinfo.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _GLINFO_
+#define _GLINFO_
+
+#include <QtCore/QtGlobal>
+
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_CLASS(QString)
+
+namespace QtDiag {
+
+QString glInfo(const QObject *o);
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/nativewindowdump.cpp b/tests/manual/diaglib/nativewindowdump.cpp
new file mode 100644
index 0000000000..a6c741a085
--- /dev/null
+++ b/tests/manual/diaglib/nativewindowdump.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nativewindowdump.h"
+
+namespace QtDiag {
+
+void dumpNativeWindows(WId)
+{
+}
+
+void dumpNativeQtTopLevels()
+{
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/nativewindowdump.h b/tests/manual/diaglib/nativewindowdump.h
new file mode 100644
index 0000000000..405998feea
--- /dev/null
+++ b/tests/manual/diaglib/nativewindowdump.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _NATIVEWINDOWDUMP_
+#define _NATIVEWINDOWDUMP_
+
+#include <QtGui/qwindowdefs.h>
+
+namespace QtDiag {
+
+void dumpNativeWindows(WId root = 0);
+void dumpNativeQtTopLevels();
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/nativewindowdump_win.cpp b/tests/manual/diaglib/nativewindowdump_win.cpp
new file mode 100644
index 0000000000..814b580f4b
--- /dev/null
+++ b/tests/manual/diaglib/nativewindowdump_win.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nativewindowdump.h"
+#include "qwindowdump.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QDebug>
+#include <QtCore/QVector>
+
+#include <QtCore/qt_windows.h>
+
+namespace QtDiag {
+
+struct DumpContext {
+ DumpContext() : indentation(0) {}
+
+ int indentation;
+ QSharedPointer<QTextStream> stream;
+};
+
+#define debugWinStyle(str, style, styleConstant) \
+if (style & styleConstant) \
+ str << ' ' << #styleConstant;
+
+static void formatNativeWindow(HWND hwnd, QTextStream &str)
+{
+ str << hex << showbase << quintptr(hwnd) << noshowbase << dec;
+ RECT rect;
+ if (GetWindowRect(hwnd, &rect)) {
+ str << ' ' << (rect.right - rect.left) << 'x' << (rect.bottom - rect.top)
+ << '+' << rect.left << '+' << rect.top;
+ }
+ if (IsWindowVisible(hwnd))
+ str << " [visible]";
+
+ str << hex << showbase;
+ if (const LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE)) {
+ str << " style=" << style;
+ debugWinStyle(str, style, WS_OVERLAPPED)
+ debugWinStyle(str, style, WS_POPUP)
+ debugWinStyle(str, style, WS_MINIMIZE)
+ debugWinStyle(str, style, WS_CHILD)
+ debugWinStyle(str, style, WS_VISIBLE)
+ debugWinStyle(str, style, WS_DISABLED)
+ debugWinStyle(str, style, WS_CLIPSIBLINGS)
+ debugWinStyle(str, style, WS_CLIPCHILDREN)
+ debugWinStyle(str, style, WS_MAXIMIZE)
+ debugWinStyle(str, style, WS_CAPTION)
+ debugWinStyle(str, style, WS_BORDER)
+ debugWinStyle(str, style, WS_DLGFRAME)
+ debugWinStyle(str, style, WS_VSCROLL)
+ debugWinStyle(str, style, WS_HSCROLL)
+ debugWinStyle(str, style, WS_SYSMENU)
+ debugWinStyle(str, style, WS_THICKFRAME)
+ debugWinStyle(str, style, WS_GROUP)
+ debugWinStyle(str, style, WS_TABSTOP)
+ debugWinStyle(str, style, WS_MINIMIZEBOX)
+ debugWinStyle(str, style, WS_MAXIMIZEBOX)
+ }
+ if (const LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE)) {
+ str << " exStyle=" << exStyle;
+ debugWinStyle(str, exStyle, WS_EX_DLGMODALFRAME)
+ debugWinStyle(str, exStyle, WS_EX_NOPARENTNOTIFY)
+ debugWinStyle(str, exStyle, WS_EX_TOPMOST)
+ debugWinStyle(str, exStyle, WS_EX_ACCEPTFILES)
+ debugWinStyle(str, exStyle, WS_EX_TRANSPARENT)
+ debugWinStyle(str, exStyle, WS_EX_MDICHILD)
+ debugWinStyle(str, exStyle, WS_EX_TOOLWINDOW)
+ debugWinStyle(str, exStyle, WS_EX_WINDOWEDGE)
+ debugWinStyle(str, exStyle, WS_EX_CLIENTEDGE)
+ debugWinStyle(str, exStyle, WS_EX_CONTEXTHELP)
+ debugWinStyle(str, exStyle, WS_EX_RIGHT)
+ debugWinStyle(str, exStyle, WS_EX_LEFT)
+ debugWinStyle(str, exStyle, WS_EX_RTLREADING)
+ debugWinStyle(str, exStyle, WS_EX_LTRREADING)
+ debugWinStyle(str, exStyle, WS_EX_LEFTSCROLLBAR)
+ debugWinStyle(str, exStyle, WS_EX_RIGHTSCROLLBAR)
+ debugWinStyle(str, exStyle, WS_EX_CONTROLPARENT)
+ debugWinStyle(str, exStyle, WS_EX_STATICEDGE)
+ debugWinStyle(str, exStyle, WS_EX_APPWINDOW)
+ debugWinStyle(str, exStyle, WS_EX_LAYERED)
+ debugWinStyle(str, exStyle, WS_EX_NOINHERITLAYOUT)
+ debugWinStyle(str, exStyle, WS_EX_NOREDIRECTIONBITMAP)
+ debugWinStyle(str, exStyle, WS_EX_LAYOUTRTL)
+ debugWinStyle(str, exStyle, WS_EX_COMPOSITED)
+ debugWinStyle(str, exStyle, WS_EX_NOACTIVATE)
+ }
+ str << noshowbase << dec;
+
+ wchar_t buf[512];
+ if (GetWindowText(hwnd, buf, sizeof(buf)/sizeof(buf[0])))
+ str << " title=\"" << QString::fromWCharArray(buf) << '"';
+ if (GetClassName(hwnd, buf, sizeof(buf)/sizeof(buf[0])))
+ str << " class=\"" << QString::fromWCharArray(buf) << '"';
+ str << '\n';
+}
+
+static void dumpNativeWindowRecursion(HWND hwnd, DumpContext *dc);
+
+BOOL CALLBACK dumpWindowEnumChildProc(HWND hwnd, LPARAM lParam)
+{
+ dumpNativeWindowRecursion(hwnd, reinterpret_cast<DumpContext *>(lParam));
+ return TRUE;
+}
+
+static void dumpNativeWindowRecursion(HWND hwnd, DumpContext *dc)
+{
+ indentStream(*dc->stream, dc->indentation);
+ formatNativeWindow(hwnd, *dc->stream);
+ DumpContext nextLevel = *dc;
+ nextLevel.indentation += 2;
+ EnumChildWindows(hwnd, dumpWindowEnumChildProc, reinterpret_cast<LPARAM>(&nextLevel));
+}
+
+/* recurse by Z order, same result */
+static void dumpNativeWindowRecursionByZ(HWND hwnd, DumpContext *dc)
+{
+ indentStream(*dc->stream, dc->indentation);
+ formatNativeWindow(hwnd, *dc->stream);
+ if (const HWND topChild = GetTopWindow(hwnd)) {
+ DumpContext nextLevel = *dc;
+ nextLevel.indentation += 2;
+ for (HWND child = topChild; child ; child = GetNextWindow(child, GW_HWNDNEXT))
+ dumpNativeWindowRecursionByZ(child, &nextLevel);
+ }
+}
+
+typedef QVector<WId> WIdVector;
+
+static void dumpNativeWindows(const WIdVector& wins)
+{
+ DumpContext dc;
+ QString s;
+ dc.stream = QSharedPointer<QTextStream>(new QTextStream(&s));
+ foreach (WId win, wins)
+ dumpNativeWindowRecursion(reinterpret_cast<HWND>(win), &dc);
+#if QT_VERSION > 0x050000
+ qDebug().noquote() << s;
+#else
+ qDebug("%s", qPrintable(s));
+#endif
+}
+
+void dumpNativeWindows(WId rootIn)
+{
+ const WId root = rootIn ? rootIn : reinterpret_cast<WId>(GetDesktopWindow());
+ dumpNativeWindows(WIdVector(1, root));
+}
+
+BOOL CALLBACK findQtTopLevelEnumChildProc(HWND hwnd, LPARAM lParam)
+{
+ WIdVector *v = reinterpret_cast<WIdVector *>(lParam);
+ wchar_t buf[512];
+ if (GetClassName(hwnd, buf, sizeof(buf)/sizeof(buf[0]))) {
+ if (wcsstr(buf, L"Qt"))
+ v->append(reinterpret_cast<WId>(hwnd));
+ }
+ return TRUE;
+}
+
+static WIdVector findQtTopLevels()
+{
+ WIdVector result;
+ EnumChildWindows(GetDesktopWindow(),
+ findQtTopLevelEnumChildProc,
+ reinterpret_cast<LPARAM>(&result));
+ return result;
+}
+
+void dumpNativeQtTopLevels()
+{
+ dumpNativeWindows(findQtTopLevels());
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/qwidgetdump.cpp b/tests/manual/diaglib/qwidgetdump.cpp
new file mode 100644
index 0000000000..d4f985c7c8
--- /dev/null
+++ b/tests/manual/diaglib/qwidgetdump.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwidgetdump.h"
+
+#include <QWidget>
+#if QT_VERSION > 0x050000
+# include <QtGui/QScreen>
+# include <QtGui/QWindow>
+#endif
+#include <QApplication>
+#include <QtCore/QMetaObject>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+namespace QtDiag {
+
+static void dumpWidgetRecursion(QTextStream &str, const QWidget *w,
+ FormatWindowOptions options, int depth = 0)
+{
+ indentStream(str, 2 * depth);
+ formatObject(str, w);
+ str << ' ' << (w->isVisible() ? "[visible] " : "[hidden] ");
+ if (const WId nativeWinId = w->internalWinId())
+ str << "[native: " << hex << showbase << nativeWinId << dec << noshowbase << "] ";
+ if (w->isWindow())
+ str << "[top] ";
+ str << (w->testAttribute(Qt::WA_Mapped) ? "[mapped] " : "[not mapped] ");
+ if (w->testAttribute(Qt::WA_DontCreateNativeAncestors))
+ str << "[NoNativeAncestors] ";
+ formatRect(str, w->geometry());
+ if (!(options & DontPrintWindowFlags)) {
+ str << ' ';
+ formatWindowFlags(str, w->windowFlags());
+ }
+ str << '\n';
+#if QT_VERSION > 0x050000
+ if (const QWindow *win = w->windowHandle()) {
+ indentStream(str, 2 * (1 + depth));
+ formatWindow(str, win, options);
+ str << '\n';
+ }
+#endif // Qt 5
+ foreach (const QObject *co, w->children()) {
+ if (co->isWidgetType())
+ dumpWidgetRecursion(str, static_cast<const QWidget *>(co), options, depth + 1);
+ }
+}
+
+void dumpAllWidgets(FormatWindowOptions options)
+{
+ QString d;
+ QTextStream str(&d);
+ str << "### QWidgets:\n";
+ foreach (QWidget *tw, QApplication::topLevelWidgets())
+ dumpWidgetRecursion(str, tw, options);
+#if QT_VERSION > 0x050000
+ qDebug().noquote() << d;
+#else
+ qDebug("%s", qPrintable(d));
+#endif
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/qwidgetdump.h b/tests/manual/diaglib/qwidgetdump.h
new file mode 100644
index 0000000000..f9615b5d2f
--- /dev/null
+++ b/tests/manual/diaglib/qwidgetdump.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _WIDGETDUMP_
+#define _WIDGETDUMP_
+
+#include "qwindowdump.h"
+
+namespace QtDiag {
+
+void dumpAllWidgets(FormatWindowOptions options = 0);
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/qwindowdump.cpp b/tests/manual/diaglib/qwindowdump.cpp
new file mode 100644
index 0000000000..2ecc52ca77
--- /dev/null
+++ b/tests/manual/diaglib/qwindowdump.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowdump.h"
+
+#if QT_VERSION > 0x050000
+# include <QtGui/QGuiApplication>
+# include <QtGui/QScreen>
+# include <QtGui/QWindow>
+# include <qpa/qplatformwindow.h>
+#endif
+#include <QtCore/QMetaObject>
+#include <QtCore/QRect>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+namespace QtDiag {
+
+void indentStream(QTextStream &s, int indent)
+{
+ for (int i = 0; i < indent; ++i)
+ s << ' ';
+}
+
+void formatObject(QTextStream &str, const QObject *o)
+{
+ str << o->metaObject()->className();
+ const QString on = o->objectName();
+ if (!on.isEmpty())
+ str << "/\"" << on << '"';
+}
+
+void formatRect(QTextStream &str, const QRect &geom)
+{
+ str << geom.width() << 'x' << geom.height()
+ << forcesign << geom.x() << geom.y() << noforcesign;
+}
+
+#define debugType(s, type, typeConstant) \
+if ((type & typeConstant) == typeConstant) \
+ s << ' ' << #typeConstant;
+
+#define debugFlag(s, flags, flagConstant) \
+if (flags & flagConstant) \
+ s << ' ' << #flagConstant;
+
+void formatWindowFlags(QTextStream &str, const Qt::WindowFlags flags)
+{
+ str << showbase << hex << unsigned(flags) << dec << noshowbase;
+ const Qt::WindowFlags windowType = flags & Qt::WindowType_Mask;
+ debugFlag(str, flags, Qt::Window)
+ debugType(str, windowType, Qt::Dialog)
+ debugType(str, windowType, Qt::Sheet)
+ debugType(str, windowType, Qt::Drawer)
+ debugType(str, windowType, Qt::Popup)
+ debugType(str, windowType, Qt::Tool)
+ debugType(str, windowType, Qt::ToolTip)
+ debugType(str, windowType, Qt::SplashScreen)
+ debugType(str, windowType, Qt::Desktop)
+ debugType(str, windowType, Qt::SubWindow)
+#if QT_VERSION > 0x050000
+ debugType(str, windowType, Qt::ForeignWindow)
+ debugType(str, windowType, Qt::CoverWindow)
+#endif
+ debugFlag(str, flags, Qt::MSWindowsFixedSizeDialogHint)
+ debugFlag(str, flags, Qt::MSWindowsOwnDC)
+ debugFlag(str, flags, Qt::X11BypassWindowManagerHint)
+ debugFlag(str, flags, Qt::FramelessWindowHint)
+ debugFlag(str, flags, Qt::WindowTitleHint)
+ debugFlag(str, flags, Qt::WindowSystemMenuHint)
+ debugFlag(str, flags, Qt::WindowMinimizeButtonHint)
+ debugFlag(str, flags, Qt::WindowMaximizeButtonHint)
+ debugFlag(str, flags, Qt::WindowContextHelpButtonHint)
+ debugFlag(str, flags, Qt::WindowShadeButtonHint)
+ debugFlag(str, flags, Qt::WindowStaysOnTopHint)
+ debugFlag(str, flags, Qt::CustomizeWindowHint)
+#if QT_VERSION > 0x050000
+ debugFlag(str, flags, Qt::WindowTransparentForInput)
+ debugFlag(str, flags, Qt::WindowOverridesSystemGestures)
+ debugFlag(str, flags, Qt::WindowDoesNotAcceptFocus)
+ debugFlag(str, flags, Qt::NoDropShadowWindowHint)
+ debugFlag(str, flags, Qt::WindowFullscreenButtonHint)
+#endif
+ debugFlag(str, flags, Qt::WindowStaysOnBottomHint)
+ debugFlag(str, flags, Qt::MacWindowToolBarButtonHint)
+ debugFlag(str, flags, Qt::BypassGraphicsProxyWidget)
+ debugFlag(str, flags, Qt::WindowOkButtonHint)
+ debugFlag(str, flags, Qt::WindowCancelButtonHint)
+}
+
+#if QT_VERSION > 0x050000
+
+void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options)
+{
+ const QPlatformWindow *pw = w->handle();
+ formatObject(str, w);
+ str << ' ' << (w->isVisible() ? "[visible] " : "[hidden] ");
+ if (const WId nativeWinId = pw ? pw->winId() : WId(0))
+ str << "[native: " << hex << showbase << nativeWinId << dec << noshowbase << "] ";
+ if (w->isTopLevel())
+ str << "[top] ";
+ if (w->isExposed())
+ str << "[exposed] ";
+ formatRect(str, w->geometry());
+ if (!(options & DontPrintWindowFlags)) {
+ str << ' ';
+ formatWindowFlags(str, w->flags());
+ }
+ str << '\n';
+}
+
+static void dumpWindowRecursion(QTextStream &str, const QWindow *w,
+ FormatWindowOptions options = 0, int depth = 0)
+{
+ indentStream(str, 2 * depth);
+ formatWindow(str, w);
+ foreach (const QObject *co, w->children()) {
+ if (co->isWindowType())
+ dumpWindowRecursion(str, static_cast<const QWindow *>(co), options, depth + 1);
+ }
+}
+
+void dumpAllWindows(FormatWindowOptions options)
+{
+ QString d;
+ QTextStream str(&d);
+ str << "### QWindows:\n";
+ foreach (QWindow *w, QGuiApplication::topLevelWindows())
+ dumpWindowRecursion(str, w, options);
+ qDebug().noquote() << d;
+}
+
+#else // Qt 5
+class QWindow {};
+
+void formatWindow(QTextStream &, const QWindow *, FormatWindowOptions)
+{
+}
+
+void dumpAllWindows(FormatWindowOptions options)
+{
+}
+
+#endif // Qt 4
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/qwindowdump.h b/tests/manual/diaglib/qwindowdump.h
new file mode 100644
index 0000000000..ab7c0243e9
--- /dev/null
+++ b/tests/manual/diaglib/qwindowdump.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _WINDOWDUMP_
+#define _WINDOWDUMP_
+
+#include <QtCore/qnamespace.h>
+
+QT_FORWARD_DECLARE_CLASS(QRect)
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_CLASS(QWindow)
+QT_FORWARD_DECLARE_CLASS(QTextStream)
+
+namespace QtDiag {
+
+enum FormatWindowOption {
+ DontPrintWindowFlags = 0x001
+};
+
+Q_DECLARE_FLAGS(FormatWindowOptions, FormatWindowOption)
+Q_DECLARE_OPERATORS_FOR_FLAGS(FormatWindowOptions)
+
+void indentStream(QTextStream &s, int indent);
+void formatObject(QTextStream &str, const QObject *o);
+void formatRect(QTextStream &str, const QRect &geom);
+void formatWindowFlags(QTextStream &str, const Qt::WindowFlags flags);
+
+void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options = 0);
+void dumpAllWindows(FormatWindowOptions options = 0);
+
+} // namespace QtDiag
+
+#endif