Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qwindowcontainer.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "qwidget_p.h"
6#include <QtGui/qwindow.h>
7#include <QtGui/private/qguiapplication_p.h>
8#include <qpa/qplatformintegration.h>
9#include <QDebug>
10
11#if QT_CONFIG(mdiarea)
12#include <QMdiSubWindow>
13#endif
14#include <QAbstractScrollArea>
15#include <QPainter>
16
18
19using namespace Qt::StringLiterals;
20
22{
23public:
24 Q_DECLARE_PUBLIC(QWindowContainer)
25
27 : window(nullptr)
28 , oldFocusWindow(nullptr)
30 {
31 }
32
34
36 QWindowContainer *wc = qobject_cast<QWindowContainer *>(w);
37 if (wc)
38 return wc->d_func();
39 return nullptr;
40 }
41
44 if (!q->isWindow() && (q->geometry().bottom() <= 0 || q->geometry().right() <= 0))
45 /* Qt (e.g. QSplitter) sometimes prefer to hide a widget by *not* calling
46 setVisible(false). This is often done by setting its coordinates to a sufficiently
47 negative value so that its clipped outside the parent. Since a QWindow is not clipped
48 to widgets in general, it needs to be dealt with as a special case.
49 */
50 window->setGeometry(q->geometry());
51 else if (usesNativeWidgets)
52 window->setGeometry(q->rect());
53 else
54 window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
55 }
56
58 {
59 if (window->parent() == nullptr)
60 return;
62 if (q->internalWinId()) {
63 // Allow use native widgets if the window container is already a native widget
64 usesNativeWidgets = true;
65 return;
66 }
67 bool nativeWidgetSet = false;
68 QWidget *p = q->parentWidget();
69 while (p) {
70 if (false
71#if QT_CONFIG(mdiarea)
72 || qobject_cast<QMdiSubWindow *>(p) != 0
73#endif
74#if QT_CONFIG(scrollarea)
75 || qobject_cast<QAbstractScrollArea *>(p) != 0
76#endif
77 ) {
78 q->winId();
79 nativeWidgetSet = true;
80 break;
81 }
82 p = p->parentWidget();
83 }
84 usesNativeWidgets = nativeWidgetSet;
85 }
86
89 QWidget *p = q;
90 while (p) {
92 d->createExtra();
93 d->extra->hasWindowContainer = true;
94 p = p->parentWidget();
95 }
96 }
97
98 bool isStillAnOrphan() const {
99 return window->parent() == &fakeParent;
100 }
101
105
107};
108
109
110
169{
170 return new QWindowContainer(window, parent, flags);
171}
172
179{
180 Q_D(QWindowContainer);
181 if (Q_UNLIKELY(!embeddedWindow)) {
182 qWarning("QWindowContainer: embedded window cannot be null");
183 return;
184 }
185
186 d->window = embeddedWindow;
187
188 QString windowName = d->window->objectName();
189 if (windowName.isEmpty())
190 windowName = QString::fromUtf8(d->window->metaObject()->className());
191 d->fakeParent.setObjectName(windowName + "ContainerFakeParent"_L1);
192
193 d->window->setParent(&d->fakeParent);
194 d->window->parent()->installEventFilter(this);
195 d->window->setFlag(Qt::SubWindow);
196
197 setAcceptDrops(true);
198
199 connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow*)), this, SLOT(focusWindowChanged(QWindow*)));
200}
201
203{
204 Q_D(const QWindowContainer);
205 return d->window;
206}
207
213{
214 Q_D(QWindowContainer);
215
216 // Call destroy() explicitly first. The dtor would do this too, but
217 // QEvent::PlatformSurface delivery relies on virtuals. Getting
218 // SurfaceAboutToBeDestroyed can be essential for OpenGL, Vulkan, etc.
219 // QWindow subclasses in particular. Keep these working.
220 if (d->window)
221 d->window->destroy();
222
223 delete d->window;
224}
225
226
227
232void QWindowContainer::focusWindowChanged(QWindow *focusWindow)
233{
234 Q_D(QWindowContainer);
235 d->oldFocusWindow = focusWindow;
236 if (focusWindow == d->window) {
238 if (widget)
240 }
241}
242
248{
249 Q_D(QWindowContainer);
250 if (!d->window)
251 return false;
252
253 if (e->type() == QEvent::ChildRemoved) {
254 QChildEvent *ce = static_cast<QChildEvent *>(e);
255 if (ce->child() == d->window) {
256 o->removeEventFilter(this);
257 d->window = nullptr;
258 }
259 }
260 return false;
261}
262
268{
269 Q_D(QWindowContainer);
270 if (!d->window)
271 return QWidget::event(e);
272
273 QEvent::Type type = e->type();
274 switch (type) {
275 // The only thing we are interested in is making sure our sizes stay
276 // in sync, so do a catch-all case.
277 case QEvent::Resize:
278 d->updateGeometry();
279 break;
280 case QEvent::Move:
281 d->updateGeometry();
282 break;
284 d->updateGeometry();
285 break;
286 case QEvent::Show:
287 d->updateUsesNativeWidgets();
288 if (d->isStillAnOrphan()) {
289 d->window->parent()->removeEventFilter(this);
290 d->window->setParent(d->usesNativeWidgets
291 ? windowHandle()
292 : window()->windowHandle());
293 d->fakeParent.destroy();
294 if (d->window->parent())
295 d->window->parent()->installEventFilter(this);
296 }
297 if (d->window->parent()) {
298 d->markParentChain();
299 d->window->show();
300 }
301 break;
302 case QEvent::Hide:
303 if (d->window->parent())
304 d->window->hide();
305 break;
306 case QEvent::FocusIn:
307 if (d->window->parent()) {
308 if (d->oldFocusWindow != d->window) {
309 d->window->requestActivate();
310 } else {
312 next->setFocus();
313 }
314 }
315 break;
316#if QT_CONFIG(draganddrop)
317 case QEvent::Drop:
318 case QEvent::DragMove:
321 return e->isAccepted();
323 // Don't reject drag events for the entire widget when one
324 // item rejects the drag enter
326 e->accept();
327 return true;
328#endif
329
330 case QEvent::Paint:
331 {
334 if (needsPunch) {
335 QPainter p(this);
336 p.setCompositionMode(QPainter::CompositionMode_Source);
337 p.fillRect(rect(), Qt::transparent);
338 }
339 break;
340 }
341
342 default:
343 break;
344 }
345
346 return QWidget::event(e);
347}
348
351{
352 const QObjectList &children = parent->children();
353 for (int i=0; i<children.size(); ++i) {
354 QWidget *w = qobject_cast<QWidget *>(children.at(i));
355 if (w) {
356 QWidgetPrivate *wd = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(w));
357 if (wd->extra && wd->extra->hasWindowContainer)
358 callback(w);
359 }
360 }
361}
362
364{
366 if (d->window->parent())
367 d->window->parent()->removeEventFilter(parent);
368 d->window->setParent(&d->fakeParent);
369 d->window->parent()->installEventFilter(parent);
370 }
372}
373
375{
377 if (d->window->parent()) {
378 d->updateUsesNativeWidgets();
379 d->markParentChain();
380 QWidget *toplevel = d->usesNativeWidgets ? parent : parent->window();
381 if (!toplevel->windowHandle()) {
382 QWidgetPrivate *tld = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(toplevel));
383 tld->createTLExtra();
384 tld->createTLSysExtra();
385 Q_ASSERT(toplevel->windowHandle());
386 }
387 d->window->parent()->removeEventFilter(parent);
388 d->window->setParent(toplevel->windowHandle());
390 d->fakeParent.destroy();
391 d->updateGeometry();
392 }
393 }
395}
396
398{
400 if (d->window->parent())
401 d->updateGeometry();
402 }
404}
405
407{
409 if (d->window->parent())
410 d->window->raise();
411 }
413}
414
416{
418 if (d->window->parent())
419 d->window->lower();
420 }
422}
423
425
426#include "moc_qwindowcontainer_p.cpp"
static QWidget * focusWidget()
Returns the application widget that has the keyboard input focus, or \nullptr if no widget in this ap...
\inmodule QtCore
Definition qcoreevent.h:372
QObject * child() const
Returns the child object that was added or removed.
Definition qcoreevent.h:377
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
\inmodule QtCore
Definition qcoreevent.h:45
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
@ PolishRequest
Definition qcoreevent.h:110
@ ChildRemoved
Definition qcoreevent.h:108
@ DragEnter
Definition qcoreevent.h:101
@ FocusIn
Definition qcoreevent.h:66
@ DragLeave
Definition qcoreevent.h:103
static QPlatformIntegration * platformIntegration()
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
\inmodule QtCore
Definition qobject.h:90
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2269
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
@ CompositionMode_Source
Definition qpainter.h:101
virtual bool hasCapability(Capability cap) const
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore
Definition qpointer.h:18
\inmodule QtCore\reentrant
Definition qrect.h:30
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
void createTLExtra()
Definition qwidget.cpp:1582
static QWidgetPrivate * get(QWidget *w)
Definition qwidget_p.h:211
std::unique_ptr< QWExtra > extra
Definition qwidget_p.h:639
void createTLSysExtra()
Definition qwidget.cpp:1377
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
QWidget * window() const
Returns the window for this widget, i.e.
Definition qwidget.cpp:4320
QWidget * nextInFocusChain() const
Returns the next widget in this widget's focus chain.
Definition qwidget.cpp:6868
void clearFocus()
Takes keyboard input focus from the widget.
Definition qwidget.cpp:6706
void setAcceptDrops(bool on)
Definition qwidget.cpp:3443
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
static QWidget * createWindowContainer(QWindow *window, QWidget *parent=nullptr, Qt::WindowFlags flags=Qt::WindowFlags())
Creates a QWidget that makes it possible to embed window into a QWidget-based application.
QWindow * windowHandle() const
If this is a native widget, return the associated QWindow.
Definition qwidget.cpp:2490
WId winId() const
Returns the window system identifier of the widget.
Definition qwidget.cpp:2364
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8912
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
QPointer< QWindow > window
static QWindowContainerPrivate * get(QWidget *w)
static void parentWasChanged(QWidget *parent)
bool event(QEvent *ev) override
QWindowContainer(QWindow *embeddedWindow, QWidget *parent=nullptr, Qt::WindowFlags f={ })
static void parentWasRaised(QWidget *parent)
static void parentWasMoved(QWidget *parent)
static void parentWasLowered(QWidget *parent)
QWindow * containedWindow() const
static void toplevelAboutToBeDestroyed(QWidget *parent)
bool eventFilter(QObject *, QEvent *ev) override
\inmodule QtGui
Definition qwindow.h:63
void setGeometry(int posx, int posy, int w, int h)
Sets the geometry of the window, excluding its window frame, to a rectangle constructed from posx,...
Definition qwindow.cpp:1744
QOpenGLWidget * widget
[1]
double e
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:46
@ SubWindow
Definition qnamespace.h:215
#define Q_UNLIKELY(x)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
#define qWarning
Definition qlogging.h:162
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLfloat GLfloat GLfloat w
[0]
GLenum type
GLbitfield flags
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QT_CONFIG(feature)
unsigned int uint
Definition qtypes.h:29
QWidget * qobject_cast< QWidget * >(QObject *o)
Definition qwidget.h:786
void(* qwindowcontainer_traverse_callback)(QWidget *parent)
static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback)
aWidget window() -> setWindowTitle("New Window Title")
[2]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent