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