1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtWidgets module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qapplication.h"
42#include "qapplication_p.h"
43#include "qbrush.h"
44#include "qcursor.h"
45#include "qdesktopwidget_p.h"
46#include "qevent.h"
47#include "qlayout.h"
48#include "qmenu.h"
49#include "qmetaobject.h"
50#include "qpixmap.h"
51#include "qpointer.h"
52#include "qstack.h"
53#include "qstyle.h"
54#include "qstylefactory.h"
55#include "qvariant.h"
56#include "qwidget.h"
57#include "qstyleoption.h"
58#include "qstylehints.h"
59#ifndef QT_NO_ACCESSIBILITY
60# include "qaccessible.h"
61#endif
62#if 0 // Used to be included in Qt4 for Q_WS_MAC
63# include "qt_mac_p.h"
64# include "qt_cocoa_helpers_mac_p.h"
65# include "qmainwindow.h"
66# include "qtoolbar.h"
67# include <private/qmainwindowlayout_p.h>
68#endif
69#include <qpa/qplatformwindow.h>
70#include <qpa/qplatformbackingstore.h>
71#include "private/qwidgetwindow_p.h"
72#include "qpainter.h"
73#include "qtooltip.h"
74#include "qwhatsthis.h"
75#include "qdebug.h"
76#include "private/qstylesheetstyle_p.h"
77#include "private/qstyle_p.h"
78#include "qfileinfo.h"
79#include <QtGui/private/qhighdpiscaling_p.h>
80#include <QtGui/qinputmethod.h>
81#include <QtGui/qopenglcontext.h>
82#include <QtGui/private/qopenglcontext_p.h>
83#include <QtGui/qoffscreensurface.h>
84
85#include <private/qgraphicseffect_p.h>
86#include <qbackingstore.h>
87#include <private/qwidgetbackingstore_p.h>
88#if 0 // Used to be included in Qt4 for Q_WS_MAC
89# include <private/qpaintengine_mac_p.h>
90#endif
91#include <private/qpaintengine_raster_p.h>
92
93#include "qwidget_p.h"
94#include <QtGui/private/qwindow_p.h>
95#include "qaction_p.h"
96#include "qlayout_p.h"
97#include "QtWidgets/qgraphicsproxywidget.h"
98#include "QtWidgets/qgraphicsscene.h"
99#include "private/qgraphicsproxywidget_p.h"
100#include "QtWidgets/qabstractscrollarea.h"
101#include "private/qabstractscrollarea_p.h"
102#include "private/qevent_p.h"
103
104#include "private/qgesturemanager_p.h"
105
106#ifdef QT_KEYPAD_NAVIGATION
107#include "qtabwidget.h" // Needed in inTabWidget()
108#endif // QT_KEYPAD_NAVIGATION
109
110#include "qwindowcontainer_p.h"
111
112#include <QtPlatformHeaders/qxcbwindowfunctions.h>
113
114// widget/widget data creation count
115//#define QWIDGET_EXTRA_DEBUG
116//#define ALIEN_DEBUG
117
118QT_BEGIN_NAMESPACE
119
120static bool qt_enable_backingstore = true;
121#if 0 // Used to be included in Qt4 for Q_WS_X11
122// for compatibility with Qt 4.0
123Q_WIDGETS_EXPORT void qt_x11_set_global_double_buffer(bool enable)
124{
125 qt_enable_backingstore = enable;
126}
127#endif
128
129#if 0 // Used to be included in Qt4 for Q_WS_MAC
130bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false;
131#endif
132
133static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
134{
135 return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) &&
136 qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
137}
138
139static inline bool hasBackingStoreSupport()
140{
141 return true;
142}
143
144#if 0 // Used to be included in Qt4 for Q_WS_MAC
145# define QT_NO_PAINT_DEBUG
146#endif
147
148extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
149extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
150
151/*!
152 \internal
153 \class QWidgetBackingStoreTracker
154 \brief Class which allows tracking of which widgets are using a given backing store
155
156 QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
157 which maintains a list of the QWidgets which are currently using the backing
158 store. This list is modified via the registerWidget and unregisterWidget functions.
159 */
160
161QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
162 : m_ptr(0)
163{
164
165}
166
167QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
168{
169 delete m_ptr;
170}
171
172/*!
173 \internal
174 Destroy the contained QWidgetBackingStore, if not null, and clear the list of
175 widgets using the backing store, then create a new QWidgetBackingStore, providing
176 the QWidget.
177 */
178void QWidgetBackingStoreTracker::create(QWidget *widget)
179{
180 destroy();
181 m_ptr = new QWidgetBackingStore(widget);
182}
183
184/*!
185 \internal
186 Destroy the contained QWidgetBackingStore, if not null, and clear the list of
187 widgets using the backing store.
188 */
189void QWidgetBackingStoreTracker::destroy()
190{
191 delete m_ptr;
192 m_ptr = 0;
193 m_widgets.clear();
194}
195
196/*!
197 \internal
198 Add the widget to the list of widgets currently using the backing store.
199 If the widget was already in the list, this function is a no-op.
200 */
201void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
202{
203 Q_ASSERT(m_ptr);
204 Q_ASSERT(w->internalWinId());
205 Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
206 m_widgets.insert(w);
207}
208
209/*!
210 \internal
211 Remove the widget from the list of widgets currently using the backing store.
212 If the widget was in the list, and removing it causes the list to be empty,
213 the backing store is deleted.
214 If the widget was not in the list, this function is a no-op.
215 */
216void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
217{
218 if (m_widgets.remove(w) && m_widgets.isEmpty()) {
219 delete m_ptr;
220 m_ptr = 0;
221 }
222}
223
224/*!
225 \internal
226 Recursively remove widget and all of its descendents.
227 */
228void QWidgetBackingStoreTracker::unregisterWidgetSubtree(QWidget *widget)
229{
230 unregisterWidget(widget);
231 foreach (QObject *child, widget->children())
232 if (QWidget *childWidget = qobject_cast<QWidget *>(child))
233 unregisterWidgetSubtree(childWidget);
234}
235
236QWidgetPrivate::QWidgetPrivate(int version)
237 : QObjectPrivate(version)
238 , extra(0)
239 , focus_next(0)
240 , focus_prev(0)
241 , focus_child(0)
242 , layout(0)
243 , needsFlush(0)
244 , redirectDev(0)
245 , widgetItem(0)
246 , extraPaintEngine(0)
247 , polished(0)
248 , graphicsEffect(0)
249#if !defined(QT_NO_IM)
250 , imHints(Qt::ImhNone)
251#endif
252#ifndef QT_NO_TOOLTIP
253 , toolTipDuration(-1)
254#endif
255 , inheritedFontResolveMask(0)
256 , inheritedPaletteResolveMask(0)
257 , leftmargin(0)
258 , topmargin(0)
259 , rightmargin(0)
260 , bottommargin(0)
261 , leftLayoutItemMargin(0)
262 , topLayoutItemMargin(0)
263 , rightLayoutItemMargin(0)
264 , bottomLayoutItemMargin(0)
265 , hd(0)
266 , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
267 , fg_role(QPalette::NoRole)
268 , bg_role(QPalette::NoRole)
269 , dirtyOpaqueChildren(1)
270 , isOpaque(0)
271 , retainSizeWhenHiddenChanged(0)
272 , inDirtyList(0)
273 , isScrolled(0)
274 , isMoved(0)
275 , usesDoubleBufferedGLContext(0)
276 , mustHaveWindowHandle(0)
277 , renderToTexture(0)
278 , textureChildSeen(0)
279#ifndef QT_NO_IM
280 , inheritsInputMethodHints(0)
281#endif
282#ifndef QT_NO_OPENGL
283 , renderToTextureReallyDirty(1)
284 , renderToTextureComposeActive(0)
285#endif
286 , childrenHiddenByWState(0)
287 , childrenShownByExpose(0)
288#if defined(Q_OS_WIN)
289 , noPaintOnScreen(0)
290#endif
291#if 0 // Used to be included in Qt4 for Q_WS_X11
292 , picture(0)
293#elif 0 // Used to be included in Qt4 for Q_WS_WIN
294 #ifndef QT_NO_GESTURES
295 , nativeGesturePanEnabled(0)
296 #endif
297#elif 0 // Used to be included in Qt4 for Q_WS_MAC
298 , needWindowChange(0)
299 , window_event(0)
300 , qd_hd(0)
301#endif
302{
303 if (Q_UNLIKELY(!qApp)) {
304 qFatal("QWidget: Must construct a QApplication before a QWidget");
305 return;
306 }
307
308#ifdef QT_BUILD_INTERNAL
309 // Don't check the version parameter in internal builds.
310 // This allows incompatible versions to be loaded, possibly for testing.
311 Q_UNUSED(version);
312#else
313 if (Q_UNLIKELY(version != QObjectPrivateVersion))
314 qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
315 version, QObjectPrivateVersion);
316#endif
317
318 isWidget = true;
319 memset(high_attributes, 0, sizeof(high_attributes));
320#if 0 // Used to be included in Qt4 for Q_WS_MAC
321 drawRectOriginalAdded = false;
322 originalDrawMethod = true;
323 changeMethods = false;
324 isInUnifiedToolbar = false;
325 unifiedSurface = 0;
326 toolbar_ancestor = 0;
327 flushRequested = false;
328 touchEventsEnabled = false;
329#endif
330#ifdef QWIDGET_EXTRA_DEBUG
331 static int count = 0;
332 qDebug() << "widgets" << ++count;
333#endif
334}
335
336
337QWidgetPrivate::~QWidgetPrivate()
338{
339 if (widgetItem)
340 widgetItem->wid = 0;
341
342 if (extra)
343 deleteExtra();
344
345#ifndef QT_NO_GRAPHICSEFFECT
346 delete graphicsEffect;
347#endif //QT_NO_GRAPHICSEFFECT
348}
349
350/*!
351 \internal
352*/
353void QWidgetPrivate::scrollChildren(int dx, int dy)
354{
355 Q_Q(QWidget);
356 if (q->children().size() > 0) { // scroll children
357 QPoint pd(dx, dy);
358 QObjectList childObjects = q->children();
359 for (int i = 0; i < childObjects.size(); ++i) { // move all children
360 QWidget *w = qobject_cast<QWidget*>(childObjects.at(i));
361 if (w && !w->isWindow()) {
362 QPoint oldp = w->pos();
363 QRect r(w->pos() + pd, w->size());
364 w->data->crect = r;
365 if (w->testAttribute(Qt::WA_WState_Created))
366 w->d_func()->setWSGeometry();
367 w->d_func()->setDirtyOpaqueRegion();
368 QMoveEvent e(r.topLeft(), oldp);
369 QApplication::sendEvent(w, &e);
370 }
371 }
372 }
373}
374
375void QWidgetPrivate::setWSGeometry()
376{
377 Q_Q(QWidget);
378 if (QWindow *window = q->windowHandle())
379 window->setGeometry(data.crect);
380}
381
382void QWidgetPrivate::updateWidgetTransform(QEvent *event)
383{
384 Q_Q(QWidget);
385 if (q == QGuiApplication::focusObject() || event->type() == QEvent::FocusIn) {
386 QTransform t;
387 QPoint p = q->mapTo(q->topLevelWidget(), QPoint(0,0));
388 t.translate(p.x(), p.y());
389 QGuiApplication::inputMethod()->setInputItemTransform(t);
390 QGuiApplication::inputMethod()->setInputItemRectangle(q->rect());
391 QGuiApplication::inputMethod()->update(Qt::ImInputItemClipRectangle);
392 }
393}
394
395#ifdef QT_KEYPAD_NAVIGATION
396QPointer<QWidget> QWidgetPrivate::editingWidget;
397
398/*!
399 Returns \c true if this widget currently has edit focus; otherwise false.
400
401 This feature is only available in Qt for Embedded Linux.
402
403 \sa setEditFocus(), QApplication::keypadNavigationEnabled()
404*/
405bool QWidget::hasEditFocus() const
406{
407 const QWidget* w = this;
408 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
409 w = w->d_func()->extra->focus_proxy;
410 return QWidgetPrivate::editingWidget == w;
411}
412
413/*!
414 \fn void QWidget::setEditFocus(bool enable)
415
416 If \a enable is true, make this widget have edit focus, in which
417 case Qt::Key_Up and Qt::Key_Down will be delivered to the widget
418 normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to
419 change focus.
420
421 This feature is only available in Qt for Embedded Linux.
422
423 \sa hasEditFocus(), QApplication::keypadNavigationEnabled()
424*/
425void QWidget::setEditFocus(bool on)
426{
427 QWidget *f = this;
428 while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
429 f = f->d_func()->extra->focus_proxy;
430
431 if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f)
432 QWidgetPrivate::editingWidget->setEditFocus(false);
433
434 if (on && !f->hasFocus())
435 f->setFocus();
436
437 if ((!on && !QWidgetPrivate::editingWidget)
438 || (on && QWidgetPrivate::editingWidget == f)) {
439 return;
440 }
441
442 if (!on && QWidgetPrivate::editingWidget == f) {
443 QWidgetPrivate::editingWidget = 0;
444 QEvent event(QEvent::LeaveEditFocus);
445 QApplication::sendEvent(f, &event);
446 QApplication::sendEvent(f->style(), &event);
447 } else if (on) {
448 QWidgetPrivate::editingWidget = f;
449 QEvent event(QEvent::EnterEditFocus);
450 QApplication::sendEvent(f, &event);
451 QApplication::sendEvent(f->style(), &event);
452 }
453}
454#endif
455
456/*!
457 \property QWidget::autoFillBackground
458 \brief whether the widget background is filled automatically
459 \since 4.1
460
461 If enabled, this property will cause Qt to fill the background of the
462 widget before invoking the paint event. The color used is defined by the
463 QPalette::Window color role from the widget's \l{QPalette}{palette}.
464
465 In addition, Windows are always filled with QPalette::Window, unless the
466 WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
467
468 This property cannot be turned off (i.e., set to false) if a widget's
469 parent has a static gradient for its background.
470
471 \warning Use this property with caution in conjunction with
472 \l{Qt Style Sheets}. When a widget has a style sheet with a valid
473 background or a border-image, this property is automatically disabled.
474
475 By default, this property is \c false.
476
477 \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
478 {QWidget#Transparency and Double Buffering}{Transparency and Double Buffering}
479*/
480bool QWidget::autoFillBackground() const
481{
482 Q_D(const QWidget);
483 return d->extra && d->extra->autoFillBackground;
484}
485
486void QWidget::setAutoFillBackground(bool enabled)
487{
488 Q_D(QWidget);
489 if (!d->extra)
490 d->createExtra();
491 if (d->extra->autoFillBackground == enabled)
492 return;
493
494 d->extra->autoFillBackground = enabled;
495 d->updateIsOpaque();
496 update();
497 d->updateIsOpaque();
498}
499
500/*!
501 \class QWidget
502 \brief The QWidget class is the base class of all user interface objects.
503
504 \ingroup basicwidgets
505 \inmodule QtWidgets
506
507 The widget is the atom of the user interface: it receives mouse, keyboard
508 and other events from the window system, and paints a representation of
509 itself on the screen. Every widget is rectangular, and they are sorted in a
510 Z-order. A widget is clipped by its parent and by the widgets in front of
511 it.
512
513 A widget that is not embedded in a parent widget is called a window.
514 Usually, windows have a frame and a title bar, although it is also possible
515 to create windows without such decoration using suitable
516 \l{Qt::WindowFlags}{window flags}). In Qt, QMainWindow and the various
517 subclasses of QDialog are the most common window types.
518
519 Every widget's constructor accepts one or two standard arguments:
520
521 \list 1
522 \li \c{QWidget *parent = 0} is the parent of the new widget. If it is 0
523 (the default), the new widget will be a window. If not, it will be
524 a child of \e parent, and be constrained by \e parent's geometry
525 (unless you specify Qt::Window as window flag).
526 \li \c{Qt::WindowFlags f = 0} (where available) sets the window flags;
527 the default is suitable for almost all widgets, but to get, for
528 example, a window without a window system frame, you must use
529 special flags.
530 \endlist
531
532 QWidget has many member functions, but some of them have little direct
533 functionality; for example, QWidget has a font property, but never uses
534 this itself. There are many subclasses which provide real functionality,
535 such as QLabel, QPushButton, QListWidget, and QTabWidget.
536
537
538 \section1 Top-Level and Child Widgets
539
540 A widget without a parent widget is always an independent window (top-level
541 widget). For these widgets, setWindowTitle() and setWindowIcon() set the
542 title bar and icon respectively.
543
544 Non-window widgets are child widgets, displayed within their parent
545 widgets. Most widgets in Qt are mainly useful as child widgets. For
546 example, it is possible to display a button as a top-level window, but most
547 people prefer to put their buttons inside other widgets, such as QDialog.
548
549 \image parent-child-widgets.png A parent widget containing various child widgets.
550
551 The diagram above shows a QGroupBox widget being used to hold various child
552 widgets in a layout provided by QGridLayout. The QLabel child widgets have
553 been outlined to indicate their full sizes.
554
555 If you want to use a QWidget to hold child widgets you will usually want to
556 add a layout to the parent QWidget. See \l{Layout Management} for more
557 information.
558
559
560 \section1 Composite Widgets
561
562 When a widget is used as a container to group a number of child widgets, it
563 is known as a composite widget. These can be created by constructing a
564 widget with the required visual properties - a QFrame, for example - and
565 adding child widgets to it, usually managed by a layout. The above diagram
566 shows such a composite widget that was created using Qt Designer.
567
568 Composite widgets can also be created by subclassing a standard widget,
569 such as QWidget or QFrame, and adding the necessary layout and child
570 widgets in the constructor of the subclass. Many of the \l{Qt Widgets Examples}
571 {examples provided with Qt} use this approach, and it is also covered in
572 the Qt \l{Tutorials}.
573
574
575 \section1 Custom Widgets and Painting
576
577 Since QWidget is a subclass of QPaintDevice, subclasses can be used to
578 display custom content that is composed using a series of painting
579 operations with an instance of the QPainter class. This approach contrasts
580 with the canvas-style approach used by the \l{Graphics View}
581 {Graphics View Framework} where items are added to a scene by the
582 application and are rendered by the framework itself.
583
584 Each widget performs all painting operations from within its paintEvent()
585 function. This is called whenever the widget needs to be redrawn, either
586 as a result of some external change or when requested by the application.
587
588 The \l{widgets/analogclock}{Analog Clock example} shows how a simple widget
589 can handle paint events.
590
591
592 \section1 Size Hints and Size Policies
593
594 When implementing a new widget, it is almost always useful to reimplement
595 sizeHint() to provide a reasonable default size for the widget and to set
596 the correct size policy with setSizePolicy().
597
598 By default, composite widgets which do not provide a size hint will be
599 sized according to the space requirements of their child widgets.
600
601 The size policy lets you supply good default behavior for the layout
602 management system, so that other widgets can contain and manage yours
603 easily. The default size policy indicates that the size hint represents
604 the preferred size of the widget, and this is often good enough for many
605 widgets.
606
607 \note The size of top-level widgets are constrained to 2/3 of the desktop's
608 height and width. You can resize() the widget manually if these bounds are
609 inadequate.
610
611
612 \section1 Events
613
614 Widgets respond to events that are typically caused by user actions. Qt
615 delivers events to widgets by calling specific event handler functions with
616 instances of QEvent subclasses containing information about each event.
617
618 If your widget only contains child widgets, you probably do not need to
619 implement any event handlers. If you want to detect a mouse click in a
620 child widget call the child's underMouse() function inside the widget's
621 mousePressEvent().
622
623 The \l{widgets/scribble}{Scribble example} implements a wider set of
624 events to handle mouse movement, button presses, and window resizing.
625
626 You will need to supply the behavior and content for your own widgets, but
627 here is a brief overview of the events that are relevant to QWidget,
628 starting with the most common ones:
629
630 \list
631 \li paintEvent() is called whenever the widget needs to be repainted.
632 Every widget displaying custom content must implement it. Painting
633 using a QPainter can only take place in a paintEvent() or a
634 function called by a paintEvent().
635 \li resizeEvent() is called when the widget has been resized.
636 \li mousePressEvent() is called when a mouse button is pressed while
637 the mouse cursor is inside the widget, or when the widget has
638 grabbed the mouse using grabMouse(). Pressing the mouse without
639 releasing it is effectively the same as calling grabMouse().
640 \li mouseReleaseEvent() is called when a mouse button is released. A
641 widget receives mouse release events when it has received the
642 corresponding mouse press event. This means that if the user
643 presses the mouse inside \e your widget, then drags the mouse
644 somewhere else before releasing the mouse button, \e your widget
645 receives the release event. There is one exception: if a popup menu
646 appears while the mouse button is held down, this popup immediately
647 steals the mouse events.
648 \li mouseDoubleClickEvent() is called when the user double-clicks in
649 the widget. If the user double-clicks, the widget receives a mouse
650 press event, a mouse release event, (a mouse click event,) a second
651 mouse press, this event and finally a second mouse release event.
652 (Some mouse move events may also be
653 received if the mouse is not held steady during this operation.) It
654 is \e{not possible} to distinguish a click from a double-click
655 until the second click arrives. (This is one reason why most GUI
656 books recommend that double-clicks be an extension of
657 single-clicks, rather than trigger a different action.)
658 \endlist
659
660 Widgets that accept keyboard input need to reimplement a few more event
661 handlers:
662
663 \list
664 \li keyPressEvent() is called whenever a key is pressed, and again when
665 a key has been held down long enough for it to auto-repeat. The
666 \uicontrol Tab and \uicontrol Shift+Tab keys are only passed to the widget if
667 they are not used by the focus-change mechanisms. To force those
668 keys to be processed by your widget, you must reimplement
669 QWidget::event().
670 \li focusInEvent() is called when the widget gains keyboard focus
671 (assuming you have called setFocusPolicy()). Well-behaved widgets
672 indicate that they own the keyboard focus in a clear but discreet
673 way.
674 \li focusOutEvent() is called when the widget loses keyboard focus.
675 \endlist
676
677 You may be required to also reimplement some of the less common event
678 handlers:
679
680 \list
681 \li mouseMoveEvent() is called whenever the mouse moves while a mouse
682 button is held down. This can be useful during drag and drop
683 operations. If you call \l{setMouseTracking()}{setMouseTracking}(true),
684 you get mouse move events even when no buttons are held down.
685 (See also the \l{Drag and Drop} guide.)
686 \li keyReleaseEvent() is called whenever a key is released and while it
687 is held down (if the key is auto-repeating). In that case, the
688 widget will receive a pair of key release and key press event for
689 every repeat. The \uicontrol Tab and \uicontrol Shift+Tab keys are only passed
690 to the widget if they are not used by the focus-change mechanisms.
691 To force those keys to be processed by your widget, you must
692 reimplement QWidget::event().
693 \li wheelEvent() is called whenever the user turns the mouse wheel
694 while the widget has the focus.
695 \li enterEvent() is called when the mouse enters the widget's screen
696 space. (This excludes screen space owned by any of the widget's
697 children.)
698 \li leaveEvent() is called when the mouse leaves the widget's screen
699 space. If the mouse enters a child widget it will not cause a
700 leaveEvent().
701 \li moveEvent() is called when the widget has been moved relative to
702 its parent.
703 \li closeEvent() is called when the user closes the widget (or when
704 close() is called).
705 \endlist
706
707 There are also some rather obscure events described in the documentation
708 for QEvent::Type. To handle these events, you need to reimplement event()
709 directly.
710
711 The default implementation of event() handles \uicontrol Tab and \uicontrol Shift+Tab
712 (to move the keyboard focus), and passes on most of the other events to
713 one of the more specialized handlers above.
714
715 Events and the mechanism used to deliver them are covered in
716 \l{The Event System}.
717
718 \section1 Groups of Functions and Properties
719
720 \table
721 \header \li Context \li Functions and Properties
722
723 \row \li Window functions \li
724 show(),
725 hide(),
726 raise(),
727 lower(),
728 close().
729
730 \row \li Top-level windows \li
731 \l windowModified, \l windowTitle, \l windowIcon,
732 \l isActiveWindow, activateWindow(), \l minimized, showMinimized(),
733 \l maximized, showMaximized(), \l fullScreen, showFullScreen(),
734 showNormal().
735
736 \row \li Window contents \li
737 update(),
738 repaint(),
739 scroll().
740
741 \row \li Geometry \li
742 \l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(),
743 \l sizePolicy, sizeHint(), minimumSizeHint(),
744 updateGeometry(), layout(),
745 \l frameGeometry, \l geometry, \l childrenRect, \l childrenRegion,
746 adjustSize(),
747 mapFromGlobal(), mapToGlobal(),
748 mapFromParent(), mapToParent(),
749 \l maximumSize, \l minimumSize, \l sizeIncrement,
750 \l baseSize, setFixedSize()
751
752 \row \li Mode \li
753 \l visible, isVisibleTo(),
754 \l enabled, isEnabledTo(),
755 \l modal,
756 isWindow(),
757 \l mouseTracking,
758 \l updatesEnabled,
759 visibleRegion().
760
761 \row \li Look and feel \li
762 style(),
763 setStyle(),
764 \l styleSheet,
765 \l cursor,
766 \l font,
767 \l palette,
768 backgroundRole(), setBackgroundRole(),
769 fontInfo(), fontMetrics().
770
771 \row \li Keyboard focus functions \li
772 \l focus, \l focusPolicy,
773 setFocus(), clearFocus(), setTabOrder(), setFocusProxy(),
774 focusNextChild(), focusPreviousChild().
775
776 \row \li Mouse and keyboard grabbing \li
777 grabMouse(), releaseMouse(),
778 grabKeyboard(), releaseKeyboard(),
779 mouseGrabber(), keyboardGrabber().
780
781 \row \li Event handlers \li
782 event(),
783 mousePressEvent(),
784 mouseReleaseEvent(),
785 mouseDoubleClickEvent(),
786 mouseMoveEvent(),
787 keyPressEvent(),
788 keyReleaseEvent(),
789 focusInEvent(),
790 focusOutEvent(),
791 wheelEvent(),
792 enterEvent(),
793 leaveEvent(),
794 paintEvent(),
795 moveEvent(),
796 resizeEvent(),
797 closeEvent(),
798 dragEnterEvent(),
799 dragMoveEvent(),
800 dragLeaveEvent(),
801 dropEvent(),
802 childEvent(),
803 showEvent(),
804 hideEvent(),
805 customEvent().
806 changeEvent(),
807
808 \row \li System functions \li
809 parentWidget(), window(), setParent(), winId(),
810 find(), metric().
811
812 \row \li Context menu \li
813 contextMenuPolicy, contextMenuEvent(),
814 customContextMenuRequested(), actions()
815
816 \row \li Interactive help \li
817 setToolTip(), setWhatsThis()
818
819 \endtable
820
821
822 \section1 Widget Style Sheets
823
824 In addition to the standard widget styles for each platform, widgets can
825 also be styled according to rules specified in a \l{styleSheet}
826 {style sheet}. This feature enables you to customize the appearance of
827 specific widgets to provide visual cues to users about their purpose. For
828 example, a button could be styled in a particular way to indicate that it
829 performs a destructive action.
830
831 The use of widget style sheets is described in more detail in the
832 \l{Qt Style Sheets} document.
833
834
835 \section1 Transparency and Double Buffering
836
837 Since Qt 4.0, QWidget automatically double-buffers its painting, so there
838 is no need to write double-buffering code in paintEvent() to avoid
839 flicker.
840
841 Since Qt 4.1, the Qt::WA_ContentsPropagated widget attribute has been
842 deprecated. Instead, the contents of parent widgets are propagated by
843 default to each of their children as long as Qt::WA_PaintOnScreen is not
844 set. Custom widgets can be written to take advantage of this feature by
845 updating irregular regions (to create non-rectangular child widgets), or
846 painting with colors that have less than full alpha component. The
847 following diagram shows how attributes and properties of a custom widget
848 can be fine-tuned to achieve different effects.
849
850 \image propagation-custom.png
851
852 In the above diagram, a semi-transparent rectangular child widget with an
853 area removed is constructed and added to a parent widget (a QLabel showing
854 a pixmap). Then, different properties and widget attributes are set to
855 achieve different effects:
856
857 \list
858 \li The left widget has no additional properties or widget attributes
859 set. This default state suits most custom widgets using
860 transparency, are irregularly-shaped, or do not paint over their
861 entire area with an opaque brush.
862 \li The center widget has the \l autoFillBackground property set. This
863 property is used with custom widgets that rely on the widget to
864 supply a default background, and do not paint over their entire
865 area with an opaque brush.
866 \li The right widget has the Qt::WA_OpaquePaintEvent widget attribute
867 set. This indicates that the widget will paint over its entire area
868 with opaque colors. The widget's area will initially be
869 \e{uninitialized}, represented in the diagram with a red diagonal
870 grid pattern that shines through the overpainted area. The
871 Qt::WA_OpaquePaintArea attribute is useful for widgets that need to
872 paint their own specialized contents quickly and do not need a
873 default filled background.
874 \endlist
875
876 To rapidly update custom widgets with simple background colors, such as
877 real-time plotting or graphing widgets, it is better to define a suitable
878 background color (using setBackgroundRole() with the
879 QPalette::Window role), set the \l autoFillBackground property, and only
880 implement the necessary drawing functionality in the widget's paintEvent().
881
882 To rapidly update custom widgets that constantly paint over their entire
883 areas with opaque content, e.g., video streaming widgets, it is better to
884 set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead
885 associated with repainting the widget's background.
886
887 If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and}
888 the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent
889 attribute takes precedence. Depending on your requirements, you should
890 choose either one of them.
891
892 Since Qt 4.1, the contents of parent widgets are also propagated to
893 standard Qt widgets. This can lead to some unexpected results if the
894 parent widget is decorated in a non-standard way, as shown in the diagram
895 below.
896
897 \image propagation-standard.png
898
899 The scope for customizing the painting behavior of standard Qt widgets,
900 without resorting to subclassing, is slightly less than that possible for
901 custom widgets. Usually, the desired appearance of a standard widget can be
902 achieved by setting its \l autoFillBackground property.
903
904
905 \section1 Creating Translucent Windows
906
907 Since Qt 4.5, it has been possible to create windows with translucent regions
908 on window systems that support compositing.
909
910 To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground
911 attribute with setAttribute() and ensure that its background is painted with
912 non-opaque colors in the regions you want to be partially transparent.
913
914 Platform notes:
915
916 \list
917 \li X11: This feature relies on the use of an X server that supports ARGB visuals
918 and a compositing window manager.
919 \li Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
920 for the translucency to work.
921 \endlist
922
923
924 \section1 Native Widgets vs Alien Widgets
925
926 Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
927 system. They do not have a native window handle associated with them. This
928 feature significantly speeds up widget painting, resizing, and removes flicker.
929
930 Should you require the old behavior with native windows, you can choose
931 one of the following options:
932
933 \list 1
934 \li Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
935 \li Set the Qt::AA_NativeWindows attribute on your application. All
936 widgets will be native widgets.
937 \li Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
938 and all of its ancestors will become native (unless
939 Qt::WA_DontCreateNativeAncestors is set).
940 \li Call QWidget::winId to enforce a native window (this implies 3).
941 \li Set the Qt::WA_PaintOnScreen attribute to enforce a native window
942 (this implies 3).
943 \endlist
944
945 \sa QEvent, QPainter, QGridLayout, QBoxLayout
946
947*/
948
949QWidgetMapper *QWidgetPrivate::mapper = 0; // widget with wid
950QWidgetSet *QWidgetPrivate::allWidgets = 0; // widgets with no wid
951
952
953/*****************************************************************************
954 QWidget utility functions
955 *****************************************************************************/
956
957QRegion qt_dirtyRegion(QWidget *widget)
958{
959 if (!widget)
960 return QRegion();
961
962 QWidgetBackingStore *bs = qt_widget_private(widget)->maybeBackingStore();
963 if (!bs)
964 return QRegion();
965
966 return bs->dirtyRegion(widget);
967}
968
969/*****************************************************************************
970 QWidget member functions
971 *****************************************************************************/
972
973/*
974 Widget state flags:
975 \list
976 \li Qt::WA_WState_Created The widget has a valid winId().
977 \li Qt::WA_WState_Visible The widget is currently visible.
978 \li Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
979 become visible unless you call show() on it. Qt::WA_WState_Hidden
980 implies !Qt::WA_WState_Visible.
981 \li Qt::WA_WState_CompressKeys Compress keyboard events.
982 \li Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
983 \li Qt::WA_WState_InPaintEvent Currently processing a paint event.
984 \li Qt::WA_WState_Reparented The widget has been reparented.
985 \li Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
986 \li Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
987 \endlist
988*/
989
990struct QWidgetExceptionCleaner
991{
992 /* this cleans up when the constructor throws an exception */
993 static inline void cleanup(QWidget *that, QWidgetPrivate *d)
994 {
995#ifdef QT_NO_EXCEPTIONS
996 Q_UNUSED(that);
997 Q_UNUSED(d);
998#else
999 QWidgetPrivate::allWidgets->remove(that);
1000 if (d->focus_next != that) {
1001 if (d->focus_next)
1002 d->focus_next->d_func()->focus_prev = d->focus_prev;
1003 if (d->focus_prev)
1004 d->focus_prev->d_func()->focus_next = d->focus_next;
1005 }
1006#endif
1007 }
1008};
1009
1010/*!
1011 Constructs a widget which is a child of \a parent, with widget
1012 flags set to \a f.
1013
1014 If \a parent is 0, the new widget becomes a window. If
1015 \a parent is another widget, this widget becomes a child window
1016 inside \a parent. The new widget is deleted when its \a parent is
1017 deleted.
1018
1019 The widget flags argument, \a f, is normally 0, but it can be set
1020 to customize the frame of a window (i.e. \a
1021 parent must be 0). To customize the frame, use a value composed
1022 from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}.
1023
1024 If you add a child widget to an already visible widget you must
1025 explicitly show the child to make it visible.
1026
1027 Note that the X11 version of Qt may not be able to deliver all
1028 combinations of style flags on all systems. This is because on
1029 X11, Qt can only ask the window manager, and the window manager
1030 can override the application's settings. On Windows, Qt can set
1031 whatever flags you want.
1032
1033 \sa windowFlags
1034*/
1035QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
1036 : QObject(*new QWidgetPrivate, 0), QPaintDevice()
1037{
1038 QT_TRY {
1039 d_func()->init(parent, f);
1040 } QT_CATCH(...) {
1041 QWidgetExceptionCleaner::cleanup(this, d_func());
1042 QT_RETHROW;
1043 }
1044}
1045
1046
1047/*! \internal
1048*/
1049QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
1050 : QObject(dd, 0), QPaintDevice()
1051{
1052 Q_D(QWidget);
1053 QT_TRY {
1054 d->init(parent, f);
1055 } QT_CATCH(...) {
1056 QWidgetExceptionCleaner::cleanup(this, d_func());
1057 QT_RETHROW;
1058 }
1059}
1060
1061/*!
1062 \internal
1063*/
1064int QWidget::devType() const
1065{
1066 return QInternal::Widget;
1067}
1068
1069
1070//### w is a "this" ptr, passed as a param because QWorkspace needs special logic
1071void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
1072{
1073 bool customize = (flags & (Qt::CustomizeWindowHint
1074 | Qt::FramelessWindowHint
1075 | Qt::WindowTitleHint
1076 | Qt::WindowSystemMenuHint
1077 | Qt::WindowMinimizeButtonHint
1078 | Qt::WindowMaximizeButtonHint
1079 | Qt::WindowCloseButtonHint
1080 | Qt::WindowContextHelpButtonHint));
1081
1082 uint type = (flags & Qt::WindowType_Mask);
1083
1084 if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
1085 type = Qt::Window;
1086 flags |= Qt::Window;
1087 }
1088
1089 if (flags & Qt::CustomizeWindowHint) {
1090 // modify window flags to make them consistent.
1091 // Only enable this on non-Mac platforms. Since the old way of doing this would
1092 // interpret WindowSystemMenuHint as a close button and we can't change that behavior
1093 // we can't just add this in.
1094#if 1 // Used to be excluded in Qt4 for Q_WS_MAC
1095 if ((flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint))
1096# ifdef Q_OS_WIN
1097 && type != Qt::Dialog // QTBUG-2027, allow for menu-less dialogs.
1098# endif
1099 ) {
1100 flags |= Qt::WindowSystemMenuHint;
1101#else
1102 if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint
1103 | Qt::WindowSystemMenuHint)) {
1104#endif
1105 flags |= Qt::WindowTitleHint;
1106 flags &= ~Qt::FramelessWindowHint;
1107 }
1108 } else if (customize && !(flags & Qt::FramelessWindowHint)) {
1109 // if any of the window hints that affect the titlebar are set
1110 // and the window is supposed to have frame, we add a titlebar
1111 // and system menu by default.
1112 flags |= Qt::WindowSystemMenuHint;
1113 flags |= Qt::WindowTitleHint;
1114 }
1115 if (customize)
1116 ; // don't modify window flags if the user explicitly set them.
1117 else if (type == Qt::Dialog || type == Qt::Sheet)
1118 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint;
1119 else if (type == Qt::Tool)
1120 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
1121 else
1122 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint |
1123 Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint;
1124 if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
1125 flags |= Qt::WindowTransparentForInput;
1126}
1127
1128void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
1129{
1130 Q_Q(QWidget);
1131 if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance())))
1132 qFatal("QWidget: Cannot create a QWidget without QApplication");
1133
1134 Q_ASSERT(allWidgets);
1135 if (allWidgets)
1136 allWidgets->insert(q);
1137
1138 int targetScreen = -1;
1139 if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
1140 const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(parentWidget);
1141 targetScreen = sw ? sw->screenNumber() : 0;
1142 parentWidget = 0;
1143 }
1144
1145 q->data = &data;
1146
1147#ifndef QT_NO_THREAD
1148 if (!parent) {
1149 Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
1150 "Widgets must be created in the GUI thread.");
1151 }
1152#endif
1153
1154#if 0 // Used to be included in Qt4 for Q_WS_X11
1155 if (desktopWidget) {
1156 // make sure the widget is created on the same screen as the
1157 // programmer specified desktop widget
1158 xinfo = desktopWidget->d_func()->xinfo;
1159 }
1160#endif
1161 if (targetScreen >= 0) {
1162 topData()->initialScreenIndex = targetScreen;
1163 if (QWindow *window = q->windowHandle())
1164 window->setScreen(QGuiApplication::screens().value(targetScreen, Q_NULLPTR));
1165 }
1166
1167 data.fstrut_dirty = true;
1168
1169 data.winid = 0;
1170 data.widget_attributes = 0;
1171 data.window_flags = f;
1172 data.window_state = 0;
1173 data.focus_policy = 0;
1174 data.context_menu_policy = Qt::DefaultContextMenu;
1175 data.window_modality = Qt::NonModal;
1176
1177 data.sizehint_forced = 0;
1178 data.is_closing = 0;
1179 data.in_show = 0;
1180 data.in_set_window_state = 0;
1181 data.in_destructor = false;
1182
1183 // Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle.
1184 if (f & Qt::MSWindowsOwnDC) {
1185 mustHaveWindowHandle = 1;
1186 q->setAttribute(Qt::WA_NativeWindow);
1187 }
1188//#if 0 // Used to be included in Qt4 for Q_WS_MAC
1189// q->setAttribute(Qt::WA_NativeWindow);
1190//#endif
1191
1192 q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
1193 adjustQuitOnCloseAttribute();
1194
1195 q->setAttribute(Qt::WA_WState_Hidden);
1196
1197 //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
1198 data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
1199 focus_next = focus_prev = q;
1200
1201 if ((f & Qt::WindowType_Mask) == Qt::Desktop)
1202 q->create();
1203 else if (parentWidget)
1204 q->setParent(parentWidget, data.window_flags);
1205 else {
1206 adjustFlags(data.window_flags, q);
1207 resolveLayoutDirection();
1208 // opaque system background?
1209 const QBrush &background = q->palette().brush(QPalette::Window);
1210 setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque());
1211 }
1212 data.fnt = QFont(data.fnt, q);
1213#if 0 // Used to be included in Qt4 for Q_WS_X11
1214 data.fnt.x11SetScreen(xinfo.screen());
1215#endif
1216
1217 q->setAttribute(Qt::WA_PendingMoveEvent);
1218 q->setAttribute(Qt::WA_PendingResizeEvent);
1219
1220 if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
1221 QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
1222
1223 if (QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation)) // ### fixme: Qt 6: Remove AA_ImmediateWidgetCreation.
1224 q->create();
1225
1226 QEvent e(QEvent::Create);
1227 QApplication::sendEvent(q, &e);
1228 QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
1229
1230 extraPaintEngine = 0;
1231
1232#if 0 // Used to be included in Qt4 for Q_WS_MAC
1233 // If we add a child to the unified toolbar, we have to redirect the painting.
1234 if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) {
1235 if (parentWidget->d_func()->unifiedSurface) {
1236 QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor;
1237 parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset);
1238 }
1239 }
1240#endif
1241}
1242
1243
1244
1245void QWidgetPrivate::createRecursively()
1246{
1247 Q_Q(QWidget);
1248 q->create(0, true, true);
1249 for (int i = 0; i < children.size(); ++i) {
1250 QWidget *child = qobject_cast<QWidget *>(children.at(i));
1251 if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(Qt::WA_WState_Created))
1252 child->d_func()->createRecursively();
1253 }
1254}
1255
1256
1257// ### fixme: Qt 6: Remove parameter window from QWidget::create()
1258
1259/*!
1260 Creates a new widget window.
1261
1262 The parameter \a window is ignored in Qt 5. Please use
1263 QWindow::fromWinId() to create a QWindow wrapping a foreign
1264 window and pass it to QWidget::createWindowContainer() instead.
1265
1266 Initializes the window (sets the geometry etc.) if \a
1267 initializeWindow is true. If \a initializeWindow is false, no
1268 initialization is performed. This parameter only makes sense if \a
1269 window is a valid window.
1270
1271 Destroys the old window if \a destroyOldWindow is true. If \a
1272 destroyOldWindow is false, you are responsible for destroying the
1273 window yourself (using platform native code).
1274
1275 The QWidget constructor calls create(0,true,true) to create a
1276 window for this widget.
1277
1278 \sa createWindowContainer(), QWindow::fromWinId()
1279*/
1280
1281void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
1282{
1283 Q_D(QWidget);
1284 if (Q_UNLIKELY(window))
1285 qWarning("QWidget::create(): Parameter 'window' does not have any effect.");
1286 if (testAttribute(Qt::WA_WState_Created) && window == 0 && internalWinId())
1287 return;
1288
1289 if (d->data.in_destructor)
1290 return;
1291
1292 Qt::WindowType type = windowType();
1293 Qt::WindowFlags &flags = data->window_flags;
1294
1295 if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
1296 type = Qt::Window;
1297 flags |= Qt::Window;
1298 }
1299
1300 if (QWidget *parent = parentWidget()) {
1301 if (type & Qt::Window) {
1302 if (!parent->testAttribute(Qt::WA_WState_Created))
1303 parent->createWinId();
1304 } else if (testAttribute(Qt::WA_NativeWindow) && !parent->internalWinId()
1305 && !testAttribute(Qt::WA_DontCreateNativeAncestors)) {
1306 // We're about to create a native child widget that doesn't have a native parent;
1307 // enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors
1308 // attribute is set.
1309 d->createWinId();
1310 // Nothing more to do.
1311 Q_ASSERT(testAttribute(Qt::WA_WState_Created));
1312 Q_ASSERT(internalWinId());
1313 return;
1314 }
1315 }
1316
1317
1318 static const bool paintOnScreenEnv = qEnvironmentVariableIntValue("QT_ONSCREEN_PAINT") > 0;
1319 if (paintOnScreenEnv)
1320 setAttribute(Qt::WA_PaintOnScreen);
1321
1322 if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows))
1323 setAttribute(Qt::WA_NativeWindow);
1324
1325#ifdef ALIEN_DEBUG
1326 qDebug() << "QWidget::create:" << this << "parent:" << parentWidget()
1327 << "Alien?" << !testAttribute(Qt::WA_NativeWindow);
1328#endif
1329
1330#if 0 /* Used to be included in Qt4 for Q_WS_WIN */ && !defined(QT_NO_DRAGANDDROP)
1331 // Unregister the dropsite (if already registered) before we
1332 // re-create the widget with a native window.
1333 if (testAttribute(Qt::WA_WState_Created) && !internalWinId() && testAttribute(Qt::WA_NativeWindow)
1334 && d->extra && d->extra->dropTarget) {
1335 d->registerDropSite(false);
1336 }
1337#endif
1338
1339 d->updateIsOpaque();
1340
1341 setAttribute(Qt::WA_WState_Created); // set created flag
1342 d->create_sys(window, initializeWindow, destroyOldWindow);
1343
1344 // a real toplevel window needs a backing store
1345 if (isWindow() && windowType() != Qt::Desktop) {
1346 d->topData()->backingStoreTracker.destroy();
1347 if (hasBackingStoreSupport())
1348 d->topData()->backingStoreTracker.create(this);
1349 }
1350
1351 d->setModal_sys();
1352
1353 if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
1354 setAttribute(Qt::WA_DropSiteRegistered, true);
1355
1356#ifdef QT_EVAL
1357 extern void qt_eval_init_widget(QWidget *w);
1358 qt_eval_init_widget(this);
1359#endif
1360
1361 // need to force the resting of the icon after changing parents
1362 if (testAttribute(Qt::WA_SetWindowIcon))
1363 d->setWindowIcon_sys();
1364
1365 if (isWindow() && !d->topData()->iconText.isEmpty())
1366 d->setWindowIconText_helper(d->topData()->iconText);
1367 if (isWindow() && !d->topData()->caption.isEmpty())
1368 d->setWindowTitle_helper(d->topData()->caption);
1369 if (windowType() != Qt::Desktop) {
1370 d->updateSystemBackground();
1371
1372 if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon))
1373 d->setWindowIcon_sys();
1374 }
1375
1376 // Frame strut update needed in cases where there are native widgets such as QGLWidget,
1377 // as those force native window creation on their ancestors before they are shown.
1378 // If the strut is not updated, any subsequent move of the top level window before show
1379 // will cause window frame to be ignored when positioning the window.
1380 // Note that this only helps on platforms that handle window creation synchronously.
1381 d->updateFrameStrut();
1382}
1383
1384void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
1385{
1386 QObjectList children = parentWidget->children();
1387 for (int i = 0; i < children.size(); i++) {
1388 if (children.at(i)->isWidgetType()) {
1389 const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
1390 if (childWidget) { // should not be necessary
1391 if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
1392 if (!childWidget->internalWinId())
1393 childWidget->winId();
1394 if (childWidget->windowHandle()) {
1395 if (childWidget->isWindow()) {
1396 childWidget->windowHandle()->setTransientParent(parentWidget->window()->windowHandle());
1397 } else {
1398 childWidget->windowHandle()->setParent(childWidget->nativeParentWidget()->windowHandle());
1399 }
1400 }
1401 } else {
1402 q_createNativeChildrenAndSetParent(childWidget);
1403 }
1404 }
1405 }
1406 }
1407
1408}
1409
1410void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
1411{
1412 Q_Q(QWidget);
1413
1414 Q_UNUSED(window);
1415 Q_UNUSED(initializeWindow);
1416 Q_UNUSED(destroyOldWindow);
1417
1418 Qt::WindowFlags flags = data.window_flags;
1419
1420 if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
1421 return; // we only care about real toplevels
1422
1423 QWindow *win = topData()->window;
1424 // topData() ensures the extra is created but does not ensure 'window' is non-null
1425 // in case the extra was already valid.
1426 if (!win) {
1427 createTLSysExtra();
1428 win = topData()->window;
1429 }
1430
1431 const auto dynamicPropertyNames = q->dynamicPropertyNames();
1432 for (const QByteArray &propertyName : dynamicPropertyNames) {
1433 if (!qstrncmp(propertyName, "_q_platform_", 12))
1434 win->setProperty(propertyName, q->property(propertyName));
1435 }
1436
1437 if (q->testAttribute(Qt::WA_ShowWithoutActivating))
1438 win->setProperty("_q_showWithoutActivating", QVariant(true));
1439 if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
1440 win->setProperty("_q_macAlwaysShowToolWindow", QVariant::fromValue(QVariant(true)));
1441 setNetWmWindowTypes(true); // do nothing if none of WA_X11NetWmWindowType* is set
1442 win->setFlags(data.window_flags);
1443 fixPosIncludesFrame();
1444 if (q->testAttribute(Qt::WA_Moved)
1445 || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
1446 win->setGeometry(q->geometry());
1447 else
1448 win->resize(q->size());
1449 if (win->isTopLevel()) {
1450 int screenNumber = topData()->initialScreenIndex;
1451 topData()->initialScreenIndex = -1;
1452 if (screenNumber < 0) {
1453 screenNumber = q->windowType() != Qt::Desktop
1454 ? QApplication::desktop()->screenNumber(q) : 0;
1455 }
1456 win->setScreen(QGuiApplication::screens().value(screenNumber, Q_NULLPTR));
1457 }
1458
1459 QSurfaceFormat format = win->requestedFormat();
1460 if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface
1461 && q->testAttribute(Qt::WA_TranslucentBackground)) {
1462 format.setAlphaBufferSize(8);
1463 }
1464 win->setFormat(format);
1465
1466 if (QWidget *nativeParent = q->nativeParentWidget()) {
1467 if (nativeParent->windowHandle()) {
1468 if (flags & Qt::Window) {
1469 win->setTransientParent(nativeParent->window()->windowHandle());
1470 win->setParent(0);
1471 } else {
1472 win->setTransientParent(0);
1473 win->setParent(nativeParent->windowHandle());
1474 }
1475 }
1476 }
1477
1478 qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
1479 QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
1480 win->create();
1481 // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing.
1482 if ((flags & Qt::Desktop) == Qt::Window)
1483 win->handle()->setFrameStrutEventsEnabled(true);
1484
1485 data.window_flags = win->flags();
1486 if (!win->isTopLevel()) // In a Widget world foreign windows can only be top level
1487 data.window_flags &= ~Qt::ForeignWindow;
1488
1489 if (!topData()->role.isNull())
1490 QXcbWindowFunctions::setWmWindowRole(win, topData()->role.toLatin1());
1491
1492 QBackingStore *store = q->backingStore();
1493
1494 if (!store) {
1495 if (win && q->windowType() != Qt::Desktop) {
1496 if (q->isTopLevel())
1497 q->setBackingStore(new QBackingStore(win));
1498 } else {
1499 q->setAttribute(Qt::WA_PaintOnScreen, true);
1500 }
1501 }
1502
1503 setWindowModified_helper();
1504 WId id = win->winId();
1505 // See the QPlatformWindow::winId() documentation
1506 Q_ASSERT(id != WId(0));
1507 setWinId(id);
1508
1509 // Check children and create windows for them if necessary
1510 q_createNativeChildrenAndSetParent(q);
1511
1512 if (extra && !extra->mask.isEmpty())
1513 setMask_sys(extra->mask);
1514
1515 if (data.crect.width() == 0 || data.crect.height() == 0) {
1516 q->setAttribute(Qt::WA_OutsideWSRange, true);
1517 } else if (q->isVisible()) {
1518 // If widget is already shown, set window visible, too
1519 win->setVisible(true);
1520 }
1521}
1522
1523#ifdef Q_OS_WIN
1524static const char activeXNativeParentHandleProperty[] = "_q_embedded_native_parent_handle";
1525#endif
1526
1527void QWidgetPrivate::createTLSysExtra()
1528{
1529 Q_Q(QWidget);
1530 if (!extra->topextra->window && (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())) {
1531 extra->topextra->window = new QWidgetWindow(q);
1532 if (extra->minw || extra->minh)
1533 extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh));
1534 if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX)
1535 extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
1536 if (extra->topextra->opacity != 255 && q->isWindow())
1537 extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255));
1538#ifdef Q_OS_WIN
1539 // Pass on native parent handle for Widget embedded into Active X.
1540 const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty);
1541 if (activeXNativeParentHandle.isValid())
1542 extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle);
1543 if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget"))
1544 extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true));
1545#endif
1546 }
1547
1548}
1549
1550/*!
1551 Destroys the widget.
1552
1553 All this widget's children are deleted first. The application
1554 exits if this widget is the main widget.
1555*/
1556
1557QWidget::~QWidget()
1558{
1559 Q_D(QWidget);
1560 d->data.in_destructor = true;
1561
1562#if defined (QT_CHECK_STATE)
1563 if (Q_UNLIKELY(paintingActive()))
1564 qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
1565#endif
1566
1567#ifndef QT_NO_GESTURES
1568 if (QGestureManager *manager = QGestureManager::instance()) {
1569 // \forall Qt::GestureType type : ungrabGesture(type) (inlined)
1570 for (auto it = d->gestureContext.keyBegin(), end = d->gestureContext.keyEnd(); it != end; ++it)
1571 manager->cleanupCachedGestures(this, *it);
1572 }
1573 d->gestureContext.clear();
1574#endif
1575
1576 // force acceptDrops false before winId is destroyed.
1577 d->registerDropSite(false);
1578
1579#ifndef QT_NO_ACTION
1580 // remove all actions from this widget
1581 for (int i = 0; i < d->actions.size(); ++i) {
1582 QActionPrivate *apriv = d->actions.at(i)->d_func();
1583 apriv->widgets.removeAll(this);
1584 }
1585 d->actions.clear();
1586#endif
1587
1588#ifndef QT_NO_SHORTCUT
1589 // Remove all shortcuts grabbed by this
1590 // widget, unless application is closing
1591 if (!QApplicationPrivate::is_app_closing && testAttribute(Qt::WA_GrabbedShortcut))
1592 qApp->d_func()->shortcutMap.removeShortcut(0, this, QKeySequence());
1593#endif
1594
1595 // delete layout while we still are a valid widget
1596 delete d->layout;
1597 d->layout = 0;
1598 // Remove myself from focus list
1599
1600 Q_ASSERT(d->focus_next->d_func()->focus_prev == this);
1601 Q_ASSERT(d->focus_prev->d_func()->focus_next == this);
1602
1603 if (d->focus_next != this) {
1604 d->focus_next->d_func()->focus_prev = d->focus_prev;
1605 d->focus_prev->d_func()->focus_next = d->focus_next;
1606 d->focus_next = d->focus_prev = 0;
1607 }
1608
1609
1610 QT_TRY {
1611#ifndef QT_NO_GRAPHICSVIEW
1612 const QWidget* w = this;
1613 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
1614 w = w->d_func()->extra->focus_proxy;
1615 QWidget *window = w->window();
1616 QWExtra *e = window ? window->d_func()->extra : 0;
1617 if (!e || !e->proxyWidget || (w->parentWidget() && w->parentWidget()->d_func()->focus_child == this))
1618#endif
1619 clearFocus();
1620 } QT_CATCH(...) {
1621 // swallow this problem because we are in a destructor
1622 }
1623
1624 d->setDirtyOpaqueRegion();
1625
1626 if (isWindow() && isVisible() && internalWinId()) {
1627 QT_TRY {
1628 d->close_helper(QWidgetPrivate::CloseNoEvent);
1629 } QT_CATCH(...) {
1630 // if we're out of memory, at least hide the window.
1631 QT_TRY {
1632 hide();
1633 } QT_CATCH(...) {
1634 // and if that also doesn't work, then give up
1635 }
1636 }
1637 }
1638
1639#if 0 /* Used to be included in Qt4 for Q_WS_WIN */ || 0 /* Used to be included in Qt4 for Q_WS_X11 */|| 0 /* Used to be included in Qt4 for Q_WS_MAC */
1640 else if (!internalWinId() && isVisible()) {
1641 qApp->d_func()->sendSyntheticEnterLeave(this);
1642 }
1643#endif
1644 else if (isVisible()) {
1645 qApp->d_func()->sendSyntheticEnterLeave(this);
1646 }
1647
1648 if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
1649 bs->removeDirtyWidget(this);
1650 if (testAttribute(Qt::WA_StaticContents))
1651 bs->removeStaticWidget(this);
1652 }
1653
1654 delete d->needsFlush;
1655 d->needsFlush = 0;
1656
1657 // The next 20 lines are duplicated from QObject, but required here
1658 // since QWidget deletes is children itself
1659 bool blocked = d->blockSig;
1660 d->blockSig = 0; // unblock signals so we always emit destroyed()
1661
1662 if (d->isSignalConnected(0)) {
1663 QT_TRY {
1664 emit destroyed(this);
1665 } QT_CATCH(...) {
1666 // all the signal/slots connections are still in place - if we don't
1667 // quit now, we will crash pretty soon.
1668 qWarning("Detected an unexpected exception in ~QWidget while emitting destroyed().");
1669 QT_RETHROW;
1670 }
1671 }
1672
1673 if (d->declarativeData) {
1674 if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
1675 if (QAbstractDeclarativeData::destroyed_qml1)
1676 QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
1677 } else {
1678 if (QAbstractDeclarativeData::destroyed)
1679 QAbstractDeclarativeData::destroyed(d->declarativeData, this);
1680 }
1681 d->declarativeData = 0; // don't activate again in ~QObject
1682 }
1683
1684 d->blockSig = blocked;
1685
1686#if 0 // Used to be included in Qt4 for Q_WS_MAC
1687 // QCocoaView holds a pointer back to this widget. Clear it now
1688 // to make sure it's not followed later on. The lifetime of the
1689 // QCocoaView might exceed the lifetime of this widget in cases
1690 // where Cocoa itself holds references to it.
1691 extern void qt_mac_clearCocoaViewQWidgetPointers(QWidget *);
1692 qt_mac_clearCocoaViewQWidgetPointers(this);
1693#endif
1694
1695 if (!d->children.isEmpty())
1696 d->deleteChildren();
1697
1698 QApplication::removePostedEvents(this);
1699
1700 QT_TRY {
1701 destroy(); // platform-dependent cleanup
1702 } QT_CATCH(...) {
1703 // if this fails we can't do anything about it but at least we are not allowed to throw.
1704 }
1705 --QWidgetPrivate::instanceCounter;
1706
1707 if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
1708 QWidgetPrivate::allWidgets->remove(this);
1709
1710 QT_TRY {
1711 QEvent e(QEvent::Destroy);
1712 QCoreApplication::sendEvent(this, &e);
1713 } QT_CATCH(const std::exception&) {
1714 // if this fails we can't do anything about it but at least we are not allowed to throw.
1715 }
1716}
1717
1718int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances
1719int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances
1720
1721void QWidgetPrivate::setWinId(WId id) // set widget identifier
1722{
1723 Q_Q(QWidget);
1724 // the user might create a widget with Qt::Desktop window
1725 // attribute (or create another QDesktopWidget instance), which
1726 // will have the same windowid (the root window id) as the
1727 // qt_desktopWidget. We should not add the second desktop widget
1728 // to the mapper.
1729 bool userDesktopWidget = qt_desktopWidget != 0 && qt_desktopWidget != q && q->windowType() == Qt::Desktop;
1730 if (mapper && data.winid && !userDesktopWidget) {
1731 mapper->remove(data.winid);
1732 }
1733
1734 const WId oldWinId = data.winid;
1735
1736 data.winid = id;
1737#if 0 // Used to be included in Qt4 for Q_WS_X11
1738 hd = id; // X11: hd == ident
1739#endif
1740 if (mapper && id && !userDesktopWidget) {
1741 mapper->insert(data.winid, q);
1742 }
1743
1744 if(oldWinId != id) {
1745 QEvent e(QEvent::WinIdChange);
1746 QCoreApplication::sendEvent(q, &e);
1747 }
1748}
1749
1750void QWidgetPrivate::createTLExtra()
1751{
1752 if (!extra)
1753 createExtra();
1754 if (!extra->topextra) {
1755 QTLWExtra* x = extra->topextra = new QTLWExtra;
1756 x->icon = 0;
1757 x->backingStore = 0;
1758 x->sharedPainter = 0;
1759 x->incw = x->inch = 0;
1760 x->basew = x->baseh = 0;
1761 x->frameStrut.setCoords(0, 0, 0, 0);
1762 x->normalGeometry = QRect(0,0,-1,-1);
1763 x->savedFlags = 0;
1764 x->opacity = 255;
1765 x->posIncludesFrame = 0;
1766 x->sizeAdjusted = false;
1767 x->inTopLevelResize = false;
1768 x->inRepaint = false;
1769 x->embedded = 0;
1770 x->window = 0;
1771 x->shareContext = 0;
1772 x->initialScreenIndex = -1;
1773#if 0 // Used to be included in Qt4 for Q_WS_MAC
1774 x->wasMaximized = false;
1775#endif
1776#ifdef QWIDGET_EXTRA_DEBUG
1777 static int count = 0;
1778 qDebug() << "tlextra" << ++count;
1779#endif
1780 }
1781}
1782
1783/*!
1784 \internal
1785 Creates the widget extra data.
1786*/
1787
1788void QWidgetPrivate::createExtra()
1789{
1790 if (!extra) { // if not exists
1791 extra = new QWExtra;
1792 extra->glContext = 0;
1793 extra->topextra = 0;
1794#ifndef QT_NO_GRAPHICSVIEW
1795 extra->proxyWidget = 0;
1796#endif
1797#ifndef QT_NO_CURSOR
1798 extra->curs = 0;
1799#endif
1800 extra->minw = 0;
1801 extra->minh = 0;
1802 extra->maxw = QWIDGETSIZE_MAX;
1803 extra->maxh = QWIDGETSIZE_MAX;
1804 extra->customDpiX = 0;
1805 extra->customDpiY = 0;
1806 extra->explicitMinSize = 0;
1807 extra->explicitMaxSize = 0;
1808 extra->autoFillBackground = 0;
1809 extra->nativeChildrenForced = 0;
1810 extra->inRenderWithPainter = 0;
1811 extra->hasWindowContainer = false;
1812 extra->hasMask = 0;
1813 createSysExtra();
1814#ifdef QWIDGET_EXTRA_DEBUG
1815 static int count = 0;
1816 qDebug() << "extra" << ++count;
1817#endif
1818 }
1819}
1820
1821void QWidgetPrivate::createSysExtra()
1822{
1823}
1824
1825/*!
1826 \internal
1827 Deletes the widget extra data.
1828*/
1829
1830void QWidgetPrivate::deleteExtra()
1831{
1832 if (extra) { // if exists
1833#ifndef QT_NO_CURSOR
1834 delete extra->curs;
1835#endif
1836 deleteSysExtra();
1837#ifndef QT_NO_STYLE_STYLESHEET
1838 // dereference the stylesheet style
1839 if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style))
1840 proxy->deref();
1841#endif
1842 if (extra->topextra) {
1843 deleteTLSysExtra();
1844 // extra->topextra->backingStore destroyed in QWidgetPrivate::deleteTLSysExtra()
1845 delete extra->topextra->icon;
1846 delete extra->topextra;
1847 }
1848 delete extra;
1849 // extra->xic destroyed in QWidget::destroy()
1850 extra = 0;
1851 }
1852}
1853
1854void QWidgetPrivate::deleteSysExtra()
1855{
1856}
1857
1858static void deleteBackingStore(QWidgetPrivate *d)
1859{
1860 QTLWExtra *topData = d->topData();
1861
1862 // The context must be current when destroying the backing store as it may attempt to
1863 // release resources like textures and shader programs. The window may not be suitable
1864 // anymore as there will often not be a platform window underneath at this stage. Fall
1865 // back to a QOffscreenSurface in this case.
1866 QScopedPointer<QOffscreenSurface> tempSurface;
1867#ifndef QT_NO_OPENGL
1868 if (d->textureChildSeen && topData->shareContext) {
1869 if (topData->window->handle()) {
1870 topData->shareContext->makeCurrent(topData->window);
1871 } else {
1872 tempSurface.reset(new QOffscreenSurface);
1873 tempSurface->setFormat(topData->shareContext->format());
1874 tempSurface->create();
1875 topData->shareContext->makeCurrent(tempSurface.data());
1876 }
1877 }
1878#endif
1879
1880 delete topData->backingStore;
1881 topData->backingStore = 0;
1882
1883#ifndef QT_NO_OPENGL
1884 if (d->textureChildSeen && topData->shareContext)
1885 topData->shareContext->doneCurrent();
1886#endif
1887}
1888
1889void QWidgetPrivate::deleteTLSysExtra()
1890{
1891 if (extra && extra->topextra) {
1892 //the qplatformbackingstore may hold a reference to the window, so the backingstore
1893 //needs to be deleted first. If the backingstore holds GL resources, we need to
1894 // make the context current here. This is taken care of by deleteBackingStore().
1895
1896 extra->topextra->backingStoreTracker.destroy();
1897 deleteBackingStore(this);
1898#ifndef QT_NO_OPENGL
1899 qDeleteAll(extra->topextra->widgetTextures);
1900 extra->topextra->widgetTextures.clear();
1901 delete extra->topextra->shareContext;
1902 extra->topextra->shareContext = 0;
1903#endif
1904
1905 //the toplevel might have a context with a "qglcontext associated with it. We need to
1906 //delete the qglcontext before we delete the qplatformopenglcontext.
1907 //One unfortunate thing about this is that we potentially create a glContext just to
1908 //delete it straight afterwards.
1909 if (extra->topextra->window) {
1910 extra->topextra->window->destroy();
1911 }
1912 delete extra->topextra->window;
1913 extra->topextra->window = 0;
1914
1915 }
1916}
1917
1918/*
1919 Returns \c true if there are widgets above this which overlap with
1920 \a rect, which is in parent's coordinate system (same as crect).
1921*/
1922
1923bool QWidgetPrivate::isOverlapped(const QRect &rect) const
1924{
1925 Q_Q(const QWidget);
1926
1927 const QWidget *w = q;
1928 QRect r = rect;
1929 while (w) {
1930 if (w->isWindow())
1931 return false;
1932 QWidgetPrivate *pd = w->parentWidget()->d_func();
1933 bool above = false;
1934 for (int i = 0; i < pd->children.size(); ++i) {
1935 QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
1936 if (!sibling || !sibling->isVisible() || sibling->isWindow())
1937 continue;
1938 if (!above) {
1939 above = (sibling == w);
1940 continue;
1941 }
1942
1943 if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
1944 const QWExtra *siblingExtra = sibling->d_func()->extra;
1945 if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
1946 && !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
1947 continue;
1948 }
1949 return true;
1950 }
1951 }
1952 w = w->parentWidget();
1953 r.translate(pd->data.crect.topLeft());
1954 }
1955 return false;
1956}
1957
1958void QWidgetPrivate::syncBackingStore()
1959{
1960 if (paintOnScreen()) {
1961 repaint_sys(dirty);
1962 dirty = QRegion();
1963 } else if (QWidgetBackingStore *bs = maybeBackingStore()) {
1964 bs->sync();
1965 }
1966}
1967
1968void QWidgetPrivate::syncBackingStore(const QRegion &region)
1969{
1970 if (paintOnScreen())
1971 repaint_sys(region);
1972 else if (QWidgetBackingStore *bs = maybeBackingStore()) {
1973 bs->sync(q_func(), region);
1974 }
1975}
1976
1977void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
1978{
1979 Q_Q(QWidget);
1980
1981 if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled())
1982 return; // nothing we can do
1983
1984 if (enable != q->testAttribute(Qt::WA_UpdatesDisabled))
1985 return; // nothing to do
1986
1987 q->setAttribute(Qt::WA_UpdatesDisabled, !enable);
1988 if (enable)
1989 q->update();
1990
1991 Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
1992 for (int i = 0; i < children.size(); ++i) {
1993 QWidget *w = qobject_cast<QWidget *>(children.at(i));
1994 if (w && !w->isWindow() && !w->testAttribute(attribute))
1995 w->d_func()->setUpdatesEnabled_helper(enable);
1996 }
1997}
1998
1999/*!
2000 \internal
2001
2002 Propagate this widget's palette to all children, except style sheet
2003 widgets, and windows that don't enable window propagation (palettes don't
2004 normally propagate to windows).
2005*/
2006void QWidgetPrivate::propagatePaletteChange()
2007{
2008 Q_Q(QWidget);
2009 // Propagate a new inherited mask to all children.
2010#ifndef QT_NO_GRAPHICSVIEW
2011 if (!q->parentWidget() && extra && extra->proxyWidget) {
2012 QGraphicsProxyWidget *p = extra->proxyWidget;
2013 inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolve();
2014 } else
2015#endif //QT_NO_GRAPHICSVIEW
2016 if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
2017 inheritedPaletteResolveMask = 0;
2018 }
2019 int mask = data.pal.resolve() | inheritedPaletteResolveMask;
2020
2021 const bool useStyleSheetPropagationInWidgetStyles =
2022 QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
2023
2024 QEvent pc(QEvent::PaletteChange);
2025 QApplication::sendEvent(q, &pc);
2026 for (int i = 0; i < children.size(); ++i) {
2027 QWidget *w = qobject_cast<QWidget*>(children.at(i));
2028 if (w && (!w->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
2029 && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
2030 QWidgetPrivate *wd = w->d_func();
2031 wd->inheritedPaletteResolveMask = mask;
2032 wd->resolvePalette();
2033 }
2034 }
2035}
2036
2037/*
2038 Returns the widget's clipping rectangle.
2039*/
2040QRect QWidgetPrivate::clipRect() const
2041{
2042 Q_Q(const QWidget);
2043 const QWidget * w = q;
2044 if (!w->isVisible())
2045 return QRect();
2046 QRect r = effectiveRectFor(q->rect());
2047 int ox = 0;
2048 int oy = 0;
2049 while (w
2050 && w->isVisible()
2051 && !w->isWindow()
2052 && w->parentWidget()) {
2053 ox -= w->x();
2054 oy -= w->y();
2055 w = w->parentWidget();
2056 r &= QRect(ox, oy, w->width(), w->height());
2057 }
2058 return r;
2059}
2060
2061/*
2062 Returns the widget's clipping region (without siblings).
2063*/
2064QRegion QWidgetPrivate::clipRegion() const
2065{
2066 Q_Q(const QWidget);
2067 if (!q->isVisible())
2068 return QRegion();
2069 QRegion r(q->rect());
2070 const QWidget * w = q;
2071 const QWidget *ignoreUpTo;
2072 int ox = 0;
2073 int oy = 0;
2074 while (w
2075 && w->isVisible()
2076 && !w->isWindow()
2077 && w->parentWidget()) {
2078 ox -= w->x();
2079 oy -= w->y();
2080 ignoreUpTo = w;
2081 w = w->parentWidget();
2082 r &= QRegion(ox, oy, w->width(), w->height());
2083
2084 int i = 0;
2085 while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo))
2086 ;
2087 for ( ; i < w->d_func()->children.size(); ++i) {
2088 if(QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) {
2089 if(sibling->isVisible() && !sibling->isWindow()) {
2090 QRect siblingRect(ox+sibling->x(), oy+sibling->y(),
2091 sibling->width(), sibling->height());
2092 if (qRectIntersects(siblingRect, q->rect()))
2093 r -= QRegion(siblingRect);
2094 }
2095 }
2096 }
2097 }
2098 return r;
2099}
2100
2101void QWidgetPrivate::setSystemClip(QPaintDevice *paintDevice, const QRegion &region)
2102{
2103// Transform the system clip region from device-independent pixels to device pixels
2104 QPaintEngine *paintEngine = paintDevice->paintEngine();
2105 QTransform scaleTransform;
2106 const qreal devicePixelRatio = paintDevice->devicePixelRatioF();
2107 scaleTransform.scale(devicePixelRatio, devicePixelRatio);
2108 paintEngine->d_func()->systemClip = scaleTransform.map(region);
2109}
2110
2111#ifndef QT_NO_GRAPHICSEFFECT
2112void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
2113{
2114 Q_Q(QWidget);
2115 QWidget *w = q;
2116 do {
2117 if (w->graphicsEffect()) {
2118 QWidgetEffectSourcePrivate *sourced =
2119 static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
2120 if (!sourced->updateDueToGraphicsEffect)
2121 w->graphicsEffect()->source()->d_func()->invalidateCache();
2122 }
2123 w = w->parentWidget();
2124 } while (w);
2125}
2126#endif //QT_NO_GRAPHICSEFFECT
2127
2128void QWidgetPrivate::setDirtyOpaqueRegion()
2129{
2130 Q_Q(QWidget);
2131
2132 dirtyOpaqueChildren = true;
2133
2134#ifndef QT_NO_GRAPHICSEFFECT
2135 invalidateGraphicsEffectsRecursively();
2136#endif //QT_NO_GRAPHICSEFFECT
2137
2138 if (q->isWindow())
2139 return;
2140
2141 QWidget *parent = q->parentWidget();
2142 if (!parent)
2143 return;
2144
2145 // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly?
2146 QWidgetPrivate *pd = parent->d_func();
2147 if (!pd->dirtyOpaqueChildren)
2148 pd->setDirtyOpaqueRegion();
2149}
2150
2151const QRegion &QWidgetPrivate::getOpaqueChildren() const
2152{
2153 if (!dirtyOpaqueChildren)
2154 return opaqueChildren;
2155
2156 QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
2157 that->opaqueChildren = QRegion();
2158
2159 for (int i = 0; i < children.size(); ++i) {
2160 QWidget *child = qobject_cast<QWidget *>(children.at(i));
2161 if (!child || !child->isVisible() || child->isWindow())
2162 continue;
2163
2164 const QPoint offset = child->geometry().topLeft();
2165 QWidgetPrivate *childd = child->d_func();
2166 QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren();
2167 if (childd->extra && childd->extra->hasMask)
2168 r &= childd->extra->mask;
2169 if (r.isEmpty())
2170 continue;
2171 r.translate(offset);
2172 that->opaqueChildren += r;
2173 }
2174
2175 that->opaqueChildren &= q_func()->rect();
2176 that->dirtyOpaqueChildren = false;
2177
2178 return that->opaqueChildren;
2179}
2180
2181void QWidgetPrivate::subtractOpaqueChildren(QRegion &source, const QRect &clipRect) const
2182{
2183 if (children.isEmpty() || clipRect.isEmpty())
2184 return;
2185
2186 const QRegion &r = getOpaqueChildren();
2187 if (!r.isEmpty())
2188 source -= (r & clipRect);
2189}
2190
2191//subtract any relatives that are higher up than me --- this is too expensive !!!
2192void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirtySiblingsAbove,
2193 bool alsoNonOpaque) const
2194{
2195 Q_Q(const QWidget);
2196 static int disableSubtractOpaqueSiblings = qEnvironmentVariableIntValue("QT_NO_SUBTRACTOPAQUESIBLINGS");
2197 if (disableSubtractOpaqueSiblings || q->isWindow())
2198 return;
2199
2200#if 0 // Used to be included in Qt4 for Q_WS_MAC
2201 if (q->d_func()->isInUnifiedToolbar)
2202 return;
2203#endif
2204
2205 QRect clipBoundingRect;
2206 bool dirtyClipBoundingRect = true;
2207
2208 QRegion parentClip;
2209 bool dirtyParentClip = true;
2210
2211 QPoint parentOffset = data.crect.topLeft();
2212
2213 const QWidget *w = q;
2214
2215 while (w) {
2216 if (w->isWindow())
2217 break;
2218 QWidgetPrivate *pd = w->parentWidget()->d_func();
2219 const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
2220 const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
2221 for (int i = myIndex + 1; i < pd->children.size(); ++i) {
2222 QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
2223 if (!sibling || !sibling->isVisible() || sibling->isWindow())
2224 continue;
2225
2226 const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
2227 if (!qRectIntersects(siblingGeometry, widgetGeometry))
2228 continue;
2229
2230 if (dirtyClipBoundingRect) {
2231 clipBoundingRect = sourceRegion.boundingRect();
2232 dirtyClipBoundingRect = false;
2233 }
2234
2235 if (!qRectIntersects(siblingGeometry, clipBoundingRect.translated(parentOffset)))
2236 continue;
2237
2238 if (dirtyParentClip) {
2239 parentClip = sourceRegion.translated(parentOffset);
2240 dirtyParentClip = false;
2241 }
2242
2243 const QPoint siblingPos(sibling->data->crect.topLeft());
2244 const QRect siblingClipRect(sibling->d_func()->clipRect());
2245 QRegion siblingDirty(parentClip);
2246 siblingDirty &= (siblingClipRect.translated(siblingPos));
2247 const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
2248 && !sibling->d_func()->graphicsEffect;
2249 if (hasMask)
2250 siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
2251 if (siblingDirty.isEmpty())
2252 continue;
2253
2254 if (sibling->d_func()->isOpaque || alsoNonOpaque) {
2255 if (hasMask) {
2256 siblingDirty.translate(-parentOffset);
2257 sourceRegion -= siblingDirty;
2258 } else {
2259 sourceRegion -= siblingGeometry.translated(-parentOffset);
2260 }
2261 } else {
2262 if (hasDirtySiblingsAbove)
2263 *hasDirtySiblingsAbove = true;
2264 if (sibling->d_func()->children.isEmpty())
2265 continue;
2266 QRegion opaqueSiblingChildren(sibling->d_func()->getOpaqueChildren());
2267 opaqueSiblingChildren.translate(-parentOffset + siblingPos);
2268 sourceRegion -= opaqueSiblingChildren;
2269 }
2270 if (sourceRegion.isEmpty())
2271 return;
2272
2273 dirtyClipBoundingRect = true;
2274 dirtyParentClip = true;
2275 }
2276
2277 w = w->parentWidget();
2278 parentOffset += pd->data.crect.topLeft();
2279 dirtyParentClip = true;
2280 }
2281}
2282
2283void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
2284{
2285 Q_Q(const QWidget);
2286
2287 const QWidget *w = q;
2288 QPoint offset;
2289
2290#ifndef QT_NO_GRAPHICSEFFECT
2291 if (graphicsEffect) {
2292 w = q->parentWidget();
2293 offset -= data.crect.topLeft();
2294 }
2295#endif //QT_NO_GRAPHICSEFFECT
2296
2297 while (w) {
2298 const QWidgetPrivate *wd = w->d_func();
2299 if (wd->extra && wd->extra->hasMask)
2300 region &= (w != q) ? wd->extra->mask.translated(offset) : wd->extra->mask;
2301 if (w->isWindow())
2302 return;
2303 offset -= wd->data.crect.topLeft();
2304 w = w->parentWidget();
2305 }
2306}
2307
2308bool QWidgetPrivate::paintOnScreen() const
2309{
2310#if defined(QT_NO_BACKINGSTORE)
2311 return true;
2312#else
2313 Q_Q(const QWidget);
2314 if (q->testAttribute(Qt::WA_PaintOnScreen)
2315 || (!q->isWindow() && q->window()->testAttribute(Qt::WA_PaintOnScreen))) {
2316 return true;
2317 }
2318
2319 return !qt_enable_backingstore;
2320#endif
2321}
2322
2323void QWidgetPrivate::updateIsOpaque()
2324{
2325 // hw: todo: only needed if opacity actually changed
2326 setDirtyOpaqueRegion();
2327
2328#ifndef QT_NO_GRAPHICSEFFECT
2329 if (graphicsEffect) {
2330 // ### We should probably add QGraphicsEffect::isOpaque at some point.
2331 setOpaque(false);
2332 return;
2333 }
2334#endif //QT_NO_GRAPHICSEFFECT
2335
2336 Q_Q(QWidget);
2337#if 0 // Used to be included in Qt4 for Q_WS_X11
2338 if (q->testAttribute(Qt::WA_X11OpenGLOverlay)) {
2339 setOpaque(false);
2340 return;
2341 }
2342#endif
2343
2344 if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
2345 setOpaque(true);
2346 return;
2347 }
2348
2349 const QPalette &pal = q->palette();
2350
2351 if (q->autoFillBackground()) {
2352 const QBrush &autoFillBrush = pal.brush(q->backgroundRole());
2353 if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
2354 setOpaque(true);
2355 return;
2356 }
2357 }
2358
2359 if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) {
2360 const QBrush &windowBrush = q->palette().brush(QPalette::Window);
2361 if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
2362 setOpaque(true);
2363 return;
2364 }
2365 }
2366 setOpaque(false);
2367}
2368
2369void QWidgetPrivate::setOpaque(bool opaque)
2370{
2371 if (isOpaque != opaque) {
2372 isOpaque = opaque;
2373 updateIsTranslucent();
2374 }
2375}
2376
2377void QWidgetPrivate::updateIsTranslucent()
2378{
2379 Q_Q(QWidget);
2380 if (QWindow *window = q->windowHandle()) {
2381 QSurfaceFormat format = window->format();
2382 const int oldAlpha = format.alphaBufferSize();
2383 const int newAlpha = q->testAttribute(Qt::WA_TranslucentBackground)? 8 : 0;
2384 if (oldAlpha != newAlpha) {
2385 format.setAlphaBufferSize(newAlpha);
2386 window->setFormat(format);
2387 }
2388 }
2389}
2390
2391static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
2392{
2393 Q_ASSERT(painter);
2394
2395 if (brush.style() == Qt::TexturePattern) {
2396#if 0 // Used to be included in Qt4 for Q_WS_MAC
2397 // Optimize pattern filling on mac by using HITheme directly
2398 // when filling with the standard widget background.
2399 // Defined in qmacstyle_mac.cpp
2400 extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
2401 qt_mac_fill_background(painter, rgn, brush);
2402#else
2403 {
2404 const QRect rect(rgn.boundingRect());
2405 painter->setClipRegion(rgn);
2406 painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
2407 }
2408#endif
2409
2410 } else if (brush.gradient()
2411 && brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
2412 painter->save();
2413 painter->setClipRegion(rgn);
2414 painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
2415 painter->restore();
2416 } else {
2417 for (const QRect &rect : rgn)
2418 painter->fillRect(rect, brush);
2419 }
2420}
2421
2422void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
2423{
2424 Q_Q(const QWidget);
2425
2426#ifndef QT_NO_SCROLLAREA
2427 bool resetBrushOrigin = false;
2428 QPointF oldBrushOrigin;
2429 //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
2430 QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
2431 if (scrollArea && scrollArea->viewport() == q) {
2432 QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
2433 QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
2434 oldBrushOrigin = painter->brushOrigin();
2435 resetBrushOrigin = true;
2436 painter->setBrushOrigin(-priv->contentsOffset());
2437
2438 }
2439#endif // QT_NO_SCROLLAREA
2440
2441 const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
2442
2443 if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
2444 const QBrush bg = q->palette().brush(QPalette::Window);
2445 if (!(flags & DontSetCompositionMode)) {
2446 //copy alpha straight in
2447 QPainter::CompositionMode oldMode = painter->compositionMode();
2448 painter->setCompositionMode(QPainter::CompositionMode_Source);
2449 fillRegion(painter, rgn, bg);
2450 painter->setCompositionMode(oldMode);
2451 } else {
2452 fillRegion(painter, rgn, bg);
2453 }
2454 }
2455
2456 if (q->autoFillBackground())
2457 fillRegion(painter, rgn, autoFillBrush);
2458
2459 if (q->testAttribute(Qt::WA_StyledBackground)) {
2460 painter->setClipRegion(rgn);
2461 QStyleOption opt;
2462 opt.initFrom(q);
2463 q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
2464 }
2465
2466#ifndef QT_NO_SCROLLAREA
2467 if (resetBrushOrigin)
2468 painter->setBrushOrigin(oldBrushOrigin);
2469#endif // QT_NO_SCROLLAREA
2470}
2471
2472/*
2473 \internal
2474 This function is called when a widget is hidden or destroyed.
2475 It resets some application global pointers that should only refer active,
2476 visible widgets.
2477*/
2478
2479#if 0 // Used to be included in Qt4 for Q_WS_MAC
2480 extern QPointer<QWidget> qt_button_down;
2481#else
2482 extern QWidget *qt_button_down;
2483#endif
2484
2485void QWidgetPrivate::deactivateWidgetCleanup()
2486{
2487 Q_Q(QWidget);
2488 // If this was the active application window, reset it
2489 if (QApplication::activeWindow() == q)
2490 QApplication::setActiveWindow(0);
2491 // If the is the active mouse press widget, reset it
2492 if (q == qt_button_down)
2493 qt_button_down = 0;
2494}
2495
2496
2497/*!
2498 Returns a pointer to the widget with window identifer/handle \a
2499 id.
2500
2501 The window identifier type depends on the underlying window
2502 system, see \c qwindowdefs.h for the actual definition. If there
2503 is no widget with this identifier, 0 is returned.
2504*/
2505
2506QWidget *QWidget::find(WId id)
2507{
2508 return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0;
2509}
2510
2511
2512
2513/*!
2514 \fn WId QWidget::internalWinId() const
2515 \internal
2516 Returns the window system identifier of the widget, or 0 if the widget is not created yet.
2517
2518*/
2519
2520/*!
2521 \fn WId QWidget::winId() const
2522
2523 Returns the window system identifier of the widget.
2524
2525 Portable in principle, but if you use it you are probably about to
2526 do something non-portable. Be careful.
2527
2528 If a widget is non-native (alien) and winId() is invoked on it, that widget
2529 will be provided a native handle.
2530
2531 This value may change at run-time. An event with type QEvent::WinIdChange
2532 will be sent to the widget following a change in window system identifier.
2533
2534 \sa find()
2535*/
2536WId QWidget::winId() const
2537{
2538 if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
2539#ifdef ALIEN_DEBUG
2540 qDebug() << "QWidget::winId: creating native window for" << this;
2541#endif
2542 QWidget *that = const_cast<QWidget*>(this);
2543 that->setAttribute(Qt::WA_NativeWindow);
2544 that->d_func()->createWinId();
2545 return that->data->winid;
2546 }
2547 return data->winid;
2548}
2549
2550void QWidgetPrivate::createWinId()
2551{
2552 Q_Q(QWidget);
2553
2554#ifdef ALIEN_DEBUG
2555 qDebug() << "QWidgetPrivate::createWinId for" << q;
2556#endif
2557 const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow);
2558 if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
2559 if (!q->isWindow()) {
2560 QWidget *parent = q->parentWidget();
2561 QWidgetPrivate *pd = parent->d_func();
2562 if (forceNativeWindow && !q->testAttribute(Qt::WA_DontCreateNativeAncestors))
2563 parent->setAttribute(Qt::WA_NativeWindow);
2564 if (!parent->internalWinId()) {
2565 pd->createWinId();
2566 }
2567
2568 for (int i = 0; i < pd->children.size(); ++i) {
2569 QWidget *w = qobject_cast<QWidget *>(pd->children.at(i));
2570 if (w && !w->isWindow() && (!w->testAttribute(Qt::WA_WState_Created)
2571 || (!w->internalWinId() && w->testAttribute(Qt::WA_NativeWindow)))) {
2572 w->create();
2573 }
2574 }
2575 } else {
2576 q->create();
2577 }
2578 }
2579}
2580
2581
2582/*!
2583\internal
2584Ensures that the widget has a window system identifier, i.e. that it is known to the windowing system.
2585
2586*/
2587
2588void QWidget::createWinId()
2589{
2590 Q_D(QWidget);
2591#ifdef ALIEN_DEBUG
2592 qDebug() << "QWidget::createWinId" << this;
2593#endif
2594// qWarning("QWidget::createWinId is obsolete, please fix your code.");
2595 d->createWinId();
2596}
2597
2598/*!
2599 \since 4.4
2600
2601 Returns the effective window system identifier of the widget, i.e. the
2602 native parent's window system identifier.
2603
2604 If the widget is native, this function returns the native widget ID.
2605 Otherwise, the window ID of the first native parent widget, i.e., the
2606 top-level widget that contains this widget, is returned.
2607
2608 \note We recommend that you do not store this value as it is likely to
2609 change at run-time.
2610
2611 \sa nativeParentWidget()
2612*/
2613WId QWidget::effectiveWinId() const
2614{
2615 const WId id = internalWinId();
2616 if (id || !testAttribute(Qt::WA_WState_Created))
2617 return id;
2618 if (const QWidget *realParent = nativeParentWidget())
2619 return realParent->internalWinId();
2620 return 0;
2621}
2622
2623/*!
2624 If this is a native widget, return the associated QWindow.
2625 Otherwise return null.
2626
2627 Native widgets include toplevel widgets, QGLWidget, and child widgets
2628 on which winId() was called.
2629
2630 \since 5.0
2631
2632 \sa winId()
2633*/
2634QWindow *QWidget::windowHandle() const
2635{
2636 Q_D(const QWidget);
2637 QTLWExtra *extra = d->maybeTopData();
2638 if (extra)
2639 return extra->window;
2640
2641 return 0;
2642}
2643
2644#ifndef QT_NO_STYLE_STYLESHEET
2645
2646/*!
2647 \property QWidget::styleSheet
2648 \brief the widget's style sheet
2649 \since 4.2
2650
2651 The style sheet contains a textual description of customizations to the
2652 widget's style, as described in the \l{Qt Style Sheets} document.
2653
2654 Since Qt 4.5, Qt style sheets fully supports \macos.
2655
2656 \warning Qt style sheets are currently not supported for custom QStyle
2657 subclasses. We plan to address this in some future release.
2658
2659 \sa setStyle(), QApplication::styleSheet, {Qt Style Sheets}
2660*/
2661QString QWidget::styleSheet() const
2662{
2663 Q_D(const QWidget);
2664 if (!d->extra)
2665 return QString();
2666 return d->extra->styleSheet;
2667}
2668
2669void QWidget::setStyleSheet(const QString& styleSheet)
2670{
2671 Q_D(QWidget);
2672 if (data->in_destructor)
2673 return;
2674 d->createExtra();
2675
2676 QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style);
2677 d->extra->styleSheet = styleSheet;
2678 if (styleSheet.isEmpty()) { // stylesheet removed
2679 if (!proxy)
2680 return;
2681
2682 d->inheritStyle();
2683 return;
2684 }
2685
2686 if (proxy) { // style sheet update
2687 if (d->polished)
2688 proxy->repolish(this);
2689 return;
2690 }
2691
2692 if (testAttribute(Qt::WA_SetStyle)) {
2693 d->setStyle_helper(new QStyleSheetStyle(d->extra->style), true);
2694 } else {
2695 d->setStyle_helper(new QStyleSheetStyle(0), true);
2696 }
2697}
2698
2699#endif // QT_NO_STYLE_STYLESHEET
2700
2701/*!
2702 \sa QWidget::setStyle(), QApplication::setStyle(), QApplication::style()
2703*/
2704
2705QStyle *QWidget::style() const
2706{
2707 Q_D(const QWidget);
2708
2709 if (d->extra && d->extra->style)
2710 return d->extra->style;
2711 return QApplication::style();
2712}
2713
2714/*!
2715 Sets the widget's GUI style to \a style. The ownership of the style
2716 object is not transferred.
2717
2718 If no style is set, the widget uses the application's style,
2719 QApplication::style() instead.
2720
2721 Setting a widget's style has no effect on existing or future child
2722 widgets.
2723
2724 \warning This function is particularly useful for demonstration
2725 purposes, where you want to show Qt's styling capabilities. Real
2726 applications should avoid it and use one consistent GUI style
2727 instead.
2728
2729 \warning Qt style sheets are currently not supported for custom QStyle
2730 subclasses. We plan to address this in some future release.
2731
2732 \sa style(), QStyle, QApplication::style(), QApplication::setStyle()
2733*/
2734
2735void QWidget::setStyle(QStyle *style)
2736{
2737 Q_D(QWidget);
2738 setAttribute(Qt::WA_SetStyle, style != 0);
2739 d->createExtra();
2740#ifndef QT_NO_STYLE_STYLESHEET
2741 if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) {
2742 //if for some reason someone try to set a QStyleSheetStyle, ref it
2743 //(this may happen for exemple in QButtonDialogBox which propagates its style)
2744 proxy->ref();
2745 d->setStyle_helper(style, false);
2746 } else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) {
2747 // if we have an application stylesheet or have a proxy already, propagate
2748 d->setStyle_helper(new QStyleSheetStyle(style), true);
2749 } else
2750#endif
2751 d->setStyle_helper(style, false);
2752}
2753
2754void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
2755#if 0 // Used to be included in Qt4 for Q_WS_MAC
2756 metalHack
2757#endif
2758 )
2759{
2760 Q_Q(QWidget);
2761 QStyle *oldStyle = q->style();
2762#ifndef QT_NO_STYLE_STYLESHEET
2763 QPointer<QStyle> origStyle;
2764#endif
2765
2766#if 0 // Used to be included in Qt4 for Q_WS_MAC
2767 // the metalhack boolean allows Qt/Mac to do a proper re-polish depending
2768 // on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever
2769 // set when changing that attribute and passes the widget's CURRENT style.
2770 // therefore no need to do a reassignment.
2771 if (!metalHack)
2772#endif
2773 {
2774 createExtra();
2775
2776#ifndef QT_NO_STYLE_STYLESHEET
2777 origStyle = extra->style.data();
2778#endif
2779 extra->style = newStyle;
2780 }
2781
2782 // repolish
2783 if (q->windowType() != Qt::Desktop) {
2784 if (polished) {
2785 oldStyle->unpolish(q);
2786#if 0 // Used to be included in Qt4 for Q_WS_MAC
2787 if (metalHack)
2788 macUpdateMetalAttribute();
2789#endif
2790 q->style()->polish(q);
2791#if 0 // Used to be included in Qt4 for Q_WS_MAC
2792 } else if (metalHack) {
2793 macUpdateMetalAttribute();
2794#endif
2795 }
2796 }
2797
2798 if (propagate) {
2799 // We copy the list because the order may be modified
2800 const QObjectList childrenList = children;
2801 for (int i = 0; i < childrenList.size(); ++i) {
2802 QWidget *c = qobject_cast<QWidget*>(childrenList.at(i));
2803 if (c)
2804 c->d_func()->inheritStyle();
2805 }
2806 }
2807
2808#ifndef QT_NO_STYLE_STYLESHEET
2809 if (!qobject_cast<QStyleSheetStyle*>(newStyle)) {
2810 if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) {
2811 cssStyle->clearWidgetFont(q);
2812 }
2813 }
2814#endif
2815
2816 QEvent e(QEvent::StyleChange);
2817 QApplication::sendEvent(q, &e);
2818
2819#ifndef QT_NO_STYLE_STYLESHEET
2820 // dereference the old stylesheet style
2821 if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data()))
2822 proxy->deref();
2823#endif
2824}
2825
2826// Inherits style from the current parent and propagates it as necessary
2827void QWidgetPrivate::inheritStyle()
2828{
2829#ifndef QT_NO_STYLE_STYLESHEET
2830 Q_Q(QWidget);
2831
2832 QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0;
2833
2834 if (!q->styleSheet().isEmpty()) {
2835 Q_ASSERT(proxy);
2836 proxy->repolish(q);
2837 return;
2838 }
2839
2840 QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0);
2841 QWidget *parent = q->parentWidget();
2842 QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0;
2843 // If we have stylesheet on app or parent has stylesheet style, we need
2844 // to be running a proxy
2845 if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) {
2846 QStyle *newStyle = parentStyle;
2847 if (q->testAttribute(Qt::WA_SetStyle))
2848 newStyle = new QStyleSheetStyle(origStyle);
2849 else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle))
2850 newProxy->ref();
2851
2852 setStyle_helper(newStyle, true);
2853 return;
2854 }
2855
2856 // So, we have no stylesheet on parent/app and we have an empty stylesheet
2857 // we just need our original style back
2858 if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different?
2859 return;
2860
2861 // We could have inherited the proxy from our parent (which has a custom style)
2862 // In such a case we need to start following the application style (i.e revert
2863 // the propagation behavior of QStyleSheetStyle)
2864 if (!q->testAttribute(Qt::WA_SetStyle))
2865 origStyle = 0;
2866
2867 setStyle_helper(origStyle, true);
2868#endif // QT_NO_STYLE_STYLESHEET
2869}
2870
2871
2872/*!
2873 \fn bool QWidget::isWindow() const
2874
2875 Returns \c true if the widget is an independent window, otherwise
2876 returns \c false.
2877
2878 A window is a widget that isn't visually the child of any other
2879 widget and that usually has a frame and a
2880 \l{QWidget::setWindowTitle()}{window title}.
2881
2882 A window can have a \l{QWidget::parentWidget()}{parent widget}.
2883 It will then be grouped with its parent and deleted when the
2884 parent is deleted, minimized when the parent is minimized etc. If
2885 supported by the window manager, it will also have a common
2886 taskbar entry with its parent.
2887
2888 QDialog and QMainWindow widgets are by default windows, even if a
2889 parent widget is specified in the constructor. This behavior is
2890 specified by the Qt::Window flag.
2891
2892 \sa window(), isModal(), parentWidget()
2893*/
2894
2895/*!
2896 \property QWidget::modal
2897 \brief whether the widget is a modal widget
2898
2899 This property only makes sense for windows. A modal widget
2900 prevents widgets in all other windows from getting any input.
2901
2902 By default, this property is \c false.
2903
2904 \sa isWindow(), windowModality, QDialog
2905*/
2906
2907/*!
2908 \property QWidget::windowModality
2909 \brief which windows are blocked by the modal widget
2910 \since 4.1
2911
2912 This property only makes sense for windows. A modal widget
2913 prevents widgets in other windows from getting input. The value of
2914 this property controls which windows are blocked when the widget
2915 is visible. Changing this property while the window is visible has
2916 no effect; you must hide() the widget first, then show() it again.
2917
2918 By default, this property is Qt::NonModal.
2919
2920 \sa isWindow(), QWidget::modal, QDialog
2921*/
2922
2923Qt::WindowModality QWidget::windowModality() const
2924{
2925 return static_cast<Qt::WindowModality>(data->window_modality);
2926}
2927
2928void QWidget::setWindowModality(Qt::WindowModality windowModality)
2929{
2930 data->window_modality = windowModality;
2931 // setModal_sys() will be called by setAttribute()
2932 setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
2933 setAttribute(Qt::WA_SetWindowModality, true);
2934}
2935
2936void QWidgetPrivate::setModal_sys()
2937{
2938 Q_Q(QWidget);
2939 if (q->windowHandle())
2940 q->windowHandle()->setModality(q->windowModality());
2941}
2942
2943/*!
2944 \fn bool QWidget::underMouse() const
2945
2946 Returns \c true if the widget is under the mouse cursor; otherwise
2947 returns \c false.
2948
2949 This value is not updated properly during drag and drop
2950 operations.
2951
2952 \sa enterEvent(), leaveEvent()
2953*/
2954
2955/*!
2956 \property QWidget::minimized
2957 \brief whether this widget is minimized (iconified)
2958
2959 This property is only relevant for windows.
2960
2961 By default, this property is \c false.
2962
2963 \sa showMinimized(), visible, show(), hide(), showNormal(), maximized
2964*/
2965bool QWidget::isMinimized() const
2966{ return data->window_state & Qt::WindowMinimized; }
2967
2968/*!
2969 Shows the widget minimized, as an icon.
2970
2971 Calling this function only affects \l{isWindow()}{windows}.
2972
2973 \sa showNormal(), showMaximized(), show(), hide(), isVisible(),
2974 isMinimized()
2975*/
2976void QWidget::showMinimized()
2977{
2978 bool isMin = isMinimized();
2979 if (isMin && isVisible())
2980 return;
2981
2982 ensurePolished();
2983
2984 if (!isMin)
2985 setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
2986 setVisible(true);
2987}
2988
2989/*!
2990 \property QWidget::maximized
2991 \brief whether this widget is maximized
2992
2993 This property is only relevant for windows.
2994
2995 \note Due to limitations on some window systems, this does not always
2996 report the expected results (e.g., if the user on X11 maximizes the
2997 window via the window manager, Qt has no way of distinguishing this
2998 from any other resize). This is expected to improve as window manager
2999 protocols evolve.
3000
3001 By default, this property is \c false.
3002
3003 \sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized
3004*/
3005bool QWidget::isMaximized() const
3006{ return data->window_state & Qt::WindowMaximized; }
3007
3008
3009
3010/*!
3011 Returns the current window state. The window state is a OR'ed
3012 combination of Qt::WindowState: Qt::WindowMinimized,
3013 Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
3014
3015 \sa Qt::WindowState, setWindowState()
3016 */
3017Qt::WindowStates QWidget::windowState() const
3018{
3019 return Qt::WindowStates(data->window_state);
3020}
3021
3022/*!\internal
3023
3024 The function sets the window state on child widgets similar to
3025 setWindowState(). The difference is that the window state changed
3026 event has the isOverride() flag set. It exists mainly to keep
3027 QWorkspace working.
3028 */
3029void QWidget::overrideWindowState(Qt::WindowStates newstate)
3030{
3031 QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true);
3032 data->window_state = newstate;
3033 QApplication::sendEvent(this, &e);
3034}
3035
3036Qt::WindowState effectiveState(Qt::WindowStates state)
3037{
3038 if (state & Qt::WindowMinimized)
3039 return Qt::WindowMinimized;
3040 else if (state & Qt::WindowFullScreen)
3041 return Qt::WindowFullScreen;
3042 else if (state & Qt::WindowMaximized)
3043 return Qt::WindowMaximized;
3044 return Qt::WindowNoState;
3045}
3046
3047/*!
3048 \fn void QWidget::setWindowState(Qt::WindowStates windowState)
3049
3050 Sets the window state to \a windowState. The window state is a OR'ed
3051 combination of Qt::WindowState: Qt::WindowMinimized,
3052 Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
3053
3054 If the window is not visible (i.e. isVisible() returns \c false), the
3055 window state will take effect when show() is called. For visible
3056 windows, the change is immediate. For example, to toggle between
3057 full-screen and normal mode, use the following code:
3058
3059 \snippet code/src_gui_kernel_qwidget.cpp 0
3060
3061 In order to restore and activate a minimized window (while
3062 preserving its maximized and/or full-screen state), use the following:
3063
3064 \snippet code/src_gui_kernel_qwidget.cpp 1
3065
3066 Calling this function will hide the widget. You must call show() to make
3067 the widget visible again.
3068
3069 \note On some window systems Qt::WindowActive is not immediate, and may be
3070 ignored in certain cases.
3071
3072 When the window state changes, the widget receives a changeEvent()
3073 of type QEvent::WindowStateChange.
3074
3075 \sa Qt::WindowState, windowState()
3076*/
3077void QWidget::setWindowState(Qt::WindowStates newstate)
3078{
3079 Q_D(QWidget);
3080 Qt::WindowStates oldstate = windowState();
3081 if (oldstate == newstate)
3082 return;
3083 if (isWindow() && !testAttribute(Qt::WA_WState_Created))
3084 create();
3085
3086 data->window_state = newstate;
3087 data->in_set_window_state = 1;
3088 Qt::WindowState newEffectiveState = effectiveState(newstate);
3089 Qt::WindowState oldEffectiveState = effectiveState(oldstate);
3090 if (isWindow() && newEffectiveState != oldEffectiveState) {
3091 // Ensure the initial size is valid, since we store it as normalGeometry below.
3092 if (!testAttribute(Qt::WA_Resized) && !isVisible())
3093 adjustSize();
3094
3095 d->createTLExtra();
3096 if (oldEffectiveState == Qt::WindowNoState)
3097 d->topData()->normalGeometry = geometry();
3098
3099 Q_ASSERT(windowHandle());
3100 windowHandle()->setWindowState(newEffectiveState);
3101 }
3102 data->in_set_window_state = 0;
3103
3104 if (newstate & Qt::WindowActive)
3105 activateWindow();
3106
3107 QWindowStateChangeEvent e(oldstate);
3108 QApplication::sendEvent(this, &e);
3109}
3110
3111/*!
3112 \property QWidget::fullScreen
3113 \brief whether the widget is shown in full screen mode
3114
3115 A widget in full screen mode occupies the whole screen area and does not
3116 display window decorations, such as a title bar.
3117
3118 By default, this property is \c false.
3119
3120 \sa windowState(), minimized, maximized
3121*/
3122bool QWidget::isFullScreen() const
3123{ return data->window_state & Qt::WindowFullScreen; }
3124
3125/*!
3126 Shows the widget in full-screen mode.
3127
3128 Calling this function only affects \l{isWindow()}{windows}.
3129
3130 To return from full-screen mode, call showNormal().
3131
3132 Full-screen mode works fine under Windows, but has certain
3133 problems under X. These problems are due to limitations of the
3134 ICCCM protocol that specifies the communication between X11
3135 clients and the window manager. ICCCM simply does not understand
3136 the concept of non-decorated full-screen windows. Therefore, the
3137 best we can do is to request a borderless window and place and
3138 resize it to fill the entire screen. Depending on the window
3139 manager, this may or may not work. The borderless window is
3140 requested using MOTIF hints, which are at least partially
3141 supported by virtually all modern window managers.
3142
3143 An alternative would be to bypass the window manager entirely and
3144 create a window with the Qt::X11BypassWindowManagerHint flag. This
3145 has other severe problems though, like totally broken keyboard focus
3146 and very strange effects on desktop changes or when the user raises
3147 other windows.
3148
3149 X11 window managers that follow modern post-ICCCM specifications
3150 support full-screen mode properly.
3151
3152 \sa showNormal(), showMaximized(), show(), hide(), isVisible()
3153*/
3154void QWidget::showFullScreen()
3155{
3156#if 0 // Used to be included in Qt4 for Q_WS_MAC
3157 // If the unified toolbar is enabled, we have to disable it before going fullscreen.
3158 QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
3159 if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) {
3160 mainWindow->setUnifiedTitleAndToolBarOnMac(false);
3161 QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
3162 mainLayout->activateUnifiedToolbarAfterFullScreen = true;
3163 }
3164#endif
3165 ensurePolished();
3166
3167 setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
3168 | Qt::WindowFullScreen);
3169 setVisible(true);
3170#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen
3171 // activating it here before libscreen activates it causes problems
3172 activateWindow();
3173#endif
3174}
3175
3176/*!
3177 Shows the widget maximized.
3178
3179 Calling this function only affects \l{isWindow()}{windows}.
3180
3181 On X11, this function may not work properly with certain window
3182 managers. See the \l{Window Geometry} documentation for an explanation.
3183
3184 \sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible()
3185*/
3186void QWidget::showMaximized()
3187{
3188 ensurePolished();
3189
3190 setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen))
3191 | Qt::WindowMaximized);
3192#if 0 // Used to be included in Qt4 for Q_WS_MAC
3193 // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
3194 QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
3195 if (mainWindow)
3196 {
3197 QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
3198 if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
3199 mainWindow->setUnifiedTitleAndToolBarOnMac(true);
3200 mainLayout->activateUnifiedToolbarAfterFullScreen = false;
3201 }
3202 }
3203#endif
3204 setVisible(true);
3205}
3206
3207/*!
3208 Restores the widget after it has been maximized or minimized.
3209
3210 Calling this function only affects \l{isWindow()}{windows}.
3211
3212 \sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible()
3213*/
3214void QWidget::showNormal()
3215{
3216 ensurePolished();
3217
3218 setWindowState(windowState() & ~(Qt::WindowMinimized
3219 | Qt::WindowMaximized
3220 | Qt::WindowFullScreen));
3221#if 0 // Used to be included in Qt4 for Q_WS_MAC
3222 // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
3223 QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
3224 if (mainWindow)
3225 {
3226 QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
3227 if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
3228 mainWindow->setUnifiedTitleAndToolBarOnMac(true);
3229 mainLayout->activateUnifiedToolbarAfterFullScreen = false;
3230 }
3231 }
3232#endif
3233 setVisible(true);
3234}
3235
3236/*!
3237 Returns \c true if this widget would become enabled if \a ancestor is
3238 enabled; otherwise returns \c false.
3239
3240
3241
3242 This is the case if neither the widget itself nor every parent up
3243 to but excluding \a ancestor has been explicitly disabled.
3244
3245 isEnabledTo(0) returns false if this widget or any if its ancestors
3246 was explicitly disabled.
3247
3248 The word ancestor here means a parent widget within the same window.
3249
3250 Therefore isEnabledTo(0) stops at this widget's window, unlike
3251 isEnabled() which also takes parent windows into considerations.
3252
3253 \sa setEnabled(), enabled
3254*/
3255
3256bool QWidget::isEnabledTo(const QWidget *ancestor) const
3257{
3258 const QWidget * w = this;
3259 while (!w->testAttribute(Qt::WA_ForceDisabled)
3260 && !w->isWindow()
3261 && w->parentWidget()
3262 && w->parentWidget() != ancestor)
3263 w = w->parentWidget();
3264 return !w->testAttribute(Qt::WA_ForceDisabled);
3265}
3266
3267#ifndef QT_NO_ACTION
3268/*!
3269 Appends the action \a action to this widget's list of actions.
3270
3271 All QWidgets have a list of \l{QAction}s, however they can be
3272 represented graphically in many different ways. The default use of
3273 the QAction list (as returned by actions()) is to create a context
3274 QMenu.
3275
3276 A QWidget should only have one of each action and adding an action
3277 it already has will not cause the same action to be in the widget twice.
3278
3279 The ownership of \a action is not transferred to this QWidget.
3280
3281 \sa removeAction(), insertAction(), actions(), QMenu
3282*/
3283void QWidget::addAction(QAction *action)
3284{
3285 insertAction(0, action);
3286}
3287
3288/*!
3289 Appends the actions \a actions to this widget's list of actions.
3290
3291 \sa removeAction(), QMenu, addAction()
3292*/
3293#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
3294void QWidget::addActions(const QList<QAction *> &actions)
3295#else
3296void QWidget::addActions(QList<QAction*> actions)
3297#endif
3298{
3299 for(int i = 0; i < actions.count(); i++)
3300 insertAction(0, actions.at(i));
3301}
3302
3303/*!
3304 Inserts the action \a action to this widget's list of actions,
3305 before the action \a before. It appends the action if \a before is 0 or
3306 \a before is not a valid action for this widget.
3307
3308 A QWidget should only have one of each action.
3309
3310 \sa removeAction(), addAction(), QMenu, contextMenuPolicy, actions()
3311*/
3312void QWidget::insertAction(QAction *before, QAction *action)
3313{
3314 if (Q_UNLIKELY(!action)) {
3315 qWarning("QWidget::insertAction: Attempt to insert null action");
3316 return;
3317 }
3318
3319 Q_D(QWidget);
3320 if(d->actions.contains(action))
3321 removeAction(action);
3322
3323 int pos = d->actions.indexOf(before);
3324 if (pos < 0) {
3325 before = 0;
3326 pos = d->actions.size();
3327 }
3328 d->actions.insert(pos, action);
3329
3330 QActionPrivate *apriv = action->d_func();
3331 apriv->widgets.append(this);
3332
3333 QActionEvent e(QEvent::ActionAdded, action, before);
3334 QApplication::sendEvent(this, &e);
3335}
3336
3337/*!
3338 Inserts the actions \a actions to this widget's list of actions,
3339 before the action \a before. It appends the action if \a before is 0 or
3340 \a before is not a valid action for this widget.
3341
3342 A QWidget can have at most one of each action.
3343
3344 \sa removeAction(), QMenu, insertAction(), contextMenuPolicy
3345*/
3346#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
3347void QWidget::insertActions(QAction *before, const QList<QAction*> &actions)
3348#else
3349void QWidget::insertActions(QAction *before, QList<QAction*> actions)
3350#endif
3351{
3352 for(int i = 0; i < actions.count(); ++i)
3353 insertAction(before, actions.at(i));
3354}
3355
3356/*!
3357 Removes the action \a action from this widget's list of actions.
3358 \sa insertAction(), actions(), insertAction()
3359*/
3360void QWidget::removeAction(QAction *action)
3361{
3362 if (!action)
3363 return;
3364
3365 Q_D(QWidget);
3366
3367 QActionPrivate *apriv = action->d_func();
3368 apriv->widgets.removeAll(this);
3369
3370 if (d->actions.removeAll(action)) {
3371 QActionEvent e(QEvent::ActionRemoved, action);
3372 QApplication::sendEvent(this, &e);
3373 }
3374}
3375
3376/*!
3377 Returns the (possibly empty) list of this widget's actions.
3378
3379 \sa contextMenuPolicy, insertAction(), removeAction()
3380*/
3381QList<QAction*> QWidget::actions() const
3382{
3383 Q_D(const QWidget);
3384 return d->actions;
3385}
3386#endif // QT_NO_ACTION
3387
3388/*!
3389 \fn bool QWidget::isEnabledToTLW() const
3390 \obsolete
3391
3392 This function is deprecated. It is equivalent to isEnabled()
3393*/
3394
3395/*!
3396 \property QWidget::enabled
3397 \brief whether the widget is enabled
3398
3399 In general an enabled widget handles keyboard and mouse events; a disabled
3400 widget does not. An exception is made with \l{QAbstractButton}.
3401
3402 Some widgets display themselves differently when they are
3403 disabled. For example a button might draw its label grayed out. If
3404 your widget needs to know when it becomes enabled or disabled, you
3405 can use the changeEvent() with type QEvent::EnabledChange.
3406
3407 Disabling a widget implicitly disables all its children. Enabling
3408 respectively enables all child widgets unless they have been
3409 explicitly disabled. It it not possible to explicitly enable a child
3410 widget which is not a window while its parent widget remains disabled.
3411
3412 By default, this property is \c true.
3413
3414 \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3415*/
3416void QWidget::setEnabled(bool enable)
3417{
3418 Q_D(QWidget);
3419 setAttribute(Qt::WA_ForceDisabled, !enable);
3420 d->setEnabled_helper(enable);
3421}
3422
3423void QWidgetPrivate::setEnabled_helper(bool enable)
3424{
3425 Q_Q(QWidget);
3426
3427 if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled())
3428 return; // nothing we can do
3429
3430 if (enable != q->testAttribute(Qt::WA_Disabled))
3431 return; // nothing to do
3432
3433 q->setAttribute(Qt::WA_Disabled, !enable);
3434 updateSystemBackground();
3435
3436 if (!enable && q->window()->focusWidget() == q) {
3437 bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled());
3438 if (!parentIsEnabled || !q->focusNextChild())
3439 q->clearFocus();
3440 }
3441
3442 Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled;
3443 for (int i = 0; i < children.size(); ++i) {
3444 QWidget *w = qobject_cast<QWidget *>(children.at(i));
3445 if (w && !w->testAttribute(attribute))
3446 w->d_func()->setEnabled_helper(enable);
3447 }
3448#if 0 // Used to be included in Qt4 for Q_WS_X11
3449 if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
3450 // enforce the windows behavior of clearing the cursor on
3451 // disabled widgets
3452 qt_x11_enforce_cursor(q);
3453 }
3454#endif
3455#ifndef QT_NO_CURSOR
3456 if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
3457 // enforce the windows behavior of clearing the cursor on
3458 // disabled widgets
3459 qt_qpa_set_cursor(q, false);
3460 }
3461#endif
3462#if 0 // Used to be included in Qt4 for Q_WS_MAC
3463 setEnabled_helper_sys(enable);
3464#endif
3465#ifndef QT_NO_IM
3466 if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) {
3467 QWidget *focusWidget = effectiveFocusWidget();
3468
3469 if (enable) {
3470 if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
3471 QGuiApplication::inputMethod()->update(Qt::ImEnabled);
3472 } else {
3473 QGuiApplication::inputMethod()->commit();
3474 QGuiApplication::inputMethod()->update(Qt::ImEnabled);
3475 }
3476 }
3477#endif //QT_NO_IM
3478 QEvent e(QEvent::EnabledChange);
3479 QApplication::sendEvent(q, &e);
3480}
3481
3482/*!
3483 \property QWidget::acceptDrops
3484 \brief whether drop events are enabled for this widget
3485
3486 Setting this property to true announces to the system that this
3487 widget \e may be able to accept drop events.
3488
3489 If the widget is the desktop (windowType() == Qt::Desktop), this may
3490 fail if another application is using the desktop; you can call
3491 acceptDrops() to test if this occurs.
3492
3493 \warning Do not modify this property in a drag and drop event handler.
3494
3495 By default, this property is \c false.
3496
3497 \sa {Drag and Drop}
3498*/
3499bool QWidget::acceptDrops() const
3500{
3501 return testAttribute(Qt::WA_AcceptDrops);
3502}
3503
3504void QWidget::setAcceptDrops(bool on)
3505{
3506 setAttribute(Qt::WA_AcceptDrops, on);
3507
3508}
3509
3510void QWidgetPrivate::registerDropSite(bool on)
3511{
3512 Q_UNUSED(on);
3513}
3514
3515/*!
3516 Disables widget input events if \a disable is true; otherwise
3517 enables input events.
3518
3519 See the \l enabled documentation for more information.
3520
3521 \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3522*/
3523void QWidget::setDisabled(bool disable)
3524{
3525 setEnabled(!disable);
3526}
3527
3528/*!
3529 \property QWidget::frameGeometry
3530 \brief geometry of the widget relative to its parent including any
3531 window frame
3532
3533 See the \l{Window Geometry} documentation for an overview of geometry
3534 issues with windows.
3535
3536 By default, this property contains a value that depends on the user's
3537 platform and screen geometry.
3538
3539 \sa geometry(), x(), y(), pos()
3540*/
3541QRect QWidget::frameGeometry() const
3542{
3543 Q_D(const QWidget);
3544 if (isWindow() && ! (windowType() == Qt::Popup)) {
3545 QRect fs = d->frameStrut();
3546 return QRect(data->crect.x() - fs.left(),
3547 data->crect.y() - fs.top(),
3548 data->crect.width() + fs.left() + fs.right(),
3549 data->crect.height() + fs.top() + fs.bottom());
3550 }
3551 return data->crect;
3552}
3553
3554/*!
3555 \property QWidget::x
3556
3557 \brief the x coordinate of the widget relative to its parent including
3558 any window frame
3559
3560 See the \l{Window Geometry} documentation for an overview of geometry
3561 issues with windows.
3562
3563 By default, this property has a value of 0.
3564
3565 \sa frameGeometry, y, pos
3566*/
3567int QWidget::x() const
3568{
3569 Q_D(const QWidget);
3570 if (isWindow() && ! (windowType() == Qt::Popup))
3571 return data->crect.x() - d->frameStrut().left();
3572 return data->crect.x();
3573}
3574
3575/*!
3576 \property QWidget::y
3577 \brief the y coordinate of the widget relative to its parent and
3578 including any window frame
3579
3580 See the \l{Window Geometry} documentation for an overview of geometry
3581 issues with windows.
3582
3583 By default, this property has a value of 0.
3584
3585 \sa frameGeometry, x, pos
3586*/
3587int QWidget::y() const
3588{
3589 Q_D(const QWidget);
3590 if (isWindow() && ! (windowType() == Qt::Popup))
3591 return data->crect.y() - d->frameStrut().top();
3592 return data->crect.y();
3593}
3594
3595/*!
3596 \property QWidget::pos
3597 \brief the position of the widget within its parent widget
3598
3599 If the widget is a window, the position is that of the widget on
3600 the desktop, including its frame.
3601
3602 When changing the position, the widget, if visible, receives a
3603 move event (moveEvent()) immediately. If the widget is not
3604 currently visible, it is guaranteed to receive an event before it
3605 is shown.
3606
3607 By default, this property contains a position that refers to the
3608 origin.
3609
3610 \warning Calling move() or setGeometry() inside moveEvent() can
3611 lead to infinite recursion.
3612
3613 See the \l{Window Geometry} documentation for an overview of geometry
3614 issues with windows.
3615
3616 \sa frameGeometry, size, x(), y()
3617*/
3618QPoint QWidget::pos() const
3619{
3620 Q_D(const QWidget);
3621 QPoint result = data->crect.topLeft();
3622 if (isWindow() && ! (windowType() == Qt::Popup))
3623 if (!d->maybeTopData() || !d->maybeTopData()->posIncludesFrame)
3624 result -= d->frameStrut().topLeft();
3625 return result;
3626}
3627
3628/*!
3629 \property QWidget::geometry
3630 \brief the geometry of the widget relative to its parent and
3631 excluding the window frame
3632
3633 When changing the geometry, the widget, if visible, receives a
3634 move event (moveEvent()) and/or a resize event (resizeEvent())
3635 immediately. If the widget is not currently visible, it is
3636 guaranteed to receive appropriate events before it is shown.
3637
3638 The size component is adjusted if it lies outside the range
3639 defined by minimumSize() and maximumSize().
3640
3641 \warning Calling setGeometry() inside resizeEvent() or moveEvent()
3642 can lead to infinite recursion.
3643
3644 See the \l{Window Geometry} documentation for an overview of geometry
3645 issues with windows.
3646
3647 By default, this property contains a value that depends on the user's
3648 platform and screen geometry.
3649
3650 \sa frameGeometry(), rect(), move(), resize(), moveEvent(),
3651 resizeEvent(), minimumSize(), maximumSize()
3652*/
3653
3654/*!
3655 \property QWidget::normalGeometry
3656
3657 \brief the geometry of the widget as it will appear when shown as
3658 a normal (not maximized or full screen) top-level widget
3659
3660 For child widgets this property always holds an empty rectangle.
3661
3662 By default, this property contains an empty rectangle.
3663
3664 \sa QWidget::windowState(), QWidget::geometry
3665*/
3666
3667/*!
3668 \property QWidget::size
3669 \brief the size of the widget excluding any window frame
3670
3671 If the widget is visible when it is being resized, it receives a resize event
3672 (resizeEvent()) immediately. If the widget is not currently
3673 visible, it is guaranteed to receive an event before it is shown.
3674
3675 The size is adjusted if it lies outside the range defined by
3676 minimumSize() and maximumSize().
3677
3678 By default, this property contains a value that depends on the user's
3679 platform and screen geometry.
3680
3681 \warning Calling resize() or setGeometry() inside resizeEvent() can
3682 lead to infinite recursion.
3683
3684 \note Setting the size to \c{QSize(0, 0)} will cause the widget to not
3685 appear on screen. This also applies to windows.
3686
3687 \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize()
3688*/
3689
3690/*!
3691 \property QWidget::width
3692 \brief the width of the widget excluding any window frame
3693
3694 See the \l{Window Geometry} documentation for an overview of geometry
3695 issues with windows.
3696
3697 \note Do not use this function to find the width of a screen on
3698 a \l{QDesktopWidget}{multiple screen desktop}. Read
3699 \l{QDesktopWidget#Screen Geometry}{this note} for details.
3700
3701 By default, this property contains a value that depends on the user's
3702 platform and screen geometry.
3703
3704 \sa geometry, height, size
3705*/
3706
3707/*!
3708 \property QWidget::height
3709 \brief the height of the widget excluding any window frame
3710
3711 See the \l{Window Geometry} documentation for an overview of geometry
3712 issues with windows.
3713
3714 \note Do not use this function to find the height of a screen
3715 on a \l{QDesktopWidget}{multiple screen desktop}. Read
3716 \l{QDesktopWidget#Screen Geometry}{this note} for details.
3717
3718 By default, this property contains a value that depends on the user's
3719 platform and screen geometry.
3720
3721 \sa geometry, width, size
3722*/
3723
3724/*!
3725 \property QWidget::rect
3726 \brief the internal geometry of the widget excluding any window
3727 frame
3728
3729 The rect property equals QRect(0, 0, width(), height()).
3730
3731 See the \l{Window Geometry} documentation for an overview of geometry
3732 issues with windows.
3733
3734 By default, this property contains a value that depends on the user's
3735 platform and screen geometry.
3736
3737 \sa size
3738*/
3739
3740
3741QRect QWidget::normalGeometry() const
3742{
3743 Q_D(const QWidget);
3744 if (!d->extra || !d->extra->topextra)
3745 return QRect();
3746
3747 if (!isMaximized() && !isFullScreen())
3748 return geometry();
3749
3750 return d->topData()->normalGeometry;
3751}
3752
3753
3754/*!
3755 \property QWidget::childrenRect
3756 \brief the bounding rectangle of the widget's children
3757
3758 Hidden children are excluded.
3759
3760 By default, for a widget with no children, this property contains a
3761 rectangle with zero width and height located at the origin.
3762
3763 \sa childrenRegion(), geometry()
3764*/
3765
3766QRect QWidget::childrenRect() const
3767{
3768 Q_D(const QWidget);
3769 QRect r(0, 0, 0, 0);
3770 for (int i = 0; i < d->children.size(); ++i) {
3771 QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
3772 if (w && !w->isWindow() && !w->isHidden())
3773 r |= w->geometry();
3774 }
3775 return r;
3776}
3777
3778/*!
3779 \property QWidget::childrenRegion
3780 \brief the combined region occupied by the widget's children
3781
3782 Hidden children are excluded.
3783
3784 By default, for a widget with no children, this property contains an
3785 empty region.
3786
3787 \sa childrenRect(), geometry(), mask()
3788*/
3789
3790QRegion QWidget::childrenRegion() const
3791{
3792 Q_D(const QWidget);
3793 QRegion r;
3794 for (int i = 0; i < d->children.size(); ++i) {
3795 QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
3796 if (w && !w->isWindow() && !w->isHidden()) {
3797 QRegion mask = w->mask();
3798 if (mask.isEmpty())
3799 r |= w->geometry();
3800 else
3801 r |= mask.translated(w->pos());
3802 }
3803 }
3804 return r;
3805}
3806
3807
3808/*!
3809 \property QWidget::minimumSize
3810 \brief the widget's minimum size
3811
3812 The widget cannot be resized to a smaller size than the minimum
3813 widget size. The widget's size is forced to the minimum size if
3814 the current size is smaller.
3815
3816 The minimum size set by this function will override the minimum size
3817 defined by QLayout. In order to unset the minimum size, use a
3818 value of \c{QSize(0, 0)}.
3819
3820 By default, this property contains a size with zero width and height.
3821
3822 \sa minimumWidth, minimumHeight, maximumSize, sizeIncrement
3823*/
3824
3825QSize QWidget::minimumSize() const
3826{
3827 Q_D(const QWidget);
3828 return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0);
3829}
3830
3831/*!
3832 \property QWidget::maximumSize
3833 \brief the widget's maximum size in pixels
3834
3835 The widget cannot be resized to a larger size than the maximum
3836 widget size.
3837
3838 By default, this property contains a size in which both width and height
3839 have values of 16777215.
3840
3841 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3842 of widgets.
3843
3844 \sa maximumWidth, maximumHeight, minimumSize, sizeIncrement
3845*/
3846
3847QSize QWidget::maximumSize() const
3848{
3849 Q_D(const QWidget);
3850 return d->extra ? QSize(d->extra->maxw, d->extra->maxh)
3851 : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
3852}
3853
3854
3855/*!
3856 \property QWidget::minimumWidth
3857 \brief the widget's minimum width in pixels
3858
3859 This property corresponds to the width held by the \l minimumSize property.
3860
3861 By default, this property has a value of 0.
3862
3863 \sa minimumSize, minimumHeight
3864*/
3865
3866/*!
3867 \property QWidget::minimumHeight
3868 \brief the widget's minimum height in pixels
3869
3870 This property corresponds to the height held by the \l minimumSize property.
3871
3872 By default, this property has a value of 0.
3873
3874 \sa minimumSize, minimumWidth
3875*/
3876
3877/*!
3878 \property QWidget::maximumWidth
3879 \brief the widget's maximum width in pixels
3880
3881 This property corresponds to the width held by the \l maximumSize property.
3882
3883 By default, this property contains a value of 16777215.
3884
3885 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3886 of widgets.
3887
3888 \sa maximumSize, maximumHeight
3889*/
3890
3891/*!
3892 \property QWidget::maximumHeight
3893 \brief the widget's maximum height in pixels
3894
3895 This property corresponds to the height held by the \l maximumSize property.
3896
3897 By default, this property contains a value of 16777215.
3898
3899 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3900 of widgets.
3901
3902 \sa maximumSize, maximumWidth
3903*/
3904
3905/*!
3906 \property QWidget::sizeIncrement
3907 \brief the size increment of the widget
3908
3909 When the user resizes the window, the size will move in steps of
3910 sizeIncrement().width() pixels horizontally and
3911 sizeIncrement.height() pixels vertically, with baseSize() as the
3912 basis. Preferred widget sizes are for non-negative integers \e i
3913 and \e j:
3914 \snippet code/src_gui_kernel_qwidget.cpp 2
3915
3916 Note that while you can set the size increment for all widgets, it
3917 only affects windows.
3918
3919 By default, this property contains a size with zero width and height.
3920
3921 \warning The size increment has no effect under Windows, and may
3922 be disregarded by the window manager on X11.
3923
3924 \sa size, minimumSize, maximumSize
3925*/
3926QSize QWidget::sizeIncrement() const
3927{
3928 Q_D(const QWidget);
3929 return (d->extra && d->extra->topextra)
3930 ? QSize(d->extra->topextra->incw, d->extra->topextra->inch)
3931 : QSize(0, 0);
3932}
3933
3934/*!
3935 \property QWidget::baseSize
3936 \brief the base size of the widget
3937
3938 The base size is used to calculate a proper widget size if the
3939 widget defines sizeIncrement().
3940
3941 By default, for a newly-created widget, this property contains a size with
3942 zero width and height.
3943
3944 \sa setSizeIncrement()
3945*/
3946
3947QSize QWidget::baseSize() const
3948{
3949 Q_D(const QWidget);
3950 return (d->extra != 0 && d->extra->topextra != 0)
3951 ? QSize(d->extra->topextra->basew, d->extra->topextra->baseh)
3952 : QSize(0, 0);
3953}
3954
3955bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
3956{
3957 Q_Q(QWidget);
3958
3959 int mw = minw, mh = minh;
3960 if (mw == QWIDGETSIZE_MAX)
3961 mw = 0;
3962 if (mh == QWIDGETSIZE_MAX)
3963 mh = 0;
3964 if (Q_UNLIKELY(minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX)) {
3965 qWarning("QWidget::setMinimumSize: (%s/%s) "
3966 "The largest allowed size is (%d,%d)",
3967 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
3968 QWIDGETSIZE_MAX);
3969 minw = mw = qMin<int>(minw, QWIDGETSIZE_MAX);
3970 minh = mh = qMin<int>(minh, QWIDGETSIZE_MAX);
3971 }
3972 if (Q_UNLIKELY(minw < 0 || minh < 0)) {
3973 qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
3974 "are not possible",
3975 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
3976 minw = mw = qMax(minw, 0);
3977 minh = mh = qMax(minh, 0);
3978 }
3979 createExtra();
3980 if (extra->minw == mw && extra->minh == mh)
3981 return false;
3982 extra->minw = mw;
3983 extra->minh = mh;
3984 extra->explicitMinSize = (mw ? Qt::Horizontal : 0) | (mh ? Qt::Vertical : 0);
3985 return true;
3986}
3987
3988void QWidgetPrivate::setConstraints_sys()
3989{
3990 Q_Q(QWidget);
3991 if (extra && q->windowHandle()) {
3992 QWindow *win = q->windowHandle();
3993 QWindowPrivate *winp = qt_window_private(win);
3994
3995 winp->minimumSize = QSize(extra->minw, extra->minh);
3996 winp->maximumSize = QSize(extra->maxw, extra->maxh);
3997
3998 if (extra->topextra) {
3999 winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
4000 winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
4001 }
4002
4003 if (winp->platformWindow) {
4004 fixPosIncludesFrame();
4005 winp->platformWindow->propagateSizeHints();
4006 }
4007 }
4008}
4009
4010/*!
4011 \overload
4012
4013 This function corresponds to setMinimumSize(QSize(minw, minh)).
4014 Sets the minimum width to \a minw and the minimum height to \a
4015 minh.
4016*/
4017
4018void QWidget::setMinimumSize(int minw, int minh)
4019{
4020 Q_D(QWidget);
4021 if (!d->setMinimumSize_helper(minw, minh))
4022 return;
4023
4024 if (isWindow())
4025 d->setConstraints_sys();
4026 if (minw > width() || minh > height()) {
4027 bool resized = testAttribute(Qt::WA_Resized);
4028 bool maximized = isMaximized();
4029 resize(qMax(minw,width()), qMax(minh,height()));
4030 setAttribute(Qt::WA_Resized, resized); //not a user resize
4031 if (maximized)
4032 data->window_state = data->window_state | Qt::WindowMaximized;
4033 }
4034#ifndef QT_NO_GRAPHICSVIEW
4035 if (d->extra) {
4036 if (d->extra->proxyWidget)
4037 d->extra->proxyWidget->setMinimumSize(minw, minh);
4038 }
4039#endif
4040 d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
4041}
4042
4043bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh)
4044{
4045 Q_Q(QWidget);
4046 if (Q_UNLIKELY(maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX)) {
4047 qWarning("QWidget::setMaximumSize: (%s/%s) "
4048 "The largest allowed size is (%d,%d)",
4049 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
4050 QWIDGETSIZE_MAX);
4051 maxw = qMin<int>(maxw, QWIDGETSIZE_MAX);
4052 maxh = qMin<int>(maxh, QWIDGETSIZE_MAX);
4053 }
4054 if (Q_UNLIKELY(maxw < 0 || maxh < 0)) {
4055 qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
4056 "are not possible",
4057 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh);
4058 maxw = qMax(maxw, 0);
4059 maxh = qMax(maxh, 0);
4060 }
4061 createExtra();
4062 if (extra->maxw == maxw && extra->maxh == maxh)
4063 return false;
4064 extra->maxw = maxw;
4065 extra->maxh = maxh;
4066 extra->explicitMaxSize = (maxw != QWIDGETSIZE_MAX ? Qt::Horizontal : 0) |
4067 (maxh != QWIDGETSIZE_MAX ? Qt::Vertical : 0);
4068 return true;
4069}
4070
4071/*!
4072 \overload
4073
4074 This function corresponds to setMaximumSize(QSize(\a maxw, \a
4075 maxh)). Sets the maximum width to \a maxw and the maximum height
4076 to \a maxh.
4077*/
4078void QWidget::setMaximumSize(int maxw, int maxh)
4079{
4080 Q_D(QWidget);
4081 if (!d->setMaximumSize_helper(maxw, maxh))
4082 return;
4083
4084 if (isWindow())
4085 d->setConstraints_sys();
4086 if (maxw < width() || maxh < height()) {
4087 bool resized = testAttribute(Qt::WA_Resized);
4088 resize(qMin(maxw,width()), qMin(maxh,height()));
4089 setAttribute(Qt::WA_Resized, resized); //not a user resize
4090 }
4091
4092#ifndef QT_NO_GRAPHICSVIEW
4093 if (d->extra) {
4094 if (d->extra->proxyWidget)
4095 d->extra->proxyWidget->setMaximumSize(maxw, maxh);
4096 }
4097#endif
4098
4099 d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
4100}
4101
4102/*!
4103 \overload
4104
4105 Sets the x (width) size increment to \a w and the y (height) size
4106 increment to \a h.
4107*/
4108void QWidget::setSizeIncrement(int w, int h)
4109{
4110 Q_D(QWidget);
4111 d->createTLExtra();
4112 QTLWExtra* x = d->topData();
4113 if (x->incw == w && x->inch == h)
4114 return;
4115 x->incw = w;
4116 x->inch = h;
4117 if (isWindow())
4118 d->setConstraints_sys();
4119}
4120
4121/*!
4122 \overload
4123
4124 This corresponds to setBaseSize(QSize(\a basew, \a baseh)). Sets
4125 the widgets base size to width \a basew and height \a baseh.
4126*/
4127void QWidget::setBaseSize(int basew, int baseh)
4128{
4129 Q_D(QWidget);
4130 d->createTLExtra();
4131 QTLWExtra* x = d->topData();
4132 if (x->basew == basew && x->baseh == baseh)
4133 return;
4134 x->basew = basew;
4135 x->baseh = baseh;
4136 if (isWindow())
4137 d->setConstraints_sys();
4138}
4139
4140/*!
4141 Sets both the minimum and maximum sizes of the widget to \a s,
4142 thereby preventing it from ever growing or shrinking.
4143
4144 This will override the default size constraints set by QLayout.
4145
4146 To remove constraints, set the size to QWIDGETSIZE_MAX.
4147
4148 Alternatively, if you want the widget to have a
4149 fixed size based on its contents, you can call
4150 QLayout::setSizeConstraint(QLayout::SetFixedSize);
4151
4152 \sa maximumSize, minimumSize
4153*/
4154
4155void QWidget::setFixedSize(const QSize & s)
4156{
4157 setFixedSize(s.width(), s.height());
4158}
4159
4160
4161/*!
4162 \fn void QWidget::setFixedSize(int w, int h)
4163 \overload
4164
4165 Sets the width of the widget to \a w and the height to \a h.
4166*/
4167
4168void QWidget::setFixedSize(int w, int h)
4169{
4170 Q_D(QWidget);
4171 bool minSizeSet = d->setMinimumSize_helper(w, h);
4172 bool maxSizeSet = d->setMaximumSize_helper(w, h);
4173 if (!minSizeSet && !maxSizeSet)
4174 return;
4175
4176 if (isWindow())
4177 d->setConstraints_sys();
4178 else
4179 d->updateGeometry_helper(true);
4180
4181 if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX)
4182 resize(w, h);
4183}
4184
4185void QWidget::setMinimumWidth(int w)
4186{
4187 Q_D(QWidget);
4188 d->createExtra();
4189 uint expl = d->extra->explicitMinSize | (w ? Qt::Horizontal : 0);
4190 setMinimumSize(w, minimumSize().height());
4191 d->extra->explicitMinSize = expl;
4192}
4193
4194void QWidget::setMinimumHeight(int h)
4195{
4196 Q_D(QWidget);
4197 d->createExtra();
4198 uint expl = d->extra->explicitMinSize | (h ? Qt::Vertical : 0);
4199 setMinimumSize(minimumSize().width(), h);
4200 d->extra->explicitMinSize = expl;
4201}
4202
4203void QWidget::setMaximumWidth(int w)
4204{
4205 Q_D(QWidget);
4206 d->createExtra();
4207 uint expl = d->extra->explicitMaxSize | (w == QWIDGETSIZE_MAX ? 0 : Qt::Horizontal);
4208 setMaximumSize(w, maximumSize().height());
4209 d->extra->explicitMaxSize = expl;
4210}
4211
4212void QWidget::setMaximumHeight(int h)
4213{
4214 Q_D(QWidget);
4215 d->createExtra();
4216 uint expl = d->extra->explicitMaxSize | (h == QWIDGETSIZE_MAX ? 0 : Qt::Vertical);
4217 setMaximumSize(maximumSize().width(), h);
4218 d->extra->explicitMaxSize = expl;
4219}
4220
4221/*!
4222 Sets both the minimum and maximum width of the widget to \a w
4223 without changing the heights. Provided for convenience.
4224
4225 \sa sizeHint(), minimumSize(), maximumSize(), setFixedSize()
4226*/
4227
4228void QWidget::setFixedWidth(int w)
4229{
4230 Q_D(QWidget);
4231 d->createExtra();
4232 uint explMin = d->extra->explicitMinSize | Qt::Horizontal;
4233 uint explMax = d->extra->explicitMaxSize | Qt::Horizontal;
4234 setMinimumSize(w, minimumSize().height());
4235 setMaximumSize(w, maximumSize().height());
4236 d->extra->explicitMinSize = explMin;
4237 d->extra->explicitMaxSize = explMax;
4238}
4239
4240
4241/*!
4242 Sets both the minimum and maximum heights of the widget to \a h
4243 without changing the widths. Provided for convenience.
4244
4245 \sa sizeHint(), minimumSize(), maximumSize(), setFixedSize()
4246*/
4247
4248void QWidget::setFixedHeight(int h)
4249{
4250 Q_D(QWidget);
4251 d->createExtra();
4252 uint explMin = d->extra->explicitMinSize | Qt::Vertical;
4253 uint explMax = d->extra->explicitMaxSize | Qt::Vertical;
4254 setMinimumSize(minimumSize().width(), h);
4255 setMaximumSize(maximumSize().width(), h);
4256 d->extra->explicitMinSize = explMin;
4257 d->extra->explicitMaxSize = explMax;
4258}
4259
4260
4261/*!
4262 Translates the widget coordinate \a pos to the coordinate system
4263 of \a parent. The \a parent must not be 0 and must be a parent
4264 of the calling widget.
4265
4266 \sa mapFrom(), mapToParent(), mapToGlobal(), underMouse()
4267*/
4268
4269QPoint QWidget::mapTo(const QWidget * parent, const QPoint & pos) const
4270{
4271 QPoint p = pos;
4272 if (parent) {
4273 const QWidget * w = this;
4274 while (w != parent) {
4275 Q_ASSERT_X(w, "QWidget::mapTo(const QWidget *parent, const QPoint &pos)",
4276 "parent must be in parent hierarchy");
4277 p = w->mapToParent(p);
4278 w = w->parentWidget();
4279 }
4280 }
4281 return p;
4282}
4283
4284
4285/*!
4286 Translates the widget coordinate \a pos from the coordinate system
4287 of \a parent to this widget's coordinate system. The \a parent
4288 must not be 0 and must be a parent of the calling widget.
4289
4290 \sa mapTo(), mapFromParent(), mapFromGlobal(), underMouse()
4291*/
4292
4293QPoint QWidget::mapFrom(const QWidget * parent, const QPoint & pos) const
4294{
4295 QPoint p(pos);
4296 if (parent) {
4297 const QWidget * w = this;
4298 while (w != parent) {
4299 Q_ASSERT_X(w, "QWidget::mapFrom(const QWidget *parent, const QPoint &pos)",
4300 "parent must be in parent hierarchy");
4301
4302 p = w->mapFromParent(p);
4303 w = w->parentWidget();
4304 }
4305 }
4306 return p;
4307}
4308
4309
4310/*!
4311 Translates the widget coordinate \a pos to a coordinate in the
4312 parent widget.
4313
4314 Same as mapToGlobal() if the widget has no parent.
4315
4316 \sa mapFromParent(), mapTo(), mapToGlobal(), underMouse()
4317*/
4318
4319QPoint QWidget::mapToParent(const QPoint &pos) const
4320{
4321 return pos + data->crect.topLeft();
4322}
4323
4324/*!
4325 Translates the parent widget coordinate \a pos to widget
4326 coordinates.
4327
4328 Same as mapFromGlobal() if the widget has no parent.
4329
4330 \sa mapToParent(), mapFrom(), mapFromGlobal(), underMouse()
4331*/
4332
4333QPoint QWidget::mapFromParent(const QPoint &pos) const
4334{
4335 return pos - data->crect.topLeft();
4336}
4337
4338
4339/*!
4340 Returns the window for this widget, i.e. the next ancestor widget
4341 that has (or could have) a window-system frame.
4342
4343 If the widget is a window, the widget itself is returned.
4344
4345 Typical usage is changing the window title:
4346
4347 \snippet code/src_gui_kernel_qwidget.cpp 3
4348
4349 \sa isWindow()
4350*/
4351
4352QWidget *QWidget::window() const
4353{
4354 QWidget *w = const_cast<QWidget *>(this);
4355 QWidget *p = w->parentWidget();
4356 while (!w->isWindow() && p) {
4357 w = p;
4358 p = p->parentWidget();
4359 }
4360 return w;
4361}
4362
4363/*!
4364 \since 4.4
4365
4366 Returns the native parent for this widget, i.e. the next ancestor widget
4367 that has a system identifier, or 0 if it does not have any native parent.
4368
4369 \sa effectiveWinId()
4370*/
4371QWidget *QWidget::nativeParentWidget() const
4372{
4373 QWidget *parent = parentWidget();
4374 while (parent && !parent->internalWinId())
4375 parent = parent->parentWidget();
4376 return parent;
4377}
4378
4379/*! \fn QWidget *QWidget::topLevelWidget() const
4380 \obsolete
4381
4382 Use window() instead.
4383*/
4384
4385
4386
4387/*!
4388 Returns the background role of the widget.
4389
4390 The background role defines the brush from the widget's \l palette that
4391 is used to render the background.
4392
4393 If no explicit background role is set, the widget inherts its parent
4394 widget's background role.
4395
4396 \sa setBackgroundRole(), foregroundRole()
4397 */
4398QPalette::ColorRole QWidget::backgroundRole() const
4399{
4400
4401 const QWidget *w = this;
4402 do {
4403 QPalette::ColorRole role = w->d_func()->bg_role;
4404 if (role != QPalette::NoRole)
4405 return role;
4406 if (w->isWindow() || w->windowType() == Qt::SubWindow)
4407 break;
4408 w = w->parentWidget();
4409 } while (w);
4410 return QPalette::Window;
4411}
4412
4413/*!
4414 Sets the background role of the widget to \a role.
4415
4416 The background role defines the brush from the widget's \l palette that
4417 is used to render the background.
4418
4419 If \a role is QPalette::NoRole, then the widget inherits its
4420 parent's background role.
4421
4422 Note that styles are free to choose any color from the palette.
4423 You can modify the palette or set a style sheet if you don't
4424 achieve the result you want with setBackgroundRole().
4425
4426 \sa backgroundRole(), foregroundRole()
4427 */
4428
4429void QWidget::setBackgroundRole(QPalette::ColorRole role)
4430{
4431 Q_D(QWidget);
4432 d->bg_role = role;
4433 d->updateSystemBackground();
4434 d->propagatePaletteChange();
4435 d->updateIsOpaque();
4436}
4437
4438/*!
4439 Returns the foreground role.
4440
4441 The foreground role defines the color from the widget's \l palette that
4442 is used to draw the foreground.
4443
4444 If no explicit foreground role is set, the function returns a role
4445 that contrasts with the background role.
4446
4447 \sa setForegroundRole(), backgroundRole()
4448 */
4449QPalette::ColorRole QWidget::foregroundRole() const
4450{
4451 Q_D(const QWidget);
4452 QPalette::ColorRole rl = QPalette::ColorRole(d->fg_role);
4453 if (rl != QPalette::NoRole)
4454 return rl;
4455 QPalette::ColorRole role = QPalette::WindowText;
4456 switch (backgroundRole()) {
4457 case QPalette::Button:
4458 role = QPalette::ButtonText;
4459 break;
4460 case QPalette::Base:
4461 role = QPalette::Text;
4462 break;
4463 case QPalette::Dark:
4464 case QPalette::Shadow:
4465 role = QPalette::Light;
4466 break;
4467 case QPalette::Highlight:
4468 role = QPalette::HighlightedText;
4469 break;
4470 case QPalette::ToolTipBase:
4471 role = QPalette::ToolTipText;
4472 break;
4473 default:
4474 ;
4475 }
4476 return role;
4477}
4478
4479/*!
4480 Sets the foreground role of the widget to \a role.
4481
4482 The foreground role defines the color from the widget's \l palette that
4483 is used to draw the foreground.
4484
4485 If \a role is QPalette::NoRole, the widget uses a foreground role
4486 that contrasts with the background role.
4487
4488 Note that styles are free to choose any color from the palette.
4489 You can modify the palette or set a style sheet if you don't
4490 achieve the result you want with setForegroundRole().
4491
4492 \sa foregroundRole(), backgroundRole()
4493 */
4494void QWidget::setForegroundRole(QPalette::ColorRole role)
4495{
4496 Q_D(QWidget);
4497 d->fg_role = role;
4498 d->updateSystemBackground();
4499 d->propagatePaletteChange();
4500}
4501
4502/*!
4503 \property QWidget::palette
4504 \brief the widget's palette
4505
4506 This property describes the widget's palette. The palette is used by the
4507 widget's style when rendering standard components, and is available as a
4508 means to ensure that custom widgets can maintain consistency with the
4509 native platform's look and feel. It's common that different platforms, or
4510 different styles, have different palettes.
4511
4512 When you assign a new palette to a widget, the color roles from this
4513 palette are combined with the widget's default palette to form the
4514 widget's final palette. The palette entry for the widget's background role
4515 is used to fill the widget's background (see QWidget::autoFillBackground),
4516 and the foreground role initializes QPainter's pen.
4517
4518 The default depends on the system environment. QApplication maintains a
4519 system/theme palette which serves as a default for all widgets. There may
4520 also be special palette defaults for certain types of widgets (e.g., on
4521 Windows XP and Vista, all classes that derive from QMenuBar have a special
4522 default palette). You can also define default palettes for widgets
4523 yourself by passing a custom palette and the name of a widget to
4524 QApplication::setPalette(). Finally, the style always has the option of
4525 polishing the palette as it's assigned (see QStyle::polish()).
4526
4527 QWidget propagates explicit palette roles from parent to child. If you
4528 assign a brush or color to a specific role on a palette and assign that
4529 palette to a widget, that role will propagate to all the widget's
4530 children, overriding any system defaults for that role. Note that palettes
4531 by default don't propagate to windows (see isWindow()) unless the
4532 Qt::WA_WindowPropagation attribute is enabled.
4533
4534 QWidget's palette propagation is similar to its font propagation.
4535
4536 The current style, which is used to render the content of all standard Qt
4537 widgets, is free to choose colors and brushes from the widget palette, or
4538 in some cases, to ignore the palette (partially, or completely). In
4539 particular, certain styles like GTK style, Mac style, Windows XP, and
4540 Vista style, depend on third party APIs to render the content of widgets,
4541 and these styles typically do not follow the palette. Because of this,
4542 assigning roles to a widget's palette is not guaranteed to change the
4543 appearance of the widget. Instead, you may choose to apply a \l
4544 styleSheet. You can refer to our Knowledge Base article
4545 \l{http://qt.nokia.com/developer/knowledgebase/22}{here} for more
4546 information.
4547
4548 \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
4549 When using style sheets, the palette of a widget can be customized using
4550 the "color", "background-color", "selection-color",
4551 "selection-background-color" and "alternate-background-color".
4552
4553 \sa QApplication::palette(), QWidget::font()
4554*/
4555const QPalette &QWidget::palette() const
4556{
4557 if (!isEnabled()) {
4558 data->pal.setCurrentColorGroup(QPalette::Disabled);
4559 } else if ((!isVisible() || isActiveWindow())
4560#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
4561 && !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this))
4562#endif
4563 ) {
4564 data->pal.setCurrentColorGroup(QPalette::Active);
4565 } else {
4566#if 0 // Used to be included in Qt4 for Q_WS_MAC
4567 extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
4568 if (qt_mac_can_clickThrough(this))
4569 data->pal.setCurrentColorGroup(QPalette::Active);
4570 else
4571#endif
4572 data->pal.setCurrentColorGroup(QPalette::Inactive);
4573 }
4574 return data->pal;
4575}
4576
4577void QWidget::setPalette(const QPalette &palette)
4578{
4579 Q_D(QWidget);
4580 setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
4581
4582 // Determine which palette is inherited from this widget's ancestors and
4583 // QApplication::palette, resolve this against \a palette (attributes from
4584 // the inherited palette are copied over this widget's palette). Then
4585 // propagate this palette to this widget's children.
4586 QPalette naturalPalette = d->naturalWidgetPalette(d->inheritedPaletteResolveMask);
4587 QPalette resolvedPalette = palette.resolve(naturalPalette);
4588 d->setPalette_helper(resolvedPalette);
4589}
4590
4591/*!
4592 \internal
4593
4594 Returns the palette that the widget \a w inherits from its ancestors and
4595 QApplication::palette. \a inheritedMask is the combination of the widget's
4596 ancestors palette request masks (i.e., which attributes from the parent
4597 widget's palette are implicitly imposed on this widget by the user). Note
4598 that this font does not take into account the palette set on \a w itself.
4599*/
4600QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
4601{
4602 Q_Q(const QWidget);
4603
4604 const bool useStyleSheetPropagationInWidgetStyles =
4605 QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
4606
4607 QPalette naturalPalette = QApplication::palette(q);
4608 if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
4609 && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
4610#ifndef QT_NO_GRAPHICSVIEW
4611 || (extra && extra->proxyWidget)
4612#endif //QT_NO_GRAPHICSVIEW
4613 )) {
4614 if (QWidget *p = q->parentWidget()) {
4615 if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
4616 if (!naturalPalette.isCopyOf(QApplication::palette())) {
4617 QPalette inheritedPalette = p->palette();
4618 inheritedPalette.resolve(inheritedMask);
4619 naturalPalette = inheritedPalette.resolve(naturalPalette);
4620 } else {
4621 naturalPalette = p->palette();
4622 }
4623 }
4624 }
4625#ifndef QT_NO_GRAPHICSVIEW
4626 else if (extra && extra->proxyWidget) {
4627 QPalette inheritedPalette = extra->proxyWidget->palette();
4628 inheritedPalette.resolve(inheritedMask);
4629 naturalPalette = inheritedPalette.resolve(naturalPalette);
4630 }
4631#endif //QT_NO_GRAPHICSVIEW
4632 }
4633 naturalPalette.resolve(0);
4634 return naturalPalette;
4635}
4636/*!
4637 \internal
4638
4639 Determine which palette is inherited from this widget's ancestors and
4640 QApplication::palette, resolve this against this widget's palette
4641 (attributes from the inherited palette are copied over this widget's
4642 palette). Then propagate this palette to this widget's children.
4643*/
4644void QWidgetPrivate::resolvePalette()
4645{
4646 QPalette naturalPalette = naturalWidgetPalette(inheritedPaletteResolveMask);
4647 QPalette resolvedPalette = data.pal.resolve(naturalPalette);
4648 setPalette_helper(resolvedPalette);
4649}
4650
4651void QWidgetPrivate::setPalette_helper(const QPalette &palette)
4652{
4653 Q_Q(QWidget);
4654 if (data.pal == palette && data.pal.resolve() == palette.resolve())
4655 return;
4656 data.pal = palette;
4657 updateSystemBackground();
4658 propagatePaletteChange();
4659 updateIsOpaque();
4660 q->update();
4661 updateIsOpaque();
4662}
4663
4664void QWidgetPrivate::updateSystemBackground()
4665{
4666}
4667
4668/*!
4669 \property QWidget::font
4670 \brief the font currently set for the widget
4671
4672 This property describes the widget's requested font. The font is used by
4673 the widget's style when rendering standard components, and is available as
4674 a means to ensure that custom widgets can maintain consistency with the
4675 native platform's look and feel. It's common that different platforms, or
4676 different styles, define different fonts for an application.
4677
4678 When you assign a new font to a widget, the properties from this font are
4679 combined with the widget's default font to form the widget's final
4680 font. You can call fontInfo() to get a copy of the widget's final
4681 font. The final font is also used to initialize QPainter's font.
4682
4683 The default depends on the system environment. QApplication maintains a
4684 system/theme font which serves as a default for all widgets. There may
4685 also be special font defaults for certain types of widgets. You can also
4686 define default fonts for widgets yourself by passing a custom font and the
4687 name of a widget to QApplication::setFont(). Finally, the font is matched
4688 against Qt's font database to find the best match.
4689
4690 QWidget propagates explicit font properties from parent to child. If you
4691 change a specific property on a font and assign that font to a widget,
4692 that property will propagate to all the widget's children, overriding any
4693 system defaults for that property. Note that fonts by default don't
4694 propagate to windows (see isWindow()) unless the Qt::WA_WindowPropagation
4695 attribute is enabled.
4696
4697 QWidget's font propagation is similar to its palette propagation.
4698
4699 The current style, which is used to render the content of all standard Qt
4700 widgets, is free to choose to use the widget font, or in some cases, to
4701 ignore it (partially, or completely). In particular, certain styles like
4702 GTK style, Mac style, Windows XP, and Vista style, apply special
4703 modifications to the widget font to match the platform's native look and
4704 feel. Because of this, assigning properties to a widget's font is not
4705 guaranteed to change the appearance of the widget. Instead, you may choose
4706 to apply a \l styleSheet.
4707
4708 \note If \l{Qt Style Sheets} are used on the same widget as setFont(),
4709 style sheets will take precedence if the settings conflict.
4710
4711 \sa fontInfo(), fontMetrics()
4712*/
4713
4714void QWidget::setFont(const QFont &font)
4715{
4716 Q_D(QWidget);
4717
4718#ifndef QT_NO_STYLE_STYLESHEET
4719 const QStyleSheetStyle* style;
4720 if (d->extra && (style = qobject_cast<const QStyleSheetStyle*>(d->extra->style))) {
4721 style->saveWidgetFont(this, font);
4722 }
4723#endif
4724
4725 setAttribute(Qt::WA_SetFont, font.resolve() != 0);
4726
4727 // Determine which font is inherited from this widget's ancestors and
4728 // QApplication::font, resolve this against \a font (attributes from the
4729 // inherited font are copied over). Then propagate this font to this
4730 // widget's children.
4731 QFont naturalFont = d->naturalWidgetFont(d->inheritedFontResolveMask);
4732 QFont resolvedFont = font.resolve(naturalFont);
4733 d->setFont_helper(resolvedFont);
4734}
4735
4736/*
4737 \internal
4738
4739 Returns the font that the widget \a w inherits from its ancestors and
4740 QAppli