qwindowcontainer.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/kernel/qwindowcontainer.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qwindowcontainer_p.h"-
41#include "qwidget_p.h"-
42#include <QtGui/qwindow.h>-
43#include <QtGui/private/qguiapplication_p.h>-
44#include <qpa/qplatformintegration.h>-
45#include <QDebug>-
46-
47#include <QMdiSubWindow>-
48#include <QAbstractScrollArea>-
49-
50QT_BEGIN_NAMESPACE-
51-
52class QWindowContainerPrivate : public QWidgetPrivate-
53{-
54public:-
55 Q_DECLARE_PUBLIC(QWindowContainer)-
56-
57 QWindowContainerPrivate()-
58 : window(0)-
59 , oldFocusWindow(0)-
60 , usesNativeWidgets(false)-
61 {-
62 }
never executed: end of block
0
63-
64 ~QWindowContainerPrivate() { }-
65-
66 static QWindowContainerPrivate *get(QWidget *w) {-
67 QWindowContainer *wc = qobject_cast<QWindowContainer *>(w);-
68 if (wc)
wcDescription
TRUEnever evaluated
FALSEnever evaluated
0
69 return wc->d_func();
never executed: return wc->d_func();
0
70 return 0;
never executed: return 0;
0
71 }-
72-
73 void updateGeometry() {-
74 Q_Q(QWindowContainer);-
75 if (!q->isWindow() && (q->geometry().bottom() <= 0 || q->geometry().right() <= 0))
!q->isWindow()Description
TRUEnever evaluated
FALSEnever evaluated
q->geometry().bottom() <= 0Description
TRUEnever evaluated
FALSEnever evaluated
q->geometry().right() <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
76 /* Qt (e.g. QSplitter) sometimes prefer to hide a widget by *not* calling-
77 setVisible(false). This is often done by setting its coordinates to a sufficiently-
78 negative value so that its clipped outside the parent. Since a QWindow is not clipped-
79 to widgets in general, it needs to be dealt with as a special case.-
80 */-
81 window->setGeometry(q->geometry());
never executed: window->setGeometry(q->geometry());
0
82 else if (usesNativeWidgets)
usesNativeWidgetsDescription
TRUEnever evaluated
FALSEnever evaluated
0
83 window->setGeometry(q->rect());
never executed: window->setGeometry(q->rect());
0
84 else-
85 window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
never executed: window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
0
86 }-
87-
88 void updateUsesNativeWidgets()-
89 {-
90 if (usesNativeWidgets || window->parent() == 0)
usesNativeWidgetsDescription
TRUEnever evaluated
FALSEnever evaluated
window->parent() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
91 return;
never executed: return;
0
92 Q_Q(QWindowContainer);-
93 if (q->internalWinId()) {
q->internalWinId()Description
TRUEnever evaluated
FALSEnever evaluated
0
94 // Allow use native widgets if the window container is already a native widget-
95 usesNativeWidgets = true;-
96 return;
never executed: return;
0
97 }-
98 QWidget *p = q->parentWidget();-
99 while (p) {
pDescription
TRUEnever evaluated
FALSEnever evaluated
0
100 if (-
101#ifndef QT_NO_MDIAREA-
102 qobject_cast<QMdiSubWindow *>(p) != 0 ||
qobject_cast<Q...dow *>(p) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
103#endif-
104 qobject_cast<QAbstractScrollArea *>(p) != 0) {
qobject_cast<Q...rea *>(p) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
105 q->winId();-
106 usesNativeWidgets = true;-
107 break;
never executed: break;
0
108 }-
109 p = p->parentWidget();-
110 }
never executed: end of block
0
111 }
never executed: end of block
0
112-
113 void markParentChain() {-
114 Q_Q(QWindowContainer);-
115 QWidget *p = q;-
116 while (p) {
pDescription
TRUEnever evaluated
FALSEnever evaluated
0
117 QWidgetPrivate *d = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(p));-
118 d->createExtra();-
119 d->extra->hasWindowContainer = true;-
120 p = p->parentWidget();-
121 }
never executed: end of block
0
122 }
never executed: end of block
0
123-
124 bool isStillAnOrphan() const {-
125 return window->parent() == &fakeParent;
never executed: return window->parent() == &fakeParent;
0
126 }-
127-
128 QPointer<QWindow> window;-
129 QWindow *oldFocusWindow;-
130 QWindow fakeParent;-
131-
132 uint usesNativeWidgets : 1;-
133};-
134-
135-
136-
137/*!-
138 \fn QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent, Qt::WindowFlags flags);-
139-
140 Creates a QWidget that makes it possible to embed \a window into-
141 a QWidget-based application.-
142-
143 The window container is created as a child of \a parent and with-
144 window flags \a flags.-
145-
146 Once the window has been embedded into the container, the-
147 container will control the window's geometry and-
148 visibility. Explicit calls to QWindow::setGeometry(),-
149 QWindow::show() or QWindow::hide() on an embedded window is not-
150 recommended.-
151-
152 The container takes over ownership of \a window. The window can-
153 be removed from the window container with a call to-
154 QWindow::setParent().-
155-
156 The window container is attached as a native child window to the-
157 toplevel window it is a child of. When a window container is used-
158 as a child of a QAbstractScrollArea or QMdiArea, it will-
159 create a \l {Native Widgets vs Alien Widgets} {native window} for-
160 every widget in its parent chain to allow for proper stacking and-
161 clipping in this use case. Creating a native window for the window-
162 container also allows for proper stacking and clipping. This must-
163 be done before showing the window container. Applications with-
164 many native child windows may suffer from performance issues.-
165-
166 The window container has a number of known limitations:-
167-
168 \list-
169-
170 \li Stacking order; The embedded window will stack on top of the-
171 widget hierarchy as an opaque box. The stacking order of multiple-
172 overlapping window container instances is undefined.-
173-
174 \li Rendering Integration; The window container does not interoperate-
175 with QGraphicsProxyWidget, QWidget::render() or similar functionality.-
176-
177 \li Focus Handling; It is possible to let the window container-
178 instance have any focus policy and it will delegate focus to the-
179 window via a call to QWindow::requestActivate(). However,-
180 returning to the normal focus chain from the QWindow instance will-
181 be up to the QWindow instance implementation itself. For instance,-
182 when entering a Qt Quick based window with tab focus, it is quite-
183 likely that further tab presses will only cycle inside the QML-
184 application. Also, whether QWindow::requestActivate() actually-
185 gives the window focus, is platform dependent.-
186-
187 \li Using many window container instances in a QWidget-based-
188 application can greatly hurt the overall performance of the-
189 application.-
190-
191 \endlist-
192 */-
193-
194QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent, Qt::WindowFlags flags)-
195{-
196 return new QWindowContainer(window, parent, flags);
never executed: return new QWindowContainer(window, parent, flags);
0
197}-
198-
199-
200-
201/*!-
202 \internal-
203 */-
204-
205QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt::WindowFlags flags)-
206 : QWidget(*new QWindowContainerPrivate, parent, flags)-
207{-
208 Q_D(QWindowContainer);-
209 if (Q_UNLIKELY(!embeddedWindow)) {
__builtin_expe...indow), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
210 qWarning("QWindowContainer: embedded window cannot be null");-
211 return;
never executed: return;
0
212 }-
213-
214 // The embedded QWindow must use the same logic as QWidget when it comes to the surface type.-
215 // Otherwise we may end up with BadMatch failures on X11.-
216 if (embeddedWindow->surfaceType() == QSurface::RasterSurface
embeddedWindow...:RasterSurfaceDescription
TRUEnever evaluated
FALSEnever evaluated
0
217 && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RasterGLSurface)
QGuiApplicatio...sterGLSurface)Description
TRUEnever evaluated
FALSEnever evaluated
0
218 && !QApplication::testAttribute(Qt::AA_ForceRasterWidgets))
!QApplication:...RasterWidgets)Description
TRUEnever evaluated
FALSEnever evaluated
0
219 embeddedWindow->setSurfaceType(QSurface::RasterGLSurface);
never executed: embeddedWindow->setSurfaceType(QSurface::RasterGLSurface);
0
220-
221 d->window = embeddedWindow;-
222 d->window->setParent(&d->fakeParent);-
223 setAcceptDrops(true);-
224-
225 connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow*)), this, SLOT(focusWindowChanged(QWindow*)));-
226}
never executed: end of block
0
227-
228QWindow *QWindowContainer::containedWindow() const-
229{-
230 Q_D(const QWindowContainer);-
231 return d->window;
never executed: return d->window;
0
232}-
233-
234/*!-
235 \internal-
236 */-
237-
238QWindowContainer::~QWindowContainer()-
239{-
240 Q_D(QWindowContainer);-
241 delete d->window;-
242}
never executed: end of block
0
243-
244-
245-
246/*!-
247 \internal-
248 */-
249-
250void QWindowContainer::focusWindowChanged(QWindow *focusWindow)-
251{-
252 Q_D(QWindowContainer);-
253 d->oldFocusWindow = focusWindow;-
254 if (focusWindow == d->window) {
focusWindow == d->windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
255 QWidget *widget = QApplication::focusWidget();-
256 if (widget)
widgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
257 widget->clearFocus();
never executed: widget->clearFocus();
0
258 }
never executed: end of block
0
259}
never executed: end of block
0
260-
261/*!-
262 \internal-
263 */-
264-
265bool QWindowContainer::event(QEvent *e)-
266{-
267 Q_D(QWindowContainer);-
268 if (!d->window)
!d->windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
269 return QWidget::event(e);
never executed: return QWidget::event(e);
0
270-
271 QEvent::Type type = e->type();-
272 switch (type) {-
273 case QEvent::ChildRemoved: {
never executed: case QEvent::ChildRemoved:
0
274 QChildEvent *ce = static_cast<QChildEvent *>(e);-
275 if (ce->child() == d->window)
ce->child() == d->windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 d->window = 0;
never executed: d->window = 0;
0
277 break;
never executed: break;
0
278 }-
279 // The only thing we are interested in is making sure our sizes stay-
280 // in sync, so do a catch-all case.-
281 case QEvent::Resize:
never executed: case QEvent::Resize:
0
282 d->updateGeometry();-
283 break;
never executed: break;
0
284 case QEvent::Move:
never executed: case QEvent::Move:
0
285 d->updateGeometry();-
286 break;
never executed: break;
0
287 case QEvent::PolishRequest:
never executed: case QEvent::PolishRequest:
0
288 d->updateGeometry();-
289 break;
never executed: break;
0
290 case QEvent::Show:
never executed: case QEvent::Show:
0
291 d->updateUsesNativeWidgets();-
292 if (d->isStillAnOrphan()) {
d->isStillAnOrphan()Description
TRUEnever evaluated
FALSEnever evaluated
0
293 d->window->setParent(d->usesNativeWidgets-
294 ? windowHandle()-
295 : window()->windowHandle());-
296 }
never executed: end of block
0
297 if (d->window->parent()) {
d->window->parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
298 d->markParentChain();-
299 d->window->show();-
300 }
never executed: end of block
0
301 break;
never executed: break;
0
302 case QEvent::Hide:
never executed: case QEvent::Hide:
0
303 if (d->window->parent())
d->window->parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
304 d->window->hide();
never executed: d->window->hide();
0
305 break;
never executed: break;
0
306 case QEvent::FocusIn:
never executed: case QEvent::FocusIn:
0
307 if (d->window->parent()) {
d->window->parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
308 if (d->oldFocusWindow != d->window) {
d->oldFocusWindow != d->windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
309 d->window->requestActivate();-
310 } else {
never executed: end of block
0
311 QWidget *next = nextInFocusChain();-
312 next->setFocus();-
313 }
never executed: end of block
0
314 }-
315 break;
never executed: break;
0
316#ifndef QT_NO_DRAGANDDROP-
317 case QEvent::Drop:
never executed: case QEvent::Drop:
0
318 case QEvent::DragMove:
never executed: case QEvent::DragMove:
0
319 case QEvent::DragLeave:
never executed: case QEvent::DragLeave:
0
320 QCoreApplication::sendEvent(d->window, e);-
321 return e->isAccepted();
never executed: return e->isAccepted();
0
322 case QEvent::DragEnter:
never executed: case QEvent::DragEnter:
0
323 // Don't reject drag events for the entire widget when one-
324 // item rejects the drag enter-
325 QCoreApplication::sendEvent(d->window, e);-
326 e->accept();-
327 return true;
never executed: return true;
0
328#endif-
329 default:
never executed: default:
0
330 break;
never executed: break;
0
331 }-
332-
333 return QWidget::event(e);
never executed: return QWidget::event(e);
0
334}-
335-
336typedef void (*qwindowcontainer_traverse_callback)(QWidget *parent);-
337static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback)-
338{-
339 const QObjectList &children = parent->children();-
340 for (int i=0; i<children.size(); ++i) {
i<children.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
341 QWidget *w = qobject_cast<QWidget *>(children.at(i));-
342 if (w) {
wDescription
TRUEnever evaluated
FALSEnever evaluated
0
343 QWidgetPrivate *wd = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(w));-
344 if (wd->extra && wd->extra->hasWindowContainer)
wd->extraDescription
TRUEnever evaluated
FALSEnever evaluated
wd->extra->hasWindowContainerDescription
TRUEnever evaluated
FALSEnever evaluated
0
345 callback(w);
never executed: callback(w);
0
346 }
never executed: end of block
0
347 }
never executed: end of block
0
348}
never executed: end of block
0
349-
350void QWindowContainer::toplevelAboutToBeDestroyed(QWidget *parent)-
351{-
352 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
QWindowContain...e::get(parent)Description
TRUEnever evaluated
FALSEnever evaluated
0
353 d->window->setParent(&d->fakeParent);-
354 }
never executed: end of block
0
355 qwindowcontainer_traverse(parent, toplevelAboutToBeDestroyed);-
356}
never executed: end of block
0
357-
358void QWindowContainer::parentWasChanged(QWidget *parent)-
359{-
360 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
QWindowContain...e::get(parent)Description
TRUEnever evaluated
FALSEnever evaluated
0
361 if (d->window->parent()) {
d->window->parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
362 d->updateUsesNativeWidgets();-
363 d->markParentChain();-
364 QWidget *toplevel = d->usesNativeWidgets ? parent : parent->window();
d->usesNativeWidgetsDescription
TRUEnever evaluated
FALSEnever evaluated
0
365 if (!toplevel->windowHandle()) {
!toplevel->windowHandle()Description
TRUEnever evaluated
FALSEnever evaluated
0
366 QWidgetPrivate *tld = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(toplevel));-
367 tld->createTLExtra();-
368 tld->createTLSysExtra();-
369 Q_ASSERT(toplevel->windowHandle());-
370 }
never executed: end of block
0
371 d->window->setParent(toplevel->windowHandle());-
372 d->updateGeometry();-
373 }
never executed: end of block
0
374 }
never executed: end of block
0
375 qwindowcontainer_traverse(parent, parentWasChanged);-
376}
never executed: end of block
0
377-
378void QWindowContainer::parentWasMoved(QWidget *parent)-
379{-
380 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
QWindowContain...e::get(parent)Description
TRUEnever evaluated
FALSEnever evaluated
0
381 if (d->window->parent())
d->window->parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
382 d->updateGeometry();
never executed: d->updateGeometry();
0
383 }
never executed: end of block
0
384 qwindowcontainer_traverse(parent, parentWasMoved);-
385}
never executed: end of block
0
386-
387void QWindowContainer::parentWasRaised(QWidget *parent)-
388{-
389 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
QWindowContain...e::get(parent)Description
TRUEnever evaluated
FALSEnever evaluated
0
390 if (d->window->parent())
d->window->parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
391 d->window->raise();
never executed: d->window->raise();
0
392 }
never executed: end of block
0
393 qwindowcontainer_traverse(parent, parentWasRaised);-
394}
never executed: end of block
0
395-
396void QWindowContainer::parentWasLowered(QWidget *parent)-
397{-
398 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
QWindowContain...e::get(parent)Description
TRUEnever evaluated
FALSEnever evaluated
0
399 if (d->window->parent())
d->window->parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
400 d->window->lower();
never executed: d->window->lower();
0
401 }
never executed: end of block
0
402 qwindowcontainer_traverse(parent, parentWasLowered);-
403}
never executed: end of block
0
404-
405QT_END_NAMESPACE-
406-
407#include "moc_qwindowcontainer_p.cpp"-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9