Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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 "qwidgetwindow_p.h"
7#include <QtGui/qwindow.h>
8#include <QtGui/private/qwindow_p.h>
9#include <QtGui/private/qguiapplication_p.h>
10#include <qpa/qplatformintegration.h>
11#include <QDebug>
12
13#if QT_CONFIG(mdiarea)
14#include <QMdiSubWindow>
15#endif
16#include <QAbstractScrollArea>
17#include <QPainter>
18
19#include <QtCore/qpointer.h>
20
22
23using namespace Qt::StringLiterals;
24
26{
27public:
28 Q_DECLARE_PUBLIC(QWindowContainer)
29
31 : window(nullptr)
33 {
34 }
35
37
39 QWindowContainer *wc = qobject_cast<QWindowContainer *>(w);
40 if (wc)
41 return wc->d_func();
42 return nullptr;
43 }
44
47 if (!q->isWindow() && (q->geometry().bottom() <= 0 || q->geometry().right() <= 0))
48 /* Qt (e.g. QSplitter) sometimes prefer to hide a widget by *not* calling
49 setVisible(false). This is often done by setting its coordinates to a sufficiently
50 negative value so that its clipped outside the parent. Since a QWindow is not clipped
51 to widgets in general, it needs to be dealt with as a special case.
52 */
53 window->setGeometry(q->geometry());
54 else if (usesNativeWidgets)
55 window->setGeometry(q->rect());
56 else
57 window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
58 }
59
61 {
62 if (window->parent() == nullptr)
63 return;
65 if (q->internalWinId()) {
66 // Allow use native widgets if the window container is already a native widget
67 usesNativeWidgets = true;
68 return;
69 }
70 bool nativeWidgetSet = false;
71 QWidget *p = q->parentWidget();
72 while (p) {
73 if (false
74#if QT_CONFIG(mdiarea)
75 || qobject_cast<QMdiSubWindow *>(p) != 0
76#endif
77#if QT_CONFIG(scrollarea)
78 || qobject_cast<QAbstractScrollArea *>(p) != 0
79#endif
80 ) {
81 q->winId();
82 nativeWidgetSet = true;
83 break;
84 }
85 p = p->parentWidget();
86 }
87 usesNativeWidgets = nativeWidgetSet;
88 }
89
92 QWidget *p = q;
93 while (p) {
95 d->createExtra();
96 d->extra->hasWindowContainer = true;
97 p = p->parentWidget();
98 }
99 }
100
101 bool isStillAnOrphan() const {
102 return window->parent() == &fakeParent;
103 }
104
105 QPointer<QWindow> window;
107
109};
110
111
112
179{
180 // Embedding a QWidget in a window container doesn't make sense,
181 // and has various issues in practice, so just return the widget
182 // itself.
183 if (auto *widgetWindow = qobject_cast<QWidgetWindow *>(window)) {
184 QWidget *widget = widgetWindow->widget();
185 if (flags != Qt::WindowFlags()) {
186 qWarning() << window << "refers to a widget:" << widget
187 << "WindowFlags" << flags << "will be ignored.";
188 }
190 return widget;
191 }
192 return new QWindowContainer(window, parent, flags);
193}
194
199QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt::WindowFlags flags)
200 : QWidget(*new QWindowContainerPrivate, parent, flags)
201{
202 Q_D(QWindowContainer);
203 if (Q_UNLIKELY(!embeddedWindow)) {
204 qWarning("QWindowContainer: embedded window cannot be null");
205 return;
206 }
207
208 d->window = embeddedWindow;
209 d->window->installEventFilter(this);
210
211 QString windowName = d->window->objectName();
212 if (windowName.isEmpty())
213 windowName = QString::fromUtf8(d->window->metaObject()->className());
214 d->fakeParent.setObjectName(windowName + "ContainerFakeParent"_L1);
215
216 d->window->setParent(&d->fakeParent);
217 d->window->parent()->installEventFilter(this);
218 d->window->setFlag(Qt::SubWindow);
219
220 setAcceptDrops(true);
221
224}
225
227{
228 Q_D(const QWindowContainer);
229 return d->window;
230}
231
237{
238 Q_D(QWindowContainer);
239
240 // Call destroy() explicitly first. The dtor would do this too, but
241 // QEvent::PlatformSurface delivery relies on virtuals. Getting
242 // SurfaceAboutToBeDestroyed can be essential for OpenGL, Vulkan, etc.
243 // QWindow subclasses in particular. Keep these working.
244 if (d->window) {
245 d->window->removeEventFilter(this);
246 d->window->destroy();
247 }
248
249 delete d->window;
250}
251
257{
258 Q_D(QWindowContainer);
259 if (!d->window)
260 return false;
261
262 if (e->type() == QEvent::ChildRemoved) {
263 QChildEvent *ce = static_cast<QChildEvent *>(e);
264 if (ce->child() == d->window) {
265 o->removeEventFilter(this);
266 d->window->removeEventFilter(this);
267 d->window = nullptr;
268 }
269 } else if (e->type() == QEvent::FocusIn) {
270 if (o == d->window)
272 }
273 return false;
274}
275
281{
282 Q_D(QWindowContainer);
283 if (!d->window)
284 return QWidget::event(e);
285
286 QEvent::Type type = e->type();
287 switch (type) {
288 // The only thing we are interested in is making sure our sizes stay
289 // in sync, so do a catch-all case.
290 case QEvent::Resize:
291 d->updateGeometry();
292 break;
293 case QEvent::Move:
294 d->updateGeometry();
295 break;
297 d->updateGeometry();
298 break;
299 case QEvent::Show:
300 d->updateUsesNativeWidgets();
301 if (d->isStillAnOrphan()) {
302 d->window->parent()->removeEventFilter(this);
303 d->window->setParent(d->usesNativeWidgets
304 ? windowHandle()
305 : window()->windowHandle());
306 d->fakeParent.destroy();
307 if (d->window->parent())
308 d->window->parent()->installEventFilter(this);
309 }
310 if (d->window->parent()) {
311 d->markParentChain();
312 d->window->show();
313 }
314 break;
315 case QEvent::Hide:
316 if (d->window->parent())
317 d->window->hide();
318 break;
319 case QEvent::FocusIn:
320 if (d->window->parent()) {
321 if (QGuiApplication::focusWindow() != d->window) {
322 QFocusEvent *event = static_cast<QFocusEvent *>(e);
323 const auto reason = event->reason();
325 if (reason == Qt::TabFocusReason)
327 else if (reason == Qt::BacktabFocusReason)
329 qt_window_private(d->window)->setFocusToTarget(target, reason);
330 d->window->requestActivate();
331 }
332 }
333 break;
334#if QT_CONFIG(draganddrop)
335 case QEvent::Drop:
336 case QEvent::DragMove:
338 QCoreApplication::sendEvent(d->window, e);
339 return e->isAccepted();
341 // Don't reject drag events for the entire widget when one
342 // item rejects the drag enter
343 QCoreApplication::sendEvent(d->window, e);
344 e->accept();
345 return true;
346#endif
347
348 case QEvent::Paint:
349 {
350 static bool needsPunch = !QGuiApplicationPrivate::platformIntegration()->hasCapability(
352 if (needsPunch) {
353 QPainter p(this);
354 p.setCompositionMode(QPainter::CompositionMode_Source);
355 p.fillRect(rect(), Qt::transparent);
356 }
357 break;
358 }
359
360 default:
361 break;
362 }
363
364 return QWidget::event(e);
365}
366
368{
369 return containedWindow() ? containedWindow()->minimumSize() : QSize(0, 0);
370}
371
374{
375 const QObjectList &children = parent->children();
376 for (int i=0; i<children.size(); ++i) {
377 QWidget *w = qobject_cast<QWidget *>(children.at(i));
378 if (w) {
379 QWidgetPrivate *wd = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(w));
380 if (wd->extra && wd->extra->hasWindowContainer)
381 callback(w);
382 }
383 }
384}
385
387{
389 if (d->window->parent())
390 d->window->parent()->removeEventFilter(parent);
391 d->window->setParent(&d->fakeParent);
392 d->window->parent()->installEventFilter(parent);
393 }
395}
396
398{
400 if (d->window->parent()) {
401 d->updateUsesNativeWidgets();
402 d->markParentChain();
403 QWidget *toplevel = d->usesNativeWidgets ? parent : parent->window();
404 if (!toplevel->windowHandle()) {
405 QWidgetPrivate *tld = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(toplevel));
406 tld->createTLExtra();
407 tld->createTLSysExtra();
408 Q_ASSERT(toplevel->windowHandle());
409 }
410 d->window->parent()->removeEventFilter(parent);
411 d->window->setParent(toplevel->windowHandle());
413 d->fakeParent.destroy();
414 d->updateGeometry();
415 }
416 }
418}
419
421{
423 if (d->window->parent())
424 d->updateGeometry();
425 }
427}
428
430{
432 if (d->window->parent())
433 d->window->raise();
434 }
436}
437
439{
441 if (d->window->parent())
442 d->window->lower();
443 }
445}
446
448
449#include "moc_qwindowcontainer_p.cpp"
\inmodule QtCore
Definition qcoreevent.h:379
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
\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
Type type() const
Returns the event type.
Definition qcoreevent.h:304
bool isAccepted() const
Definition qcoreevent.h:308
void accept()
Sets the accept flag of the event object, the equivalent of calling setAccepted(true).
Definition qcoreevent.h:310
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
Qt::FocusReason reason() const
Returns the reason for this focus event.
Definition qevent.cpp:1569
static QPlatformIntegration * platformIntegration()
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
qsizetype size() const noexcept
Definition qlist.h:397
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
\inmodule QtCore
Definition qobject.h:103
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2339
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:201
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
@ CompositionMode_Source
Definition qpainter.h:101
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
void createTLExtra()
Definition qwidget.cpp:1599
static QWidgetPrivate * get(QWidget *w)
Definition qwidget_p.h:212
std::unique_ptr< QWExtra > extra
Definition qwidget_p.h:647
void createExtra()
Definition qwidget.cpp:1632
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:4313
void setParent(QWidget *parent)
Sets the parent of the widget to parent, and resets the window flags.
void updateGeometry()
Notifies the layout system that this widget has changed and may need to change geometry.
void setAcceptDrops(bool on)
Definition qwidget.cpp:3436
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
void setFocus()
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:423
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:2483
WId winId() const
Returns the window system identifier of the widget.
Definition qwidget.cpp:2357
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
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)
QSize minimumSizeHint() const override
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 minimumHeightChanged(int arg)
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:1802
void minimumWidthChanged(int arg)
QOpenGLWidget * widget
[1]
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
@ SubWindow
Definition qnamespace.h:216
@ BacktabFocusReason
@ ActiveWindowFocusReason
@ TabFocusReason
#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:166
GLfloat GLfloat GLfloat w
[0]
GLenum type
GLenum target
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:34
QWidget * qobject_cast< QWidget * >(QObject *o)
Definition qwidget.h:786
Q_GUI_EXPORT QWindowPrivate * qt_window_private(QWindow *window)
Definition qwindow.cpp:2950
void(* qwindowcontainer_traverse_callback)(QWidget *parent)
static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback)
aWidget window() -> setWindowTitle("New Window Title")
[2]