Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qapplication.h"
7#include "qbrush.h"
8#include "qcursor.h"
9#include "private/qduplicatetracker_p.h"
10#include "qevent.h"
11#include "qlayout.h"
12#if QT_CONFIG(menu)
13#include "qmenu.h"
14#endif
15#include "qmetaobject.h"
16#include "qpixmap.h"
17#include "qpointer.h"
18#include "qstack.h"
19#include "qstyle.h"
20#include "qstylefactory.h"
21#include "qvariant.h"
22#include "qwidget.h"
23#include "qstyleoption.h"
24#include "qstylehints.h"
25#if QT_CONFIG(accessibility)
26# include "qaccessible.h"
27#endif
28#include <qpa/qplatformwindow.h>
29#include <qpa/qplatformwindow_p.h>
30#include "private/qwidgetwindow_p.h"
31#include "qpainter.h"
32#if QT_CONFIG(tooltip)
33#include "qtooltip.h"
34#endif
35#if QT_CONFIG(whatsthis)
36#include "qwhatsthis.h"
37#endif
38#include "qdebug.h"
39#include "private/qstylesheetstyle_p.h"
40#include "private/qstyle_p.h"
41#include "qfileinfo.h"
42#include "qscopeguard.h"
43#include <QtGui/private/qhighdpiscaling_p.h>
44#include <QtGui/qinputmethod.h>
45
46#if QT_CONFIG(graphicseffect)
47#include <private/qgraphicseffect_p.h>
48#endif
49#include <qbackingstore.h>
50#include <private/qwidgetrepaintmanager_p.h>
51#include <private/qpaintengine_raster_p.h>
52
53#include "qwidget_p.h"
54#include <QtGui/private/qwindow_p.h>
55#if QT_CONFIG(action)
56# include "QtGui/private/qaction_p.h"
57#endif
58#include "qlayout_p.h"
59#if QT_CONFIG(graphicsview)
60#include "QtWidgets/qgraphicsproxywidget.h"
61#include "QtWidgets/qgraphicsscene.h"
62#include "private/qgraphicsproxywidget_p.h"
63#include "private/qgraphicsview_p.h"
64#endif
65#include "QtWidgets/qabstractscrollarea.h"
66#include "private/qabstractscrollarea_p.h"
67#include "private/qevent_p.h"
68
69#include "private/qgesturemanager_p.h"
70
71#ifdef QT_KEYPAD_NAVIGATION
72#if QT_CONFIG(tabwidget)
73#include "qtabwidget.h" // Needed in inTabWidget()
74#endif
75#endif // QT_KEYPAD_NAVIGATION
76
78
79#include <sstream>
80
81QT_BEGIN_NAMESPACE
82
83using namespace QNativeInterface::Private;
84using namespace Qt::StringLiterals;
85
86Q_LOGGING_CATEGORY(lcWidgetPainting, "qt.widgets.painting", QtWarningMsg);
87Q_LOGGING_CATEGORY(lcWidgetShowHide, "qt.widgets.showhide", QtWarningMsg);
88Q_STATIC_LOGGING_CATEGORY(lcWidgetWindow, "qt.widgets.window", QtWarningMsg);
89Q_STATIC_LOGGING_CATEGORY(lcWidgetFocus, "qt.widgets.focus")
90
91#ifndef QT_NO_DEBUG_STREAM
92namespace {
93 struct WidgetAttributes { const QWidget *widget; };
94 QDebug operator<<(QDebug debug, const WidgetAttributes &attributes);
95}
96#endif
97
98static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
99{
100 return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) &&
101 qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
102}
103
104extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
105
106QWidgetPrivate::QWidgetPrivate(decltype(QObjectPrivateVersion) version)
107 : QObjectPrivate(version)
108 , focus_next(nullptr)
109 , focus_prev(nullptr)
110 , focus_child(nullptr)
111 , layout(nullptr)
112 , needsFlush(nullptr)
113 , redirectDev(nullptr)
114 , widgetItem(nullptr)
115 , extraPaintEngine(nullptr)
116 , polished(nullptr)
117 , graphicsEffect(nullptr)
118#if !defined(QT_NO_IM)
119 , imHints(Qt::ImhNone)
120#endif
121#if QT_CONFIG(tooltip)
122 , toolTipDuration(-1)
123#endif
124 , directFontResolveMask(0)
125 , inheritedFontResolveMask(0)
126 , directPaletteResolveMask(0)
127 , inheritedPaletteResolveMask(0)
128 , leftmargin(0)
129 , topmargin(0)
130 , rightmargin(0)
131 , bottommargin(0)
132 , leftLayoutItemMargin(0)
133 , topLayoutItemMargin(0)
134 , rightLayoutItemMargin(0)
135 , bottomLayoutItemMargin(0)
136 , hd(nullptr)
137 , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
138 , fg_role(QPalette::NoRole)
139 , bg_role(QPalette::NoRole)
140 , dirtyOpaqueChildren(1)
141 , isOpaque(0)
142 , retainSizeWhenHiddenChanged(0)
143 , inDirtyList(0)
144 , isScrolled(0)
145 , isMoved(0)
146 , usesDoubleBufferedGLContext(0)
147 , mustHaveWindowHandle(0)
148 , renderToTexture(0)
149 , textureChildSeen(0)
150#ifndef QT_NO_IM
151 , inheritsInputMethodHints(0)
152#endif
153 , renderToTextureReallyDirty(1)
154 , usesRhiFlush(0)
155 , childrenHiddenByWState(0)
156 , childrenShownByExpose(0)
157 , dontSetExplicitShowHide(0)
158#if defined(Q_OS_WIN)
159 , noPaintOnScreen(0)
160#endif
161{
162 if (Q_UNLIKELY(!qApp)) {
163 qFatal("QWidget: Must construct a QApplication before a QWidget");
164 return;
165 }
166
167 willBeWidget = true; // used in QObject's ctor
168 memset(high_attributes, 0, sizeof(high_attributes));
169
170#ifdef QWIDGET_EXTRA_DEBUG
171 static int count = 0;
172 qDebug() << "widgets" << ++count;
173#endif
174}
175
176
177QWidgetPrivate::~QWidgetPrivate()
178{
179 if (widgetItem)
180 widgetItem->wid = nullptr;
181
182 if (extra)
183 deleteExtra();
184}
185
186/*!
187 \internal
188*/
189void QWidgetPrivate::scrollChildren(int dx, int dy)
190{
191 Q_Q(QWidget);
192 if (q->children().size() > 0) { // scroll children
193 QPoint pd(dx, dy);
194 QObjectList childObjects = q->children();
195 for (int i = 0; i < childObjects.size(); ++i) { // move all children
196 QWidget *w = qobject_cast<QWidget*>(childObjects.at(i));
197 if (w && !w->isWindow()) {
198 QPoint oldp = w->pos();
199 QRect r(w->pos() + pd, w->size());
200 w->data->crect = r;
201 if (w->testAttribute(Qt::WA_WState_Created))
202 w->d_func()->setWSGeometry();
203 w->d_func()->setDirtyOpaqueRegion();
204 QMoveEvent e(r.topLeft(), oldp);
205 QCoreApplication::sendEvent(w, &e);
206 }
207 }
208 }
209}
210
211void QWidgetPrivate::setWSGeometry()
212{
213 Q_Q(QWidget);
214 if (QWindow *window = q->windowHandle())
215 window->setGeometry(data.crect);
216}
217
218void QWidgetPrivate::updateWidgetTransform(QEvent *event)
219{
220 Q_Q(QWidget);
221 if (q == QGuiApplication::focusObject() || event->type() == QEvent::FocusIn) {
222 QTransform t;
223 QPoint p = q->mapTo(q->topLevelWidget(), QPoint(0,0));
224 t.translate(p.x(), p.y());
225 QGuiApplication::inputMethod()->setInputItemTransform(t);
226 QGuiApplication::inputMethod()->setInputItemRectangle(q->rect());
227 QGuiApplication::inputMethod()->update(Qt::ImInputItemClipRectangle);
228 }
229}
230
231#ifdef QT_KEYPAD_NAVIGATION
232QPointer<QWidget> QWidgetPrivate::editingWidget;
233
234/*!
235 Returns \c true if this widget currently has edit focus; otherwise false.
236
237 This feature is only available in Qt for Embedded Linux.
238
239 \sa setEditFocus(), QApplication::navigationMode()
240*/
241bool QWidget::hasEditFocus() const
242{
243 const QWidget* w = this;
244 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
245 w = w->d_func()->extra->focus_proxy;
246 return QWidgetPrivate::editingWidget == w;
247}
248
249/*!
250 \fn void QWidget::setEditFocus(bool enable)
251
252 If \a enable is true, make this widget have edit focus, in which
253 case Qt::Key_Up and Qt::Key_Down will be delivered to the widget
254 normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to
255 change focus.
256
257 This feature is only available in Qt for Embedded Linux.
258
259 \sa hasEditFocus(), QApplication::navigationMode()
260*/
261void QWidget::setEditFocus(bool on)
262{
263 QWidget *f = this;
264 while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
265 f = f->d_func()->extra->focus_proxy;
266
267 if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f)
268 QWidgetPrivate::editingWidget->setEditFocus(false);
269
270 if (on && !f->hasFocus())
271 f->setFocus();
272
273 if ((!on && !QWidgetPrivate::editingWidget)
274 || (on && QWidgetPrivate::editingWidget == f)) {
275 return;
276 }
277
278 if (!on && QWidgetPrivate::editingWidget == f) {
279 QWidgetPrivate::editingWidget = 0;
280 QEvent event(QEvent::LeaveEditFocus);
281 QCoreApplication::sendEvent(f, &event);
282 QCoreApplication::sendEvent(f->style(), &event);
283 } else if (on) {
284 QWidgetPrivate::editingWidget = f;
285 QEvent event(QEvent::EnterEditFocus);
286 QCoreApplication::sendEvent(f, &event);
287 QCoreApplication::sendEvent(f->style(), &event);
288 }
289}
290#endif
291
292/*!
293 \property QWidget::autoFillBackground
294 \brief whether the widget background is filled automatically
295 \since 4.1
296
297 If enabled, this property will cause Qt to fill the background of the
298 widget before invoking the paint event. The color used is defined by the
299 QPalette::Window color role from the widget's \l{QPalette}{palette}.
300
301 In addition, Windows are always filled with QPalette::Window, unless the
302 WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
303
304 This property cannot be turned off (i.e., set to false) if a widget's
305 parent has a static gradient for its background.
306
307 \warning Use this property with caution in conjunction with
308 \l{Qt Style Sheets}. When a widget has a style sheet with a valid
309 background or a border-image, this property is automatically disabled.
310
311 By default, this property is \c false.
312
313 \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
314 {QWidget#Transparency and Double Buffering}{Transparency and Double Buffering}
315*/
316bool QWidget::autoFillBackground() const
317{
318 Q_D(const QWidget);
319 return d->extra && d->extra->autoFillBackground;
320}
321
322void QWidget::setAutoFillBackground(bool enabled)
323{
324 Q_D(QWidget);
325 if (!d->extra)
326 d->createExtra();
327 if (d->extra->autoFillBackground == enabled)
328 return;
329
330 d->extra->autoFillBackground = enabled;
331 d->updateIsOpaque();
332 update();
333 d->updateIsOpaque();
334}
335
336/*!
337 \class QWidget
338 \brief The QWidget class is the base class of all user interface objects.
339
340 \ingroup basicwidgets
341 \inmodule QtWidgets
342
343 The widget is the atom of the user interface: it receives mouse, keyboard
344 and other events from the window system, and paints a representation of
345 itself on the screen. Every widget is rectangular, and they are sorted in a
346 Z-order. A widget is clipped by its parent and by the widgets in front of
347 it.
348
349 A widget that is not embedded in a parent widget is called a window.
350 Usually, windows have a frame and a title bar, although it is also possible
351 to create windows without such decoration using suitable
352 \l{Qt::WindowFlags}{window flags}. In Qt, QMainWindow and the various
353 subclasses of QDialog are the most common window types.
354
355 Every widget's constructor accepts one or two standard arguments:
356
357 \list 1
358 \li \c{QWidget *parent = nullptr} is the parent of the new widget.
359 If it is \nullptr (the default), the new widget will be a window.
360 If not, it will be a child of \e parent, and be constrained by
361 \e parent's geometry (unless you specify Qt::Window as window flag).
362 \li \c{Qt::WindowFlags f = { }} (where available) sets the window flags;
363 the default is suitable for most widgets, but to get, for
364 example, a window without a window system frame, you must use
365 special flags.
366 \endlist
367
368 QWidget has many member functions, but some of them have little direct
369 functionality; for example, QWidget has a font property, but never uses
370 this itself. There are many subclasses that provide real functionality,
371 such as QLabel, QPushButton, QListWidget, and QTabWidget.
372
373
374 \section1 Top-Level and Child Widgets
375
376 A widget without a parent widget is always an independent window (top-level
377 widget). For these widgets, setWindowTitle() and setWindowIcon() set the
378 title bar and icon, respectively.
379
380 Non-window widgets are child widgets, displayed within their parent
381 widgets. Most widgets in Qt are mainly useful as child widgets. For
382 example, it is possible to display a button as a top-level window, but most
383 people prefer to put their buttons inside other widgets, such as QDialog.
384
385 \image parent-child-widgets.png A parent widget containing various child widgets.
386
387 The diagram above shows a QGroupBox widget being used to hold various child
388 widgets in a layout provided by QGridLayout. The QLabel child widgets have
389 been outlined to indicate their full sizes.
390
391 If you want to use a QWidget to hold child widgets, you will usually want to
392 add a layout to the parent QWidget. See \l{Layout Management} for more
393 information.
394
395
396 \section1 Composite Widgets
397
398 When a widget is used as a container to group a number of child widgets, it
399 is known as a composite widget. These can be created by constructing a
400 widget with the required visual properties - a QFrame, for example - and
401 adding child widgets to it, usually managed by a layout.
402
403 Composite widgets can also be created by subclassing a standard widget,
404 such as QWidget or QFrame, and adding the necessary layout and child
405 widgets in the constructor of the subclass. Many of the \l{Qt Widgets Examples}
406 {examples provided with Qt} use this approach, and it is also covered in
407 the Qt \l{Widgets Tutorial}.
408
409
410 \section1 Custom Widgets and Painting
411
412 Since QWidget is a subclass of QPaintDevice, subclasses can be used to
413 display custom content that is composed using a series of painting
414 operations with an instance of the QPainter class. This approach contrasts
415 with the canvas-style approach used by the \l{Graphics View}
416 {Graphics View Framework} where items are added to a scene by the
417 application and are rendered by the framework itself.
418
419 Each widget performs all painting operations from within its paintEvent()
420 function. This is called whenever the widget needs to be redrawn, either
421 because of some external change or when requested by the application.
422
423 The \l{widgets/analogclock}{Analog Clock example} shows how a simple widget
424 can handle paint events.
425
426
427 \section1 Size Hints and Size Policies
428
429 When implementing a new widget, it is almost always useful to reimplement
430 sizeHint() to provide a reasonable default size for the widget and to set
431 the correct size policy with setSizePolicy().
432
433 By default, composite widgets that do not provide a size hint will be
434 sized according to the space requirements of their child widgets.
435
436 The size policy lets you supply good default behavior for the layout
437 management system, so that other widgets can contain and manage yours
438 easily. The default size policy indicates that the size hint represents
439 the preferred size of the widget, and this is often good enough for many
440 widgets.
441
442 \note The size of top-level widgets are constrained to 2/3 of the desktop's
443 height and width. You can resize() the widget manually if these bounds are
444 inadequate.
445
446
447 \section1 Events
448
449 Widgets respond to events that are typically caused by user actions. Qt
450 delivers events to widgets by calling specific event handler functions with
451 instances of QEvent subclasses containing information about each event.
452
453 If your widget only contains child widgets, you probably don't need to
454 implement any event handlers. If you want to detect a mouse click in a
455 child widget, call the child's underMouse() function inside the widget's
456 mousePressEvent().
457
458 The \l{widgets/scribble}{Scribble example} implements a wider set of
459 events to handle mouse movement, button presses, and window resizing.
460
461 You will need to supply the behavior and content for your own widgets, but
462 here is a brief overview of the events that are relevant to QWidget,
463 starting with the most common ones:
464
465 \list
466 \li paintEvent() is called whenever the widget needs to be repainted.
467 Every widget displaying custom content must implement it. Painting
468 using a QPainter can only take place in a paintEvent() or a
469 function called by a paintEvent().
470 \li resizeEvent() is called when the widget has been resized.
471 \li mousePressEvent() is called when a mouse button is pressed while
472 the mouse cursor is inside the widget, or when the widget has
473 grabbed the mouse using grabMouse(). Pressing the mouse without
474 releasing it is effectively the same as calling grabMouse().
475 \li mouseReleaseEvent() is called when a mouse button is released. A
476 widget receives mouse release events when it has received the
477 corresponding mouse press event. This means that if the user
478 presses the mouse inside \e your widget, then drags the mouse
479 somewhere else before releasing the mouse button, \e your widget
480 receives the release event. There is one exception: if a popup menu
481 appears while the mouse button is held down, this popup immediately
482 steals the mouse events.
483 \li mouseDoubleClickEvent() is called when the user double-clicks in
484 the widget. If the user double-clicks, the widget receives a mouse
485 press event, a mouse release event, (a mouse click event,) a second
486 mouse press, this event and finally a second mouse release event.
487 (Some mouse move events may also be
488 received if the mouse is not held steady during this operation.) It
489 is \e{not possible} to distinguish a click from a double-click
490 until the second click arrives. (This is one reason why most GUI
491 books recommend that double-clicks be an extension of
492 single-clicks, rather than trigger a different action.)
493 \endlist
494
495 Widgets that accept keyboard input need to reimplement a few more event
496 handlers:
497
498 \list
499 \li keyPressEvent() is called whenever a key is pressed, and again when
500 a key has been held down long enough for it to auto-repeat. The
501 \uicontrol Tab and \uicontrol Shift+Tab keys are only passed to the widget if
502 they are not used by the focus-change mechanisms. To force those
503 keys to be processed by your widget, you must reimplement
504 QWidget::event().
505 \li focusInEvent() is called when the widget gains keyboard focus
506 (assuming you have called setFocusPolicy()). Well-behaved widgets
507 indicate that they own the keyboard focus in a clear but discreet
508 way.
509 \li focusOutEvent() is called when the widget loses keyboard focus.
510 \endlist
511
512 You may be required to also reimplement some of the less common event
513 handlers:
514
515 \list
516 \li mouseMoveEvent() is called whenever the mouse moves while a mouse
517 button is held down. This can be useful during drag and drop
518 operations. If you call \l{setMouseTracking()}{setMouseTracking}(true),
519 you get mouse move events even when no buttons are held down.
520 (See also the \l{Drag and Drop in Qt}{Drag and Drop} guide.)
521 \li keyReleaseEvent() is called whenever a key is released and while it
522 is held down (if the key is auto-repeating). In that case, the
523 widget will receive a pair of key release and key press event for
524 every repeat. The \uicontrol Tab and \uicontrol Shift+Tab keys are only passed
525 to the widget if they are not used by the focus-change mechanisms.
526 To force those keys to be processed by your widget, you must
527 reimplement QWidget::event().
528 \li wheelEvent() is called whenever the user turns the mouse wheel
529 while the widget has the focus.
530 \li enterEvent() is called when the mouse enters the widget's screen
531 space. (This excludes screen space owned by any of the widget's
532 children.)
533 \li leaveEvent() is called when the mouse leaves the widget's screen
534 space. If the mouse enters a child widget, it will not cause a
535 leaveEvent().
536 \li moveEvent() is called when the widget has been moved relative to
537 its parent.
538 \li closeEvent() is called when the user closes the widget (or when
539 close() is called).
540 \endlist
541
542 There are also some rather obscure events described in the documentation
543 for QEvent::Type. To handle these events, you need to reimplement event()
544 directly.
545
546 The default implementation of event() handles \uicontrol Tab and \uicontrol Shift+Tab
547 (to move the keyboard focus), and passes on most of the other events to
548 one of the more specialized handlers above.
549
550 Events and the mechanism used to deliver them are covered in
551 \l{The Event System}.
552
553 \section1 Groups of Functions and Properties
554
555 \table
556 \header \li Context \li Functions and Properties
557
558 \row \li Window functions \li
559 show(),
560 hide(),
561 raise(),
562 lower(),
563 close().
564
565 \row \li Top-level windows \li
566 \l windowModified, \l windowTitle, \l windowIcon,
567 \l isActiveWindow, activateWindow(), \l minimized, showMinimized(),
568 \l maximized, showMaximized(), \l fullScreen, showFullScreen(),
569 showNormal().
571 \row \li Window contents \li
572 update(),
573 repaint(),
574 scroll().
575
576 \row \li Geometry \li
577 \l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(),
578 \l sizePolicy, sizeHint(), minimumSizeHint(),
579 updateGeometry(), layout(),
580 \l frameGeometry, \l geometry, \l childrenRect, \l childrenRegion,
581 adjustSize(),
582 mapFromGlobal(), mapToGlobal(),
583 mapFromParent(), mapToParent(),
584 \l maximumSize, \l minimumSize, \l sizeIncrement,
585 \l baseSize, setFixedSize()
586
587 \row \li Mode \li
588 \l visible, isVisibleTo(),
589 \l enabled, isEnabledTo(),
590 \l modal,
591 isWindow(),
592 \l mouseTracking,
593 \l updatesEnabled,
594 visibleRegion().
595
596 \row \li Look and feel \li
597 style(),
598 setStyle(),
599 \l styleSheet,
600 \l cursor,
601 \l font,
602 \l palette,
603 backgroundRole(), setBackgroundRole(),
604 fontInfo(), fontMetrics().
605
606 \row \li Keyboard focus functions \li
607 \l focus, \l focusPolicy,
608 setFocus(), clearFocus(), setTabOrder(), setFocusProxy(),
609 focusNextChild(), focusPreviousChild().
610
611 \row \li Mouse and keyboard grabbing \li
612 grabMouse(), releaseMouse(),
613 grabKeyboard(), releaseKeyboard(),
614 mouseGrabber(), keyboardGrabber().
615
616 \row \li Event handlers \li
617 event(),
618 mousePressEvent(),
619 mouseReleaseEvent(),
620 mouseDoubleClickEvent(),
621 mouseMoveEvent(),
622 keyPressEvent(),
623 keyReleaseEvent(),
624 focusInEvent(),
625 focusOutEvent(),
626 wheelEvent(),
627 enterEvent(),
628 leaveEvent(),
629 paintEvent(),
630 moveEvent(),
631 resizeEvent(),
632 closeEvent(),
633 dragEnterEvent(),
634 dragMoveEvent(),
635 dragLeaveEvent(),
636 dropEvent(),
637 childEvent(),
638 showEvent(),
639 hideEvent(),
640 customEvent().
641 changeEvent(),
642
643 \row \li System functions \li
644 parentWidget(), window(), setParent(), winId(),
645 find(), metric().
646
647 \row \li Context menu \li
648 contextMenuPolicy, contextMenuEvent(),
649 customContextMenuRequested(), actions()
650
651 \row \li Interactive help \li
652 setToolTip(), setWhatsThis()
653
654 \endtable
655
656
657 \section1 Widget Style Sheets
658
659 In addition to the standard widget styles for each platform, widgets can
660 also be styled according to rules specified in a \l{styleSheet}
661 {style sheet}. This feature enables you to customize the appearance of
662 specific widgets to provide visual cues to users about their purpose. For
663 example, a button could be styled in a particular way to indicate that it
664 performs a destructive action.
665
666 The use of widget style sheets is described in more detail in the
667 \l{Qt Style Sheets} document.
668
669
670 \section1 Transparency and Double Buffering
671
672 QWidget automatically double-buffers its painting, so there
673 is no need to write double-buffering code in paintEvent() to avoid
674 flicker.
675
676 The contents of parent widgets are propagated by
677 default to each of their children as long as Qt::WA_PaintOnScreen is not
678 set. Custom widgets can be written to take advantage of this feature by
679 updating irregular regions (to create non-rectangular child widgets), or
680 painting with colors that have less than full alpha component. The
681 following diagram shows how attributes and properties of a custom widget
682 can be fine-tuned to achieve different effects.
683
684 \image propagation-custom.png
685
686 In the above diagram, a semi-transparent rectangular child widget with an
687 area removed is constructed and added to a parent widget (a QLabel showing
688 a pixmap). Then, different properties and widget attributes are set to
689 achieve different effects:
690
691 \list
692 \li The left widget has no additional properties or widget attributes
693 set. This default state suits most custom widgets that have
694 transparency, are irregularly-shaped, or do not paint over their
695 entire area with an opaque brush.
696 \li The center widget has the \l autoFillBackground property set. This
697 property is used with custom widgets that rely on the widget to
698 supply a default background, and do not paint over their entire
699 area with an opaque brush.
700 \li The right widget has the Qt::WA_OpaquePaintEvent widget attribute
701 set. This indicates that the widget will paint over its entire area
702 with opaque colors. The widget's area will initially be
703 \e{uninitialized}, represented in the diagram with a red diagonal
704 grid pattern that shines through the overpainted area.
705 \endlist
706
707 To rapidly update custom widgets with simple background colors, such as
708 real-time plotting or graphing widgets, it is better to define a suitable
709 background color (using setBackgroundRole() with the
710 QPalette::Window role), set the \l autoFillBackground property, and only
711 implement the necessary drawing functionality in the widget's paintEvent().
712
713 To rapidly update custom widgets that constantly paint over their entire
714 areas with opaque content, for example, video streaming widgets, it is
715 better to set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary
716 overhead associated with repainting the widget's background.
717
718 If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and}
719 the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent
720 attribute takes precedence. Depending on your requirements, you should
721 choose either one of them.
722
723 The contents of parent widgets are also propagated to standard Qt widgets.
724 This can lead to some unexpected results if the parent widget is decorated
725 in a non-standard way, as shown in the diagram below.
726
727 \image propagation-standard.png
728
729 The scope for customizing the painting behavior of standard Qt widgets,
730 without resorting to subclassing, is slightly less than that possible for
731 custom widgets. Usually, the desired appearance of a standard widget can be
732 achieved by setting its \l autoFillBackground property.
733
734
735 \section1 Creating Translucent Windows
736
737 You can create windows with translucent regions on window systems that
738 support compositing.
739
740 To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground
741 attribute with setAttribute() and ensure that its background is painted with
742 non-opaque colors in the regions you want to be partially transparent.
743
744 Platform notes:
745
746 \list
747 \li X11: This feature relies on the use of an X server that supports ARGB visuals
748 and a compositing window manager.
749 \li Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
750 for the translucency to work.
751 \li \macos: The widget needs to have the Qt::FramelessWindowHint window flag set
752 for the translucency to work.
753 \endlist
754
755
756 \section1 Native Widgets vs Alien Widgets
757
758 Alien widgets are widgets unknown to the windowing system. They do not have
759 a native window handle associated with them. This feature significantly
760 speeds up widget painting, resizing, and removes flicker.
761
762 Should you require the old behavior with native windows, choose one of the
763 following options:
764
765 \list 1
766 \li Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
767 \li Set the Qt::AA_NativeWindows attribute on your application. All
768 widgets will be native widgets.
769 \li Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
770 and all its ancestors will become native (unless
771 Qt::WA_DontCreateNativeAncestors is set).
772 \li Call QWidget::winId to enforce a native window (this implies 3).
773 \li Set the Qt::WA_PaintOnScreen attribute to enforce a native window
774 (this implies 3).
775 \endlist
776
777 \sa QEvent, QPainter, QGridLayout, QBoxLayout
778
779*/
780
781QWidgetMapper *QWidgetPrivate::mapper = nullptr; // widget with wid
782QWidgetSet *QWidgetPrivate::allWidgets = nullptr; // widgets with no wid
783
784
785/*****************************************************************************
786 QWidget member functions
787 *****************************************************************************/
788
789/*
790 Widget state flags:
791 \list
792 \li Qt::WA_WState_Created The widget has a valid winId().
793 \li Qt::WA_WState_Visible The widget is currently visible.
794 \li Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
795 become visible unless you call show() on it. Qt::WA_WState_Hidden
796 implies !Qt::WA_WState_Visible.
797 \li Qt::WA_WState_CompressKeys Compress keyboard events.
798 \li Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
799 \li Qt::WA_WState_InPaintEvent Currently processing a paint event.
800 \li Qt::WA_WState_Reparented The widget has been reparented.
801 \li Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
802 \endlist
803*/
804
806{
807 /* this cleans up when the constructor throws an exception */
808 static inline void cleanup(QWidget *that, QWidgetPrivate *d)
809 {
810#ifdef QT_NO_EXCEPTIONS
811 Q_UNUSED(that);
812 Q_UNUSED(d);
813#else
814 QWidgetPrivate::allWidgets->remove(that);
815 d->removeFromFocusChain();
816#endif
817 }
818};
819
820/*!
821 Constructs a widget which is a child of \a parent, with widget
822 flags set to \a f.
823
824 If \a parent is \nullptr, the new widget becomes a window. If
825 \a parent is another widget, this widget becomes a child window
826 inside \a parent. The new widget is deleted when its \a parent is
827 deleted.
828
829 The widget flags argument, \a f, is normally 0, but it can be set
830 to customize the frame of a window (i.e. \a parent must be
831 \nullptr). To customize the frame, use a value composed
832 from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}.
833
834 If you add a child widget to an already visible widget you must
835 explicitly show the child to make it visible.
836
837 Note that the X11 version of Qt may not be able to deliver all
838 combinations of style flags on all systems. This is because on
839 X11, Qt can only ask the window manager, and the window manager
840 can override the application's settings. On Windows, Qt can set
841 whatever flags you want.
842
843 \sa windowFlags
844*/
845QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
846 : QWidget(*new QWidgetPrivate, parent, f)
847{
848}
849
850
851/*! \internal
852*/
853QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
854 : QObject(dd, nullptr), QPaintDevice()
855 , data(&dd.data)
856{
857 Q_D(QWidget);
858 QT_TRY {
859 d->init(parent, f);
860 } QT_CATCH(...) {
861 QWidgetExceptionCleaner::cleanup(this, d_func());
862 QT_RETHROW;
863 }
864}
865
866/*!
867 \internal
868*/
869int QWidget::devType() const
870{
871 return QInternal::Widget;
872}
873
874
875//### w is a "this" ptr, passed as a param because QWorkspace needs special logic
876void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
877{
878 bool customize = (flags & (Qt::CustomizeWindowHint
879 | Qt::FramelessWindowHint
880 | Qt::WindowTitleHint
881 | Qt::WindowSystemMenuHint
882 | Qt::WindowMinimizeButtonHint
883 | Qt::WindowMaximizeButtonHint
884 | Qt::WindowCloseButtonHint
885 | Qt::WindowContextHelpButtonHint));
886
887 uint type = (flags & Qt::WindowType_Mask);
888
889 if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
890 type = Qt::Window;
891 flags |= Qt::Window;
892 }
893
894 if (flags & Qt::CustomizeWindowHint) {
895 // modify window flags to make them consistent.
896 // Only enable this on non-Mac platforms. Since the old way of doing this would
897 // interpret WindowSystemMenuHint as a close button and we can't change that behavior
898 // we can't just add this in.
899 if ((flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint))
900# ifdef Q_OS_WIN
901 && type != Qt::Dialog // QTBUG-2027, allow for menu-less dialogs.
902# endif
903 ) {
904 flags |= Qt::WindowSystemMenuHint;
905 flags |= Qt::WindowTitleHint;
906 flags &= ~Qt::FramelessWindowHint;
907 }
908 } else if (customize && !(flags & Qt::FramelessWindowHint)) {
909 // if any of the window hints that affect the titlebar are set
910 // and the window is supposed to have frame, we add a titlebar
911 // and system menu by default.
912 flags |= Qt::WindowSystemMenuHint;
913 flags |= Qt::WindowTitleHint;
914 }
915 if (!customize) { // don't modify window flags if the user explicitly set them.
916 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
917 if (type != Qt::Dialog && type != Qt::Sheet && type != Qt::Tool)
918 flags |= Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowFullscreenButtonHint;
919 }
920 if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
921 flags |= Qt::WindowTransparentForInput;
922}
923
924void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
925{
926 Q_Q(QWidget);
927 isWidget = true;
928 wasWidget = true;
929
930 Q_ASSERT_X(q != parentWidget, Q_FUNC_INFO, "Cannot parent a QWidget to itself");
931
932 if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance())))
933 qFatal("QWidget: Cannot create a QWidget without QApplication");
934
935 Q_ASSERT(allWidgets);
936 if (allWidgets)
937 allWidgets->insert(q);
938
939#if QT_CONFIG(thread)
940 if (!parent) {
941 Q_ASSERT_X(QThread::isMainThread(), "QWidget",
942 "Widgets must be created in the GUI thread.");
943 }
944#endif
945
946 data.fstrut_dirty = true;
947
948 data.winid = 0;
949 data.widget_attributes = 0;
950 data.window_flags = f;
951 data.window_state = 0;
952 data.focus_policy = 0;
953 data.context_menu_policy = Qt::DefaultContextMenu;
954 data.window_modality = Qt::NonModal;
955
956 data.sizehint_forced = 0;
957 data.is_closing = false;
958 data.in_show = 0;
959 data.in_set_window_state = 0;
960 data.in_destructor = false;
961
962 // Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle.
963 if (f & Qt::MSWindowsOwnDC) {
964 mustHaveWindowHandle = 1;
965 q->setAttribute(Qt::WA_NativeWindow);
966 }
967
968 q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
969 adjustQuitOnCloseAttribute();
970
971 q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea);
972 q->setAttribute(Qt::WA_WState_Hidden);
973
974 //give potential windows a bigger "pre-initial" size; create() will give them a new size later
975 data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
976 initFocusChain();
977
978 if ((f & Qt::WindowType_Mask) == Qt::Desktop)
979 q->create();
980 else if (parentWidget)
981 q->setParent(parentWidget, data.window_flags);
982 else {
983 adjustFlags(data.window_flags, q);
984 resolveLayoutDirection();
985 // opaque system background?
986 const QBrush &background = q->palette().brush(QPalette::Window);
987 setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque());
988 }
989 data.fnt = QFont(data.fnt, q);
990
991 q->setAttribute(Qt::WA_PendingMoveEvent);
992 q->setAttribute(Qt::WA_PendingResizeEvent);
993
994 if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
995 QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
996
997 QEvent e(QEvent::Create);
998 QCoreApplication::sendEvent(q, &e);
999 QCoreApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
1000
1001 extraPaintEngine = nullptr;
1002}
1003
1004void QWidgetPrivate::createRecursively()
1005{
1006 Q_Q(QWidget);
1007 q->create(0, true, true);
1008 for (int i = 0; i < children.size(); ++i) {
1009 QWidget *child = qobject_cast<QWidget *>(children.at(i));
1010 if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(Qt::WA_WState_Created))
1011 child->d_func()->createRecursively();
1012 }
1013}
1014
1015QRhi *QWidgetPrivate::rhi() const
1016{
1017 Q_Q(const QWidget);
1018 if (auto *backingStore = q->backingStore()) {
1019 auto *window = windowHandle(WindowHandleMode::Closest);
1020 return backingStore->handle()->rhi(window);
1021 } else {
1022 return nullptr;
1023 }
1024}
1025
1026/*!
1027 \internal
1028 Returns the closest parent widget that has a QWindow window handle
1029
1030 \note This behavior is different from nativeParentWidget(), which
1031 returns the closest parent that has a QWindow window handle with
1032 a created QPlatformWindow, and hence native window (winId).
1033*/
1034QWidget *QWidgetPrivate::closestParentWidgetWithWindowHandle() const
1035{
1036 Q_Q(const QWidget);
1037 QWidget *parent = q->parentWidget();
1038 while (parent && !parent->windowHandle())
1039 parent = parent->parentWidget();
1040 return parent;
1041}
1042
1043QWindow *QWidgetPrivate::windowHandle(WindowHandleMode mode) const
1044{
1045 if (mode == WindowHandleMode::Direct || mode == WindowHandleMode::Closest) {
1046 if (QTLWExtra *x = maybeTopData()) {
1047 if (x->window != nullptr || mode == WindowHandleMode::Direct)
1048 return x->window;
1049 }
1050 }
1051 if (mode == WindowHandleMode::Closest) {
1052 // FIXME: Use closestParentWidgetWithWindowHandle instead
1053 if (auto nativeParent = q_func()->nativeParentWidget()) {
1054 if (auto window = nativeParent->windowHandle())
1055 return window;
1056 }
1057 }
1058 if (mode == WindowHandleMode::TopLevel || mode == WindowHandleMode::Closest) {
1059 if (auto topLevel = q_func()->topLevelWidget()) {
1060 if (auto window = topLevel ->windowHandle())
1061 return window;
1062 }
1063 }
1064 return nullptr;
1065}
1066
1067/*!
1068 \internal
1069
1070 Used by clients outside of widgets to get a handle to the
1071 closest QWindow without having to link to widgets.
1072*/
1073QWindow *QWidgetPrivate::_q_closestWindowHandle() const
1074{
1075 return windowHandle(QWidgetPrivate::WindowHandleMode::Closest);
1076}
1077
1078QScreen *QWidgetPrivate::associatedScreen() const
1079{
1080#if QT_CONFIG(graphicsview)
1081 // embedded widgets never have a screen associated, let QWidget::screen fall back to toplevel
1082 if (nearestGraphicsProxyWidget(q_func()))
1083 return nullptr;
1084#endif
1085 if (auto window = windowHandle(WindowHandleMode::Closest))
1086 return window->screen();
1087 return nullptr;
1088}
1089
1090// finds the first rhiconfig in the hierarchy that has enable==true
1091static bool q_evaluateRhiConfigRecursive(const QWidget *w, QPlatformBackingStoreRhiConfig *outConfig, QSurface::SurfaceType *outType)
1092{
1093 QPlatformBackingStoreRhiConfig config = QWidgetPrivate::get(w)->rhiConfig();
1094 if (config.isEnabled()) {
1095 if (outConfig)
1096 *outConfig = config;
1097 if (outType)
1098 *outType = QBackingStoreRhiSupport::surfaceTypeForConfig(config);
1099 return true;
1100 }
1101 for (const QObject *child : w->children()) {
1102 if (const QWidget *childWidget = qobject_cast<const QWidget *>(child)) {
1103 if (q_evaluateRhiConfigRecursive(childWidget, outConfig, outType)) {
1104 static bool optOut = qEnvironmentVariableIsSet("QT_WIDGETS_NO_CHILD_RHI");
1105 // Native child widgets should not trigger RHI for its parent
1106 // hierarchy, but will still flush the native child using RHI.
1107 if (!optOut && childWidget->testAttribute(Qt::WA_NativeWindow))
1108 continue;
1109
1110 return true;
1111 }
1112 }
1113 }
1114 return false;
1115}
1116
1117bool q_evaluateRhiConfig(const QWidget *w, QPlatformBackingStoreRhiConfig *outConfig, QSurface::SurfaceType *outType)
1118{
1119 // First, check env.vars. or other means that force the usage of rhi-based
1120 // flushing with a specific graphics API. This takes precedence over what
1121 // the widgets themselves declare. This is global, applying to all
1122 // top-levels.
1123 if (QBackingStoreRhiSupport::checkForceRhi(outConfig, outType)) {
1124 qCDebug(lcWidgetPainting) << "Tree with root" << w << "evaluated to forced flushing with QRhi";
1125 return true;
1126 }
1127
1128 // Otherwise, check the widget hierarchy to see if there is a child (or
1129 // ourselves) that declare the need for rhi-based composition.
1130 if (q_evaluateRhiConfigRecursive(w, outConfig, outType)) {
1131 qCDebug(lcWidgetPainting) << "Tree with root" << w << "evaluates to flushing with QRhi";
1132 return true;
1133 }
1134
1135 return false;
1136}
1137
1138// ### fixme: Qt 6: Remove parameter window from QWidget::create()
1139
1140/*!
1141 Creates a new widget window.
1142
1143 The parameters \a window, \a initializeWindow, and \a destroyOldWindow
1144 are ignored in Qt 5. Please use QWindow::fromWinId() to create a
1145 QWindow wrapping a foreign window and pass it to
1146 QWidget::createWindowContainer() instead.
1147
1148 \sa createWindowContainer(), QWindow::fromWinId()
1149*/
1150
1151void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
1152{
1153 Q_UNUSED(initializeWindow);
1154 Q_UNUSED(destroyOldWindow);
1155
1156 Q_D(QWidget);
1157 if (Q_UNLIKELY(window))
1158 qWarning("QWidget::create(): Parameter 'window' does not have any effect.");
1159 if (testAttribute(Qt::WA_WState_Created) && window == 0 && internalWinId())
1160 return;
1161
1162 if (d->data.in_destructor)
1163 return;
1164
1165 Qt::WindowType type = windowType();
1166 Qt::WindowFlags &flags = data->window_flags;
1167
1168 if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
1169 type = Qt::Window;
1170 flags |= Qt::Window;
1171 }
1172
1173 if (QWidget *parent = parentWidget()) {
1174 if (type & Qt::Window) {
1175 if (!parent->testAttribute(Qt::WA_WState_Created))
1176 parent->createWinId();
1177 } else if (testAttribute(Qt::WA_NativeWindow) && !parent->internalWinId()
1178 && !testAttribute(Qt::WA_DontCreateNativeAncestors)) {
1179 // We're about to create a native child widget that doesn't have a native parent;
1180 // enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors
1181 // attribute is set.
1182 d->createWinId();
1183 // Nothing more to do.
1184 Q_ASSERT(testAttribute(Qt::WA_WState_Created));
1185 Q_ASSERT(internalWinId());
1186 return;
1187 }
1188 }
1189
1190
1191 static const bool paintOnScreenEnv = qEnvironmentVariableIntValue("QT_ONSCREEN_PAINT") > 0;
1192 if (paintOnScreenEnv)
1193 setAttribute(Qt::WA_PaintOnScreen);
1194
1195 if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows))
1196 setAttribute(Qt::WA_NativeWindow);
1197
1198 d->updateIsOpaque();
1199
1200 setAttribute(Qt::WA_WState_Created); // set created flag
1201 d->create();
1202
1203 // A real toplevel window needs a paint manager
1204 if (isWindow() && windowType() != Qt::Desktop)
1205 d->topData()->repaintManager.reset(new QWidgetRepaintManager(this));
1206
1207 d->setModal_sys();
1208
1209 if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
1210 setAttribute(Qt::WA_DropSiteRegistered, true);
1211
1212 // need to force the resting of the icon after changing parents
1213 if (testAttribute(Qt::WA_SetWindowIcon))
1214 d->setWindowIcon_sys();
1215
1216 if (isWindow() && !d->topData()->iconText.isEmpty())
1217 d->setWindowIconText_helper(d->topData()->iconText);
1218 if (isWindow() && !d->topData()->caption.isEmpty())
1219 d->setWindowTitle_helper(d->topData()->caption);
1220 if (isWindow() && !d->topData()->filePath.isEmpty())
1221 d->setWindowFilePath_helper(d->topData()->filePath);
1222 if (windowType() != Qt::Desktop) {
1223 d->updateSystemBackground();
1224
1225 if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon))
1226 d->setWindowIcon_sys();
1227 }
1228
1229 // Frame strut update needed in cases where there are native widgets such as QGLWidget,
1230 // as those force native window creation on their ancestors before they are shown.
1231 // If the strut is not updated, any subsequent move of the top level window before show
1232 // will cause window frame to be ignored when positioning the window.
1233 // Note that this only helps on platforms that handle window creation synchronously.
1234 d->updateFrameStrut();
1235}
1236
1238{
1239 QObjectList children = parentWidget->children();
1240 for (int i = 0; i < children.size(); i++) {
1241 if (children.at(i)->isWidgetType()) {
1242 const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
1243 if (childWidget) { // should not be necessary
1244 if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
1245 if (!childWidget->internalWinId())
1246 childWidget->winId();
1247 if (childWidget->windowHandle()) {
1248 if (childWidget->isWindow()) {
1249 childWidget->windowHandle()->setTransientParent(parentWidget->window()->windowHandle());
1250 } else {
1251 childWidget->windowHandle()->setParent(childWidget->nativeParentWidget()->windowHandle());
1252 }
1253 }
1254 } else {
1256 }
1257 }
1258 }
1259 }
1260
1261}
1262
1263void QWidgetPrivate::create()
1264{
1265 Q_Q(QWidget);
1266
1267 if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
1268 return; // we only care about real toplevels
1269
1270 QWidgetWindow *win = topData()->window;
1271 // topData() ensures the extra is created but does not ensure 'window' is non-null
1272 // in case the extra was already valid.
1273 if (!win) {
1274 createTLSysExtra();
1275 Q_ASSERT(topData()->window);
1276 win = topData()->window;
1277 }
1278
1279 const auto dynamicPropertyNames = q->dynamicPropertyNames();
1280 for (const QByteArray &propertyName : dynamicPropertyNames) {
1281 if (!qstrncmp(propertyName, "_q_platform_", 12))
1282 win->setProperty(propertyName, q->property(propertyName));
1283 }
1284
1285 Qt::WindowFlags &flags = data.window_flags;
1286
1287#if defined(QT_PLATFORM_UIKIT)
1288 if (q->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea))
1289 flags |= Qt::ExpandedClientAreaHint;
1290#endif
1291
1292 if (q->testAttribute(Qt::WA_ShowWithoutActivating))
1293 win->setProperty("_q_showWithoutActivating", QVariant(true));
1294 if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
1295 win->setProperty("_q_macAlwaysShowToolWindow", QVariant(true));
1296 win->setFlags(flags);
1297 fixPosIncludesFrame();
1298 if (q->testAttribute(Qt::WA_Moved)
1299 || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
1300 win->setGeometry(q->geometry());
1301 else
1302 win->resize(q->size());
1303 if (win->isTopLevel()) {
1304 QScreen *targetScreen = topData()->initialScreen;
1305 topData()->initialScreen = nullptr;
1306 if (!targetScreen) {
1307 targetScreen = q->windowType() != Qt::Desktop
1308 ? q->screen() : nullptr;
1309 }
1310 win->setScreen(targetScreen);
1311 }
1312
1313 QSurfaceFormat format = win->requestedFormat();
1314 if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface
1315 && q->testAttribute(Qt::WA_TranslucentBackground)) {
1316 format.setAlphaBufferSize(8);
1317 }
1318 win->setFormat(format);
1319
1320 if (QWidget *nativeParent = q->nativeParentWidget()) {
1321 if (nativeParent->windowHandle()) {
1322 if (flags & Qt::Window) {
1323 win->setTransientParent(nativeParent->window()->windowHandle());
1324 win->setParent(nullptr);
1325 } else {
1326 win->setTransientParent(nullptr);
1327 win->setParent(nativeParent->windowHandle());
1328 }
1329 }
1330 }
1331
1332 qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
1333 QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
1334
1335 if (q->windowType() != Qt::Desktop || q->testAttribute(Qt::WA_NativeWindow)) {
1336 win->create();
1337 // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing.
1338 if (QPlatformWindow *platformWindow = win->handle())
1339 platformWindow->setFrameStrutEventsEnabled(true);
1340 }
1341
1342 data.window_flags = win->flags();
1343
1344#if QT_CONFIG(xcb)
1345 if (!topData()->role.isNull()) {
1346 if (auto *xcbWindow = dynamic_cast<QXcbWindow*>(win->handle()))
1347 xcbWindow->setWindowRole(topData()->role);
1348 }
1349#endif
1350
1351 QBackingStore *store = q->backingStore();
1352 usesRhiFlush = false;
1353
1354 if (q->windowType() == Qt::Desktop) {
1355 q->setAttribute(Qt::WA_PaintOnScreen, true);
1356 } else {
1357 if (!store && q->isWindow())
1358 q->setBackingStore(new QBackingStore(win));
1359
1360 QPlatformBackingStoreRhiConfig rhiConfig;
1361 usesRhiFlush = q_evaluateRhiConfig(q, &rhiConfig, nullptr);
1362 if (usesRhiFlush && q->backingStore()) {
1363 // Trigger creation of support infrastructure up front,
1364 // now that we have a specific RHI configuration.
1365 q->backingStore()->handle()->createRhi(win, rhiConfig);
1366 }
1367 }
1368
1369 setWindowModified_helper();
1370
1371 if (win->handle()) {
1372 WId id = win->winId();
1373 // See the QPlatformWindow::winId() documentation
1374 Q_ASSERT(id != WId(0));
1375 setWinId(id);
1376 }
1377 setNetWmWindowTypes(true); // do nothing if none of WA_X11NetWmWindowType* is set
1378
1379 // Check children and create windows for them if necessary
1380 q_createNativeChildrenAndSetParent(q);
1381
1382 if (extra && !extra->mask.isEmpty())
1383 setMask_sys(extra->mask);
1384
1385 if (data.crect.width() == 0 || data.crect.height() == 0) {
1386 q->setAttribute(Qt::WA_OutsideWSRange, true);
1387 } else {
1388 q->setAttribute(Qt::WA_OutsideWSRange, false);
1389 if (q->isVisible()) {
1390 // If widget is already shown, set window visible, too
1391 win->setNativeWindowVisibility(true);
1392 }
1393 }
1394}
1395
1396#ifdef Q_OS_WIN
1397static const char activeXNativeParentHandleProperty[] = "_q_embedded_native_parent_handle";
1398#endif
1399
1400void QWidgetPrivate::createTLSysExtra()
1401{
1402 Q_Q(QWidget);
1403 if (!extra->topextra->window && (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())) {
1404 extra->topextra->window = new QWidgetWindow(q);
1405 if (extra->minw || extra->minh)
1406 extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh));
1407 if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX)
1408 extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
1409 if (extra->topextra->opacity != 255 && q->isWindow())
1410 extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255));
1411
1412 const bool isTipLabel = q->inherits("QTipLabel");
1413 const bool isAlphaWidget = !isTipLabel && q->inherits("QAlphaWidget");
1414#ifdef Q_OS_WIN
1415 // Pass on native parent handle for Widget embedded into Active X.
1416 const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty);
1417 if (activeXNativeParentHandle.isValid())
1418 extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle);
1419 if (isTipLabel || isAlphaWidget)
1420 extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true));
1421#endif
1422 if (isTipLabel || isAlphaWidget || q->inherits("QRollEffect"))
1423 qt_window_private(extra->topextra->window)->setAutomaticPositionAndResizeEnabled(false);
1424
1425 updateIsTranslucent();
1426 }
1427
1428}
1429
1430/*!
1431 Destroys the widget.
1432
1433 All this widget's children are deleted first. The application
1434 exits if this widget is the main widget.
1435*/
1436
1437QWidget::~QWidget()
1438{
1439 Q_D(QWidget);
1440 d->data.in_destructor = true;
1441
1442#if defined (QT_CHECK_STATE)
1443 if (Q_UNLIKELY(paintingActive()))
1444 qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
1445#endif
1446
1447#ifndef QT_NO_GESTURES
1448 if (QGestureManager *manager = QGestureManager::instance(QGestureManager::DontForceCreation)) {
1449 // \forall Qt::GestureType type : ungrabGesture(type) (inlined)
1450 for (auto it = d->gestureContext.keyBegin(), end = d->gestureContext.keyEnd(); it != end; ++it)
1451 manager->cleanupCachedGestures(this, *it);
1452 }
1453 d->gestureContext.clear();
1454#endif
1455
1456#ifndef QT_NO_ACTION
1457 // remove all actions from this widget
1458 for (auto action : std::as_const(d->actions)) {
1459 QActionPrivate *apriv = action->d_func();
1460 apriv->associatedObjects.removeAll(this);
1461 }
1462 d->actions.clear();
1463#endif
1464
1465#ifndef QT_NO_SHORTCUT
1466 // Remove all shortcuts grabbed by this
1467 // widget, unless application is closing
1468 if (!QApplicationPrivate::is_app_closing && testAttribute(Qt::WA_GrabbedShortcut))
1469 QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(0, this, QKeySequence());
1470#endif
1471
1472 // delete layout while we still are a valid widget
1473 delete d->layout;
1474 d->layout = nullptr;
1475
1476 // Remove this from focus list
1477 d->removeFromFocusChain(QWidgetPrivate::FocusChainRemovalRule::AssertConsistency);
1478
1479 QT_TRY {
1480#if QT_CONFIG(graphicsview)
1481 const QWidget* w = this;
1482 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
1483 w = w->d_func()->extra->focus_proxy;
1484 QWidget *window = w->window();
1485 QWExtra *e = window ? window->d_func()->extra.get() : nullptr ;
1486 if (!e || !e->proxyWidget || (w->parentWidget() && w->parentWidget()->d_func()->focus_child == this))
1487#endif
1488 clearFocus();
1489 } QT_CATCH(...) {
1490 // swallow this problem because we are in a destructor
1491 }
1492
1493 d->setDirtyOpaqueRegion();
1494
1495 if (isWindow() && isVisible() && internalWinId()) {
1496 QT_TRY {
1497 d->close();
1498 } QT_CATCH(...) {
1499 // if we're out of memory, at least hide the window.
1500 QT_TRY {
1501 hide();
1502 } QT_CATCH(...) {
1503 // and if that also doesn't work, then give up
1504 }
1505 }
1506 } else if (isVisible()) {
1507 qApp->d_func()->sendSyntheticEnterLeave(this);
1508 }
1509
1510 if (QWidgetRepaintManager *repaintManager = d->maybeRepaintManager()) {
1511 repaintManager->removeDirtyWidget(this);
1512 if (testAttribute(Qt::WA_StaticContents))
1513 repaintManager->removeStaticWidget(this);
1514 }
1515
1516 delete d->needsFlush;
1517 d->needsFlush = nullptr;
1518
1519 // The next 20 lines are duplicated from QObject, but required here
1520 // since QWidget deletes is children itself
1521 bool blocked = d->blockSig;
1522 d->blockSig = 0; // unblock signals so we always emit destroyed()
1523
1524 if (d->isSignalConnected(0)) {
1525 QT_TRY {
1526 emit destroyed(this);
1527 } QT_CATCH(...) {
1528 // all the signal/slots connections are still in place - if we don't
1529 // quit now, we will crash pretty soon.
1530 qWarning("Detected an unexpected exception in ~QWidget while emitting destroyed().");
1531 QT_RETHROW;
1532 }
1533 }
1534
1535 if (d->declarativeData) {
1536 d->wasDeleted = true; // needed, so that destroying the declarative data does the right thing
1537 if (QAbstractDeclarativeData::destroyed)
1538 QAbstractDeclarativeData::destroyed(d->declarativeData, this);
1539 d->declarativeData = nullptr; // don't activate again in ~QObject
1540 d->wasDeleted = false;
1541 }
1542
1543 d->blockSig = blocked;
1544
1545 if (!d->children.isEmpty())
1546 d->deleteChildren();
1547
1548 QCoreApplication::removePostedEvents(this);
1549
1550 QT_TRY {
1551 destroy(); // platform-dependent cleanup
1552 } QT_CATCH(...) {
1553 // if this fails we can't do anything about it but at least we are not allowed to throw.
1554 }
1555 --QWidgetPrivate::instanceCounter;
1556
1557 if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
1558 QWidgetPrivate::allWidgets->remove(this);
1559
1560 QT_TRY {
1561 QEvent e(QEvent::Destroy);
1562 QCoreApplication::sendEvent(this, &e);
1563 } QT_CATCH(const std::exception&) {
1564 // if this fails we can't do anything about it but at least we are not allowed to throw.
1565 }
1566
1567#if QT_CONFIG(graphicseffect)
1568 delete d->graphicsEffect;
1569#endif
1570 d->deleteExtra();
1571
1572 d->isWidget = false;
1573}
1574
1575int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances
1576int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances
1577
1578void QWidgetPrivate::setWinId(WId id) // set widget identifier
1579{
1580 Q_Q(QWidget);
1581 if (mapper && data.winid) {
1582 mapper->remove(data.winid);
1583 }
1584
1585 const WId oldWinId = data.winid;
1586
1587 data.winid = id;
1588 if (mapper && id) {
1589 mapper->insert(data.winid, q);
1590 }
1591
1592 if (oldWinId != id) {
1593 QEvent e(QEvent::WinIdChange);
1594 QCoreApplication::sendEvent(q, &e);
1595 }
1596}
1597
1598void QWidgetPrivate::createTLExtra()
1599{
1600 if (!extra)
1601 createExtra();
1602 if (!extra->topextra) {
1603 extra->topextra = std::make_unique<QTLWExtra>();
1604 QTLWExtra* x = extra->topextra.get();
1605 x->backingStore = nullptr;
1606 x->sharedPainter = nullptr;
1607 x->incw = x->inch = 0;
1608 x->basew = x->baseh = 0;
1609 x->frameStrut.setCoords(0, 0, 0, 0);
1610 x->normalGeometry = QRect(0,0,-1,-1);
1611 x->savedFlags = { };
1612 x->opacity = 255;
1613 x->posIncludesFrame = 0;
1614 x->sizeAdjusted = false;
1615 x->embedded = 0;
1616 x->window = nullptr;
1617 x->initialScreen = nullptr;
1618
1619#ifdef QWIDGET_EXTRA_DEBUG
1620 static int count = 0;
1621 qDebug() << "tlextra" << ++count;
1622#endif
1623 }
1624}
1625
1626/*!
1627 \internal
1628 Creates the widget extra data.
1629*/
1630
1631void QWidgetPrivate::createExtra()
1632{
1633 if (!extra) { // if not exists
1634 extra = std::make_unique<QWExtra>();
1635 extra->glContext = nullptr;
1636#if QT_CONFIG(graphicsview)
1637 extra->proxyWidget = nullptr;
1638#endif
1639 extra->minw = 0;
1640 extra->minh = 0;
1641 extra->maxw = QWIDGETSIZE_MAX;
1642 extra->maxh = QWIDGETSIZE_MAX;
1643 extra->customDpiX = 0;
1644 extra->customDpiY = 0;
1645 extra->explicitMinSize = 0;
1646 extra->explicitMaxSize = 0;
1647 extra->autoFillBackground = 0;
1648 extra->nativeChildrenForced = 0;
1649 extra->inRenderWithPainter = 0;
1650 extra->hasWindowContainer = false;
1651 extra->hasMask = 0;
1652 createSysExtra();
1653#ifdef QWIDGET_EXTRA_DEBUG
1654 static int count = 0;
1655 qDebug() << "extra" << ++count;
1656#endif
1657 }
1658}
1659
1660void QWidgetPrivate::createSysExtra()
1661{
1662}
1663
1664/*!
1665 \internal
1666 Deletes the widget extra data.
1667*/
1668
1669void QWidgetPrivate::deleteExtra()
1670{
1671 if (extra) { // if exists
1672 deleteSysExtra();
1673#ifndef QT_NO_STYLE_STYLESHEET
1674 // dereference the stylesheet style
1675 if (QStyleSheetStyle *proxy = qt_styleSheet(extra->style))
1676 proxy->deref();
1677#endif
1678 if (extra->topextra)
1679 deleteTLSysExtra();
1680
1681 // extra->xic destroyed in QWidget::destroy()
1682 extra.reset();
1683 }
1684}
1685
1686void QWidgetPrivate::deleteSysExtra()
1687{
1688}
1689
1690void QWidgetPrivate::deleteTLSysExtra()
1691{
1692 Q_Q(QWidget);
1693 if (extra && extra->topextra) {
1694 if (extra->hasWindowContainer)
1695 QWindowContainer::toplevelAboutToBeDestroyed(q);
1696
1697 delete extra->topextra->window;
1698 extra->topextra->window = nullptr;
1699 }
1700}
1701
1702/*
1703 Returns \c region of widgets above this which overlap with
1704 \a rect, which is in parent's coordinate system (same as crect).
1705*/
1706
1707QRegion QWidgetPrivate::overlappedRegion(const QRect &rect, bool breakAfterFirst) const
1708{
1709 Q_Q(const QWidget);
1710
1711 const QWidget *w = q;
1712 QRect r = rect;
1713 QPoint p;
1714 QRegion region;
1715 while (w) {
1716 if (w->isWindow())
1717 break;
1718 QWidgetPrivate *pd = w->parentWidget()->d_func();
1719 bool above = false;
1720 for (int i = 0; i < pd->children.size(); ++i) {
1721 QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
1722 if (!sibling || !sibling->isVisible() || sibling->isWindow())
1723 continue;
1724 if (!above) {
1725 above = (sibling == w);
1726 continue;
1727 }
1728
1729 const QRect siblingRect = sibling->d_func()->effectiveRectFor(sibling->data->crect);
1730 if (qRectIntersects(siblingRect, r)) {
1731 const auto &siblingExtra = sibling->d_func()->extra;
1732 if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
1733 && !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
1734 continue;
1735 }
1736 region += siblingRect.translated(-p);
1737 if (breakAfterFirst)
1738 break;
1739 }
1740 }
1741 w = w->parentWidget();
1742 r.translate(pd->data.crect.topLeft());
1743 p += pd->data.crect.topLeft();
1744 }
1745 return region;
1746}
1747
1748void QWidgetPrivate::syncBackingStore()
1749{
1750 if (shouldPaintOnScreen()) {
1751 paintOnScreen(dirty);
1752 dirty = QRegion();
1753 } else if (QWidgetRepaintManager *repaintManager = maybeRepaintManager()) {
1754 repaintManager->sync();
1755 }
1756}
1757
1758void QWidgetPrivate::syncBackingStore(const QRegion &region)
1759{
1760 if (shouldPaintOnScreen())
1761 paintOnScreen(region);
1762 else if (QWidgetRepaintManager *repaintManager = maybeRepaintManager()) {
1763 repaintManager->sync(q_func(), region);
1764 }
1765}
1766
1767void QWidgetPrivate::paintOnScreen(const QRegion &rgn)
1768{
1769 if (data.in_destructor)
1770 return;
1771
1772 if (shouldDiscardSyncRequest())
1773 return;
1774
1775 Q_Q(QWidget);
1776 if (q->testAttribute(Qt::WA_StaticContents)) {
1777 if (!extra)
1778 createExtra();
1779 extra->staticContentsSize = data.crect.size();
1780 }
1781
1782 QPaintEngine *engine = q->paintEngine();
1783
1784 // QGLWidget does not support partial updates if:
1785 // 1) The context is double buffered
1786 // 2) The context is single buffered and auto-fill background is enabled.
1787 const bool noPartialUpdateSupport = (engine && (engine->type() == QPaintEngine::OpenGL
1788 || engine->type() == QPaintEngine::OpenGL2))
1789 && (usesDoubleBufferedGLContext || q->autoFillBackground());
1790 QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn);
1791
1792 toBePainted &= clipRect();
1793 clipToEffectiveMask(toBePainted);
1794 if (toBePainted.isEmpty())
1795 return; // Nothing to repaint.
1796
1797 drawWidget(q, toBePainted, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen, nullptr);
1798
1799 if (Q_UNLIKELY(q->paintingActive()))
1800 qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
1801}
1802
1803void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
1804{
1805 Q_Q(QWidget);
1806
1807 if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled())
1808 return; // nothing we can do
1809
1810 if (enable != q->testAttribute(Qt::WA_UpdatesDisabled))
1811 return; // nothing to do
1812
1813 q->setAttribute(Qt::WA_UpdatesDisabled, !enable);
1814 if (enable)
1815 q->update();
1816
1817 Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
1818 for (int i = 0; i < children.size(); ++i) {
1819 QWidget *w = qobject_cast<QWidget *>(children.at(i));
1820 if (w && !w->isWindow() && !w->testAttribute(attribute))
1821 w->d_func()->setUpdatesEnabled_helper(enable);
1822 }
1823}
1824
1825/*!
1826 \internal
1827
1828 Propagate this widget's palette to all children, except style sheet
1829 widgets, and windows that don't enable window propagation (palettes don't
1830 normally propagate to windows).
1831*/
1832void QWidgetPrivate::propagatePaletteChange()
1833{
1834 Q_Q(QWidget);
1835 // Propagate a new inherited mask to all children.
1836#if QT_CONFIG(graphicsview)
1837 if (!q->parentWidget() && extra && extra->proxyWidget) {
1838 QGraphicsProxyWidget *p = extra->proxyWidget;
1839 inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolveMask();
1840 } else
1841#endif // QT_CONFIG(graphicsview)
1842 if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
1843 inheritedPaletteResolveMask = 0;
1844 }
1845
1846 directPaletteResolveMask = data.pal.resolveMask();
1847 auto mask = directPaletteResolveMask | inheritedPaletteResolveMask;
1848
1849 const bool useStyleSheetPropagationInWidgetStyles =
1850 QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
1851
1852 QEvent pc(QEvent::PaletteChange);
1853 QCoreApplication::sendEvent(q, &pc);
1854 for (int i = 0; i < children.size(); ++i) {
1855 QWidget *w = qobject_cast<QWidget*>(children.at(i));
1856 if (w && (!w->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
1857 && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
1858 QWidgetPrivate *wd = w->d_func();
1859 wd->inheritedPaletteResolveMask = mask;
1860 wd->resolvePalette();
1861 }
1862 }
1863}
1864
1865/*
1866 Returns the widget's clipping rectangle.
1867*/
1868QRect QWidgetPrivate::clipRect() const
1869{
1870 Q_Q(const QWidget);
1871 const QWidget * w = q;
1872 if (!w->isVisible())
1873 return QRect();
1874 QRect r = effectiveRectFor(q->rect());
1875 int ox = 0;
1876 int oy = 0;
1877 while (w
1878 && w->isVisible()
1879 && !w->isWindow()
1880 && w->parentWidget()) {
1881 ox -= w->x();
1882 oy -= w->y();
1883 w = w->parentWidget();
1884 r &= QRect(ox, oy, w->width(), w->height());
1885 }
1886 return r;
1887}
1888
1889/*
1890 Returns the widget's clipping region (without siblings).
1891*/
1892QRegion QWidgetPrivate::clipRegion() const
1893{
1894 Q_Q(const QWidget);
1895 if (!q->isVisible())
1896 return QRegion();
1897 QRegion r(q->rect());
1898 const QWidget * w = q;
1899 const QWidget *ignoreUpTo;
1900 int ox = 0;
1901 int oy = 0;
1902 while (w
1903 && w->isVisible()
1904 && !w->isWindow()
1905 && w->parentWidget()) {
1906 ox -= w->x();
1907 oy -= w->y();
1908 ignoreUpTo = w;
1909 w = w->parentWidget();
1910 r &= QRegion(ox, oy, w->width(), w->height());
1911
1912 int i = 0;
1913 while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo))
1914 ;
1915 for ( ; i < w->d_func()->children.size(); ++i) {
1916 if (QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) {
1917 if (sibling->isVisible() && !sibling->isWindow()) {
1918 QRect siblingRect(ox+sibling->x(), oy+sibling->y(),
1919 sibling->width(), sibling->height());
1920 if (qRectIntersects(siblingRect, q->rect()))
1921 r -= QRegion(siblingRect);
1922 }
1923 }
1924 }
1925 }
1926 return r;
1927}
1928
1929void QWidgetPrivate::setSystemClip(QPaintEngine *paintEngine, qreal devicePixelRatio, const QRegion &region)
1930{
1931// Transform the system clip region from device-independent pixels to device pixels
1932 QTransform scaleTransform;
1933 scaleTransform.scale(devicePixelRatio, devicePixelRatio);
1934
1935 paintEngine->d_func()->baseSystemClip = region;
1936 paintEngine->d_func()->setSystemTransform(scaleTransform);
1937
1938}
1939
1940#if QT_CONFIG(graphicseffect)
1941void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
1942{
1943 Q_Q(QWidget);
1944 QWidget *w = q;
1945 do {
1946 if (w->graphicsEffect()) {
1947 QWidgetEffectSourcePrivate *sourced =
1948 static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
1949 if (!sourced->updateDueToGraphicsEffect)
1950 w->graphicsEffect()->source()->d_func()->invalidateCache();
1951 }
1952 w = w->parentWidget();
1953 } while (w);
1954}
1955#endif // QT_CONFIG(graphicseffect)
1956
1957void QWidgetPrivate::setDirtyOpaqueRegion()
1958{
1959 Q_Q(QWidget);
1960
1961 dirtyOpaqueChildren = true;
1962
1963#if QT_CONFIG(graphicseffect)
1964 invalidateGraphicsEffectsRecursively();
1965#endif // QT_CONFIG(graphicseffect)
1966
1967 if (q->isWindow())
1968 return;
1969
1970 QWidget *parent = q->parentWidget();
1971 if (!parent)
1972 return;
1973
1974 // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly?
1975 QWidgetPrivate *pd = parent->d_func();
1976 if (!pd->dirtyOpaqueChildren)
1977 pd->setDirtyOpaqueRegion();
1978}
1979
1980const QRegion &QWidgetPrivate::getOpaqueChildren() const
1981{
1982 if (!dirtyOpaqueChildren)
1983 return opaqueChildren;
1984
1985 QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
1986 that->opaqueChildren = QRegion();
1987
1988 for (int i = 0; i < children.size(); ++i) {
1989 QWidget *child = qobject_cast<QWidget *>(children.at(i));
1990 if (!child || !child->isVisible() || child->isWindow())
1991 continue;
1992
1993 const QPoint offset = child->geometry().topLeft();
1994 QWidgetPrivate *childd = child->d_func();
1995 QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren();
1996 if (childd->extra && childd->extra->hasMask)
1997 r &= childd->extra->mask;
1998 if (r.isEmpty())
1999 continue;
2000 r.translate(offset);
2001 that->opaqueChildren += r;
2002 }
2003
2004 that->opaqueChildren &= q_func()->rect();
2005 that->dirtyOpaqueChildren = false;
2006
2007 return that->opaqueChildren;
2008}
2009
2010void QWidgetPrivate::subtractOpaqueChildren(QRegion &source, const QRect &clipRect) const
2011{
2012 if (children.isEmpty() || clipRect.isEmpty())
2013 return;
2014
2015 const QRegion &r = getOpaqueChildren();
2016 if (!r.isEmpty())
2017 source -= (r & clipRect);
2018}
2019
2020//subtract any relatives that are higher up than me --- this is too expensive !!!
2021void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirtySiblingsAbove,
2022 bool alsoNonOpaque) const
2023{
2024 Q_Q(const QWidget);
2025 static int disableSubtractOpaqueSiblings = qEnvironmentVariableIntValue("QT_NO_SUBTRACTOPAQUESIBLINGS");
2026 if (disableSubtractOpaqueSiblings || q->isWindow())
2027 return;
2028
2029 QRect clipBoundingRect;
2030 bool dirtyClipBoundingRect = true;
2031
2032 QRegion parentClip;
2033 bool dirtyParentClip = true;
2034
2035 QPoint parentOffset = data.crect.topLeft();
2036
2037 const QWidget *w = q;
2038
2039 while (w) {
2040 if (w->isWindow())
2041 break;
2042 QWidgetPrivate *pd = w->parentWidget()->d_func();
2043 const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
2044 const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
2045 for (int i = myIndex + 1; i < pd->children.size(); ++i) {
2046 QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
2047 if (!sibling || !sibling->isVisible() || sibling->isWindow())
2048 continue;
2049
2050 const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
2051 if (!qRectIntersects(siblingGeometry, widgetGeometry))
2052 continue;
2053
2054 if (dirtyClipBoundingRect) {
2055 clipBoundingRect = sourceRegion.boundingRect();
2056 dirtyClipBoundingRect = false;
2057 }
2058
2059 if (!qRectIntersects(siblingGeometry, clipBoundingRect.translated(parentOffset)))
2060 continue;
2061
2062 if (dirtyParentClip) {
2063 parentClip = sourceRegion.translated(parentOffset);
2064 dirtyParentClip = false;
2065 }
2066
2067 const QPoint siblingPos(sibling->data->crect.topLeft());
2068 const QRect siblingClipRect(sibling->d_func()->clipRect());
2069 QRegion siblingDirty(parentClip);
2070 siblingDirty &= (siblingClipRect.translated(siblingPos));
2071 const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
2072 && !sibling->d_func()->graphicsEffect;
2073 if (hasMask)
2074 siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
2075 if (siblingDirty.isEmpty())
2076 continue;
2077
2078 if (sibling->d_func()->isOpaque || alsoNonOpaque) {
2079 if (hasMask) {
2080 siblingDirty.translate(-parentOffset);
2081 sourceRegion -= siblingDirty;
2082 } else {
2083 sourceRegion -= siblingGeometry.translated(-parentOffset);
2084 }
2085 } else {
2086 if (hasDirtySiblingsAbove)
2087 *hasDirtySiblingsAbove = true;
2088 if (sibling->d_func()->children.isEmpty())
2089 continue;
2090 QRegion opaqueSiblingChildren(sibling->d_func()->getOpaqueChildren());
2091 opaqueSiblingChildren.translate(-parentOffset + siblingPos);
2092 sourceRegion -= opaqueSiblingChildren;
2093 }
2094 if (sourceRegion.isEmpty())
2095 return;
2096
2097 dirtyClipBoundingRect = true;
2098 dirtyParentClip = true;
2099 }
2100
2101 w = w->parentWidget();
2102 parentOffset += pd->data.crect.topLeft();
2103 dirtyParentClip = true;
2104 }
2105}
2106
2107void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
2108{
2109 Q_Q(const QWidget);
2110
2111 const QWidget *w = q;
2112 QPoint offset;
2113
2114#if QT_CONFIG(graphicseffect)
2115 if (graphicsEffect && !w->isWindow()) {
2116 w = q->parentWidget();
2117 offset -= data.crect.topLeft();
2118 }
2119#endif // QT_CONFIG(graphicseffect)
2120
2121 while (w) {
2122 const QWidgetPrivate *wd = w->d_func();
2123 if (wd->extra && wd->extra->hasMask)
2124 region &= (w != q) ? wd->extra->mask.translated(offset) : wd->extra->mask;
2125 if (w->isWindow())
2126 return;
2127 offset -= wd->data.crect.topLeft();
2128 w = w->parentWidget();
2129 }
2130}
2131
2132bool QWidgetPrivate::shouldPaintOnScreen() const
2133{
2134#if defined(QT_NO_BACKINGSTORE)
2135 return true;
2136#else
2137 Q_Q(const QWidget);
2138 if (q->testAttribute(Qt::WA_PaintOnScreen)
2139 || (!q->isWindow() && q->window()->testAttribute(Qt::WA_PaintOnScreen))) {
2140 return true;
2141 }
2142
2143 return false;
2144#endif
2145}
2146
2147void QWidgetPrivate::updateIsOpaque()
2148{
2149 // hw: todo: only needed if opacity actually changed
2150 setDirtyOpaqueRegion();
2151
2152#if QT_CONFIG(graphicseffect)
2153 if (graphicsEffect) {
2154 // ### We should probably add QGraphicsEffect::isOpaque at some point.
2155 setOpaque(false);
2156 return;
2157 }
2158#endif // QT_CONFIG(graphicseffect)
2159
2160 Q_Q(QWidget);
2161 if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
2162 setOpaque(true);
2163 return;
2164 }
2165
2166 const QPalette &pal = q->palette();
2167
2168 if (q->autoFillBackground()) {
2169 const QBrush &autoFillBrush = pal.brush(q->backgroundRole());
2170 if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
2171 setOpaque(true);
2172 return;
2173 }
2174 }
2175
2176 if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) {
2177 const QBrush &windowBrush = q->palette().brush(QPalette::Window);
2178 if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
2179 setOpaque(true);
2180 return;
2181 }
2182 }
2183 setOpaque(false);
2184}
2185
2186void QWidgetPrivate::setOpaque(bool opaque)
2187{
2188 if (isOpaque != opaque) {
2189 isOpaque = opaque;
2190 updateIsTranslucent();
2191 }
2192}
2193
2194void QWidgetPrivate::updateIsTranslucent()
2195{
2196 Q_Q(QWidget);
2197 if (QWindow *window = q->windowHandle()) {
2198 QSurfaceFormat format = window->format();
2199 const int oldAlpha = format.alphaBufferSize();
2200 const int newAlpha = q->testAttribute(Qt::WA_TranslucentBackground) ? 8 : -1;
2201 if (oldAlpha != newAlpha) {
2202 // QTBUG-85714: Do this only when the QWindow has not yet been create()'ed yet.
2203 //
2204 // If that is not the case, then the setFormat() is not just futile
2205 // but downright dangerous. Futile because the format matters only
2206 // when creating the native window, no point in changing it
2207 // afterwards. Dangerous because a QOpenGLContext or something else
2208 // may eventually query the QWindow's format(), in order to ensure
2209 // compatibility (in terms of native concepts such as pixel format,
2210 // EGLConfig, etc.), and if we change it here, then the returned
2211 // format does not describe reality anymore. (reality being the
2212 // settings with which the native resource was created).
2213 //
2214 // Whereas if one does a destroy()-create() then this all here
2215 // won't matter because the format is updated in
2216 // QWidgetPrivate::create() again.
2217 //
2218 if (!window->handle()) {
2219 format.setAlphaBufferSize(newAlpha);
2220 window->setFormat(format);
2221 }
2222 }
2223 }
2224}
2225
2226static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
2227{
2228 Q_ASSERT(painter);
2229
2230 if (brush.style() == Qt::TexturePattern) {
2231 const QRect rect(rgn.boundingRect());
2232 painter->setClipRegion(rgn);
2233 painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
2234 } else if (brush.gradient()
2235 && (brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode
2236 || brush.gradient()->coordinateMode() == QGradient::ObjectMode)) {
2237 painter->save();
2238 painter->setClipRegion(rgn);
2239 painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
2240 painter->restore();
2241 } else {
2242 for (const QRect &rect : rgn)
2243 painter->fillRect(rect, brush);
2244 }
2245}
2246
2247bool QWidgetPrivate::updateBrushOrigin(QPainter *painter, const QBrush &brush) const
2248{
2249#if QT_CONFIG(scrollarea)
2250 Q_Q(const QWidget);
2251 //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
2252 if (brush.style() == Qt::NoBrush || brush.style() == Qt::SolidPattern)
2253 return false;
2254 QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
2255 if (scrollArea && scrollArea->viewport() == q) {
2256 QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
2257 QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
2258 painter->setBrushOrigin(-priv->contentsOffset());
2259 }
2260#endif // QT_CONFIG(scrollarea)
2261 return true;
2262}
2263
2264void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, DrawWidgetFlags flags) const
2265{
2266 Q_Q(const QWidget);
2267
2268 bool brushOriginSet = false;
2269 const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
2270
2271 if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
2272 const QBrush bg = q->palette().brush(QPalette::Window);
2273 if (!brushOriginSet)
2274 brushOriginSet = updateBrushOrigin(painter, bg);
2275 if (!(flags & DontSetCompositionMode)) {
2276 //copy alpha straight in
2277 QPainter::CompositionMode oldMode = painter->compositionMode();
2278 painter->setCompositionMode(QPainter::CompositionMode_Source);
2279 fillRegion(painter, rgn, bg);
2280 painter->setCompositionMode(oldMode);
2281 } else {
2282 fillRegion(painter, rgn, bg);
2283 }
2284 }
2285
2286 if (q->autoFillBackground()) {
2287 if (!brushOriginSet)
2288 brushOriginSet = updateBrushOrigin(painter, autoFillBrush);
2289 fillRegion(painter, rgn, autoFillBrush);
2290 }
2291
2292 if (q->testAttribute(Qt::WA_StyledBackground)) {
2293 painter->setClipRegion(rgn);
2294 QStyleOption opt;
2295 opt.initFrom(q);
2296 q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
2297 }
2298}
2299
2300/*
2301 \internal
2302 This function is called when a widget is hidden or destroyed.
2303 It resets some application global pointers that should only refer active,
2304 visible widgets.
2305*/
2306
2308
2309void QWidgetPrivate::deactivateWidgetCleanup()
2310{
2311 Q_Q(QWidget);
2312 // If this was the active application window, reset it
2313 if (QApplication::activeWindow() == q)
2314 QApplicationPrivate::setActiveWindow(nullptr);
2315 // If the is the active mouse press widget, reset it
2316 if (q == qt_button_down)
2317 qt_button_down = nullptr;
2318}
2319
2320
2321/*!
2322 Returns a pointer to the widget with window identifier/handle \a
2323 id.
2324
2325 The window identifier type depends on the underlying window
2326 system, see \c qwindowdefs.h for the actual definition. If there
2327 is no widget with this identifier, \nullptr is returned.
2328*/
2329
2330QWidget *QWidget::find(WId id)
2331{
2332 return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : nullptr;
2333}
2334
2335
2336
2337/*!
2338 \fn WId QWidget::internalWinId() const
2339 \internal
2340 Returns the window system identifier of the widget, or 0 if the widget is not created yet.
2341
2342*/
2343
2344/*!
2345 \fn WId QWidget::winId() const
2346
2347 Returns the window system identifier of the widget.
2348
2349 Portable in principle, but if you use it you are probably about to
2350 do something non-portable. Be careful.
2351
2352 If a widget is non-native (alien) and winId() is invoked on it, that widget
2353 will be provided a native handle.
2354
2355 This value may change at run-time. An event with type QEvent::WinIdChange
2356 will be sent to the widget following a change in window system identifier.
2357
2358 \sa find()
2359*/
2360WId QWidget::winId() const
2361{
2362 if (!data->in_destructor
2363 && (!testAttribute(Qt::WA_WState_Created) || !internalWinId()))
2364 {
2365 QWidget *that = const_cast<QWidget*>(this);
2366 that->setAttribute(Qt::WA_NativeWindow);
2367 that->d_func()->createWinId();
2368 return that->data->winid;
2369 }
2370 return data->winid;
2371}
2372
2373void QWidgetPrivate::createWinId()
2374{
2375 Q_Q(QWidget);
2376
2377 const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow);
2378 if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
2379 if (!q->isWindow()) {
2380 QWidget *parent = q->parentWidget();
2381 QWidgetPrivate *pd = parent->d_func();
2382 if (forceNativeWindow && !q->testAttribute(Qt::WA_DontCreateNativeAncestors))
2383 parent->setAttribute(Qt::WA_NativeWindow);
2384 if (!parent->internalWinId()) {
2385 pd->createWinId();
2386 }
2387
2388 for (int i = 0; i < pd->children.size(); ++i) {
2389 QWidget *w = qobject_cast<QWidget *>(pd->children.at(i));
2390 if (w && !w->isWindow() && (!w->testAttribute(Qt::WA_WState_Created)
2391 || (!w->internalWinId() && w->testAttribute(Qt::WA_NativeWindow)))) {
2392 w->create();
2393 }
2394 }
2395 } else {
2396 q->create();
2397 }
2398 }
2399}
2400
2401/*!
2402\internal
2403Ensures that the widget is set on the screen point is on. This is handy getting a correct
2404size hint before a resize in e.g QMenu and QToolTip.
2405Returns if the screen was changed.
2406*/
2407
2408bool QWidgetPrivate::setScreenForPoint(const QPoint &pos)
2409{
2410 Q_Q(QWidget);
2411 if (!q->isWindow())
2412 return false;
2413 // Find the screen for pos and make the widget understand it is on that screen.
2414 return setScreen(QGuiApplication::screenAt(pos));
2415}
2416
2417/*!
2418\internal
2419Ensures that the widget's QWindow is set to be on the given \a screen.
2420Returns true if the screen was changed.
2421*/
2422
2423bool QWidgetPrivate::setScreen(QScreen *screen)
2424{
2425 Q_Q(QWidget);
2426 if (!screen || !q->isWindow())
2427 return false;
2428 const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
2429 if (currentScreen != screen) {
2430 topData()->initialScreen = screen;
2431 if (windowHandle())
2432 windowHandle()->setScreen(screen);
2433 return true;
2434 }
2435 return false;
2436}
2437
2438/*!
2439\internal
2440Ensures that the widget has a window system identifier, i.e. that it is known to the windowing system.
2441
2442*/
2443
2444void QWidget::createWinId()
2445{
2446 Q_D(QWidget);
2447 d->createWinId();
2448}
2449
2450/*!
2451 \since 4.4
2452
2453 Returns the effective window system identifier of the widget, i.e. the
2454 native parent's window system identifier.
2455
2456 If the widget is native, this function returns the native widget ID.
2457 Otherwise, the window ID of the first native parent widget, i.e., the
2458 top-level widget that contains this widget, is returned.
2459
2460 \note We recommend that you do not store this value as it is likely to
2461 change at run-time.
2462
2463 \sa nativeParentWidget()
2464*/
2465WId QWidget::effectiveWinId() const
2466{
2467 const WId id = internalWinId();
2468 if (id || !testAttribute(Qt::WA_WState_Created))
2469 return id;
2470 if (const QWidget *realParent = nativeParentWidget())
2471 return realParent->internalWinId();
2472 return 0;
2473}
2474
2475/*!
2476 If this is a native widget, return the associated QWindow.
2477 Otherwise return null.
2478
2479 Native widgets include toplevel widgets, QGLWidget, and child widgets
2480 on which winId() was called.
2481
2482 \since 5.0
2483
2484 \sa winId(), screen()
2485*/
2486QWindow *QWidget::windowHandle() const
2487{
2488 Q_D(const QWidget);
2489 return d->windowHandle();
2490}
2491
2492/*!
2493 Returns the screen the widget is on.
2494
2495 \since 5.14
2496
2497 \sa windowHandle()
2498*/
2499QScreen *QWidget::screen() const
2500{
2501 Q_D(const QWidget);
2502 if (auto associatedScreen = d->associatedScreen())
2503 return associatedScreen;
2504 if (auto topLevel = window()) {
2505 if (auto topData = qt_widget_private(topLevel)->topData()) {
2506 if (topData->initialScreen)
2507 return topData->initialScreen;
2508 }
2509 if (auto screenByPos = QGuiApplication::screenAt(topLevel->geometry().center()))
2510 return screenByPos;
2511 }
2512 return QGuiApplication::primaryScreen();
2513}
2514
2515/*!
2516 Sets the screen on which the widget should be shown to \a screen.
2517
2518 Setting the screen only makes sense for windows. If necessary, the widget's
2519 window will get recreated on \a screen.
2520
2521 \note If the screen is part of a virtual desktop of multiple screens,
2522 the window will not move automatically to \a screen. To place the
2523 window relative to the screen, use the screen's topLeft() position.
2524
2525 \sa QWindow::setScreen()
2526*/
2527void QWidget::setScreen(QScreen *screen)
2528{
2529 Q_D(QWidget);
2530 d->setScreen(screen);
2531}
2532
2533#ifndef QT_NO_STYLE_STYLESHEET
2534
2535/*!
2536 \property QWidget::styleSheet
2537 \brief the widget's style sheet
2538 \since 4.2
2539
2540 The style sheet contains a textual description of customizations to the
2541 widget's style, as described in the \l{Qt Style Sheets} document.
2542
2543 Since Qt 4.5, Qt style sheets fully supports \macos.
2544
2545 \warning Qt style sheets are currently not supported for custom QStyle
2546 subclasses. We plan to address this in some future release.
2547
2548 \sa setStyle(), QApplication::styleSheet, {Qt Style Sheets}
2549*/
2550QString QWidget::styleSheet() const
2551{
2552 Q_D(const QWidget);
2553 if (!d->extra)
2554 return QString();
2555 return d->extra->styleSheet;
2556}
2557
2558void QWidget::setStyleSheet(const QString& styleSheet)
2559{
2560 Q_D(QWidget);
2561 if (data->in_destructor)
2562 return;
2563 d->createExtra();
2564
2565 QStyleSheetStyle *proxy = qt_styleSheet(d->extra->style);
2566 d->extra->styleSheet = styleSheet;
2567 if (styleSheet.isEmpty()) { // stylesheet removed
2568 if (!proxy)
2569 return;
2570
2571 d->inheritStyle();
2572 return;
2573 }
2574
2575 if (proxy) { // style sheet update
2576 bool repolish = d->polished;
2577 if (!repolish) {
2578 const auto childWidgets = findChildren<QWidget*>();
2579 for (auto child : childWidgets) {
2580 repolish = child->d_func()->polished;
2581 if (repolish)
2582 break;
2583 }
2584 }
2585 if (repolish)
2586 proxy->repolish(this);
2587 return;
2588 }
2589
2590 if (testAttribute(Qt::WA_SetStyle)) {
2591 d->setStyle_helper(new QStyleSheetStyle(d->extra->style), true);
2592 } else {
2593 d->setStyle_helper(new QStyleSheetStyle(nullptr), true);
2594 }
2595}
2596
2597#endif // QT_NO_STYLE_STYLESHEET
2598
2599/*!
2600 \sa QWidget::setStyle(), QApplication::setStyle(), QApplication::style()
2601*/
2602
2603QStyle *QWidget::style() const
2604{
2605 Q_D(const QWidget);
2606
2607 if (d->extra && d->extra->style)
2608 return d->extra->style;
2609 return QApplication::style();
2610}
2611
2612/*!
2613 Sets the widget's GUI style to \a style. The ownership of the style
2614 object is not transferred.
2615
2616 If no style is set, the widget uses the application's style,
2617 QApplication::style() instead.
2618
2619 Setting a widget's style has no effect on existing or future child
2620 widgets.
2621
2622 \warning This function is particularly useful for demonstration
2623 purposes, where you want to show Qt's styling capabilities. Real
2624 applications should avoid it and use one consistent GUI style
2625 instead.
2626
2627 \warning Qt style sheets are currently not supported for custom QStyle
2628 subclasses. We plan to address this in some future release.
2629
2630 \sa style(), QStyle, QApplication::style(), QApplication::setStyle()
2631*/
2632
2633void QWidget::setStyle(QStyle *style)
2634{
2635 Q_D(QWidget);
2636 setAttribute(Qt::WA_SetStyle, style != nullptr);
2637 d->createExtra();
2638#ifndef QT_NO_STYLE_STYLESHEET
2639 if (QStyleSheetStyle *styleSheetStyle = qt_styleSheet(style)) {
2640 //if for some reason someone try to set a QStyleSheetStyle, ref it
2641 //(this may happen for example in QButtonDialogBox which propagates its style)
2642 styleSheetStyle->ref();
2643 d->setStyle_helper(style, false);
2644 } else if (qt_styleSheet(d->extra->style) || !qApp->styleSheet().isEmpty()) {
2645 // if we have an application stylesheet or have a proxy already, propagate
2646 d->setStyle_helper(new QStyleSheetStyle(style), true);
2647 } else
2648#endif
2649 d->setStyle_helper(style, false);
2650}
2651
2652void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate)
2653{
2654 Q_Q(QWidget);
2655 QStyle *oldStyle = q->style();
2656
2657 createExtra();
2658
2659#ifndef QT_NO_STYLE_STYLESHEET
2660 QPointer<QStyle> origStyle = extra->style;
2661#endif
2662 extra->style = newStyle;
2663
2664 // repolish
2665 if (polished && q->windowType() != Qt::Desktop) {
2666 oldStyle->unpolish(q);
2667 q->style()->polish(q);
2668 }
2669
2670 if (propagate) {
2671 // We copy the list because the order may be modified
2672 const QObjectList childrenList = children;
2673 for (int i = 0; i < childrenList.size(); ++i) {
2674 QWidget *c = qobject_cast<QWidget*>(childrenList.at(i));
2675 if (c)
2676 c->d_func()->inheritStyle();
2677 }
2678 }
2679
2680#ifndef QT_NO_STYLE_STYLESHEET
2681 if (!qt_styleSheet(newStyle)) {
2682 if (const QStyleSheetStyle* cssStyle = qt_styleSheet(origStyle)) {
2683 cssStyle->clearWidgetFont(q);
2684 }
2685 }
2686#endif
2687
2688 QEvent e(QEvent::StyleChange);
2689 QCoreApplication::sendEvent(q, &e);
2690
2691#ifndef QT_NO_STYLE_STYLESHEET
2692 // dereference the old stylesheet style
2693 if (QStyleSheetStyle *proxy = qt_styleSheet(origStyle))
2694 proxy->deref();
2695#endif
2696}
2697
2698// Inherits style from the current parent and propagates it as necessary
2699void QWidgetPrivate::inheritStyle()
2700{
2701#ifndef QT_NO_STYLE_STYLESHEET
2702 Q_Q(QWidget);
2703
2704 QStyle *extraStyle = extra ? (QStyle*)extra->style : nullptr;
2705
2706 QStyleSheetStyle *proxy = qt_styleSheet(extraStyle);
2707
2708 if (!q->styleSheet().isEmpty()) {
2709 Q_ASSERT(proxy);
2710 proxy->repolish(q);
2711 return;
2712 }
2713
2714 QStyle *origStyle = proxy ? proxy->base : extraStyle;
2715 QWidget *parent = q->parentWidget();
2716 QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : nullptr;
2717 // If we have stylesheet on app or parent has stylesheet style, we need
2718 // to be running a proxy
2719 if (!qApp->styleSheet().isEmpty() || qt_styleSheet(parentStyle)) {
2720 QStyle *newStyle = parentStyle;
2721 if (q->testAttribute(Qt::WA_SetStyle) && qt_styleSheet(origStyle) == nullptr)
2722 newStyle = new QStyleSheetStyle(origStyle);
2723 else if (auto *styleSheetStyle = qt_styleSheet(origStyle))
2724 newStyle = styleSheetStyle;
2725 else if (QStyleSheetStyle *newProxy = qt_styleSheet(parentStyle))
2726 newProxy->ref();
2727
2728 setStyle_helper(newStyle, true);
2729 return;
2730 }
2731
2732 // So, we have no stylesheet on parent/app and we have an empty stylesheet
2733 // we just need our original style back
2734 if (origStyle == extraStyle) // is it any different?
2735 return;
2736
2737 // We could have inherited the proxy from our parent (which has a custom style)
2738 // In such a case we need to start following the application style (i.e revert
2739 // the propagation behavior of QStyleSheetStyle)
2740 if (!q->testAttribute(Qt::WA_SetStyle))
2741 origStyle = nullptr;
2742
2743 setStyle_helper(origStyle, true);
2744#endif // QT_NO_STYLE_STYLESHEET
2745}
2746
2747
2748/*!
2749 \fn bool QWidget::isWindow() const
2750
2751 Returns \c true if the widget is an independent window, otherwise
2752 returns \c false.
2753
2754 A window is a widget that isn't visually the child of any other
2755 widget and that usually has a frame and a
2756 \l{QWidget::setWindowTitle()}{window title}.
2757
2758 A window can have a \l{QWidget::parentWidget()}{parent widget}.
2759 It will then be grouped with its parent and deleted when the
2760 parent is deleted, minimized when the parent is minimized etc. If
2761 supported by the window manager, it will also have a common
2762 taskbar entry with its parent.
2763
2764 QDialog and QMainWindow widgets are by default windows, even if a
2765 parent widget is specified in the constructor. This behavior is
2766 specified by the Qt::Window flag.
2767
2768 \sa window(), isModal(), parentWidget()
2769*/
2770
2771/*!
2772 \property QWidget::modal
2773 \brief whether the widget is a modal widget
2774
2775 This property only makes sense for windows. A modal widget
2776 prevents widgets in all other windows from getting any input.
2777
2778 By default, this property is \c false.
2779
2780 \sa isWindow(), windowModality, QDialog
2781*/
2782
2783/*!
2784 \property QWidget::windowModality
2785 \brief which windows are blocked by the modal widget
2786 \since 4.1
2787
2788 This property only makes sense for windows. A modal widget
2789 prevents widgets in other windows from getting input. The value of
2790 this property controls which windows are blocked when the widget
2791 is visible. Changing this property while the window is visible has
2792 no effect; you must hide() the widget first, then show() it again.
2793
2794 By default, this property is Qt::NonModal.
2795
2796 \sa isWindow(), QWidget::modal, QDialog
2797*/
2798
2799Qt::WindowModality QWidget::windowModality() const
2800{
2801 return static_cast<Qt::WindowModality>(data->window_modality);
2802}
2803
2804void QWidget::setWindowModality(Qt::WindowModality windowModality)
2805{
2806 data->window_modality = windowModality;
2807 // setModal_sys() will be called by setAttribute()
2808 setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
2809 setAttribute(Qt::WA_SetWindowModality, true);
2810}
2811
2812void QWidgetPrivate::setModal_sys()
2813{
2814 Q_Q(QWidget);
2815 if (q->windowHandle())
2816 q->windowHandle()->setModality(q->windowModality());
2817}
2818
2819/*!
2820 \fn bool QWidget::underMouse() const
2821
2822 Returns \c true if the widget is under the mouse cursor; otherwise
2823 returns \c false.
2824
2825 This value is not updated properly during drag and drop
2826 operations.
2827
2828 \sa enterEvent(), leaveEvent()
2829*/
2830
2831/*!
2832 \property QWidget::minimized
2833 \brief whether this widget is minimized (iconified)
2834
2835 This property is only relevant for windows.
2836
2837 By default, this property is \c false.
2838
2839 \sa showMinimized(), visible, show(), hide(), showNormal(), maximized
2840*/
2841bool QWidget::isMinimized() const
2842{ return data->window_state & Qt::WindowMinimized; }
2843
2844/*!
2845 Shows the widget minimized, as an icon.
2846
2847 Calling this function only affects \l{isWindow()}{windows}.
2848
2849 \sa showNormal(), showMaximized(), show(), hide(), isVisible(),
2850 isMinimized()
2851*/
2852void QWidget::showMinimized()
2853{
2854 bool isMin = isMinimized();
2855 if (isMin && isVisible())
2856 return;
2857
2858 ensurePolished();
2859
2860 if (!isMin)
2861 setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
2862 setVisible(true);
2863}
2864
2865/*!
2866 \property QWidget::maximized
2867 \brief whether this widget is maximized
2868
2869 This property is only relevant for windows.
2870
2871 \note Due to limitations on some window systems, this does not always
2872 report the expected results (e.g., if the user on X11 maximizes the
2873 window via the window manager, Qt has no way of distinguishing this
2874 from any other resize). This is expected to improve as window manager
2875 protocols evolve.
2876
2877 By default, this property is \c false.
2878
2879 \sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized
2880*/
2881bool QWidget::isMaximized() const
2882{ return data->window_state & Qt::WindowMaximized; }
2883
2884
2885
2886/*!
2887 Returns the current window state. The window state is a OR'ed
2888 combination of Qt::WindowState: Qt::WindowMinimized,
2889 Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
2890
2891 \sa Qt::WindowState, setWindowState()
2892 */
2893Qt::WindowStates QWidget::windowState() const
2894{
2895 return Qt::WindowStates(data->window_state);
2896}
2897
2898/*!\internal
2899
2900 The function sets the window state on child widgets similar to
2901 setWindowState(). The difference is that the window state changed
2902 event has the isOverride() flag set. It exists mainly to keep
2903 QWorkspace working.
2904 */
2905void QWidget::overrideWindowState(Qt::WindowStates newstate)
2906{
2907 QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true);
2908 data->window_state = newstate;
2909 QCoreApplication::sendEvent(this, &e);
2910}
2911
2912/*!
2913 \fn void QWidget::setWindowState(Qt::WindowStates windowState)
2914
2915 Sets the window state to \a windowState. The window state is a OR'ed
2916 combination of Qt::WindowState: Qt::WindowMinimized,
2917 Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
2918
2919 If the window is not visible (i.e. isVisible() returns \c false), the
2920 window state will take effect when show() is called. For visible
2921 windows, the change is immediate. For example, to toggle between
2922 full-screen and normal mode, use the following code:
2923
2924 \snippet code/src_gui_kernel_qwidget.cpp 0
2925
2926 To restore and activate a minimized window (while
2927 preserving its maximized and/or full-screen state), use the following:
2928
2929 \snippet code/src_gui_kernel_qwidget.cpp 1
2930
2931 Calling this function will hide the widget. You must call show() to make
2932 the widget visible again.
2933
2934 \note On some window systems Qt::WindowActive is not immediate, and may be
2935 ignored in certain cases.
2936
2937 When the window state changes, the widget receives a changeEvent()
2938 of type QEvent::WindowStateChange.
2939
2940 \sa Qt::WindowState, windowState()
2941*/
2942void QWidget::setWindowState(Qt::WindowStates newstate)
2943{
2944 Q_D(QWidget);
2945 Qt::WindowStates oldstate = windowState();
2946 if (newstate.testFlag(Qt::WindowMinimized)) // QTBUG-46763
2947 newstate.setFlag(Qt::WindowActive, false);
2948 if (oldstate == newstate)
2949 return;
2950 if (isWindow() && !testAttribute(Qt::WA_WState_Created))
2951 create();
2952
2953 data->window_state = newstate;
2954 data->in_set_window_state = 1;
2955 if (isWindow()) {
2956 // Ensure the initial size is valid, since we store it as normalGeometry below.
2957 if (!testAttribute(Qt::WA_Resized) && !isVisible())
2958 adjustSize();
2959
2960 d->createTLExtra();
2961 if (!(oldstate & (Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)))
2962 d->topData()->normalGeometry = geometry();
2963
2964 Q_ASSERT(windowHandle());
2965 windowHandle()->setWindowStates(newstate & ~Qt::WindowActive);
2966 }
2967 data->in_set_window_state = 0;
2968
2969 if (newstate & Qt::WindowActive)
2970 activateWindow();
2971
2972 QWindowStateChangeEvent e(oldstate);
2973 QCoreApplication::sendEvent(this, &e);
2974}
2975
2976/*!
2977 \property QWidget::fullScreen
2978 \brief whether the widget is shown in full screen mode
2979
2980 A widget in full screen mode occupies the whole screen area and does not
2981 display window decorations, such as a title bar.
2982
2983 By default, this property is \c false.
2984
2985 \sa windowState(), minimized, maximized
2986*/
2987bool QWidget::isFullScreen() const
2988{ return data->window_state & Qt::WindowFullScreen; }
2989
2990/*!
2991 Shows the widget in full-screen mode.
2992
2993 Calling this function only affects \l{isWindow()}{windows}.
2994
2995 To return from full-screen mode, call showNormal() or close().
2996
2997 \note Full-screen mode works fine under Windows, but has certain
2998 problems under X. These problems are due to limitations of the
2999 ICCCM protocol that specifies the communication between X11
3000 clients and the window manager. ICCCM simply does not understand
3001 the concept of non-decorated full-screen windows. Therefore, the
3002 best you can do is to request a borderless window and place and
3003 resize it to fill the entire screen. Depending on the window
3004 manager, this may or may not work. The borderless window is
3005 requested using MOTIF hints, which are at least partially
3006 supported by virtually all modern window managers.
3007
3008 An alternative would be to bypass the window manager entirely and
3009 create a window with the Qt::X11BypassWindowManagerHint flag. This
3010 has other severe problems though, like broken keyboard focus
3011 and very strange effects on desktop changes or when the user raises
3012 other windows.
3013
3014 X11 window managers that follow modern post-ICCCM specifications
3015 support full-screen mode properly.
3016
3017 On macOS, showing a window full screen puts the entire application in
3018 full-screen mode, providing it with a dedicated desktop. Showing another
3019 window while the application runs in full-screen mode might automatically
3020 make that window full screen as well. To prevent that, exit full-screen
3021 mode by calling showNormal() or by close() on the full screen window
3022 before showing another window.
3023
3024 \sa showNormal(), showMaximized(), show(), isVisible(), close()
3025*/
3026void QWidget::showFullScreen()
3027{
3028 ensurePolished();
3029
3030 setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
3031 | Qt::WindowFullScreen);
3032 setVisible(true);
3033#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen
3034 // activating it here before libscreen activates it causes problems
3035 activateWindow();
3036#endif
3037}
3038
3039/*!
3040 Shows the widget maximized.
3041
3042 Calling this function only affects \l{isWindow()}{windows}.
3043
3044 On X11, this function may not work properly with certain window
3045 managers. See the \l{Window Geometry} documentation for an explanation.
3046
3047 \sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible()
3048*/
3049void QWidget::showMaximized()
3050{
3051 ensurePolished();
3052
3053 setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen))
3054 | Qt::WindowMaximized);
3055 setVisible(true);
3056}
3057
3058/*!
3059 Restores the widget after it has been maximized or minimized.
3060
3061 Calling this function only affects \l{isWindow()}{windows}.
3062
3063 \sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible()
3064*/
3065void QWidget::showNormal()
3066{
3067 ensurePolished();
3068
3069 setWindowState(windowState() & ~(Qt::WindowMinimized
3070 | Qt::WindowMaximized
3071 | Qt::WindowFullScreen));
3072 setVisible(true);
3073}
3074
3075/*!
3076 Returns \c true if this widget would become enabled if \a ancestor is
3077 enabled; otherwise returns \c false.
3078
3079
3080
3081 This is the case if neither the widget itself nor every parent up
3082 to but excluding \a ancestor has been explicitly disabled.
3083
3084 isEnabledTo(0) returns false if this widget or any if its ancestors
3085 was explicitly disabled.
3086
3087 The word ancestor here means a parent widget within the same window.
3088
3089 Therefore isEnabledTo(0) stops at this widget's window, unlike
3090 isEnabled() which also takes parent windows into considerations.
3091
3092 \sa setEnabled(), enabled
3093*/
3094
3095bool QWidget::isEnabledTo(const QWidget *ancestor) const
3096{
3097 const QWidget * w = this;
3098 while (!w->testAttribute(Qt::WA_ForceDisabled)
3099 && !w->isWindow()
3100 && w->parentWidget()
3101 && w->parentWidget() != ancestor)
3102 w = w->parentWidget();
3103 return !w->testAttribute(Qt::WA_ForceDisabled);
3104}
3105
3106#ifndef QT_NO_ACTION
3107/*!
3108 Appends the action \a action to this widget's list of actions.
3109
3110 All QWidgets have a list of \l{QAction}s. However, they can be
3111 represented graphically in many different ways. The default use of
3112 the QAction list (as returned by actions()) is to create a context
3113 QMenu.
3114
3115 A QWidget should only have one of each action and adding an action
3116 it already has will not cause the same action to be in the widget twice.
3117
3118 The ownership of \a action is not transferred to this QWidget.
3119
3120 \sa removeAction(), insertAction(), actions(), QMenu
3121*/
3122void QWidget::addAction(QAction *action)
3123{
3124 insertAction(nullptr, action);
3125}
3126
3127/*!
3128 Appends the actions \a actions to this widget's list of actions.
3129
3130 \sa removeAction(), QMenu, addAction()
3131*/
3132void QWidget::addActions(const QList<QAction *> &actions)
3133{
3134 for(int i = 0; i < actions.size(); i++)
3135 insertAction(nullptr, actions.at(i));
3136}
3137
3138/*!
3139 Inserts the action \a action to this widget's list of actions,
3140 before the action \a before. It appends the action if \a before is \nullptr or
3141 \a before is not a valid action for this widget.
3142
3143 A QWidget should only have one of each action.
3144
3145 \sa removeAction(), addAction(), QMenu, contextMenuPolicy, actions()
3146*/
3147void QWidget::insertAction(QAction *before, QAction *action)
3148{
3149 if (Q_UNLIKELY(!action)) {
3150 qWarning("QWidget::insertAction: Attempt to insert null action");
3151 return;
3152 }
3153
3154 Q_D(QWidget);
3155 if (d->actions.contains(action))
3156 removeAction(action);
3157
3158 int pos = d->actions.indexOf(before);
3159 if (pos < 0) {
3160 before = nullptr;
3161 pos = d->actions.size();
3162 }
3163 d->actions.insert(pos, action);
3164
3165 QActionPrivate *apriv = action->d_func();
3166 apriv->associatedObjects.append(this);
3167
3168 QActionEvent e(QEvent::ActionAdded, action, before);
3169 QCoreApplication::sendEvent(this, &e);
3170}
3171
3172/*!
3173 Inserts the actions \a actions to this widget's list of actions,
3174 before the action \a before. It appends the action if \a before is \nullptr or
3175 \a before is not a valid action for this widget.
3176
3177 A QWidget can have at most one of each action.
3178
3179 \sa removeAction(), QMenu, insertAction(), contextMenuPolicy
3180*/
3181void QWidget::insertActions(QAction *before, const QList<QAction*> &actions)
3182{
3183 for(int i = 0; i < actions.size(); ++i)
3184 insertAction(before, actions.at(i));
3185}
3186
3187/*!
3188 Removes the action \a action from this widget's list of actions.
3189 \sa insertAction(), actions(), insertAction()
3190*/
3191void QWidget::removeAction(QAction *action)
3192{
3193 if (!action)
3194 return;
3195
3196 Q_D(QWidget);
3197
3198 QActionPrivate *apriv = action->d_func();
3199 apriv->associatedObjects.removeAll(this);
3200
3201 if (d->actions.removeAll(action)) {
3202 QActionEvent e(QEvent::ActionRemoved, action);
3203 QCoreApplication::sendEvent(this, &e);
3204 }
3205}
3206
3207/*!
3208 Returns the (possibly empty) list of this widget's actions.
3209
3210 \sa contextMenuPolicy, insertAction(), removeAction()
3211*/
3212QList<QAction*> QWidget::actions() const
3213{
3214 Q_D(const QWidget);
3215 return d->actions;
3216}
3217
3218/*!
3219 \fn QAction *QWidget::addAction(const QString &text);
3220 \fn QAction *QWidget::addAction(const QString &text, const QKeySequence &shortcut);
3221 \fn QAction *QWidget::addAction(const QIcon &icon, const QString &text);
3222 \fn QAction *QWidget::addAction(const QIcon &icon, const QString &text, const QKeySequence &shortcut);
3223
3224 \since 6.3
3225
3226 These convenience functions create a new action with text \a text,
3227 icon \a icon and shortcut \a shortcut, if any.
3228
3229 The functions add the newly created action to the widget's
3230 list of actions, and return it.
3231
3232 QWidget takes ownership of the returned QAction.
3233*/
3234QAction *QWidget::addAction(const QString &text)
3235{
3236 QAction *ret = new QAction(text, this);
3237 addAction(ret);
3238 return ret;
3239}
3240
3241QAction *QWidget::addAction(const QIcon &icon, const QString &text)
3242{
3243 QAction *ret = new QAction(icon, text, this);
3244 addAction(ret);
3245 return ret;
3246}
3247
3248#if QT_CONFIG(shortcut)
3249QAction *QWidget::addAction(const QString &text, const QKeySequence &shortcut)
3250{
3251 QAction *ret = addAction(text);
3252 ret->setShortcut(shortcut);
3253 return ret;
3254}
3255
3256QAction *QWidget::addAction(const QIcon &icon, const QString &text, const QKeySequence &shortcut)
3257{
3258 QAction *ret = addAction(icon, text);
3259 ret->setShortcut(shortcut);
3260 return ret;
3261}
3262#endif
3263
3264/*!
3265 \fn QAction *QWidget::addAction(const QString &text, const QObject *receiver, const char* member, Qt::ConnectionType type)
3266 \fn QAction *QWidget::addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, Qt::ConnectionType type)
3267 \fn QAction *QWidget::addAction(const QString &text, const QKeySequence &shortcut, const QObject *receiver, const char* member, Qt::ConnectionType type)
3268 \fn QAction *QWidget::addAction(const QIcon &icon, const QString &text, const QKeySequence &shortcut, const QObject *receiver, const char* member, Qt::ConnectionType type)
3269
3270 \overload
3271 \since 6.3
3272
3273 This convenience function creates a new action with the text \a
3274 text, icon \a icon, and shortcut \a shortcut, if any.
3275
3276 The action's \l{QAction::triggered()}{triggered()} signal is connected
3277 to the \a receiver's \a member slot. The function adds the newly created
3278 action to the widget's list of actions and returns it.
3279
3280 QWidget takes ownership of the returned QAction.
3281*/
3282QAction *QWidget::addAction(const QString &text, const QObject *receiver, const char* member,
3283 Qt::ConnectionType type)
3284{
3285 QAction *action = addAction(text);
3286 QObject::connect(action, SIGNAL(triggered(bool)), receiver, member, type);
3287 return action;
3288}
3289
3290QAction *QWidget::addAction(const QIcon &icon, const QString &text,
3291 const QObject *receiver, const char* member,
3292 Qt::ConnectionType type)
3293{
3294 QAction *action = addAction(icon, text);
3295 QObject::connect(action, SIGNAL(triggered(bool)), receiver, member, type);
3296 return action;
3297}
3298
3299#if QT_CONFIG(shortcut)
3300QAction *QWidget::addAction(const QString &text, const QKeySequence &shortcut,
3301 const QObject *receiver, const char* member,
3302 Qt::ConnectionType type)
3303{
3304 QAction *action = addAction(text, receiver, member, type);
3305 action->setShortcut(shortcut);
3306 return action;
3307}
3308
3309QAction *QWidget::addAction(const QIcon &icon, const QString &text, const QKeySequence &shortcut,
3310 const QObject *receiver, const char* member,
3311 Qt::ConnectionType type)
3312{
3313 QAction *action = addAction(icon, text, receiver, member, type);
3314 action->setShortcut(shortcut);
3315 return action;
3316}
3317#endif // QT_CONFIG(shortcut)
3318
3319/*!
3320 \fn template<typename...Args, typename = compatible_action_slot_args<Args...>> QAction *QWidget::addAction(const QString &text, Args&&...args)
3321 \fn template<typename...Args, typename = compatible_action_slot_args<Args...>> QAction *QWidget::addAction(const QString &text, const QKeySequence &shortcut, Args&&...args)
3322 \fn template<typename...Args, typename = compatible_action_slot_args<Args...>> QAction *QWidget::addAction(const QIcon &icon, const QString &text, Args&&...args)
3323 \fn template<typename...Args, typename = compatible_action_slot_args<Args...>> QAction *QWidget::addAction(const QIcon &icon, const QString &text, const QKeySequence &shortcut, Args&&...args)
3324
3325 \since 6.3
3326 \overload
3327
3328 These convenience functions create a new action with the text \a text,
3329 icon \a icon, and shortcut \a shortcut, if any.
3330
3331 The action's \l{QAction::triggered()}{triggered()} signal is connected
3332 as if by a call to QObject::connect(action, &QAction::triggered, args...),
3333 perfectly forwarding \a args, including a possible Qt::ConnectionType.
3334
3335 The function adds the newly created action to the widget's list of
3336 actions and returns it.
3337
3338 QWidget takes ownership of the returned QAction.
3339*/
3340#endif // QT_NO_ACTION
3341
3342/*!
3343 \property QWidget::enabled
3344 \brief whether the widget is enabled
3345
3346 In general an enabled widget handles keyboard and mouse events; a disabled
3347 widget does not. An exception is made with \l{QAbstractButton}.
3348
3349 Some widgets display themselves differently when they are
3350 disabled. For example a button might draw its label grayed out. If
3351 your widget needs to know when it becomes enabled or disabled, you
3352 can use the changeEvent() with type QEvent::EnabledChange.
3353
3354 Disabling a widget implicitly disables all its children. Enabling
3355 respectively enables all child widgets unless they have been
3356 explicitly disabled. It it not possible to explicitly enable a child
3357 widget which is not a window while its parent widget remains disabled.
3358
3359 By default, this property is \c true.
3360
3361 \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3362*/
3363void QWidget::setEnabled(bool enable)
3364{
3365 Q_D(QWidget);
3366 setAttribute(Qt::WA_ForceDisabled, !enable);
3367 d->setEnabled_helper(enable);
3368}
3369
3370void QWidgetPrivate::setEnabled_helper(bool enable)
3371{
3372 Q_Q(QWidget);
3373
3374 if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled())
3375 return; // nothing we can do
3376
3377 if (enable != q->testAttribute(Qt::WA_Disabled))
3378 return; // nothing to do
3379
3380 q->setAttribute(Qt::WA_Disabled, !enable);
3381 updateSystemBackground();
3382
3383 if (!enable && q->window()->focusWidget() == q) {
3384 bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled());
3385 if (!parentIsEnabled || !q->focusNextChild())
3386 q->clearFocus();
3387 }
3388
3389 Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled;
3390 for (int i = 0; i < children.size(); ++i) {
3391 QWidget *w = qobject_cast<QWidget *>(children.at(i));
3392 if (w && !w->testAttribute(attribute))
3393 w->d_func()->setEnabled_helper(enable);
3394 }
3395#ifndef QT_NO_CURSOR
3396 if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
3397 // enforce the windows behavior of clearing the cursor on
3398 // disabled widgets
3399 qt_qpa_set_cursor(q, false);
3400 }
3401#endif
3402#ifndef QT_NO_IM
3403 if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) {
3404 QWidget *focusWidget = effectiveFocusWidget();
3405
3406 if (enable) {
3407 if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
3408 QGuiApplication::inputMethod()->update(Qt::ImEnabled);
3409 } else {
3410 QGuiApplication::inputMethod()->commit();
3411 QGuiApplication::inputMethod()->update(Qt::ImEnabled);
3412 }
3413 }
3414#endif //QT_NO_IM
3415 QEvent e(QEvent::EnabledChange);
3416 QCoreApplication::sendEvent(q, &e);
3417}
3418
3419/*!
3420 \property QWidget::acceptDrops
3421 \brief whether drop events are enabled for this widget
3422
3423 Setting this property to true announces to the system that this
3424 widget \e may be able to accept drop events.
3425
3426 If the widget is the desktop (windowType() == Qt::Desktop), this may
3427 fail if another application is using the desktop; you can call
3428 acceptDrops() to test if this occurs.
3429
3430 \warning Do not modify this property in a drag and drop event handler.
3431
3432 By default, this property is \c false.
3433
3434 \sa {Drag and Drop in Qt}{Drag and Drop}
3435*/
3436bool QWidget::acceptDrops() const
3437{
3438 return testAttribute(Qt::WA_AcceptDrops);
3439}
3440
3441void QWidget::setAcceptDrops(bool on)
3442{
3443 setAttribute(Qt::WA_AcceptDrops, on);
3444
3445}
3446
3447/*!
3448 Disables widget input events if \a disable is true; otherwise
3449 enables input events.
3450
3451 See the \l enabled documentation for more information.
3452
3453 \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3454*/
3455void QWidget::setDisabled(bool disable)
3456{
3457 setEnabled(!disable);
3458}
3459
3460/*!
3461 \property QWidget::frameGeometry
3462 \brief geometry of the widget relative to its parent including any
3463 window frame
3464
3465 See the \l{Window Geometry} documentation for an overview of geometry
3466 issues with windows.
3467
3468 By default, this property contains a value that depends on the user's
3469 platform and screen geometry.
3470
3471 \sa geometry(), x(), y(), pos()
3472*/
3473QRect QWidget::frameGeometry() const
3474{
3475 Q_D(const QWidget);
3476 if (isWindow() && ! (windowType() == Qt::Popup)) {
3477 QRect fs = d->frameStrut();
3478 return QRect(data->crect.x() - fs.left(),
3479 data->crect.y() - fs.top(),
3480 data->crect.width() + fs.left() + fs.right(),
3481 data->crect.height() + fs.top() + fs.bottom());
3482 }
3483 return data->crect;
3484}
3485
3486/*!
3487 \property QWidget::x
3488
3489 \brief the x coordinate of the widget relative to its parent including
3490 any window frame
3491
3492 See the \l{Window Geometry} documentation for an overview of geometry
3493 issues with windows.
3494
3495 By default, this property has a value of 0.
3496
3497 \sa frameGeometry, y, pos
3498*/
3499int QWidget::x() const
3500{
3501 Q_D(const QWidget);
3502 if (isWindow() && ! (windowType() == Qt::Popup))
3503 return data->crect.x() - d->frameStrut().left();
3504 return data->crect.x();
3505}
3506
3507/*!
3508 \property QWidget::y
3509 \brief the y coordinate of the widget relative to its parent and
3510 including any window frame
3511
3512 See the \l{Window Geometry} documentation for an overview of geometry
3513 issues with windows.
3514
3515 By default, this property has a value of 0.
3516
3517 \sa frameGeometry, x, pos
3518*/
3519int QWidget::y() const
3520{
3521 Q_D(const QWidget);
3522 if (isWindow() && ! (windowType() == Qt::Popup))
3523 return data->crect.y() - d->frameStrut().top();
3524 return data->crect.y();
3525}
3526
3527/*!
3528 \property QWidget::pos
3529 \brief the position of the widget within its parent widget
3530
3531 If the widget is a window, the position is that of the widget on
3532 the desktop, including its frame.
3533
3534 When changing the position, the widget, if visible, receives a
3535 move event (moveEvent()) immediately. If the widget is not
3536 currently visible, it is guaranteed to receive an event before it
3537 is shown.
3538
3539 By default, this property contains a position that refers to the
3540 origin.
3541
3542 \warning Calling move() or setGeometry() inside moveEvent() can
3543 lead to infinite recursion.
3544
3545 See the \l{Window Geometry} documentation for an overview of geometry
3546 issues with windows.
3547
3548 \note Not all windowing systems support setting or querying top level window positions.
3549 On such a system, programmatically moving windows may not have any effect, and artificial
3550 values may be returned for the current positions, such as \c QPoint(0, 0).
3551
3552 \sa frameGeometry, size, x(), y()
3553*/
3554QPoint QWidget::pos() const
3555{
3556 Q_D(const QWidget);
3557 QPoint result = data->crect.topLeft();
3558 if (isWindow() && ! (windowType() == Qt::Popup))
3559 if (!d->maybeTopData() || !d->maybeTopData()->posIncludesFrame)
3560 result -= d->frameStrut().topLeft();
3561 return result;
3562}
3563
3564/*!
3565 \property QWidget::geometry
3566 \brief the geometry of the widget relative to its parent and
3567 excluding the window frame
3568
3569 When changing the geometry, the widget, if visible, receives a
3570 move event (moveEvent()) and/or a resize event (resizeEvent())
3571 immediately. If the widget is not currently visible, it is
3572 guaranteed to receive appropriate events before it is shown.
3573
3574 The size component is adjusted if it lies outside the range
3575 defined by minimumSize() and maximumSize().
3576
3577 \warning Calling setGeometry() inside resizeEvent() or moveEvent()
3578 can lead to infinite recursion.
3579
3580 See the \l{Window Geometry} documentation for an overview of geometry
3581 issues with windows.
3582
3583 By default, this property contains a value that depends on the user's
3584 platform and screen geometry.
3585
3586 \sa frameGeometry(), rect(), move(), resize(), moveEvent(),
3587 resizeEvent(), minimumSize(), maximumSize()
3588*/
3589
3590/*!
3591 \property QWidget::size
3592 \brief the size of the widget excluding any window frame
3593
3594 If the widget is visible when it is being resized, it receives a resize event
3595 (resizeEvent()) immediately. If the widget is not currently
3596 visible, it is guaranteed to receive an event before it is shown.
3597
3598 The size is adjusted if it lies outside the range defined by
3599 minimumSize() and maximumSize().
3600
3601 By default, this property contains a value that depends on the user's
3602 platform and screen geometry.
3603
3604 \warning Calling resize() or setGeometry() inside resizeEvent() can
3605 lead to infinite recursion.
3606
3607 \note Setting the size to \c{QSize(0, 0)} will cause the widget to not
3608 appear on screen. This also applies to windows.
3609
3610 \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize()
3611*/
3612
3613/*!
3614 \property QWidget::width
3615 \brief the width of the widget excluding any window frame
3616
3617 See the \l{Window Geometry} documentation for an overview of geometry
3618 issues with windows.
3619
3620 \note Do not use this function to find the width of a screen on
3621 a multi-screen desktop. See QScreen for details.
3622
3623 By default, this property contains a value that depends on the user's
3624 platform and screen geometry.
3625
3626 \sa geometry, height, size
3627*/
3628
3629/*!
3630 \property QWidget::height
3631 \brief the height of the widget excluding any window frame
3632
3633 See the \l{Window Geometry} documentation for an overview of geometry
3634 issues with windows.
3635
3636 By default, this property contains a value that depends on the user's
3637 platform and \l{QScreen::geometry}{screen geometry}.
3638
3639 \sa geometry, width, size
3640*/
3641
3642/*!
3643 \property QWidget::rect
3644 \brief the internal geometry of the widget excluding any window
3645 frame
3646
3647 The rect property equals QRect(0, 0, width(), height()).
3648
3649 See the \l{Window Geometry} documentation for an overview of geometry
3650 issues with windows.
3651
3652 By default, this property contains a value that depends on the user's
3653 platform and screen geometry.
3654
3655 \sa size
3656*/
3657
3658/*!
3659 \property QWidget::normalGeometry
3660
3661 \brief the geometry of the widget as it will appear when shown as
3662 a normal (not maximized or full screen) top-level widget
3663
3664 If the widget is already in this state the normal geometry will
3665 reflect the widget's current geometry().
3666
3667 For child widgets this property always holds an empty rectangle.
3668
3669 By default, this property contains an empty rectangle.
3670
3671 \sa QWidget::windowState(), QWidget::geometry
3672*/
3673QRect QWidget::normalGeometry() const
3674{
3675 Q_D(const QWidget);
3676 if (!isWindow())
3677 return QRect();
3678
3679 if (!isMaximized() && !isFullScreen())
3680 return geometry();
3681
3682 return d->topData()->normalGeometry;
3683}
3684
3685
3686/*!
3687 \property QWidget::childrenRect
3688 \brief the bounding rectangle of the widget's children
3689
3690 Hidden children are excluded.
3691
3692 By default, for a widget with no children, this property contains a
3693 rectangle with zero width and height located at the origin.
3694
3695 \sa childrenRegion(), geometry()
3696*/
3697
3698QRect QWidget::childrenRect() const
3699{
3700 Q_D(const QWidget);
3701 QRect r(0, 0, 0, 0);
3702 for (int i = 0; i < d->children.size(); ++i) {
3703 QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
3704 if (w && !w->isWindow() && !w->isHidden())
3705 r |= w->geometry();
3706 }
3707 return r;
3708}
3709
3710/*!
3711 \property QWidget::childrenRegion
3712 \brief the combined region occupied by the widget's children
3713
3714 Hidden children are excluded.
3715
3716 By default, for a widget with no children, this property contains an
3717 empty region.
3718
3719 \sa childrenRect(), geometry(), mask()
3720*/
3721
3722QRegion QWidget::childrenRegion() const
3723{
3724 Q_D(const QWidget);
3725 QRegion r;
3726 for (int i = 0; i < d->children.size(); ++i) {
3727 QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
3728 if (w && !w->isWindow() && !w->isHidden()) {
3729 QRegion mask = w->mask();
3730 if (mask.isEmpty())
3731 r |= w->geometry();
3732 else
3733 r |= mask.translated(w->pos());
3734 }
3735 }
3736 return r;
3737}
3738
3739
3740/*!
3741 \property QWidget::minimumSize
3742 \brief the widget's minimum size
3743
3744 The widget cannot be resized to a smaller size than the minimum
3745 widget size. The widget's size is forced to the minimum size if
3746 the current size is smaller.
3747
3748 The minimum size set by this function will override the minimum size
3749 defined by QLayout. To unset the minimum size, use a
3750 value of \c{QSize(0, 0)}.
3751
3752 By default, this property contains a size with zero width and height.
3753
3754 \sa minimumWidth, minimumHeight, maximumSize, sizeIncrement
3755*/
3756
3757QSize QWidget::minimumSize() const
3758{
3759 Q_D(const QWidget);
3760 return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0);
3761}
3762
3763/*!
3764 \property QWidget::maximumSize
3765 \brief the widget's maximum size in pixels
3766
3767 The widget cannot be resized to a larger size than the maximum
3768 widget size.
3769
3770 By default, this property contains a size in which both width and height
3771 have values of 16777215.
3772
3773 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3774 of widgets.
3775
3776 \sa maximumWidth, maximumHeight, minimumSize, sizeIncrement
3777*/
3778
3779QSize QWidget::maximumSize() const
3780{
3781 Q_D(const QWidget);
3782 return d->extra ? QSize(d->extra->maxw, d->extra->maxh)
3784}
3785
3786
3787/*!
3788 \property QWidget::minimumWidth
3789 \brief the widget's minimum width in pixels
3790
3791 This property corresponds to the width held by the \l minimumSize property.
3792
3793 By default, this property has a value of 0.
3794
3795 \sa minimumSize, minimumHeight
3796*/
3797
3798/*!
3799 \property QWidget::minimumHeight
3800 \brief the widget's minimum height in pixels
3801
3802 This property corresponds to the height held by the \l minimumSize property.
3803
3804 By default, this property has a value of 0.
3805
3806 \sa minimumSize, minimumWidth
3807*/
3808
3809/*!
3810 \property QWidget::maximumWidth
3811 \brief the widget's maximum width in pixels
3812
3813 This property corresponds to the width held by the \l maximumSize property.
3814
3815 By default, this property contains a value of 16777215.
3816
3817 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3818 of widgets.
3819
3820 \sa maximumSize, maximumHeight
3821*/
3822
3823/*!
3824 \property QWidget::maximumHeight
3825 \brief the widget's maximum height in pixels
3826
3827 This property corresponds to the height held by the \l maximumSize property.
3828
3829 By default, this property contains a value of 16777215.
3830
3831 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3832 of widgets.
3833
3834 \sa maximumSize, maximumWidth
3835*/
3836
3837/*!
3838 \property QWidget::sizeIncrement
3839 \brief the size increment of the widget
3840
3841 When the user resizes the window, the size will move in steps of
3842 sizeIncrement().width() pixels horizontally and
3843 sizeIncrement.height() pixels vertically, with baseSize() as the
3844 basis. Preferred widget sizes are for non-negative integers \e i
3845 and \e j:
3846 \snippet code/src_gui_kernel_qwidget.cpp 2
3847
3848 Note that while you can set the size increment for all widgets, it
3849 only affects windows.
3850
3851 By default, this property contains a size with zero width and height.
3852
3853 \warning The size increment has no effect under Windows, and may
3854 be disregarded by the window manager on X11.
3855
3856 \sa size, minimumSize, maximumSize
3857*/
3858QSize QWidget::sizeIncrement() const
3859{
3860 Q_D(const QWidget);
3861 return (d->extra && d->extra->topextra)
3862 ? QSize(d->extra->topextra->incw, d->extra->topextra->inch)
3863 : QSize(0, 0);
3864}
3865
3866/*!
3867 \property QWidget::baseSize
3868 \brief the base size of the widget
3869
3870 The base size is used to calculate a proper widget size if the
3871 widget defines sizeIncrement().
3872
3873 By default, for a newly-created widget, this property contains a size with
3874 zero width and height.
3875
3876 \sa setSizeIncrement()
3877*/
3878
3879QSize QWidget::baseSize() const
3880{
3881 Q_D(const QWidget);
3882 return (d->extra && d->extra->topextra)
3883 ? QSize(d->extra->topextra->basew, d->extra->topextra->baseh)
3884 : QSize(0, 0);
3885}
3886
3887bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
3888{
3889 Q_Q(QWidget);
3890
3891 int mw = minw, mh = minh;
3892 if (mw == QWIDGETSIZE_MAX)
3893 mw = 0;
3894 if (mh == QWIDGETSIZE_MAX)
3895 mh = 0;
3896 if (Q_UNLIKELY(minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX)) {
3897 qWarning("QWidget::setMinimumSize: (%s/%s) "
3898 "The largest allowed size is (%d,%d)",
3899 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
3901 minw = mw = qMin<int>(minw, QWIDGETSIZE_MAX);
3902 minh = mh = qMin<int>(minh, QWIDGETSIZE_MAX);
3903 }
3904 if (Q_UNLIKELY(minw < 0 || minh < 0)) {
3905 qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
3906 "are not possible",
3907 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
3908 minw = mw = qMax(minw, 0);
3909 minh = mh = qMax(minh, 0);
3910 }
3911 createExtra();
3912 if (extra->minw == mw && extra->minh == mh)
3913 return false;
3914 extra->minw = mw;
3915 extra->minh = mh;
3916 extra->explicitMinSize = (mw ? Qt::Horizontal : 0) | (mh ? Qt::Vertical : 0);
3917 return true;
3918}
3919
3920void QWidgetPrivate::setConstraints_sys()
3921{
3922 Q_Q(QWidget);
3923 if (extra && q->windowHandle()) {
3924 QWindow *win = q->windowHandle();
3925 QWindowPrivate *winp = qt_window_private(win);
3926
3927 winp->minimumSize = QSize(extra->minw, extra->minh);
3928 winp->maximumSize = QSize(extra->maxw, extra->maxh);
3929
3930 if (extra->topextra) {
3931 winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
3932 winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
3933 }
3934
3935 if (winp->platformWindow) {
3936 fixPosIncludesFrame();
3937 winp->platformWindow->propagateSizeHints();
3938 }
3939 }
3940}
3941
3942/*!
3943 \overload
3944
3945 This function corresponds to setMinimumSize(QSize(minw, minh)).
3946 Sets the minimum width to \a minw and the minimum height to \a
3947 minh.
3948*/
3949
3950void QWidget::setMinimumSize(int minw, int minh)
3951{
3952 Q_D(QWidget);
3953 if (!d->setMinimumSize_helper(minw, minh))
3954 return;
3955
3956 if (isWindow())
3957 d->setConstraints_sys();
3958 if (minw > width() || minh > height()) {
3959 bool resized = testAttribute(Qt::WA_Resized);
3960 bool maximized = isMaximized();
3961 resize(qMax(minw,width()), qMax(minh,height()));
3962 setAttribute(Qt::WA_Resized, resized); //not a user resize
3963 if (maximized)
3964 data->window_state = data->window_state | Qt::WindowMaximized;
3965 }
3966#if QT_CONFIG(graphicsview)
3967 if (d->extra) {
3968 if (d->extra->proxyWidget)
3969 d->extra->proxyWidget->setMinimumSize(minw, minh);
3970 }
3971#endif
3972 d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
3973}
3974
3975bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh)
3976{
3977 Q_Q(QWidget);
3978 if (Q_UNLIKELY(maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX)) {
3979 qWarning("QWidget::setMaximumSize: (%s/%s) "
3980 "The largest allowed size is (%d,%d)",
3981 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
3983 maxw = qMin<int>(maxw, QWIDGETSIZE_MAX);
3984 maxh = qMin<int>(maxh, QWIDGETSIZE_MAX);
3985 }
3986 if (Q_UNLIKELY(maxw < 0 || maxh < 0)) {
3987 qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
3988 "are not possible",
3989 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh);
3990 maxw = qMax(maxw, 0);
3991 maxh = qMax(maxh, 0);
3992 }
3993 createExtra();
3994 if (extra->maxw == maxw && extra->maxh == maxh)
3995 return false;
3996 extra->maxw = maxw;
3997 extra->maxh = maxh;
3998 extra->explicitMaxSize = (maxw != QWIDGETSIZE_MAX ? Qt::Horizontal : 0) |
3999 (maxh != QWIDGETSIZE_MAX ? Qt::Vertical : 0);
4000 return true;
4001}
4002
4003/*!
4004 \overload
4005
4006 This function corresponds to setMaximumSize(QSize(\a maxw, \a
4007 maxh)). Sets the maximum width to \a maxw and the maximum height
4008 to \a maxh.
4009*/
4010void QWidget::setMaximumSize(int maxw, int maxh)
4011{
4012 Q_D(QWidget);
4013 if (!d->setMaximumSize_helper(maxw, maxh))
4014 return;
4015
4016 if (isWindow())
4017 d->setConstraints_sys();
4018 if (maxw < width() || maxh < height()) {
4019 bool resized = testAttribute(Qt::WA_Resized);
4020 resize(qMin(maxw,width()), qMin(maxh,height()));
4021 setAttribute(Qt::WA_Resized, resized); //not a user resize
4022 }
4023
4024#if QT_CONFIG(graphicsview)
4025 if (d->extra) {
4026 if (d->extra->proxyWidget)
4027 d->extra->proxyWidget->setMaximumSize(maxw, maxh);
4028 }
4029#endif
4030
4031 d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
4032}
4033
4034/*!
4035 \overload
4036
4037 Sets the x (width) size increment to \a w and the y (height) size
4038 increment to \a h.
4039*/
4040void QWidget::setSizeIncrement(int w, int h)
4041{
4042 Q_D(QWidget);
4043 d->createTLExtra();
4044 QTLWExtra* x = d->topData();
4045 if (x->incw == w && x->inch == h)
4046 return;
4047 x->incw = w;
4048 x->inch = h;
4049 if (isWindow())
4050 d->setConstraints_sys();
4051}
4052
4053/*!
4054 \overload
4055
4056 This corresponds to setBaseSize(QSize(\a basew, \a baseh)). Sets
4057 the widgets base size to width \a basew and height \a baseh.
4058*/
4059void QWidget::setBaseSize(int basew, int baseh)
4060{
4061 Q_D(QWidget);
4062 d->createTLExtra();
4063 QTLWExtra* x = d->topData();
4064 if (x->basew == basew && x->baseh == baseh)
4065 return;
4066 x->basew = basew;
4067 x->baseh = baseh;
4068 if (isWindow())
4069 d->setConstraints_sys();
4070}
4071
4072/*!
4073 Sets both the minimum and maximum sizes of the widget to \a s,
4074 thereby preventing it from ever growing or shrinking.
4075
4076 This will override the default size constraints set by QLayout.
4077
4078 To remove constraints, set the size to QWIDGETSIZE_MAX.
4079
4080 Alternatively, if you want the widget to have a
4081 fixed size based on its contents, you can call
4082 QLayout::setSizeConstraint(QLayout::SetFixedSize);
4083
4084 \sa maximumSize, minimumSize
4085*/
4086
4087void QWidget::setFixedSize(const QSize & s)
4088{
4089 setFixedSize(s.width(), s.height());
4090}
4091
4092
4093/*!
4094 \fn void QWidget::setFixedSize(int w, int h)
4095 \overload
4096
4097 Sets the width of the widget to \a w and the height to \a h.
4098*/
4099
4100void QWidget::setFixedSize(int w, int h)
4101{
4102 Q_D(QWidget);
4103 bool minSizeSet = d->setMinimumSize_helper(w, h);
4104 bool maxSizeSet = d->setMaximumSize_helper(w, h);
4105 if (!minSizeSet && !maxSizeSet)
4106 return;
4107
4108 if (isWindow())
4109 d->setConstraints_sys();
4110 else
4111 d->updateGeometry_helper(true);
4112
4113 if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX)
4114 resize(w, h);
4115}
4116
4117void QWidget::setMinimumWidth(int w)
4118{
4119 Q_D(QWidget);
4120 d->createExtra();
4121 uint expl = d->extra->explicitMinSize | (w ? Qt::Horizontal : 0);
4122 setMinimumSize(w, minimumSize().height());
4123 d->extra->explicitMinSize = expl;
4124}
4125
4126void QWidget::setMinimumHeight(int h)
4127{
4128 Q_D(QWidget);
4129 d->createExtra();
4130 uint expl = d->extra->explicitMinSize | (h ? Qt::Vertical : 0);
4131 setMinimumSize(minimumSize().width(), h);
4132 d->extra->explicitMinSize = expl;
4133}
4134
4135void QWidget::setMaximumWidth(int w)
4136{
4137 Q_D(QWidget);
4138 d->createExtra();
4139 uint expl = d->extra->explicitMaxSize | (w == QWIDGETSIZE_MAX ? 0 : Qt::Horizontal);
4140 setMaximumSize(w, maximumSize().height());
4141 d->extra->explicitMaxSize = expl;
4142}
4143
4144void QWidget::setMaximumHeight(int h)
4145{
4146 Q_D(QWidget);
4147 d->createExtra();
4148 uint expl = d->extra->explicitMaxSize | (h == QWIDGETSIZE_MAX ? 0 : Qt::Vertical);
4149 setMaximumSize(maximumSize().width(), h);
4150 d->extra->explicitMaxSize = expl;
4151}
4152
4153/*!
4154 Sets both the minimum and maximum width of the widget to \a w
4155 without changing the heights. Provided for convenience.
4156
4157 \sa sizeHint(), minimumSize(), maximumSize(), setFixedSize()
4158*/
4159
4160void QWidget::setFixedWidth(int w)
4161{
4162 Q_D(QWidget);
4163 d->createExtra();
4164 uint explMin = d->extra->explicitMinSize | Qt::Horizontal;
4165 uint explMax = d->extra->explicitMaxSize | Qt::Horizontal;
4166 setMinimumSize(w, minimumSize().height());
4167 setMaximumSize(w, maximumSize().height());
4168 d->extra->explicitMinSize = explMin;
4169 d->extra->explicitMaxSize = explMax;
4170}
4171
4172
4173/*!
4174 Sets both the minimum and maximum heights of the widget to \a h
4175 without changing the widths. Provided for convenience.
4176
4177 \sa sizeHint(), minimumSize(), maximumSize(), setFixedSize()
4178*/
4179
4180void QWidget::setFixedHeight(int h)
4181{
4182 Q_D(QWidget);
4183 d->createExtra();
4184 uint explMin = d->extra->explicitMinSize | Qt::Vertical;
4185 uint explMax = d->extra->explicitMaxSize | Qt::Vertical;
4186 setMinimumSize(minimumSize().width(), h);
4187 setMaximumSize(maximumSize().width(), h);
4188 d->extra->explicitMinSize = explMin;
4189 d->extra->explicitMaxSize = explMax;
4190}
4191
4192
4193/*!
4194 Translates the widget coordinate \a pos to the coordinate system
4195 of \a parent. The \a parent must not be \nullptr and must be a parent
4196 of the calling widget.
4197
4198 \sa mapFrom(), mapToParent(), mapToGlobal(), underMouse()
4199 \since 6.0
4200*/
4201
4202QPointF QWidget::mapTo(const QWidget *parent, const QPointF &pos) const
4203{
4204 QPointF p = pos;
4205 if (parent) {
4206 const QWidget * w = this;
4207 while (w != parent) {
4208 p = w->mapToParent(p);
4209 w = w->parentWidget();
4210 if (!w) {
4211 qWarning("QWidget::mapTo(): parent must be in parent hierarchy");
4212 break;
4213 }
4214 }
4215 }
4216 return p;
4217}
4218
4219/*!
4220 \overload
4221*/
4222QPoint QWidget::mapTo(const QWidget *parent, const QPoint &pos) const
4223{
4224 return mapTo(parent, QPointF(pos)).toPoint();
4225}
4226
4227/*!
4228 Translates the widget coordinate \a pos from the coordinate system
4229 of \a parent to this widget's coordinate system. The \a parent
4230 must not be \nullptr and must be a parent of the calling widget.
4231
4232 \sa mapTo(), mapFromParent(), mapFromGlobal(), underMouse()
4233 \since 6.0
4234*/
4235
4236QPointF QWidget::mapFrom(const QWidget *parent, const QPointF &pos) const
4237{
4238 QPointF p(pos);
4239 if (parent) {
4240 const QWidget * w = this;
4241 while (w != parent) {
4242 p = w->mapFromParent(p);
4243 w = w->parentWidget();
4244 if (!w) {
4245 qWarning("QWidget::mapFrom(): parent must be in parent hierarchy");
4246 break;
4247 }
4248 }
4249 }
4250 return p;
4251}
4252
4253/*!
4254 \overload
4255*/
4256QPoint QWidget::mapFrom(const QWidget *parent, const QPoint &pos) const
4257{
4258 return mapFrom(parent, QPointF(pos)).toPoint();
4259}
4260
4261/*!
4262 Translates the widget coordinate \a pos to a coordinate in the
4263 parent widget.
4264
4265 Same as mapToGlobal() if the widget has no parent.
4266
4267 \sa mapFromParent(), mapTo(), mapToGlobal(), underMouse()
4268 \since 6.0
4269*/
4270
4271QPointF QWidget::mapToParent(const QPointF &pos) const
4272{
4273 return pos + QPointF(data->crect.topLeft());
4274}
4275
4276/*!
4277 \overload
4278*/
4279QPoint QWidget::mapToParent(const QPoint &pos) const
4280{
4281 return pos + data->crect.topLeft();
4282}
4283
4284/*!
4285 Translates the parent widget coordinate \a pos to widget
4286 coordinates.
4287
4288 Same as mapFromGlobal() if the widget has no parent.
4289
4290 \sa mapToParent(), mapFrom(), mapFromGlobal(), underMouse()
4291 \since 6.0
4292*/
4293
4294QPointF QWidget::mapFromParent(const QPointF &pos) const
4295{
4296 return pos - QPointF(data->crect.topLeft());
4297}
4298
4299/*!
4300 \overload
4301*/
4302QPoint QWidget::mapFromParent(const QPoint &pos) const
4303{
4304 return pos - data->crect.topLeft();
4305}
4306
4307
4308/*!
4309 Returns the window for this widget, i.e. the next ancestor widget
4310 that has (or could have) a window-system frame.
4311
4312 If the widget is a window, the widget itself is returned.
4313
4314 Typical usage is changing the window title:
4315
4316 \snippet code/src_gui_kernel_qwidget.cpp 3
4317
4318 \sa isWindow()
4319*/
4320
4321QWidget *QWidget::window() const
4322{
4323 QWidget *w = const_cast<QWidget *>(this);
4324 QWidget *p = w->parentWidget();
4325 while (!w->isWindow() && p) {
4326 w = p;
4327 p = p->parentWidget();
4328 }
4329 return w;
4330}
4331
4332/*!
4333 \since 4.4
4334
4335 Returns the native parent for this widget, i.e. the next ancestor widget
4336 that has a system identifier, or \nullptr if it does not have any native
4337 parent.
4338
4339 \sa effectiveWinId()
4340*/
4341QWidget *QWidget::nativeParentWidget() const
4342{
4343 QWidget *parent = parentWidget();
4344 while (parent && !parent->internalWinId())
4345 parent = parent->parentWidget();
4346 return parent;
4347}
4348
4349/*! \fn QWidget *QWidget::topLevelWidget() const
4350 \deprecated
4351
4352 Use window() instead.
4353*/
4354
4355
4356
4357/*!
4358 Returns the background role of the widget.
4359
4360 The background role defines the brush from the widget's \l palette that
4361 is used to render the background.
4362
4363 If no explicit background role is set, the widget inherits its parent
4364 widget's background role.
4365
4366 \sa setBackgroundRole(), foregroundRole()
4367 */
4368QPalette::ColorRole QWidget::backgroundRole() const
4369{
4370
4371 const QWidget *w = this;
4372 do {
4373 QPalette::ColorRole role = w->d_func()->bg_role;
4374 if (role != QPalette::NoRole)
4375 return role;
4376 if (w->isWindow() || w->windowType() == Qt::SubWindow)
4377 break;
4378 w = w->parentWidget();
4379 } while (w);
4380 return QPalette::Window;
4381}
4382
4383/*!
4384 Sets the background role of the widget to \a role.
4385
4386 The background role defines the brush from the widget's \l palette that
4387 is used to render the background.
4388
4389 If \a role is QPalette::NoRole, then the widget inherits its
4390 parent's background role.
4391
4392 Note that styles are free to choose any color from the palette.
4393 You can modify the palette or set a style sheet if you don't
4394 achieve the result you want with setBackgroundRole().
4395
4396 \sa backgroundRole(), foregroundRole()
4397 */
4398
4399void QWidget::setBackgroundRole(QPalette::ColorRole role)
4400{
4401 Q_D(QWidget);
4402 d->bg_role = role;
4403 d->updateSystemBackground();
4404 d->propagatePaletteChange();
4405 d->updateIsOpaque();
4406}
4407
4408/*!
4409 Returns the foreground role.
4410
4411 The foreground role defines the color from the widget's \l palette that
4412 is used to draw the foreground.
4413
4414 If no explicit foreground role is set, the function returns a role
4415 that contrasts with the background role.
4416
4417 \sa setForegroundRole(), backgroundRole()
4418 */
4419QPalette::ColorRole QWidget::foregroundRole() const
4420{
4421 Q_D(const QWidget);
4422 QPalette::ColorRole rl = QPalette::ColorRole(d->fg_role);
4423 if (rl != QPalette::NoRole)
4424 return rl;
4425 QPalette::ColorRole role = QPalette::WindowText;
4426 switch (backgroundRole()) {
4427 case QPalette::Button:
4428 role = QPalette::ButtonText;
4429 break;
4430 case QPalette::Base:
4431 role = QPalette::Text;
4432 break;
4433 case QPalette::Dark:
4434 case QPalette::Shadow:
4435 role = QPalette::Light;
4436 break;
4437 case QPalette::Highlight:
4438 role = QPalette::HighlightedText;
4439 break;
4440 case QPalette::ToolTipBase:
4441 role = QPalette::ToolTipText;
4442 break;
4443 default:
4444 ;
4445 }
4446 return role;
4447}
4448
4449/*!
4450 Sets the foreground role of the widget to \a role.
4451
4452 The foreground role defines the color from the widget's \l palette that
4453 is used to draw the foreground.
4454
4455 If \a role is QPalette::NoRole, the widget uses a foreground role
4456 that contrasts with the background role.
4457
4458 Note that styles are free to choose any color from the palette.
4459 You can modify the palette or set a style sheet if you don't
4460 achieve the result you want with setForegroundRole().
4461
4462 \sa foregroundRole(), backgroundRole()
4463 */
4464void QWidget::setForegroundRole(QPalette::ColorRole role)
4465{
4466 Q_D(QWidget);
4467 d->fg_role = role;
4468 d->updateSystemBackground();
4469 d->propagatePaletteChange();
4470}
4471
4472/*!
4473 \property QWidget::palette
4474 \brief the widget's palette
4475
4476 This property describes the widget's palette. The palette is used by the
4477 widget's style when rendering standard components, and is available as a
4478 means to ensure that custom widgets can maintain consistency with the
4479 native platform's look and feel. It's common that different platforms, or
4480 different styles, have different palettes.
4481
4482 When you assign a new palette to a widget, the color roles from this
4483 palette are combined with the widget's default palette to form the
4484 widget's final palette. The palette entry for the widget's background role
4485 is used to fill the widget's background (see QWidget::autoFillBackground),
4486 and the foreground role initializes QPainter's pen.
4487
4488 The default depends on the system environment. QApplication maintains a
4489 system/theme palette which serves as a default for all widgets. There may
4490 also be special palette defaults for certain types of widgets (e.g., on
4491 Windows Vista, all classes that derive from QMenuBar have a special
4492 default palette). You can also define default palettes for widgets
4493 yourself by passing a custom palette and the name of a widget to
4494 QApplication::setPalette(). Finally, the style always has the option of
4495 polishing the palette as it's assigned (see QStyle::polish()).
4496
4497 QWidget propagates explicit palette roles from parent to child. If you
4498 assign a brush or color to a specific role on a palette and assign that
4499 palette to a widget, that role will propagate to all the widget's
4500 children, overriding any system defaults for that role. Note that palettes
4501 by default don't propagate to windows (see isWindow()) unless the
4502 Qt::WA_WindowPropagation attribute is enabled.
4503
4504 QWidget's palette propagation is similar to its font propagation.
4505
4506 The current style, which is used to render the content of all standard Qt
4507 widgets, is free to choose colors and brushes from the widget palette, or,
4508 in some cases, to ignore the palette (partially, or completely). In
4509 particular, certain styles like GTK style, Mac style, and Windows Vista
4510 style, depend on third party APIs to render the content of widgets,
4511 and these styles typically do not follow the palette. Because of this,
4512 assigning roles to a widget's palette is not guaranteed to change the
4513 appearance of the widget. Instead, you may choose to apply a \l {styleSheet}.
4514
4515 \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
4516 When using style sheets, the palette of a widget can be customized using
4517 the "color", "background-color", "selection-color",
4518 "selection-background-color" and "alternate-background-color".
4519
4520 \sa QGuiApplication::palette(), QWidget::font(), {Qt Style Sheets}
4521*/
4522const QPalette &QWidget::palette() const
4523{
4524 if (!isEnabled()) {
4525 data->pal.setCurrentColorGroup(QPalette::Disabled);
4526 } else if ((!isVisible() || isActiveWindow())
4527#if defined(Q_OS_WIN)
4528 && !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this))
4529#endif
4530 ) {
4531 data->pal.setCurrentColorGroup(QPalette::Active);
4532 } else {
4533 data->pal.setCurrentColorGroup(QPalette::Inactive);
4534 }
4535 return data->pal;
4536}
4537
4538void QWidget::setPalette(const QPalette &palette)
4539{
4540 Q_D(QWidget);
4541 setAttribute(Qt::WA_SetPalette, palette.resolveMask() != 0);
4542
4543 // Determine which palette is inherited from this widget's ancestors and
4544 // QApplication::palette, resolve this against \a palette (attributes from
4545 // the inherited palette are copied over this widget's palette). Then
4546 // propagate this palette to this widget's children.
4547 QPalette naturalPalette = d->naturalWidgetPalette(d->inheritedPaletteResolveMask);
4548 QPalette resolvedPalette = palette.resolve(naturalPalette);
4549 d->setPalette_helper(resolvedPalette);
4550}
4551
4552/*!
4553 \internal
4554
4555 Returns the palette that the widget \a w inherits from its ancestors and
4556 QApplication::palette. \a inheritedMask is the combination of the widget's
4557 ancestors palette request masks (i.e., which attributes from the parent
4558 widget's palette are implicitly imposed on this widget by the user). Note
4559 that this font does not take into account the palette set on \a w itself.
4560*/
4561QPalette QWidgetPrivate::naturalWidgetPalette(QPalette::ResolveMask inheritedMask) const
4562{
4563 Q_Q(const QWidget);
4564
4565 const bool useStyleSheetPropagationInWidgetStyles =
4566 QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
4567
4568 QPalette naturalPalette = QApplication::palette(q);
4569 if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
4570 && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
4571#if QT_CONFIG(graphicsview)
4572 || (extra && extra->proxyWidget)
4573#endif // QT_CONFIG(graphicsview)
4574 )) {
4575 if (QWidget *p = q->parentWidget()) {
4576 if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
4577 if (!naturalPalette.isCopyOf(QGuiApplication::palette())) {
4578 QPalette inheritedPalette = p->palette();
4579 inheritedPalette.setResolveMask(inheritedMask);
4580 naturalPalette = inheritedPalette.resolve(naturalPalette);
4581 } else {
4582 naturalPalette = p->palette();
4583 }
4584 }
4585 }
4586#if QT_CONFIG(graphicsview)
4587 else if (extra && extra->proxyWidget) {
4588 QPalette inheritedPalette = extra->proxyWidget->palette();
4589 inheritedPalette.setResolveMask(inheritedMask);
4590 naturalPalette = inheritedPalette.resolve(naturalPalette);
4591 }
4592#endif // QT_CONFIG(graphicsview)
4593 }
4594 naturalPalette.setResolveMask(0);
4595 return naturalPalette;
4596}
4597/*!
4598 \internal
4599
4600 Determine which palette is inherited from this widget's ancestors and
4601 QApplication::palette, resolve this against this widget's palette
4602 (attributes from the inherited palette are copied over this widget's
4603 palette). Then propagate this palette to this widget's children.
4604*/
4605void QWidgetPrivate::resolvePalette()
4606{
4607 QPalette naturalPalette = naturalWidgetPalette(inheritedPaletteResolveMask);
4608 QPalette resolvedPalette = data.pal.resolve(naturalPalette);
4609 setPalette_helper(resolvedPalette);
4610}
4611
4612void QWidgetPrivate::setPalette_helper(const QPalette &palette)
4613{
4614 Q_Q(QWidget);
4615 if (data.pal == palette && data.pal.resolveMask() == palette.resolveMask())
4616 return;
4617 data.pal = palette;
4618 updateSystemBackground();
4619 propagatePaletteChange();
4620 updateIsOpaque();
4621 q->update();
4622 updateIsOpaque();
4623}
4624
4625void QWidgetPrivate::updateSystemBackground()
4626{
4627}
4628
4629/*!
4630 \property QWidget::font
4631 \brief the font currently set for the widget
4632
4633 This property describes the widget's requested font. The font is used by
4634 the widget's style when rendering standard components, and is available as
4635 a means to ensure that custom widgets can maintain consistency with the
4636 native platform's look and feel. It's common that different platforms, or
4637 different styles, define different fonts for an application.
4638
4639 When you assign a new font to a widget, the properties from this font are
4640 combined with the widget's default font to form the widget's final
4641 font. You can call fontInfo() to get a copy of the widget's final
4642 font. The final font is also used to initialize QPainter's font.
4643
4644 The default depends on the system environment. QApplication maintains a
4645 system/theme font which serves as a default for all widgets. There may
4646 also be special font defaults for certain types of widgets. You can also
4647 define default fonts for widgets yourself by passing a custom font and the
4648 name of a widget to QApplication::setFont(). Finally, the font is matched
4649 against Qt's font database to find the best match.
4650
4651 QWidget propagates explicit font properties from parent to child. If you
4652 change a specific property on a font and assign that font to a widget,
4653 that property will propagate to all the widget's children, overriding any
4654 system defaults for that property. Note that fonts by default don't
4655 propagate to windows (see isWindow()) unless the Qt::WA_WindowPropagation
4656 attribute is enabled.
4657
4658 QWidget's font propagation is similar to its palette propagation.
4659
4660 The current style, which is used to render the content of all standard Qt
4661 widgets, is free to choose to use the widget font, or in some cases, to
4662 ignore it (partially, or completely). In particular, certain styles like
4663 GTK style, Mac style, and Windows Vista style, apply special
4664 modifications to the widget font to match the platform's native look and
4665 feel. Because of this, assigning properties to a widget's font is not
4666 guaranteed to change the appearance of the widget. Instead, you may choose
4667 to apply a \l styleSheet.
4668
4669 \note If \l{Qt Style Sheets} are used on the same widget as setFont(),
4670 style sheets will take precedence if the settings conflict.
4671
4672 \sa fontInfo(), fontMetrics()
4673*/
4674
4675void QWidget::setFont(const QFont &font)
4676{
4677 Q_D(QWidget);
4678
4679#ifndef QT_NO_STYLE_STYLESHEET
4680 const QStyleSheetStyle* style;
4681 if (d->extra && (style = qt_styleSheet(d->extra->style)))
4682 style->saveWidgetFont(this, font);
4683#endif
4684
4685 setAttribute(Qt::WA_SetFont, font.resolveMask() != 0);
4686
4687 // Determine which font is inherited from this widget's ancestors and
4688 // QApplication::font, resolve this against \a font (attributes from the
4689 // inherited font are copied over). Then propagate this font to this
4690 // widget's children.
4691 QFont naturalFont = d->naturalWidgetFont(d->inheritedFontResolveMask);
4692 QFont resolvedFont = font.resolve(naturalFont);
4693 d->setFont_helper(resolvedFont);
4694}
4695
4696/*
4697 \internal
4698
4699 Returns the font that the widget \a w inherits from its ancestors and
4700 QApplication::font. \a inheritedMask is the combination of the widget's
4701 ancestors font request masks (i.e., which attributes from the parent
4702 widget's font are implicitly imposed on this widget by the user). Note
4703 that this font does not take into account the font set on \a w itself.
4704
4705 ### Stylesheet has a different font propagation mechanism. When a stylesheet
4706 is applied, fonts are not propagated anymore
4707*/
4708QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
4709{
4710 Q_Q(const QWidget);
4711
4712 const bool useStyleSheetPropagationInWidgetStyles =
4713 QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
4714
4715 QFont naturalFont = QApplication::font(q);
4716 if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
4717 && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
4718#if QT_CONFIG(graphicsview)
4719 || (extra && extra->proxyWidget)
4720#endif // QT_CONFIG(graphicsview)
4721 )) {
4722 if (QWidget *p = q->parentWidget()) {
4723 if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
4724 if (!naturalFont.isCopyOf(QApplication::font())) {
4725 if (inheritedMask != 0) {
4726 QFont inheritedFont = p->font();
4727 inheritedFont.setResolveMask(inheritedMask);
4728 naturalFont = inheritedFont.resolve(naturalFont);
4729 } // else nothing to do (naturalFont = naturalFont)
4730 } else {
4731 naturalFont = p->font();
4732 }
4733 }
4734 }
4735#if QT_CONFIG(graphicsview)
4736 else if (extra && extra->proxyWidget) {
4737 if (inheritedMask != 0) {
4738 QFont inheritedFont = extra->proxyWidget->font();
4739 inheritedFont.setResolveMask(inheritedMask);
4740 naturalFont = inheritedFont.resolve(naturalFont);
4741 } // else nothing to do (naturalFont = naturalFont)
4742 }
4743#endif // QT_CONFIG(graphicsview)
4744 }
4745 naturalFont.setResolveMask(0);
4746 return naturalFont;
4747}
4748
4749/*!
4750 \internal
4751
4752 Returns a font suitable for inheritance, where only locally set attributes are considered resolved.
4753*/
4754QFont QWidgetPrivate::localFont() const
4755{
4756 QFont localfont = data.fnt;
4757 localfont.setResolveMask(directFontResolveMask);
4758 return localfont;
4759}
4760
4761/*!
4762 \internal
4763
4764 Determine which font is implicitly imposed on this widget by its ancestors
4765 and QApplication::font, resolve this against its own font (attributes from
4766 the implicit font are copied over). Then propagate this font to this
4767 widget's children.
4768*/
4769void QWidgetPrivate::resolveFont()
4770{
4771 QFont naturalFont = naturalWidgetFont(inheritedFontResolveMask);
4772 QFont resolvedFont = localFont().resolve(naturalFont);
4773 setFont_helper(resolvedFont);
4774}
4775
4776/*!
4777 \internal
4778
4779 Assign \a font to this widget, and propagate it to all children, except
4780 style sheet widgets (handled differently) and windows that don't enable
4781 window propagation. \a implicitMask is the union of all ancestor widgets'
4782 font request masks, and determines which attributes from this widget's
4783 font should propagate.
4784*/
4785void QWidgetPrivate::updateFont(const QFont &font)
4786{
4787 Q_Q(QWidget);
4788#ifndef QT_NO_STYLE_STYLESHEET
4789 const QStyleSheetStyle* cssStyle;
4790 cssStyle = extra ? qt_styleSheet(extra->style) : nullptr;
4791 const bool useStyleSheetPropagationInWidgetStyles =
4792 QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
4793#endif
4794
4795 data.fnt = QFont(font, q);
4796
4797 // Combine new mask with natural mask and propagate to children.
4798#if QT_CONFIG(graphicsview)
4799 if (!q->parentWidget() && extra && extra->proxyWidget) {
4800 QGraphicsProxyWidget *p = extra->proxyWidget;
4801 inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolveMask();
4802 } else
4803#endif // QT_CONFIG(graphicsview)
4804 if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
4805 inheritedFontResolveMask = 0;
4806 }
4807 uint newMask = data.fnt.resolveMask() | inheritedFontResolveMask;
4808 // Set the font as also having resolved inherited traits, so the result of reading QWidget::font()
4809 // isn't all weak information, but save the original mask to be able to let new changes on the
4810 // parent widget font propagate correctly.
4811 directFontResolveMask = data.fnt.resolveMask();
4812 data.fnt.setResolveMask(newMask);
4813
4814 for (int i = 0; i < children.size(); ++i) {
4815 QWidget *w = qobject_cast<QWidget*>(children.at(i));
4816 if (w) {
4817 if (0) {
4818#ifndef QT_NO_STYLE_STYLESHEET
4819 } else if (!useStyleSheetPropagationInWidgetStyles && w->testAttribute(Qt::WA_StyleSheet)) {
4820 // Style sheets follow a different font propagation scheme.
4821 if (cssStyle)
4822 cssStyle->updateStyleSheetFont(w);
4823#endif
4824 } else if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
4825 // Propagate font changes.
4826 QWidgetPrivate *wd = w->d_func();
4827 wd->inheritedFontResolveMask = newMask;
4828 wd->resolveFont();
4829 }
4830 }
4831 }
4832
4833#ifndef QT_NO_STYLE_STYLESHEET
4834 if (!useStyleSheetPropagationInWidgetStyles && cssStyle) {
4835 cssStyle->updateStyleSheetFont(q);
4836 }
4837#endif
4838
4839 QEvent e(QEvent::FontChange);
4840 QCoreApplication::sendEvent(q, &e);
4841}
4842
4843void QWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
4844{
4845 Q_Q(QWidget);
4846
4847 if ( (direction == Qt::RightToLeft) == q->testAttribute(Qt::WA_RightToLeft))
4848 return;
4849 q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
4850 if (!children.isEmpty()) {
4851 for (int i = 0; i < children.size(); ++i) {
4852 QWidget *w = qobject_cast<QWidget*>(children.at(i));
4853 if (w && !w->isWindow() && !w->testAttribute(Qt::WA_SetLayoutDirection))
4854 w->d_func()->setLayoutDirection_helper(direction);
4855 }
4856 }
4857 QEvent e(QEvent::LayoutDirectionChange);
4858 QCoreApplication::sendEvent(q, &e);
4859}
4860
4861void QWidgetPrivate::resolveLayoutDirection()
4862{
4863 Q_Q(const QWidget);
4864 if (!q->testAttribute(Qt::WA_SetLayoutDirection))
4865 setLayoutDirection_helper(q->isWindow() ? QGuiApplication::layoutDirection() : q->parentWidget()->layoutDirection());
4866}
4867
4868/*!
4869 \property QWidget::layoutDirection
4870
4871 \brief the layout direction for this widget.
4872
4873 \note This method no longer affects text layout direction since Qt 4.7.
4874
4875 By default, this property is set to Qt::LeftToRight.
4876
4877 When the layout direction is set on a widget, it will propagate to
4878 the widget's children, but not to a child that is a window and not
4879 to a child for which setLayoutDirection() has been explicitly
4880 called. Also, child widgets added \e after setLayoutDirection()
4881 has been called for the parent do not inherit the parent's layout
4882 direction.
4883
4884
4885 \sa QApplication::layoutDirection
4886*/
4887void QWidget::setLayoutDirection(Qt::LayoutDirection direction)
4888{
4889 Q_D(QWidget);
4890
4891 if (direction == Qt::LayoutDirectionAuto) {
4892 unsetLayoutDirection();
4893 return;
4894 }
4895
4896 setAttribute(Qt::WA_SetLayoutDirection);
4897 d->setLayoutDirection_helper(direction);
4898}
4899
4900Qt::LayoutDirection QWidget::layoutDirection() const
4901{
4902 return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
4903}
4904
4905void QWidget::unsetLayoutDirection()
4906{
4907 Q_D(QWidget);
4908 setAttribute(Qt::WA_SetLayoutDirection, false);
4909 d->resolveLayoutDirection();
4910}
4911
4912/*!
4913 \fn QFontMetrics QWidget::fontMetrics() const
4914
4915 Returns the font metrics for the widget's current font.
4916 Equivalent to \c QFontMetrics(widget->font()).
4917
4918 \sa font(), fontInfo(), setFont()
4919*/
4920
4921/*!
4922 \fn QFontInfo QWidget::fontInfo() const
4923
4924 Returns the font info for the widget's current font.
4925 Equivalent to \c QFontInfo(widget->font()).
4926
4927 \sa font(), fontMetrics(), setFont()
4928*/
4929
4930
4931/*!
4932 \property QWidget::cursor
4933 \brief the cursor shape for this widget
4934
4935 The mouse cursor will assume this shape when it's over this
4936 widget. See the \l{Qt::CursorShape}{list of predefined cursor objects} for a range of useful shapes.
4937
4938 An editor widget might use an I-beam cursor:
4939 \snippet code/src_gui_kernel_qwidget.cpp 6
4940
4941 If no cursor has been set, or after a call to unsetCursor(), the
4942 parent's cursor is used.
4943
4944 By default, this property contains a cursor with the Qt::ArrowCursor
4945 shape.
4946
4947 Some underlying window implementations will reset the cursor if it
4948 leaves a widget even if the mouse is grabbed. If you want to have
4949 a cursor set for all widgets, even when outside the window, consider
4950 QGuiApplication::setOverrideCursor().
4951
4952 \sa QGuiApplication::setOverrideCursor()
4953*/
4954
4955#ifndef QT_NO_CURSOR
4956QCursor QWidget::cursor() const
4957{
4958 Q_D(const QWidget);
4959 if (testAttribute(Qt::WA_SetCursor))
4960 return (d->extra && d->extra->curs)
4961 ? *d->extra->curs
4962 : QCursor(Qt::ArrowCursor);
4963 if (isWindow() || !parentWidget())
4964 return QCursor(Qt::ArrowCursor);
4965 return parentWidget()->cursor();
4966}
4967
4968void QWidget::setCursor(const QCursor &cursor)
4969{
4970 Q_D(QWidget);
4971 if (cursor.shape() != Qt::ArrowCursor
4972 || (d->extra && d->extra->curs))
4973 {
4974 d->createExtra();
4975 d->extra->curs = std::make_unique<QCursor>(cursor);
4976 }
4977 setAttribute(Qt::WA_SetCursor);
4978 d->setCursor_sys(cursor);
4979
4980 QEvent event(QEvent::CursorChange);
4981 QCoreApplication::sendEvent(this, &event);
4982}
4983
4984void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
4985{
4986 Q_UNUSED(cursor);
4987 Q_Q(QWidget);
4988 qt_qpa_set_cursor(q, false);
4989}
4990
4991void QWidget::unsetCursor()
4992{
4993 Q_D(QWidget);
4994 if (d->extra)
4995 d->extra->curs.reset();
4996 if (!isWindow())
4997 setAttribute(Qt::WA_SetCursor, false);
4998 d->unsetCursor_sys();
4999
5000 QEvent event(QEvent::CursorChange);
5001 QCoreApplication::sendEvent(this, &event);
5002}
5003
5004void QWidgetPrivate::unsetCursor_sys()
5005{
5006 Q_Q(QWidget);
5007 qt_qpa_set_cursor(q, false);
5008}
5009
5010static inline void applyCursor(QWidget *w, const QCursor &c)
5011{
5012 if (QWindow *window = w->windowHandle())
5013 window->setCursor(c);
5014}
5015
5016static inline void unsetCursor(QWidget *w)
5017{
5018 if (QWindow *window = w->windowHandle())
5019 window->unsetCursor();
5020}
5021
5022void qt_qpa_set_cursor(QWidget *w, bool force)
5023{
5024 if (!w->testAttribute(Qt::WA_WState_Created))
5025 return;
5026
5027 static QPointer<QWidget> lastUnderMouse = nullptr;
5028 if (force) {
5029 lastUnderMouse = w;
5030 } else if (lastUnderMouse) {
5031 const WId lastWinId = lastUnderMouse->effectiveWinId();
5032 const WId winId = w->effectiveWinId();
5033 if (lastWinId && lastWinId == winId)
5034 w = lastUnderMouse;
5035 } else if (!w->internalWinId()) {
5036 return; // The mouse is not under this widget, and it's not native, so don't change it.
5037 }
5038
5039 while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
5040 && !w->testAttribute(Qt::WA_SetCursor))
5041 w = w->parentWidget();
5042
5043 QWidget *nativeParent = w;
5044 if (!w->internalWinId())
5045 nativeParent = w->nativeParentWidget();
5046 if (!nativeParent || !nativeParent->internalWinId())
5047 return;
5048
5049 if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
5050 if (w->isEnabled())
5051 applyCursor(nativeParent, w->cursor());
5052 else
5053 // Enforce the windows behavior of clearing the cursor on
5054 // disabled widgets.
5055 unsetCursor(nativeParent);
5056 } else {
5057 unsetCursor(nativeParent);
5058 }
5059}
5060#endif
5061
5062/*!
5063 \enum QWidget::RenderFlag
5064
5065 This enum describes how to render the widget when calling QWidget::render().
5066
5067 \value DrawWindowBackground If you enable this option, the widget's background
5068 is rendered into the target even if autoFillBackground is not set. By default,
5069 this option is enabled.
5070
5071 \value DrawChildren If you enable this option, the widget's children
5072 are rendered recursively into the target. By default, this option is enabled.
5073
5074 \value IgnoreMask If you enable this option, the widget's QWidget::mask()
5075 is ignored when rendering into the target. By default, this option is disabled.
5076
5077 \since 4.3
5078*/
5079
5080/*!
5081 \since 4.3
5082
5083 Renders the \a sourceRegion of this widget into the \a target
5084 using \a renderFlags to determine how to render. Rendering
5085 starts at \a targetOffset in the \a target. For example:
5086
5087 \snippet code/src_gui_kernel_qwidget.cpp 7
5088
5089 If \a sourceRegion is a null region, this function will use QWidget::rect() as
5090 the region, i.e. the entire widget.
5091
5092 Ensure that you call QPainter::end() for the \a target device's
5093 active painter (if any) before rendering. For example:
5094
5095 \snippet code/src_gui_kernel_qwidget.cpp 8
5096
5097 \note To obtain the contents of a QOpenGLWidget, use QOpenGLWidget::grabFramebuffer()
5098 instead.
5099*/
5100void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
5101 const QRegion &sourceRegion, RenderFlags renderFlags)
5102{
5103 QPainter p(target);
5104 render(&p, targetOffset, sourceRegion, renderFlags);
5105}
5106
5107/*!
5108 \overload
5109
5110 Renders the widget into the \a painter's QPainter::device().
5111
5112 Transformations and settings applied to the \a painter will be used
5113 when rendering.
5114
5115 \note The \a painter must be active. On \macos the widget will be
5116 rendered into a QPixmap and then drawn by the \a painter.
5117
5118 \sa QPainter::device()
5119*/
5120void QWidget::render(QPainter *painter, const QPoint &targetOffset,
5121 const QRegion &sourceRegion, RenderFlags renderFlags)
5122{
5123 if (Q_UNLIKELY(!painter)) {
5124 qWarning("QWidget::render: Null pointer to painter");
5125 return;
5126 }
5127
5128 if (Q_UNLIKELY(!painter->isActive())) {
5129 qWarning("QWidget::render: Cannot render with an inactive painter");
5130 return;
5131 }
5132
5133 const qreal opacity = painter->opacity();
5134 if (qFuzzyIsNull(opacity))
5135 return; // Fully transparent.
5136
5137 Q_D(QWidget);
5138 const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter;
5139 const QRegion toBePainted = !inRenderWithPainter ? d->prepareToRender(sourceRegion, renderFlags)
5140 : sourceRegion;
5141 if (toBePainted.isEmpty())
5142 return;
5143
5144 if (!d->extra)
5145 d->createExtra();
5146 d->extra->inRenderWithPainter = true;
5147
5148 QPaintEngine *engine = painter->paintEngine();
5149 Q_ASSERT(engine);
5150 QPaintEnginePrivate *enginePriv = engine->d_func();
5151 Q_ASSERT(enginePriv);
5152 QPaintDevice *target = engine->paintDevice();
5153 Q_ASSERT(target);
5154
5155 // Render via a pixmap when dealing with non-opaque painters or printers.
5156 if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) {
5157 d->render_helper(painter, targetOffset, toBePainted, renderFlags);
5158 d->extra->inRenderWithPainter = inRenderWithPainter;
5159 return;
5160 }
5161
5162 // Set new shared painter.
5163 QPainter *oldPainter = d->sharedPainter();
5164 d->setSharedPainter(painter);
5165
5166 // Save current system clip, viewport and transform,
5167 const QTransform oldTransform = enginePriv->systemTransform;
5168 const QRegion oldSystemClip = enginePriv->systemClip;
5169 const QRegion oldBaseClip = enginePriv->baseSystemClip;
5170 const QRegion oldSystemViewport = enginePriv->systemViewport;
5171 const Qt::LayoutDirection oldLayoutDirection = painter->layoutDirection();
5172
5173 // This ensures that all painting triggered by render() is clipped to the current engine clip.
5174 if (painter->hasClipping()) {
5175 const QRegion painterClip = painter->deviceTransform().map(painter->clipRegion());
5176 enginePriv->setSystemViewport(oldSystemClip.isEmpty() ? painterClip : oldSystemClip & painterClip);
5177 } else {
5178 enginePriv->setSystemViewport(oldSystemClip);
5179 }
5180 painter->setLayoutDirection(layoutDirection());
5181
5182 d->render(target, targetOffset, toBePainted, renderFlags);
5183
5184 // Restore system clip, viewport and transform.
5185 enginePriv->baseSystemClip = oldBaseClip;
5186 enginePriv->setSystemTransformAndViewport(oldTransform, oldSystemViewport);
5187 enginePriv->systemStateChanged();
5188 painter->setLayoutDirection(oldLayoutDirection);
5189
5190 // Restore shared painter.
5191 d->setSharedPainter(oldPainter);
5192
5193 d->extra->inRenderWithPainter = inRenderWithPainter;
5194}
5195
5196static void sendResizeEvents(QWidget *target)
5197{
5198 QResizeEvent e(target->size(), QSize());
5199 QCoreApplication::sendEvent(target, &e);
5200
5201 const QObjectList children = target->children();
5202 for (int i = 0; i < children.size(); ++i) {
5203 if (!children.at(i)->isWidgetType())
5204 continue;
5205 QWidget *child = static_cast<QWidget*>(children.at(i));
5206 if (!child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
5207 sendResizeEvents(child);
5208 }
5209}
5210
5211/*!
5212 \since 5.0
5213
5214 Renders the widget into a pixmap restricted by the
5215 given \a rectangle. If the widget has any children, then
5216 they are also painted in the appropriate positions.
5217
5218 If a rectangle with an invalid size is specified (the default),
5219 the entire widget is painted.
5220
5221 \sa render(), QPixmap
5222*/
5223QPixmap QWidget::grab(const QRect &rectangle)
5224{
5225 Q_D(QWidget);
5226 if (testAttribute(Qt::WA_PendingResizeEvent) || !testAttribute(Qt::WA_WState_Created))
5227 sendResizeEvents(this);
5228
5229 const QWidget::RenderFlags renderFlags = QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask;
5230
5231 const bool oldDirtyOpaqueChildren = d->dirtyOpaqueChildren;
5232 QRect r(rectangle);
5233 if (r.width() < 0 || r.height() < 0) {
5234 // For grabbing widgets that haven't been shown yet,
5235 // we trigger the layouting mechanism to determine the widget's size.
5236 r = d->prepareToRender(QRegion(), renderFlags).boundingRect();
5237 r.setTopLeft(rectangle.topLeft());
5238 }
5239
5240 if (!r.intersects(rect()))
5241 return QPixmap();
5242
5243 const qreal dpr = devicePixelRatio();
5244 QPixmap res((QSizeF(r.size()) * dpr).toSize());
5245 res.setDevicePixelRatio(dpr);
5246 if (!d->isOpaque)
5247 res.fill(Qt::transparent);
5248 d->render(&res, QPoint(), QRegion(r), renderFlags);
5249
5250 d->dirtyOpaqueChildren = oldDirtyOpaqueChildren;
5251 return res;
5252}
5253
5254/*!
5255 \brief The graphicsEffect function returns a pointer to the
5256 widget's graphics effect.
5257
5258 If the widget has no graphics effect, \nullptr is returned.
5259
5260 \since 4.6
5261
5262 \sa setGraphicsEffect()
5263*/
5264#if QT_CONFIG(graphicseffect)
5265QGraphicsEffect *QWidget::graphicsEffect() const
5266{
5267 Q_D(const QWidget);
5268 return d->graphicsEffect;
5269}
5270#endif // QT_CONFIG(graphicseffect)
5271
5272/*!
5273
5274 \brief The setGraphicsEffect function is for setting the widget's graphics effect.
5275
5276 Sets \a effect as the widget's effect. If there already is an effect installed
5277 on this widget, QWidget will delete the existing effect before installing
5278 the new \a effect.
5279
5280 If \a effect is the installed effect on a different widget, setGraphicsEffect() will remove
5281 the effect from the widget and install it on this widget.
5282
5283 QWidget takes ownership of \a effect.
5284
5285 \note This function will apply the effect on itself and all its children.
5286
5287 \note Graphics effects are not supported for OpenGL-based widgets, such as QGLWidget,
5288 QOpenGLWidget and QQuickWidget.
5289
5290 \since 4.6
5291
5292 \sa graphicsEffect()
5293*/
5294#if QT_CONFIG(graphicseffect)
5295void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
5296{
5297 Q_D(QWidget);
5298 if (d->graphicsEffect == effect)
5299 return;
5300
5301 if (d->graphicsEffect) {
5302 d->invalidateBackingStore(rect());
5303 delete d->graphicsEffect;
5304 d->graphicsEffect = nullptr;
5305 }
5306
5307 if (effect) {
5308 // Set new effect.
5309 QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
5310 QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
5311 d->graphicsEffect = effect;
5312 effect->d_func()->setGraphicsEffectSource(source);
5313 update();
5314 }
5315
5316 d->updateIsOpaque();
5317}
5318#endif // QT_CONFIG(graphicseffect)
5319
5320bool QWidgetPrivate::isAboutToShow() const
5321{
5322 if (data.in_show)
5323 return true;
5324
5325 Q_Q(const QWidget);
5326 if (q->isHidden())
5327 return false;
5328
5329 // The widget will be shown if any of its ancestors are about to show.
5330 QWidget *parent = q->parentWidget();
5331 return parent ? parent->d_func()->isAboutToShow() : false;
5332}
5333
5334QRegion QWidgetPrivate::prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags)
5335{
5336 Q_Q(QWidget);
5337 const bool isVisible = q->isVisible();
5338
5339 // Make sure the widget is laid out correctly.
5340 if (!isVisible && !isAboutToShow()) {
5341 QWidget *topLevel = q->window();
5342 (void)topLevel->d_func()->topData(); // Make sure we at least have top-data.
5343 topLevel->ensurePolished();
5344
5345 // Invalidate the layout of hidden ancestors (incl. myself) and pretend
5346 // they're not explicitly hidden.
5347 QWidget *widget = q;
5348 QWidgetList hiddenWidgets;
5349 while (widget) {
5350 if (widget->isHidden()) {
5351 widget->setAttribute(Qt::WA_WState_Hidden, false);
5352 hiddenWidgets.append(widget);
5353 if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
5354 widget->d_func()->updateGeometry_helper(true);
5355 }
5356 widget = widget->parentWidget();
5357 }
5358
5359 // Activate top-level layout.
5360 if (topLevel->d_func()->layout)
5361 topLevel->d_func()->layout->activate();
5362
5363 // Adjust size if necessary.
5364 QTLWExtra *topLevelExtra = topLevel->d_func()->maybeTopData();
5365 if (topLevelExtra && !topLevelExtra->sizeAdjusted
5366 && !topLevel->testAttribute(Qt::WA_Resized)) {
5367 topLevel->adjustSize();
5368 topLevel->setAttribute(Qt::WA_Resized, false);
5369 }
5370
5371 // Activate child layouts.
5372 topLevel->d_func()->activateChildLayoutsRecursively();
5373
5374 // We're not cheating with WA_WState_Hidden anymore.
5375 for (int i = 0; i < hiddenWidgets.size(); ++i) {
5376 QWidget *widget = hiddenWidgets.at(i);
5377 widget->setAttribute(Qt::WA_WState_Hidden);
5378 if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
5379 widget->parentWidget()->d_func()->layout->invalidate();
5380 }
5381 } else if (isVisible) {
5382 q->window()->d_func()->sendPendingMoveAndResizeEvents(true, true);
5383 }
5384
5385 // Calculate the region to be painted.
5386 QRegion toBePainted = !region.isEmpty() ? region : QRegion(q->rect());
5387 if (!(renderFlags & QWidget::IgnoreMask) && extra && extra->hasMask)
5388 toBePainted &= extra->mask;
5389 return toBePainted;
5390}
5391
5392void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &toBePainted,
5393 QWidget::RenderFlags renderFlags)
5394{
5395 Q_ASSERT(painter);
5396 Q_ASSERT(!toBePainted.isEmpty());
5397
5398 Q_Q(QWidget);
5399 const QTransform originalTransform = painter->worldTransform();
5400 const bool useDeviceCoordinates = originalTransform.isScaling();
5401 if (!useDeviceCoordinates) {
5402 // Render via a pixmap.
5403 const QRect rect = toBePainted.boundingRect();
5404 const QSize size = rect.size();
5405 if (size.isNull())
5406 return;
5407
5408 const qreal pixmapDevicePixelRatio = painter->device()->devicePixelRatio();
5409 QPixmap pixmap(size * pixmapDevicePixelRatio);
5410 pixmap.setDevicePixelRatio(pixmapDevicePixelRatio);
5411
5412 if (!(renderFlags & QWidget::DrawWindowBackground) || !isOpaque)
5413 pixmap.fill(Qt::transparent);
5414 q->render(&pixmap, QPoint(), toBePainted, renderFlags);
5415
5416 const bool restore = !(painter->renderHints() & QPainter::SmoothPixmapTransform);
5417 painter->setRenderHints(QPainter::SmoothPixmapTransform, true);
5418
5419 painter->drawPixmap(targetOffset, pixmap);
5420
5421 if (restore)
5422 painter->setRenderHints(QPainter::SmoothPixmapTransform, false);
5423
5424 } else {
5425 // Render via a pixmap in device coordinates (to avoid pixmap scaling).
5426 QTransform transform = originalTransform;
5427 transform.translate(targetOffset.x(), targetOffset.y());
5428
5429 QPaintDevice *device = painter->device();
5430 Q_ASSERT(device);
5431
5432 // Calculate device rect.
5433 const QRectF rect(toBePainted.boundingRect());
5434 QRect deviceRect = transform.mapRect(QRectF(0, 0, rect.width(), rect.height())).toAlignedRect();
5435 deviceRect &= QRect(0, 0, device->width(), device->height());
5436
5437 QPixmap pixmap(deviceRect.size());
5438 pixmap.fill(Qt::transparent);
5439
5440 // Create a pixmap device coordinate painter.
5441 QPainter pixmapPainter(&pixmap);
5442 pixmapPainter.setRenderHints(painter->renderHints());
5443 transform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y());
5444 pixmapPainter.setTransform(transform);
5445
5446 q->render(&pixmapPainter, QPoint(), toBePainted, renderFlags);
5447 pixmapPainter.end();
5448
5449 // And then draw the pixmap.
5450 painter->setTransform(QTransform());
5451 painter->drawPixmap(deviceRect.topLeft(), pixmap);
5452 painter->setTransform(originalTransform);
5453 }
5454}
5455
5456void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, DrawWidgetFlags flags,
5457 QPainter *sharedPainter, QWidgetRepaintManager *repaintManager)
5458{
5459 if (rgn.isEmpty())
5460 return;
5461
5462 Q_Q(QWidget);
5463
5464 qCInfo(lcWidgetPainting) << "Drawing" << rgn << "of" << q << "at" << offset
5465 << "into paint device" << pdev << "with" << flags;
5466
5467 const bool asRoot = flags & DrawAsRoot;
5468 bool onScreen = shouldPaintOnScreen();
5469
5470#if QT_CONFIG(graphicseffect)
5471 if (graphicsEffect && graphicsEffect->isEnabled()) {
5472 QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
5473 QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
5474 (source->d_func());
5475 if (!sourced->context) {
5476 const QRegion effectRgn((flags & UseEffectRegionBounds) ? rgn.boundingRect() : rgn);
5477 QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
5478 sourced->context = &context;
5479 if (!sharedPainter) {
5480 setSystemClip(pdev->paintEngine(), pdev->devicePixelRatio(), effectRgn.translated(offset));
5481 QPainter p(pdev);
5482 p.translate(offset);
5483 context.painter = &p;
5484 graphicsEffect->draw(&p);
5485 setSystemClip(pdev->paintEngine(), 1, QRegion());
5486 } else {
5487 context.painter = sharedPainter;
5488 if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
5489 sourced->invalidateCache();
5490 sourced->lastEffectTransform = sharedPainter->worldTransform();
5491 }
5492 sharedPainter->save();
5493 sharedPainter->translate(offset);
5494 setSystemClip(sharedPainter->paintEngine(), sharedPainter->device()->devicePixelRatio(), effectRgn.translated(offset));
5495 graphicsEffect->draw(sharedPainter);
5496 setSystemClip(sharedPainter->paintEngine(), 1, QRegion());
5497 sharedPainter->restore();
5498 }
5499 sourced->context = nullptr;
5500
5501 if (repaintManager)
5502 repaintManager->markNeedsFlush(q, effectRgn, offset);
5503
5504 return;
5505 }
5506 }
5507#endif // QT_CONFIG(graphicseffect)
5508 flags = flags & ~UseEffectRegionBounds;
5509
5510 const bool alsoOnScreen = flags & DrawPaintOnScreen;
5511 const bool recursive = flags & DrawRecursive;
5512 const bool alsoInvisible = flags & DrawInvisible;
5513
5514 Q_ASSERT(sharedPainter ? sharedPainter->isActive() : true);
5515
5516 QRegion toBePainted(rgn);
5517 if (asRoot && !alsoInvisible)
5518 toBePainted &= clipRect(); //(rgn & visibleRegion());
5519 if (!(flags & DontSubtractOpaqueChildren))
5520 subtractOpaqueChildren(toBePainted, q->rect());
5521
5522 if (!toBePainted.isEmpty()) {
5523 if (!onScreen || alsoOnScreen) {
5524 //update the "in paint event" flag
5525 if (Q_UNLIKELY(q->testAttribute(Qt::WA_WState_InPaintEvent)))
5526 qWarning("QWidget::repaint: Recursive repaint detected");
5527 q->setAttribute(Qt::WA_WState_InPaintEvent);
5528
5529 //clip away the new area
5530 QPaintEngine *paintEngine = pdev->paintEngine();
5531 if (paintEngine) {
5532 setRedirected(pdev, -offset);
5533
5534 if (sharedPainter)
5535 setSystemClip(pdev->paintEngine(), pdev->devicePixelRatio(), toBePainted);
5536 else
5537 paintEngine->d_func()->systemRect = q->data->crect;
5538
5539 //paint the background
5540 if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(Qt::WA_StyledBackground))
5541 && !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
5542 beginBackingStorePainting();
5543 QPainter p(q);
5544 p.setRenderHint(QPainter::SmoothPixmapTransform);
5545 paintBackground(&p, toBePainted, (asRoot || onScreen) ? (flags | DrawAsRoot) : DrawWidgetFlags());
5546 endBackingStorePainting();
5547 }
5548
5549 if (!sharedPainter)
5550 setSystemClip(pdev->paintEngine(), pdev->devicePixelRatio(), toBePainted.translated(offset));
5551
5552 if (!onScreen && !asRoot && !isOpaque && q->testAttribute(Qt::WA_TintedBackground)) {
5553 beginBackingStorePainting();
5554 QPainter p(q);
5555 QColor tint = q->palette().window().color();
5556 tint.setAlphaF(.6f);
5557 p.fillRect(toBePainted.boundingRect(), tint);
5558 endBackingStorePainting();
5559 }
5560 }
5561
5562#if 0
5563 qDebug() << "painting" << q << "opaque ==" << isOpaque();
5564 qDebug() << "clipping to" << toBePainted << "location == " << offset
5565 << "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size());
5566#endif
5567
5568 bool skipPaintEvent = false;
5569 if (renderToTexture) {
5570 // This widget renders into a texture which is composed later. We just need to
5571 // punch a hole in the backingstore, so the texture will be visible.
5572 beginBackingStorePainting();
5573 if (!q->testAttribute(Qt::WA_AlwaysStackOnTop) && repaintManager) {
5574 QPainter p(q);
5575 p.setCompositionMode(QPainter::CompositionMode_Source);
5576 p.fillRect(q->rect(), Qt::transparent);
5577 } else if (!repaintManager) {
5578 // We are not drawing to a backingstore: fall back to QImage
5579 QImage img = grabFramebuffer();
5580 // grabFramebuffer() always sets the format to RGB32
5581 // regardless of whether it is transparent or not.
5582 if (img.format() == QImage::Format_RGB32)
5583 img.reinterpretAsFormat(QImage::Format_ARGB32_Premultiplied);
5584 QPainter p(q);
5585 p.drawImage(q->rect(), img);
5586 skipPaintEvent = true;
5587 }
5588 endBackingStorePainting();
5589 if (renderToTextureReallyDirty)
5590 renderToTextureReallyDirty = 0;
5591 else
5592 skipPaintEvent = true;
5593 }
5594
5595 if (!skipPaintEvent) {
5596 //actually send the paint event
5597 sendPaintEvent(toBePainted);
5598 }
5599
5600 if (repaintManager)
5601 repaintManager->markNeedsFlush(q, toBePainted, offset);
5602
5603 //restore
5604 if (paintEngine) {
5605 restoreRedirected();
5606 if (!sharedPainter)
5607 paintEngine->d_func()->systemRect = QRect();
5608 else
5609 paintEngine->d_func()->currentClipDevice = nullptr;
5610
5611 setSystemClip(pdev->paintEngine(), 1, QRegion());
5612 }
5613 q->setAttribute(Qt::WA_WState_InPaintEvent, false);
5614 if (Q_UNLIKELY(q->paintingActive()))
5615 qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
5616
5617 if (paintEngine && paintEngine->autoDestruct()) {
5618 delete paintEngine;
5619 }
5620 } else if (q->isWindow()) {
5621 QPaintEngine *engine = pdev->paintEngine();
5622 if (engine) {
5623 QPainter p(pdev);
5624 p.setClipRegion(toBePainted);
5625 const QBrush bg = q->palette().brush(QPalette::Window);
5626 if (bg.style() == Qt::TexturePattern)
5627 p.drawTiledPixmap(q->rect(), bg.texture());
5628 else
5629 p.fillRect(q->rect(), bg);
5630
5631 if (engine->autoDestruct())
5632 delete engine;
5633 }
5634 }
5635 }
5636
5637 if (recursive && !children.isEmpty()) {
5638 paintSiblingsRecursive(pdev, children, children.size() - 1, rgn, offset, flags & ~DrawAsRoot,
5639 sharedPainter, repaintManager);
5640 }
5641}
5642
5643void QWidgetPrivate::sendPaintEvent(const QRegion &toBePainted)
5644{
5645 Q_Q(QWidget);
5646 QPaintEvent e(toBePainted);
5647 QCoreApplication::sendSpontaneousEvent(q, &e);
5648
5649 if (renderToTexture)
5650 resolveSamples();
5651}
5652
5653void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
5654 const QRegion &sourceRegion, QWidget::RenderFlags renderFlags)
5655{
5656 if (Q_UNLIKELY(!target)) {
5657 qWarning("QWidget::render: null pointer to paint device");
5658 return;
5659 }
5660
5661 const bool inRenderWithPainter = extra && extra->inRenderWithPainter;
5662 QRegion paintRegion = !inRenderWithPainter
5663 ? prepareToRender(sourceRegion, renderFlags)
5664 : sourceRegion;
5665 if (paintRegion.isEmpty())
5666 return;
5667
5668 QPainter *oldSharedPainter = inRenderWithPainter ? sharedPainter() : nullptr;
5669
5670 // Use the target's shared painter if set (typically set when doing
5671 // "other->render(widget);" in the widget's paintEvent.
5672 if (target->devType() == QInternal::Widget) {
5673 QWidgetPrivate *targetPrivate = static_cast<QWidget *>(target)->d_func();
5674 if (targetPrivate->extra && targetPrivate->extra->inRenderWithPainter) {
5675 QPainter *targetPainter = targetPrivate->sharedPainter();
5676 if (targetPainter && targetPainter->isActive())
5677 setSharedPainter(targetPainter);
5678 }
5679 }
5680
5681 // Use the target's redirected device if set and adjust offset and paint
5682 // region accordingly. This is typically the case when people call render
5683 // from the paintEvent.
5684 QPoint offset = targetOffset;
5685 offset -= paintRegion.boundingRect().topLeft();
5686 QPoint redirectionOffset;
5687 QPaintDevice *redirected = nullptr;
5688
5689 if (target->devType() == QInternal::Widget)
5690 redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset);
5691
5692 if (redirected) {
5693 target = redirected;
5694 offset -= redirectionOffset;
5695 }
5696
5697 if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp).
5698 if (QPaintEngine *targetEngine = target->paintEngine()) {
5699 const QRegion targetSystemClip = targetEngine->systemClip();
5700 if (!targetSystemClip.isEmpty())
5701 paintRegion &= targetSystemClip.translated(-offset);
5702 }
5703 }
5704
5705 // Set backingstore flags.
5706 DrawWidgetFlags flags = DrawPaintOnScreen | DrawInvisible;
5707 if (renderFlags & QWidget::DrawWindowBackground)
5708 flags |= DrawAsRoot;
5709
5710 if (renderFlags & QWidget::DrawChildren)
5711 flags |= DrawRecursive;
5712 else
5713 flags |= DontSubtractOpaqueChildren;
5714
5715 flags |= DontSetCompositionMode;
5716
5717 // Render via backingstore.
5718 drawWidget(target, paintRegion, offset, flags, sharedPainter());
5719
5720 // Restore shared painter.
5721 if (oldSharedPainter)
5722 setSharedPainter(oldSharedPainter);
5723}
5724
5725void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn,
5726 const QPoint &offset, DrawWidgetFlags flags
5727 , QPainter *sharedPainter, QWidgetRepaintManager *repaintManager)
5728{
5729 QWidget *w = nullptr;
5730 QRect boundingRect;
5731 bool dirtyBoundingRect = true;
5732 const bool exludeOpaqueChildren = (flags & DontDrawOpaqueChildren);
5733 const bool excludeNativeChildren = (flags & DontDrawNativeChildren);
5734
5735 do {
5736 QWidget *x = qobject_cast<QWidget*>(siblings.at(index));
5737 if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()
5738 && !(excludeNativeChildren && x->internalWinId())) {
5739 if (dirtyBoundingRect) {
5740 boundingRect = rgn.boundingRect();
5741 dirtyBoundingRect = false;
5742 }
5743
5744 if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect))) {
5745 w = x;
5746 break;
5747 }
5748 }
5749 --index;
5750 } while (index >= 0);
5751
5752 if (!w)
5753 return;
5754
5755 QWidgetPrivate *wd = w->d_func();
5756 const QPoint widgetPos(w->data->crect.topLeft());
5757 const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect;
5758 if (index > 0) {
5759 QRegion wr(rgn);
5760 if (wd->isOpaque)
5761 wr -= hasMask ? wd->extra->mask.translated(widgetPos) : w->data->crect;
5762 paintSiblingsRecursive(pdev, siblings, --index, wr, offset, flags,
5763 sharedPainter, repaintManager);
5764 }
5765
5766 if (w->updatesEnabled()
5767#if QT_CONFIG(graphicsview)
5768 && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget)
5769#endif // QT_CONFIG(graphicsview)
5770 ) {
5771 QRegion wRegion(rgn);
5772 wRegion &= wd->effectiveRectFor(w->data->crect);
5773 wRegion.translate(-widgetPos);
5774 if (hasMask)
5775 wRegion &= wd->extra->mask;
5776 wd->drawWidget(pdev, wRegion, offset + widgetPos, flags, sharedPainter, repaintManager);
5777 }
5778}
5779
5780#if QT_CONFIG(graphicseffect)
5781QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
5782{
5783 if (system != Qt::DeviceCoordinates)
5784 return m_widget->rect();
5785
5786 if (Q_UNLIKELY(!context)) {
5787 // Device coordinates without context not yet supported.
5788 qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
5789 return QRectF();
5790 }
5791
5792 return context->painter->worldTransform().mapRect(m_widget->rect());
5793}
5794
5795void QWidgetEffectSourcePrivate::draw(QPainter *painter)
5796{
5797 if (!context || context->painter != painter) {
5798 m_widget->render(painter);
5799 return;
5800 }
5801
5802 // The region saved in the context is neither clipped to the rect
5803 // nor the mask, so we have to clip it here before calling drawWidget.
5804 QRegion toBePainted = context->rgn;
5805 toBePainted &= m_widget->rect();
5806 QWidgetPrivate *wd = qt_widget_private(m_widget);
5807 if (wd->extra && wd->extra->hasMask)
5808 toBePainted &= wd->extra->mask;
5809
5810 wd->drawWidget(context->pdev, toBePainted, context->offset, context->flags,
5811 context->sharedPainter, context->repaintManager);
5812}
5813
5814QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
5815 QGraphicsEffect::PixmapPadMode mode) const
5816{
5817 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
5818 if (Q_UNLIKELY(!context && deviceCoordinates)) {
5819 // Device coordinates without context not yet supported.
5820 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
5821 return QPixmap();
5822 }
5823
5824 QPoint pixmapOffset;
5825 QRectF sourceRect = m_widget->rect();
5826
5827 if (deviceCoordinates) {
5828 const QTransform &painterTransform = context->painter->worldTransform();
5829 sourceRect = painterTransform.mapRect(sourceRect);
5830 pixmapOffset = painterTransform.map(pixmapOffset);
5831 }
5832
5833 QRect effectRect;
5834
5835 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect)
5836 effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
5837 else if (mode == QGraphicsEffect::PadToTransparentBorder)
5838 effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect();
5839 else
5840 effectRect = sourceRect.toAlignedRect();
5841
5842 if (offset)
5843 *offset = effectRect.topLeft();
5844
5845 pixmapOffset -= effectRect.topLeft();
5846
5847 qreal dpr(1.0);
5848 if (const auto *paintDevice = context->painter->device())
5849 dpr = paintDevice->devicePixelRatio();
5850 else
5851 qWarning("QWidgetEffectSourcePrivate::pixmap: Painter not active");
5852 QPixmap pixmap(effectRect.size() * dpr);
5853 pixmap.setDevicePixelRatio(dpr);
5854
5855 pixmap.fill(Qt::transparent);
5856 m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren);
5857 return pixmap;
5858}
5859#endif // QT_CONFIG(graphicseffect)
5860
5861#if QT_CONFIG(graphicsview)
5862/*!
5863 \internal
5864
5865 Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this
5866 widget and its ancestors. The search starts at \a origin (inclusive).
5867 If successful, the function returns the proxy that embeds the widget, or \nullptr if no
5868 embedded widget was found.
5869*/
5870QGraphicsProxyWidget *QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
5871{
5872 if (origin) {
5873 const auto &extra = origin->d_func()->extra;
5874 if (extra && extra->proxyWidget)
5875 return extra->proxyWidget;
5876 return nearestGraphicsProxyWidget(origin->parentWidget());
5877 }
5878 return nullptr;
5879}
5880#endif
5881
5882/*!
5883 \property QWidget::locale
5884 \brief the widget's locale
5885 \since 4.3
5886
5887 As long as no special locale has been set, this is either
5888 the parent's locale or (if this widget is a top level widget),
5889 the default locale.
5890
5891 If the widget displays dates or numbers, these should be formatted
5892 using the widget's locale.
5893
5894 \sa QLocale, QLocale::setDefault()
5895*/
5896
5897void QWidgetPrivate::setLocale_helper(const QLocale &loc, bool forceUpdate)
5898{
5899 Q_Q(QWidget);
5900 if (locale == loc && !forceUpdate)
5901 return;
5902
5903 locale = loc;
5904
5905 if (!children.isEmpty()) {
5906 for (int i = 0; i < children.size(); ++i) {
5907 QWidget *w = qobject_cast<QWidget*>(children.at(i));
5908 if (!w)
5909 continue;
5910 if (w->testAttribute(Qt::WA_SetLocale))
5911 continue;
5912 if (w->isWindow() && !w->testAttribute(Qt::WA_WindowPropagation))
5913 continue;
5914 w->d_func()->setLocale_helper(loc, forceUpdate);
5915 }
5916 }
5917 QEvent e(QEvent::LocaleChange);
5918 QCoreApplication::sendEvent(q, &e);
5919}
5920
5921void QWidget::setLocale(const QLocale &locale)
5922{
5923 Q_D(QWidget);
5924
5925 setAttribute(Qt::WA_SetLocale);
5926 d->setLocale_helper(locale);
5927}
5928
5929QLocale QWidget::locale() const
5930{
5931 Q_D(const QWidget);
5932
5933 return d->locale;
5934}
5935
5936void QWidgetPrivate::resolveLocale()
5937{
5938 Q_Q(const QWidget);
5939
5940 if (!q->testAttribute(Qt::WA_SetLocale)) {
5941 QWidget *parent = q->parentWidget();
5942 setLocale_helper(!parent || (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
5943 ? QLocale() : parent->locale());
5944 }
5945}
5946
5947void QWidget::unsetLocale()
5948{
5949 Q_D(QWidget);
5950 setAttribute(Qt::WA_SetLocale, false);
5951 d->resolveLocale();
5952}
5953
5954/*!
5955 \property QWidget::windowTitle
5956 \brief the window title (caption)
5957
5958 This property only makes sense for top-level widgets, such as
5959 windows and dialogs. If no caption has been set, the title is based of the
5960 \l windowFilePath. If neither of these is set, then the title is
5961 an empty string.
5962
5963 If you use the \l windowModified mechanism, the window title must
5964 contain a "[*]" placeholder, which indicates where the '*' should
5965 appear. Normally, it should appear right after the file name
5966 (e.g., "document1.txt[*] - Text Editor"). If the \l
5967 windowModified property is \c false (the default), the placeholder
5968 is simply removed.
5969
5970 On some desktop platforms (including Windows and Unix), the application name
5971 (from QGuiApplication::applicationDisplayName) is added at the end of the
5972 window title, if set. This is done by the QPA plugin, so it is shown to the
5973 user, but isn't part of the windowTitle string.
5974
5975 \sa windowIcon, windowModified, windowFilePath
5976*/
5977QString QWidget::windowTitle() const
5978{
5979 Q_D(const QWidget);
5980 if (d->extra && d->extra->topextra) {
5981 if (!d->extra->topextra->caption.isEmpty())
5982 return d->extra->topextra->caption;
5983 if (!d->extra->topextra->filePath.isEmpty())
5984 return QFileInfo(d->extra->topextra->filePath).fileName() + "[*]"_L1;
5985 }
5986 return QString();
5987}
5988
5989/*!
5990 Returns a modified window title with the [*] place holder
5991 replaced according to the rules described in QWidget::setWindowTitle
5992
5993 This function assumes that "[*]" can be quoted by another
5994 "[*]", so it will replace two place holders by one and
5995 a single last one by either "*" or nothing depending on
5996 the modified flag.
5997
5998 \internal
5999*/
6000QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget)
6001{
6002 Q_ASSERT(widget);
6003
6004 QString cap = title;
6005 if (cap.isEmpty())
6006 return cap;
6007
6008 const auto placeHolder = "[*]"_L1;
6009 int index = cap.indexOf(placeHolder);
6010
6011 // here the magic begins
6012 while (index != -1) {
6013 index += placeHolder.size();
6014 int count = 1;
6015 while (cap.indexOf(placeHolder, index) == index) {
6016 ++count;
6017 index += placeHolder.size();
6018 }
6019
6020 if (count%2) { // odd number of [*] -> replace last one
6021 int lastIndex = cap.lastIndexOf(placeHolder, index - 1);
6022 if (widget->isWindowModified()
6023 && widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, nullptr, widget))
6024 cap.replace(lastIndex, 3, QWidget::tr("*"));
6025 else
6026 cap.remove(lastIndex, 3);
6027 }
6028
6029 index = cap.indexOf(placeHolder, index);
6030 }
6031
6032 cap.replace("[*][*]"_L1, placeHolder);
6033
6034 return cap;
6035}
6036
6037void QWidgetPrivate::setWindowTitle_helper(const QString &title)
6038{
6039 Q_Q(QWidget);
6040 if (q->testAttribute(Qt::WA_WState_Created))
6041 setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q));
6042}
6043
6044void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
6045{
6046 Q_Q(QWidget);
6047 if (!q->isWindow())
6048 return;
6049
6050 if (QWindow *window = q->windowHandle())
6051 {
6052#if QT_CONFIG(accessibility)
6053 QString oldAccessibleName;
6054 const QAccessibleInterface *accessible = QAccessible::isActive()
6055 ? QAccessible::queryAccessibleInterface(q)
6056 : nullptr;
6057 if (accessible)
6058 oldAccessibleName = accessible->text(QAccessible::Name);
6059#endif
6060
6061 window->setTitle(caption);
6062
6063#if QT_CONFIG(accessibility)
6064 if (accessible && accessible->text(QAccessible::Name) != oldAccessibleName) {
6065 QAccessibleEvent event(q, QAccessible::NameChanged);
6066 QAccessible::updateAccessibility(&event);
6067 }
6068#endif
6069 }
6070}
6071
6072void QWidgetPrivate::setWindowIconText_helper(const QString &title)
6073{
6074 Q_Q(QWidget);
6075 if (q->testAttribute(Qt::WA_WState_Created))
6076 setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, q));
6077}
6078
6079void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
6080{
6081#if QT_CONFIG(xcb)
6082 Q_Q(QWidget);
6083 // ### The QWidget property is deprecated, but the XCB window function is not.
6084 // It should remain available for the rare application that needs it.
6085 if (QWindow *window = q->windowHandle()) {
6086 if (auto *xcbWindow = dynamic_cast<QXcbWindow*>(window->handle()))
6087 xcbWindow->setWindowIconText(iconText);
6088 }
6089#else
6090 Q_UNUSED(iconText);
6091#endif
6092}
6093
6094/*!
6095 \fn void QWidget::windowIconTextChanged(const QString &iconText)
6096
6097 This signal is emitted when the window's icon text has changed, with the
6098 new \a iconText as an argument.
6099
6100 \since 5.2
6101 \deprecated
6102
6103 This signal is deprecated.
6104*/
6105
6106void QWidget::setWindowIconText(const QString &iconText)
6107{
6108 if (QWidget::windowIconText() == iconText)
6109 return;
6110
6111 Q_D(QWidget);
6112 d->topData()->iconText = iconText;
6113 d->setWindowIconText_helper(iconText);
6114
6115 QEvent e(QEvent::IconTextChange);
6116 QCoreApplication::sendEvent(this, &e);
6117
6118 emit windowIconTextChanged(iconText);
6119}
6120
6121/*!
6122 \fn void QWidget::windowTitleChanged(const QString &title)
6123
6124 This signal is emitted when the window's title has changed, with the
6125 new \a title as an argument.
6126
6127 \since 5.2
6128*/
6129
6130void QWidget::setWindowTitle(const QString &title)
6131{
6132 if (QWidget::windowTitle() == title && !title.isEmpty() && !title.isNull())
6133 return;
6134
6135 Q_D(QWidget);
6136 d->topData()->caption = title;
6137 d->setWindowTitle_helper(title);
6138
6139 QEvent e(QEvent::WindowTitleChange);
6140 QCoreApplication::sendEvent(this, &e);
6141
6142 emit windowTitleChanged(title);
6143}
6144
6145
6146/*!
6147 \property QWidget::windowIcon
6148 \brief the widget's icon
6149
6150 This property only makes sense for windows. If no icon
6151 has been set, windowIcon() returns the application icon
6152 (QApplication::windowIcon()).
6153
6154 \note On \macos, window icons represent the active document,
6155 and will not be displayed unless a file path has also been
6156 set using setWindowFilePath.
6157
6158 \sa windowTitle, setWindowFilePath
6159*/
6160QIcon QWidget::windowIcon() const
6161{
6162 const QWidget *w = this;
6163 while (w) {
6164 const QWidgetPrivate *d = w->d_func();
6165 if (d->extra && d->extra->topextra && d->extra->topextra->icon)
6166 return *d->extra->topextra->icon;
6167 w = w->parentWidget();
6168 }
6169 return QApplication::windowIcon();
6170}
6171
6172void QWidgetPrivate::setWindowIcon_helper()
6173{
6174 Q_Q(QWidget);
6175 QEvent e(QEvent::WindowIconChange);
6176
6177 // Do not send the event if the widget is a top level.
6178 // In that case, setWindowIcon_sys does it, and event propagation from
6179 // QWidgetWindow to the top level QWidget ensures that the event reaches
6180 // the top level anyhow
6181 if (!q->windowHandle())
6182 QCoreApplication::sendEvent(q, &e);
6183 for (int i = 0; i < children.size(); ++i) {
6184 QWidget *w = qobject_cast<QWidget *>(children.at(i));
6185 if (w && !w->isWindow())
6186 QCoreApplication::sendEvent(w, &e);
6187 }
6188}
6189
6190/*!
6191 \fn void QWidget::windowIconChanged(const QIcon &icon)
6192
6193 This signal is emitted when the window's icon has changed, with the
6194 new \a icon as an argument.
6195
6196 \since 5.2
6197*/
6198
6199void QWidget::setWindowIcon(const QIcon &icon)
6200{
6201 Q_D(QWidget);
6202
6203 setAttribute(Qt::WA_SetWindowIcon, !icon.isNull());
6204 d->createTLExtra();
6205
6206 if (!d->extra->topextra->icon)
6207 d->extra->topextra->icon = std::make_unique<QIcon>(icon);
6208 else
6209 *d->extra->topextra->icon = icon;
6210
6211 d->setWindowIcon_sys();
6212 d->setWindowIcon_helper();
6213
6214 emit windowIconChanged(icon);
6215}
6216
6217void QWidgetPrivate::setWindowIcon_sys()
6218{
6219 Q_Q(QWidget);
6220 if (QWindow *window = q->windowHandle())
6221 window->setIcon(q->windowIcon());
6222}
6223
6224/*!
6225 \property QWidget::windowIconText
6226 \brief the text to be displayed on the icon of a minimized window
6227
6228 This property only makes sense for windows. If no icon
6229 text has been set, this accessor returns an empty string.
6230 It is only implemented on the X11 platform, and only certain
6231 window managers use this window property.
6232
6233 \deprecated
6234 This property is deprecated.
6235
6236 \sa windowIcon, windowTitle
6237*/
6238
6239QString QWidget::windowIconText() const
6240{
6241 Q_D(const QWidget);
6242 return (d->extra && d->extra->topextra) ? d->extra->topextra->iconText : QString();
6243}
6244
6245/*!
6246 \property QWidget::windowFilePath
6247 \since 4.4
6248 \brief the file path associated with a widget
6249
6250 This property only makes sense for windows. It associates a file path with
6251 a window. If you set the file path, but have not set the window title, Qt
6252 sets the window title to the file name of the specified path, obtained using
6253 QFileInfo::fileName().
6254
6255 If the window title is set at any point, then the window title takes precedence and
6256 will be shown instead of the file path string.
6257
6258 Additionally, on \macos, this has an added benefit that it sets the
6259 \l{http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGWindows/chapter_17_section_3.html}{proxy icon}
6260 for the window, assuming that the file path exists.
6261
6262 If no file path is set, this property contains an empty string.
6263
6264 By default, this property contains an empty string.
6265
6266 \sa windowTitle, windowIcon
6267*/
6268
6269QString QWidget::windowFilePath() const
6270{
6271 Q_D(const QWidget);
6272 return (d->extra && d->extra->topextra) ? d->extra->topextra->filePath : QString();
6273}
6274
6275void QWidget::setWindowFilePath(const QString &filePath)
6276{
6277 if (filePath == windowFilePath())
6278 return;
6279
6280 Q_D(QWidget);
6281
6282 d->createTLExtra();
6283 d->extra->topextra->filePath = filePath;
6284 d->setWindowFilePath_helper(filePath);
6285}
6286
6287void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath)
6288{
6289 if (extra->topextra && extra->topextra->caption.isEmpty()) {
6290#ifdef Q_OS_MAC
6291 setWindowTitle_helper(QFileInfo(filePath).fileName());
6292#else
6293 Q_Q(QWidget);
6294 Q_UNUSED(filePath);
6295 setWindowTitle_helper(q->windowTitle());
6296#endif
6297 }
6298#ifdef Q_OS_MAC
6299 setWindowFilePath_sys(filePath);
6300#endif
6301}
6302
6303void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
6304{
6305 Q_Q(QWidget);
6306 if (!q->isWindow())
6307 return;
6308
6309 if (QWindow *window = q->windowHandle())
6310 window->setFilePath(filePath);
6311}
6312
6313/*!
6314 Returns the window's role, or an empty string.
6315
6316 \sa windowIcon, windowTitle
6317*/
6318
6319QString QWidget::windowRole() const
6320{
6321 Q_D(const QWidget);
6322 return (d->extra && d->extra->topextra) ? d->extra->topextra->role : QString();
6323}
6324
6325/*!
6326 Sets the window's role to \a role. This only makes sense for
6327 windows on X11.
6328*/
6329void QWidget::setWindowRole(const QString &role)
6330{
6331#if QT_CONFIG(xcb)
6332 Q_D(QWidget);
6333 d->createTLExtra();
6334 d->topData()->role = role;
6335 if (windowHandle()) {
6336 if (auto *xcbWindow = dynamic_cast<QXcbWindow*>(windowHandle()->handle()))
6337 xcbWindow->setWindowRole(role);
6338 }
6339#else
6340 Q_UNUSED(role);
6341#endif
6342}
6343
6344/*!
6345 \property QWidget::mouseTracking
6346 \brief whether mouse tracking is enabled for the widget
6347
6348 If mouse tracking is disabled (the default), the widget only
6349 receives mouse move events when at least one mouse button is
6350 pressed while the mouse is being moved.
6351
6352 If mouse tracking is enabled, the widget receives mouse move
6353 events even if no buttons are pressed.
6354
6355 \sa mouseMoveEvent()
6356*/
6357
6358/*!
6359 \property QWidget::tabletTracking
6360 \brief whether tablet tracking is enabled for the widget
6361 \since 5.9
6362
6363 If tablet tracking is disabled (the default), the widget only
6364 receives tablet move events when the stylus is in contact with
6365 the tablet, or at least one stylus button is pressed,
6366 while the stylus is being moved.
6367
6368 If tablet tracking is enabled, the widget receives tablet move
6369 events even while hovering in proximity. This is useful for
6370 monitoring position as well as the auxiliary properties such
6371 as rotation and tilt, and providing feedback in the UI.
6372
6373 \sa tabletEvent()
6374*/
6375
6376
6377/*!
6378 Sets the widget's focus proxy to widget \a w. If \a w is \nullptr, the
6379 function resets this widget to have no focus proxy.
6380
6381 Some widgets can "have focus", but create a child widget, such as
6382 QLineEdit, to actually handle the focus. In this case, the widget
6383 can set the line edit to be its focus proxy.
6384
6385 setFocusProxy() sets the widget which will actually get focus when
6386 "this widget" gets it. If there is a focus proxy, setFocus() and
6387 hasFocus() operate on the focus proxy. If "this widget" is the focus
6388 widget, then setFocusProxy() moves focus to the new focus proxy.
6389
6390 \sa focusProxy()
6391*/
6392
6393void QWidget::setFocusProxy(QWidget * w)
6394{
6395 Q_D(QWidget);
6396 if (!w && !d->extra)
6397 return;
6398
6399 for (QWidget* fp = w; fp; fp = fp->focusProxy()) {
6400 if (Q_UNLIKELY(fp == this)) {
6401 qWarning("QWidget: %s (%s) already in focus proxy chain", metaObject()->className(), objectName().toLocal8Bit().constData());
6402 return;
6403 }
6404 }
6405
6406 const bool moveFocusToProxy = (QApplicationPrivate::focus_widget == this);
6407
6408 d->createExtra();
6409 d->extra->focus_proxy = w;
6410
6411 if (w && isAncestorOf(w)) {
6412 // If the focus proxy is a child of this (so this is a compound widget), then
6413 // we need to make sure that this widget is immediately in front of its own children
6414 // in the focus chain. Otherwise focusNextPrev_helper might jump over unrelated
6415 // widgets that are positioned between this compound widget, and its proxy in
6416 // the focus chain.
6417 const QWidget *parentOfW = w->parentWidget();
6418 Q_ASSERT(parentOfW); // can't be nullptr since we are an ancestor of w
6419 QWidget *firstChild = nullptr;
6420 const auto childList = children();
6421 for (QObject *child : childList) {
6422 if ((firstChild = qobject_cast<QWidget *>(child)))
6423 break;
6424 }
6425 Q_ASSERT(firstChild); // can't be nullptr since w is a child
6426 d->insertIntoFocusChainBefore(firstChild);
6427 } else if (w && w->isAncestorOf(this)) {
6428 // If the focus proxy is a parent, 'this' has to be inserted directly after its parent in the focus chain
6429 // remove it from the chain and insert this into the focus chain after its parent
6430
6431 // is this the case already?
6432 QWidget *parentsNext = w->nextInFocusChain();
6433 if (parentsNext == this) {
6434 // nothing to do.
6435 Q_ASSERT(previousInFocusChain() == w);
6436 } else {
6437 d->QWidgetPrivate::insertIntoFocusChainAfter(w);
6438 }
6439 }
6440
6441 if (moveFocusToProxy)
6442 setFocus(Qt::OtherFocusReason);
6443}
6444
6445
6446/*!
6447 Returns the focus proxy, or \nullptr if there is no focus proxy.
6448
6449 \sa setFocusProxy()
6450*/
6451
6452QWidget *QWidget::focusProxy() const
6453{
6454 Q_D(const QWidget);
6455 return d->extra ? d->extra->focus_proxy.data() : nullptr;
6456}
6457
6458
6459/*!
6460 \property QWidget::focus
6461 \brief whether this widget (or its focus proxy) has the keyboard
6462 input focus
6463
6464 By default, this property is \c false.
6465
6466 \note Obtaining the value of this property for a widget is effectively equivalent
6467 to checking whether QApplication::focusWidget() refers to the widget.
6468
6469 \sa setFocus(), clearFocus(), setFocusPolicy(), QApplication::focusWidget()
6470*/
6471bool QWidget::hasFocus() const
6472{
6473 const QWidget* w = this;
6474 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
6475 w = w->d_func()->extra->focus_proxy;
6476#if QT_CONFIG(graphicsview)
6477 if (QWidget *window = w->window()) {
6478 const auto &e = window->d_func()->extra;
6479 if (e && e->proxyWidget && e->proxyWidget->hasFocus() && window->focusWidget() == w)
6480 return true;
6481 }
6482#endif // QT_CONFIG(graphicsview)
6483 return (QApplication::focusWidget() == w);
6484}
6485
6486/*!
6487 Gives the keyboard input focus to this widget (or its focus
6488 proxy) if this widget or one of its parents is the \l{isActiveWindow()}{active window}. The \a reason argument will
6489 be passed into any focus event sent from this function, it is used
6490 to give an explanation of what caused the widget to get focus.
6491 If the window is not active, the widget will be given the focus when
6492 the window becomes active.
6493
6494 First, a focus about to change event is sent to the focus widget (if any) to
6495 tell it that it is about to lose the focus. Then focus is changed, a
6496 focus out event is sent to the previous focus item and a focus in event is sent
6497 to the new item to tell it that it just received the focus.
6498 (Nothing happens if the focus in and focus out widgets are the
6499 same.)
6500
6501 \note On embedded platforms, setFocus() will not cause an input panel
6502 to be opened by the input method. If you want this to happen, you
6503 have to send a QEvent::RequestSoftwareInputPanel event to the
6504 widget yourself.
6505
6506 setFocus() gives focus to a widget regardless of its focus policy,
6507 but does not clear any keyboard grab (see grabKeyboard()).
6508
6509 Be aware that if the widget is hidden, it will not accept focus
6510 until it is shown.
6511
6512 \warning If you call setFocus() in a function which may itself be
6513 called from focusOutEvent() or focusInEvent(), you may get an
6514 infinite recursion.
6515
6516 \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(),
6517 setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(),
6518 grabMouse(), {Keyboard Focus in Widgets}, QEvent::RequestSoftwareInputPanel
6519*/
6520
6521void QWidget::setFocus(Qt::FocusReason reason)
6522{
6523 if (!isEnabled())
6524 return;
6525
6526 QWidget *f = d_func()->deepestFocusProxy();
6527 if (!f)
6528 f = this;
6529
6530 if (QApplication::focusWidget() == f)
6531 return;
6532
6533#if QT_CONFIG(graphicsview)
6534 QWidget *previousProxyFocus = nullptr;
6535 if (const auto &topData = window()->d_func()->extra) {
6536 if (topData->proxyWidget && topData->proxyWidget->hasFocus()) {
6537 previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
6538 if (previousProxyFocus && previousProxyFocus->focusProxy())
6539 previousProxyFocus = previousProxyFocus->focusProxy();
6540 if (previousProxyFocus == f && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
6541 return;
6542 }
6543 }
6544#endif
6545
6546#if QT_CONFIG(graphicsview)
6547 // Update proxy state
6548 if (const auto &topData = window()->d_func()->extra) {
6549 if (topData->proxyWidget && !topData->proxyWidget->hasFocus()) {
6550 f->d_func()->updateFocusChild();
6551 topData->proxyWidget->d_func()->focusFromWidgetToProxy = 1;
6552 topData->proxyWidget->setFocus(reason);
6553 topData->proxyWidget->d_func()->focusFromWidgetToProxy = 0;
6554 }
6555 }
6556#endif
6557
6558 if (f->isActiveWindow()) {
6559 QWidget *prev = QApplicationPrivate::focus_widget;
6560 if (prev) {
6561 if (reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason
6562 && prev->testAttribute(Qt::WA_InputMethodEnabled)) {
6563 QGuiApplication::inputMethod()->commit();
6564 }
6565
6566 if (reason != Qt::NoFocusReason) {
6567 QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange, reason);
6568 QCoreApplication::sendEvent(prev, &focusAboutToChange);
6569 }
6570 }
6571
6572 f->d_func()->updateFocusChild();
6573
6574 QApplicationPrivate::setFocusWidget(f, reason);
6575#if QT_CONFIG(accessibility)
6576 // menus update the focus manually and this would create bogus events
6577 if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem")))
6578 {
6579 QAccessibleEvent event(f, QAccessible::Focus);
6580 QAccessible::updateAccessibility(&event);
6581 }
6582#endif
6583#if QT_CONFIG(graphicsview)
6584 if (const auto &topData = window()->d_func()->extra) {
6585 if (topData->proxyWidget) {
6586 if (previousProxyFocus && previousProxyFocus != f) {
6587 // Send event to self
6588 QFocusEvent event(QEvent::FocusOut, reason);
6589 QPointer<QWidget> that = previousProxyFocus;
6590 QCoreApplication::sendEvent(previousProxyFocus, &event);
6591 if (that)
6592 QCoreApplication::sendEvent(that->style(), &event);
6593 }
6594 if (!isHidden()) {
6595#if QT_CONFIG(graphicsview)
6596 // Update proxy state
6597 if (const auto &topData = window()->d_func()->extra)
6598 if (topData->proxyWidget && topData->proxyWidget->hasFocus())
6599 topData->proxyWidget->d_func()->updateProxyInputMethodAcceptanceFromWidget();
6600#endif
6601 // Send event to self
6602 QFocusEvent event(QEvent::FocusIn, reason);
6603 QPointer<QWidget> that = f;
6604 QCoreApplication::sendEvent(f, &event);
6605 if (that)
6606 QCoreApplication::sendEvent(that->style(), &event);
6607 }
6608 }
6609 }
6610#endif
6611 } else {
6612 f->d_func()->updateFocusChild();
6613 }
6614}
6615
6616
6617/*!\internal
6618 * A focus proxy can have its own focus proxy, which can have its own
6619 * proxy, and so on. This helper function returns the widget that sits
6620 * at the bottom of the proxy chain, and therefore the one that should
6621 * normally get focus if this widget receives a focus request.
6622 */
6623QWidget *QWidgetPrivate::deepestFocusProxy() const
6624{
6625 Q_Q(const QWidget);
6626
6627 QWidget *focusProxy = q->focusProxy();
6628 if (!focusProxy)
6629 return nullptr;
6630
6631 while (QWidget *nextFocusProxy = focusProxy->focusProxy())
6632 focusProxy = nextFocusProxy;
6633
6634 return focusProxy;
6635}
6636
6637static inline bool isEmbedded(const QWindow *w)
6638{
6639 const auto platformWindow = w->handle();
6640 return platformWindow && platformWindow->isEmbedded();
6641}
6642
6643void QWidgetPrivate::setFocus_sys()
6644{
6645 Q_Q(QWidget);
6646 // Embedded native widget may have taken the focus; get it back to toplevel
6647 // if that is the case (QTBUG-25852), unless widget is a window container.
6648 if (extra && extra->hasWindowContainer)
6649 return;
6650 // Do not activate in case the popup menu opens another application (QTBUG-70810)
6651 // unless the application is embedded (QTBUG-71991).
6652 if (QWindow *nativeWindow = q->testAttribute(Qt::WA_WState_Created) ? q->window()->windowHandle() : nullptr) {
6653 if (nativeWindow->type() != Qt::Popup && nativeWindow != QGuiApplication::focusWindow()
6654 && (QGuiApplication::applicationState() == Qt::ApplicationActive
6655 || QCoreApplication::testAttribute(Qt::AA_PluginApplication)
6656 || isEmbedded(nativeWindow))) {
6657 nativeWindow->requestActivate();
6658 }
6659 }
6660}
6661
6662// updates focus_child on parent widgets to point into this widget
6663void QWidgetPrivate::updateFocusChild()
6664{
6665 Q_Q(QWidget);
6666
6667 QWidget *w = q;
6668 if (q->isHidden()) {
6669 while (w && w->isHidden()) {
6670 w->d_func()->focus_child = q;
6671 w = w->isWindow() ? nullptr : w->parentWidget();
6672 }
6673 } else {
6674 while (w) {
6675 w->d_func()->focus_child = q;
6676 w = w->isWindow() ? nullptr : w->parentWidget();
6677 }
6678 }
6679
6680 if (QTLWExtra *extra = q->window()->d_func()->maybeTopData()) {
6681 if (extra->window)
6682 emit extra->window->focusObjectChanged(q);
6683 }
6684}
6685
6686/*!
6687 \fn void QWidget::setFocus()
6688 \overload
6689
6690 Gives the keyboard input focus to this widget (or its focus
6691 proxy) if this widget or one of its parents is the
6692 \l{isActiveWindow()}{active window}.
6693*/
6694
6695/*!
6696 Takes keyboard input focus from the widget.
6697
6698 If the widget has active focus, a \l{focusOutEvent()}{focus out event} is sent to this widget to tell it that it has
6699 lost the focus.
6700
6701 This widget must enable focus setting to get the keyboard
6702 input focus; that is, it must call setFocusPolicy().
6703
6704 \sa hasFocus(), setFocus(), focusInEvent(), focusOutEvent(),
6705 setFocusPolicy(), QApplication::focusWidget()
6706*/
6707
6708void QWidget::clearFocus()
6709{
6710 if (hasFocus()) {
6711 if (testAttribute(Qt::WA_InputMethodEnabled))
6712 QGuiApplication::inputMethod()->commit();
6713
6714 QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange);
6715 QCoreApplication::sendEvent(this, &focusAboutToChange);
6716 }
6717
6718 QTLWExtra *extra = window()->d_func()->maybeTopData();
6719 QObject *originalFocusObject = nullptr;
6720 if (extra && extra->window) {
6721 originalFocusObject = extra->window->focusObject();
6722 // the window's focus object might already be nullptr if we are in the destructor, but we still
6723 // need to update QGuiApplication and input context if we have a focus widget.
6724 if (!originalFocusObject)
6725 originalFocusObject = focusWidget();
6726 }
6727
6728 QWidget *w = this;
6729 while (w) {
6730 // Just like setFocus(), we update (clear) the focus_child of our parents
6731 if (w->d_func()->focus_child == this)
6732 w->d_func()->focus_child = nullptr;
6733 w = w->parentWidget();
6734 }
6735
6736 // We've potentially cleared the focus_child of our parents, so we need
6737 // to report this to the rest of Qt. Note that the focus_child is not the same
6738 // thing as the application's focusWidget, which is why this piece of code is
6739 // not inside a hasFocus() block.
6740 if (originalFocusObject && originalFocusObject != extra->window->focusObject())
6741 emit extra->window->focusObjectChanged(extra->window->focusObject());
6742
6743#if QT_CONFIG(graphicsview)
6744 const auto &topData = d_func()->extra;
6745 if (topData && topData->proxyWidget)
6746 topData->proxyWidget->clearFocus();
6747#endif
6748
6749 if (hasFocus()) {
6750 // Update proxy state
6751 QApplicationPrivate::setFocusWidget(nullptr, Qt::OtherFocusReason);
6752#if QT_CONFIG(accessibility)
6753 QAccessibleEvent event(this, QAccessible::Focus);
6754 QAccessible::updateAccessibility(&event);
6755#endif
6756 }
6757}
6758
6759
6760/*!
6761 \fn bool QWidget::focusNextChild()
6762
6763 Finds a new widget to give the keyboard focus to, as appropriate
6764 for \uicontrol Tab, and returns \c true if it can find a new widget, or
6765 false if it can't.
6766
6767 \sa focusPreviousChild()
6768*/
6769
6770/*!
6771 \fn bool QWidget::focusPreviousChild()
6772
6773 Finds a new widget to give the keyboard focus to, as appropriate
6774 for \uicontrol Shift+Tab, and returns \c true if it can find a new widget,
6775 or false if it can't.
6776
6777 \sa focusNextChild()
6778*/
6779
6780/*!
6781 Finds a new widget to give the keyboard focus to, as appropriate
6782 for Tab and Shift+Tab, and returns \c true if it can find a new
6783 widget, or false if it can't.
6784
6785 If \a next is true, this function searches forward, if \a next
6786 is false, it searches backward.
6787
6788 Sometimes, you will want to reimplement this function. For
6789 example, a web browser might reimplement it to move its "current
6790 active link" forward or backward, and call
6791 focusNextPrevChild() only when it reaches the last or
6792 first link on the "page".
6793
6794 Child widgets call focusNextPrevChild() on their parent widgets,
6795 but only the window that contains the child widgets decides where
6796 to redirect focus. By reimplementing this function for an object,
6797 you thus gain control of focus traversal for all child widgets.
6798
6799 \sa focusNextChild(), focusPreviousChild()
6800*/
6801
6802bool QWidget::focusNextPrevChild(bool next)
6803{
6804 QWidget* p = parentWidget();
6805 bool isSubWindow = (windowType() == Qt::SubWindow);
6806 if (!isWindow() && !isSubWindow && p)
6807 return p->focusNextPrevChild(next);
6808#if QT_CONFIG(graphicsview)
6809 Q_D(QWidget);
6810 if (d->extra && d->extra->proxyWidget)
6811 return d->extra->proxyWidget->focusNextPrevChild(next);
6812#endif
6813
6814 bool wrappingOccurred = false;
6815 QWidget *w = QApplicationPrivate::focusNextPrevChild_helper(this, next,
6816 &wrappingOccurred);
6817 if (!w) return false;
6818
6819 Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;
6820
6821 /* If we are about to wrap the focus chain, give the platform
6822 * implementation a chance to alter the wrapping behavior. This is
6823 * especially needed when the window is embedded in a window created by
6824 * another process.
6825 */
6826 if (wrappingOccurred) {
6827 QWindow *window = windowHandle();
6828 if (window != nullptr) {
6829 QWindowPrivate *winp = qt_window_private(window);
6830
6831 if (winp->platformWindow != nullptr) {
6832 QFocusEvent event(QEvent::FocusIn, reason);
6833 event.ignore();
6834 winp->platformWindow->windowEvent(&event);
6835 if (event.isAccepted()) return true;
6836 }
6837 }
6838 }
6839
6840 w->setFocus(reason);
6841 return true;
6842}
6843
6844/*!
6845 Returns the last child of this widget that setFocus had been
6846 called on. For top level widgets this is the widget that will get
6847 focus in case this window gets activated
6848
6849 This is not the same as QApplication::focusWidget(), which returns
6850 the focus widget in the currently active window.
6851*/
6852
6853QWidget *QWidget::focusWidget() const
6854{
6855 return const_cast<QWidget *>(d_func()->focus_child);
6856}
6857
6858QObject *QWidgetPrivate::focusObject()
6859{
6860 Q_Q(QWidget);
6861 QWidget *proxy = deepestFocusProxy();
6862 return proxy ? proxy : q;
6863}
6864
6865/*!
6866 Returns the next widget in this widget's focus chain.
6867
6868 \sa previousInFocusChain()
6869*/
6870QWidget *QWidget::nextInFocusChain() const
6871{
6872 Q_D(const QWidget);
6873 return d->nextPrevElementInFocusChain(QWidgetPrivate::FocusDirection::Next);
6874}
6875
6876/*!
6877 \brief The previousInFocusChain function returns the previous
6878 widget in this widget's focus chain.
6879
6880 \sa nextInFocusChain()
6881
6882 \since 4.6
6883*/
6884QWidget *QWidget::previousInFocusChain() const
6885{
6886 Q_D(const QWidget);
6887 return d->nextPrevElementInFocusChain(QWidgetPrivate::FocusDirection::Previous);
6888}
6889
6890/*!
6891 \property QWidget::isActiveWindow
6892 \brief whether this widget's window is the active window
6893
6894 The active window is the window that contains the widget that has
6895 keyboard focus (The window may still have focus if it has no
6896 widgets or none of its widgets accepts keyboard focus).
6897
6898 When popup windows are visible, this property is \c true for both the
6899 active window \e and for the popup.
6900
6901 By default, this property is \c false.
6902
6903 \sa activateWindow(), QApplication::activeWindow()
6904*/
6905bool QWidget::isActiveWindow() const
6906{
6907 QWidget *tlw = window();
6908 if (tlw == QApplication::activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup)))
6909 return true;
6910
6911#if QT_CONFIG(graphicsview)
6912 if (const auto &tlwExtra = tlw->d_func()->extra) {
6913 if (isVisible() && tlwExtra->proxyWidget)
6914 return tlwExtra->proxyWidget->isActiveWindow();
6915 }
6916#endif
6917
6918 if (style()->styleHint(QStyle::SH_Widget_ShareActivation, nullptr, this)) {
6919 if (tlw->windowType() == Qt::Tool &&
6920 !tlw->isModal() &&
6921 (!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
6922 return true;
6923 QWidget *w = QApplication::activeWindow();
6924 while(w && tlw->windowType() == Qt::Tool &&
6925 !w->isModal() && w->parentWidget()) {
6926 w = w->parentWidget()->window();
6927 if (w == tlw)
6928 return true;
6929 }
6930 }
6931
6932 // Check for an active window container
6933 if (QWindow *ww = QGuiApplication::focusWindow()) {
6934 while (ww) {
6935 QWidgetWindow *qww = qobject_cast<QWidgetWindow *>(ww);
6936 QWindowContainer *qwc = qww ? qobject_cast<QWindowContainer *>(qww->widget()) : 0;
6937 if (qwc && qwc->topLevelWidget() == tlw)
6938 return true;
6939 ww = ww->parent();
6940 }
6941 }
6942
6943 // Check if platform adaptation thinks the window is active. This is necessary for
6944 // example in case of ActiveQt servers that are embedded into another application.
6945 // Those are separate processes that are not part of the parent application Qt window/widget
6946 // hierarchy, so they need to rely on native methods to determine if they are part of the
6947 // active window.
6948 if (const QWindow *w = tlw->windowHandle()) {
6949 if (w->handle())
6950 return w->handle()->isActive();
6951 }
6952
6953 return false;
6954}
6955
6956/*!
6957 \fn void QWidget::setTabOrder(std::initializer_list<QWidget *> widgets)
6958 \overload
6959 \since 6.6
6960
6961 Sets the tab order for the widgets in the \a widgets list by calling
6962 \l{QWidget::setTabOrder(QWidget *, QWidget *)} for each consecutive
6963 pair of widgets.
6964
6965 Instead of setting up each pair manually like this:
6966
6967 \snippet code/src_gui_kernel_qwidget.cpp 9
6968
6969 you can call:
6970
6971 \snippet code/src_gui_kernel_qwidget.cpp 9.list
6972
6973 The call does not create a closed tab focus loop. If there are more widgets
6974 with \l{Qt::TabFocus} focus policy, tabbing on \c{d} will move focus to one
6975 of those widgets, not back to \c{a}.
6976
6977 \sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus in Widgets}
6978*/
6979
6980/*!
6981 Puts the \a second widget after the \a first widget in the focus order.
6982
6983 It effectively removes the \a second widget from its focus chain and
6984 inserts it after the \a first widget.
6985
6986 Note that since the tab order of the \a second widget is changed, you
6987 should order a chain like this:
6988
6989 \snippet code/src_gui_kernel_qwidget.cpp 9
6990
6991 \e not like this:
6992
6993 \snippet code/src_gui_kernel_qwidget.cpp 10
6994
6995 If \a first or \a second has a focus proxy, setTabOrder()
6996 correctly substitutes the proxy.
6997
6998 \note Since Qt 5.10: A widget that has a child as focus proxy is understood as
6999 a compound widget. When setting a tab order between one or two compound widgets, the
7000 local tab order inside each will be preserved. This means that if both widgets are
7001 compound widgets, the resulting tab order will be from the last child inside
7002 \a first, to the first child inside \a second.
7003
7004 \sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus in Widgets}
7005*/
7006void QWidget::setTabOrder(QWidget* first, QWidget *second)
7007{
7008 if (!first || !second || first == second
7009 || first->focusPolicy() == Qt::NoFocus
7010 || second->focusPolicy() == Qt::NoFocus)
7011 return;
7012
7013 if (Q_UNLIKELY(first->window() != second->window())) {
7014 qWarning("QWidget::setTabOrder: 'first' and 'second' must be in the same window");
7015 return;
7016 }
7017
7018 const auto determineLastFocusChild = [](QWidget *target, QWidget *noFurtherThan)
7019 {
7020 // Since we need to repeat the same logic for both 'first' and 'second', we add a function that
7021 // determines the last focus child for a widget, taking proxies and compound widgets into account.
7022 // If the target is not a compound widget (it doesn't have a focus proxy that points to a child),
7023 // 'lastFocusChild' will be set to the target itself.
7024 QWidget *lastFocusChild = target;
7025
7026 QWidget *focusProxy = target->d_func()->deepestFocusProxy();
7027 if (!focusProxy) {
7028 // QTBUG-81097: Another case is possible here. We can have a child
7029 // widget, that sets its focusProxy() to the parent (target).
7030 // An example of such widget is a QLineEdit, nested into
7031 // a QAbstractSpinBox. In this case such widget should be considered
7032 // the last focus child.
7033 for (auto *object : target->children()) {
7034 QWidget *w = qobject_cast<QWidget*>(object);
7035 if (w && w->focusProxy() == target) {
7036 lastFocusChild = w;
7037 break;
7038 }
7039 }
7040 } else if (target->isAncestorOf(focusProxy)) {
7041 lastFocusChild = focusProxy;
7042 for (QWidget *focusNext = lastFocusChild->nextInFocusChain();
7043 focusNext != focusProxy && target->isAncestorOf(focusNext) && focusNext->window() == focusProxy->window();
7044 focusNext = focusNext->nextInFocusChain()) {
7045 if (focusNext == noFurtherThan)
7046 break;
7047 if (focusNext->focusPolicy() != Qt::NoFocus)
7048 lastFocusChild = focusNext;
7049 }
7050 }
7051 return lastFocusChild;
7052 };
7053 // detect inflection in case we have compound widgets
7054 QWidget *lastFocusChildOfFirst = determineLastFocusChild(first, second);
7055 if (lastFocusChildOfFirst == second)
7056 lastFocusChildOfFirst = first;
7057 QWidget *lastFocusChildOfSecond = determineLastFocusChild(second, first);
7058 if (lastFocusChildOfSecond == first)
7059 lastFocusChildOfSecond = second;
7060
7061 // Return if only NoFocus widgets are between first and second
7062 QWidget *oldPrev = second->previousInFocusChain();
7063 QWidget *prevWithFocus = oldPrev;
7064 while (prevWithFocus->focusPolicy() == Qt::NoFocus)
7065 prevWithFocus = prevWithFocus->previousInFocusChain();
7066 if (prevWithFocus == first)
7067 return;
7068 const QWidgetList chain = QWidgetPrivate::takeFromFocusChain(second, lastFocusChildOfSecond);
7069 QWidgetPrivate::insertIntoFocusChain(chain, QWidgetPrivate::FocusDirection::Next, lastFocusChildOfFirst);
7070}
7071
7072void QWidget::setTabOrder(std::initializer_list<QWidget *> widgets)
7073{
7074 QWidget *prev = nullptr;
7075 for (const auto &widget : widgets) {
7076 if (!prev) {
7077 prev = widget;
7078 } else {
7079 QWidget::setTabOrder(prev, widget);
7080 prev = widget;
7081 }
7082 }
7083}
7084
7085
7086/*!\internal
7087
7088 Moves the relevant subwidgets of this widget from the \a oldtlw's
7089 tab chain to that of the new parent, if there's anything to move and
7090 we're really moving
7091
7092 This function is called from QWidget::reparent() *after* the widget
7093 has been reparented.
7094
7095 \sa reparent()
7096*/
7097
7098void QWidgetPrivate::reparentFocusWidgets(QWidget * oldtlw)
7099{
7100 Q_Q(QWidget);
7101 if (oldtlw == q->window())
7102 return; // nothing to do
7103
7104 if (focus_child)
7105 focus_child->clearFocus();
7106
7107 reparentFocusChildren(QWidgetPrivate::FocusDirection::Next);
7108}
7109
7110/*!
7111 \property QWidget::frameSize
7112 \brief the size of the widget including any window frame
7113
7114 By default, this property contains a value that depends on the user's
7115 platform and screen geometry.
7116*/
7117QSize QWidget::frameSize() const
7118{
7119 Q_D(const QWidget);
7120 if (isWindow() && !(windowType() == Qt::Popup)) {
7121 QRect fs = d->frameStrut();
7122 return QSize(data->crect.width() + fs.left() + fs.right(),
7123 data->crect.height() + fs.top() + fs.bottom());
7124 }
7125 return data->crect.size();
7126}
7127
7128/*! \fn void QWidget::move(int x, int y)
7129
7130 \overload
7131
7132 This corresponds to move(QPoint(\a x, \a y)).
7133*/
7134
7135void QWidget::move(const QPoint &p)
7136{
7137 Q_D(QWidget);
7138 setAttribute(Qt::WA_Moved);
7139 if (testAttribute(Qt::WA_WState_Created)) {
7140 if (isWindow())
7141 d->topData()->posIncludesFrame = false;
7142 d->setGeometry_sys(p.x() + geometry().x() - QWidget::x(),
7143 p.y() + geometry().y() - QWidget::y(),
7144 width(), height(), true);
7145 d->setDirtyOpaqueRegion();
7146 } else {
7147 // no frame yet: see also QWidgetPrivate::fixPosIncludesFrame(), QWindowPrivate::PositionPolicy.
7148 if (isWindow())
7149 d->topData()->posIncludesFrame = true;
7150 data->crect.moveTopLeft(p); // no frame yet
7151 setAttribute(Qt::WA_PendingMoveEvent);
7152 }
7153
7154 if (d->extra && d->extra->hasWindowContainer)
7155 QWindowContainer::parentWasMoved(this);
7156}
7157
7158// move() was invoked with Qt::WA_WState_Created not set (frame geometry
7159// unknown), that is, crect has a position including the frame.
7160// If we can determine the frame strut, fix that and clear the flag.
7161// FIXME: This does not play well with window states other than
7162// Qt::WindowNoState, as we depend on calling setGeometry() on the
7163// platform window after fixing up the position so that the new
7164// geometry is reflected in the platform window, but when the frame
7165// comes in after the window has been shown (e.g. maximized), we're
7166// not in a position to do that kind of fixup.
7167void QWidgetPrivate::fixPosIncludesFrame()
7168{
7169 Q_Q(QWidget);
7170 if (QTLWExtra *te = maybeTopData()) {
7171 if (te->posIncludesFrame) {
7172 // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
7173 // example, in QGraphicsProxyWidget).
7174 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
7175 te->posIncludesFrame = 0;
7176 } else {
7177 if (q->windowHandle() && q->windowHandle()->handle()) {
7178 updateFrameStrut();
7179 if (!q->data->fstrut_dirty) {
7180 data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
7181 te->posIncludesFrame = 0;
7182 }
7183 } // windowHandle()
7184 } // !WA_DontShowOnScreen
7185 } // posIncludesFrame
7186 } // QTLWExtra
7187}
7188
7189/*! \fn void QWidget::resize(int w, int h)
7190 \overload
7191
7192 This corresponds to resize(QSize(\a w, \a h)).
7193*/
7194
7195void QWidget::resize(const QSize &s)
7196{
7197 Q_D(QWidget);
7198 setAttribute(Qt::WA_Resized);
7199 if (testAttribute(Qt::WA_WState_Created)) {
7200 d->fixPosIncludesFrame();
7201 d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
7202 d->setDirtyOpaqueRegion();
7203 } else {
7204 const auto oldRect = data->crect;
7205 data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize()));
7206 if (oldRect != data->crect)
7207 setAttribute(Qt::WA_PendingResizeEvent);
7208 }
7209}
7210
7211void QWidget::setGeometry(const QRect &r)
7212{
7213 Q_D(QWidget);
7214 setAttribute(Qt::WA_Resized);
7215 setAttribute(Qt::WA_Moved);
7216 if (isWindow())
7217 d->topData()->posIncludesFrame = 0;
7218 if (testAttribute(Qt::WA_WState_Created)) {
7219 d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true);
7220 d->setDirtyOpaqueRegion();
7221 } else {
7222 const auto oldRect = data->crect;
7223 data->crect.setTopLeft(r.topLeft());
7224 data->crect.setSize(r.size().boundedTo(maximumSize()).expandedTo(minimumSize()));
7225 if (oldRect != data->crect) {
7226 setAttribute(Qt::WA_PendingMoveEvent);
7227 setAttribute(Qt::WA_PendingResizeEvent);
7228 }
7229 }
7230
7231 if (d->extra && d->extra->hasWindowContainer)
7232 QWindowContainer::parentWasMoved(this);
7233}
7234
7235void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
7236{
7237 Q_Q(QWidget);
7238 if (extra) { // any size restrictions?
7239 w = qMin(w,extra->maxw);
7240 h = qMin(h,extra->maxh);
7241 w = qMax(w,extra->minw);
7242 h = qMax(h,extra->minh);
7243 }
7244
7245 if (q->isWindow() && q->windowHandle()) {
7246 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
7247 if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) {
7248 x = 0;
7249 y = 0;
7250 w = q->windowHandle()->width();
7251 h = q->windowHandle()->height();
7252 }
7253 }
7254
7255 QPoint oldp = q->geometry().topLeft();
7256 QSize olds = q->size();
7257 QRect r(x, y, w, h);
7258
7259 bool isResize = olds != r.size();
7260 if (!isMove)
7261 isMove = oldp != r.topLeft();
7262
7263
7264 // We only care about stuff that changes the geometry, or may
7265 // cause the window manager to change its state
7266 if (r.size() == olds && oldp == r.topLeft())
7267 return;
7268
7269 if (!data.in_set_window_state) {
7270 q->data->window_state &= ~Qt::WindowMaximized;
7271 q->data->window_state &= ~Qt::WindowFullScreen;
7272 if (q->isWindow())
7273 topData()->normalGeometry = QRect(0, 0, -1, -1);
7274 }
7275
7276 QPoint oldPos = q->pos();
7277 data.crect = r;
7278
7279 bool needsShow = false;
7280
7281 if (q->isWindow() || q->windowHandle()) {
7282 if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) {
7283 q->setAttribute(Qt::WA_OutsideWSRange, true);
7284 if (q->isVisible())
7285 hide_sys();
7286 data.crect = QRect(x, y, w, h);
7287 } else if (q->testAttribute(Qt::WA_OutsideWSRange)) {
7288 q->setAttribute(Qt::WA_OutsideWSRange, false);
7289 needsShow = true;
7290 }
7291 }
7292
7293 if (q->isVisible()) {
7294 if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
7295 if (QWindow *win = q->windowHandle()) {
7296 if (q->isWindow()) {
7297 if (isResize && !isMove)
7298 win->resize(w, h);
7299 else if (isMove && !isResize)
7300 win->setPosition(x, y);
7301 else
7302 win->setGeometry(q->geometry());
7303 } else {
7304 QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
7305 win->setGeometry(QRect(posInNativeParent,r.size()));
7306 }
7307
7308 if (needsShow)
7309 show_sys();
7310 }
7311
7312 if (!q->isWindow()) {
7313 if (renderToTexture) {
7314 QRegion updateRegion(q->geometry());
7315 updateRegion += QRect(oldPos, olds);
7316 q->parentWidget()->d_func()->invalidateBackingStore(updateRegion);
7317 } else if (isMove && !isResize) {
7318 moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
7319 } else {
7320 invalidateBackingStore_resizeHelper(oldPos, olds);
7321 }
7322 }
7323 }
7324
7325 if (isMove) {
7326 QMoveEvent e(q->pos(), oldPos);
7327 QCoreApplication::sendEvent(q, &e);
7328 }
7329 if (isResize) {
7330 QResizeEvent e(r.size(), olds);
7331 QCoreApplication::sendEvent(q, &e);
7332 if (q->windowHandle())
7333 q->update();
7334 }
7335 } else { // not visible
7336 if (isMove && q->pos() != oldPos)
7337 q->setAttribute(Qt::WA_PendingMoveEvent, true);
7338 if (isResize)
7339 q->setAttribute(Qt::WA_PendingResizeEvent, true);
7340 }
7341
7342}
7343
7344/*!
7345 \since 4.2
7346 Saves the current geometry and state for top-level widgets.
7347
7348 To save the geometry when the window closes, you can
7349 implement a close event like this:
7350
7351 \snippet code/src_gui_kernel_qwidget.cpp 11
7352
7353 See the \l{Window Geometry} documentation for an overview of geometry
7354 issues with windows.
7355
7356 Use QMainWindow::saveState() to save the geometry and the state of
7357 toolbars and dock widgets.
7358
7359 \sa restoreGeometry(), QMainWindow::saveState(), QMainWindow::restoreState()
7360*/
7361QByteArray QWidget::saveGeometry() const
7362{
7363 QByteArray array;
7364 QDataStream stream(&array, QIODevice::WriteOnly);
7365 stream.setVersion(QDataStream::Qt_4_0);
7366 const quint32 magicNumber = 0x1D9D0CB;
7367 // Version history:
7368 // - Qt 4.2 - 4.8.6, 5.0 - 5.3 : Version 1.0
7369 // - Qt 4.8.6 - today, 5.4 - today: Version 2.0, save screen width in addition to check for high DPI scaling.
7370 // - Qt 5.12 - today : Version 3.0, save QWidget::geometry()
7371 quint16 majorVersion = 3;
7372 quint16 minorVersion = 0;
7373 const int screenNumber = QGuiApplication::screens().indexOf(screen());
7374 stream << magicNumber
7375 << majorVersion
7376 << minorVersion
7377 << frameGeometry()
7378 << normalGeometry()
7379 << qint32(screenNumber)
7380 << quint8(windowState() & Qt::WindowMaximized)
7381 << quint8(windowState() & Qt::WindowFullScreen)
7382 << qint32(screen()->geometry().width()) // added in 2.0
7383 << geometry(); // added in 3.0
7384 return array;
7385}
7386
7387/*!
7388 \internal
7389
7390 Check a if \a restoredGeometry fits into \a availableGeometry
7391 This method is used to verify that a widget is restored to a geometry, which
7392 fits into the target screen.
7393
7394 \param frameHeight represents the height of the widget's title bar, which is expected
7395 to be on its top.
7396
7397 If the size of \a restoredGeometry exceeds \a availableGeometry, its height and width
7398 will be resized to be two pixels smaller than \a availableGeometry. An exact match would
7399 be full screen.
7400
7401 If at least one edge of \a restoredGeometry is outside \a availableGeometry,
7402 \a restoredGeometry will be moved
7403 \list
7404 \li down if its top is off screen
7405 \li up if its bottom is off screen
7406 \li right if its left edge is off screen
7407 \li left if its right edge is off screen
7408 \endlist
7409 */
7410void QWidgetPrivate::checkRestoredGeometry(const QRect &availableGeometry, QRect *restoredGeometry,
7411 int frameHeight)
7412{
7413 // compare with restored geometry's height increased by frameHeight
7414 const int height = restoredGeometry->height() + frameHeight;
7415
7416 // Step 1: Resize if necessary:
7417 // make height / width 2px smaller than screen, because an exact match would be fullscreen
7418 if (availableGeometry.height() <= height)
7419 restoredGeometry->setHeight(availableGeometry.height() - 2 - frameHeight);
7420 if (availableGeometry.width() <= restoredGeometry->width())
7421 restoredGeometry->setWidth(availableGeometry.width() - 2);
7422
7423 // Step 2: Move if necessary:
7424 // Construct a rectangle from restored Geometry adjusted by frameHeight
7425 const QRect restored = restoredGeometry->adjusted(0, -frameHeight, 0, 0);
7426
7427 // Return if restoredGeometry (including frame) fits into screen
7428 if (availableGeometry.contains(restored))
7429 return;
7430
7431 // (size is correct, but at least one edge is off screen)
7432
7433 // Top out of bounds => move down
7434 if (restored.top() <= availableGeometry.top()) {
7435 restoredGeometry->moveTop(availableGeometry.top() + 1 + frameHeight);
7436 } else if (restored.bottom() >= availableGeometry.bottom()) {
7437 // Bottom out of bounds => move up
7438 restoredGeometry->moveBottom(availableGeometry.bottom() - 1);
7439 }
7440
7441 // Left edge out of bounds => move right
7442 if (restored.left() <= availableGeometry.left()) {
7443 restoredGeometry->moveLeft(availableGeometry.left() + 1);
7444 } else if (restored.right() >= availableGeometry.right()) {
7445 // Right edge out of bounds => move left
7446 restoredGeometry->moveRight(availableGeometry.right() - 1);
7447 }
7448}
7449
7450/*!
7451 \since 4.2
7452
7453 Restores the geometry and state of top-level widgets stored in the
7454 byte array \a geometry. Returns \c true on success; otherwise
7455 returns \c false.
7456
7457 If the restored geometry is off-screen, it will be modified to be
7458 inside the available screen geometry.
7459
7460 To restore geometry saved using QSettings, you can use code like
7461 this:
7462
7463 \snippet code/src_gui_kernel_qwidget.cpp 12
7464
7465 See the \l{Window Geometry} documentation for an overview of geometry
7466 issues with windows.
7467
7468 Use QMainWindow::restoreState() to restore the geometry and the
7469 state of toolbars and dock widgets.
7470
7471 \sa saveGeometry(), QSettings, QMainWindow::saveState(), QMainWindow::restoreState()
7472*/
7473bool QWidget::restoreGeometry(const QByteArray &geometry)
7474{
7475 if (geometry.size() < 4)
7476 return false;
7477 QDataStream stream(geometry);
7478 stream.setVersion(QDataStream::Qt_4_0);
7479
7480 const quint32 magicNumber = 0x1D9D0CB;
7481 quint32 storedMagicNumber;
7482 stream >> storedMagicNumber;
7483 if (storedMagicNumber != magicNumber)
7484 return false;
7485
7486 const quint16 currentMajorVersion = 3;
7487 quint16 majorVersion = 0;
7488 quint16 minorVersion = 0;
7489
7490 stream >> majorVersion >> minorVersion;
7491
7492 if (majorVersion > currentMajorVersion)
7493 return false;
7494 // (Allow all minor versions.)
7495
7496 QRect restoredFrameGeometry;
7497 QRect restoredGeometry;
7498 QRect restoredNormalGeometry;
7499 qint32 restoredScreenNumber;
7500 quint8 maximized;
7501 quint8 fullScreen;
7502 qint32 restoredScreenWidth = 0;
7503
7504 stream >> restoredFrameGeometry // Only used for sanity checks in version 0
7505 >> restoredNormalGeometry
7506 >> restoredScreenNumber
7507 >> maximized
7508 >> fullScreen;
7509
7510 if (majorVersion > 1)
7511 stream >> restoredScreenWidth;
7512 if (majorVersion > 2)
7513 stream >> restoredGeometry;
7514
7515 // ### Qt 6 - Perhaps it makes sense to dumb down the restoreGeometry() logic, see QTBUG-69104
7516
7517 if (restoredScreenNumber >= qMax(QGuiApplication::screens().size(), 1))
7518 restoredScreenNumber = 0;
7519 const QScreen *restoredScreen = QGuiApplication::screens().value(restoredScreenNumber, nullptr);
7520 const qreal screenWidthF = restoredScreen ? qreal(restoredScreen->geometry().width()) : 0;
7521 // Sanity check bailing out when large variations of screen sizes occur due to
7522 // high DPI scaling or different levels of DPI awareness.
7523 if (restoredScreenWidth) {
7524 const qreal factor = qreal(restoredScreenWidth) / screenWidthF;
7525 if (factor < 0.8 || factor > 1.25)
7526 return false;
7527 } else {
7528 // Saved by Qt 5.3 and earlier, try to prevent too large windows
7529 // unless the size will be adapted by maximized or fullscreen.
7530 if (!maximized && !fullScreen && qreal(restoredFrameGeometry.width()) / screenWidthF > 1.5)
7531 return false;
7532 }
7533
7534 const int frameHeight = QApplication::style()
7535 ? QApplication::style()->pixelMetric(QStyle::PM_TitleBarHeight, nullptr, this)
7536 : 20;
7537
7538 if (!restoredNormalGeometry.isValid())
7539 restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint());
7540 if (!restoredNormalGeometry.isValid()) {
7541 // use the widget's adjustedSize if the sizeHint() doesn't help
7542 restoredNormalGeometry.setSize(restoredNormalGeometry
7543 .size()
7544 .expandedTo(d_func()->adjustedSize()));
7545 }
7546
7547 const QRect availableGeometry = restoredScreen ? restoredScreen->availableGeometry()
7548 : QRect();
7549
7550 // Modify the restored geometry if we are about to restore to coordinates
7551 // that would make the window "lost". This happens if:
7552 // - The restored geometry is completely or partly oustside the available geometry
7553 // - The title bar is outside the available geometry.
7554
7555 QWidgetPrivate::checkRestoredGeometry(availableGeometry, &restoredGeometry, frameHeight);
7556 QWidgetPrivate::checkRestoredGeometry(availableGeometry, &restoredNormalGeometry, frameHeight);
7557
7558 if (maximized || fullScreen) {
7559 // set geometry before setting the window state to make
7560 // sure the window is maximized to the right screen.
7561 Qt::WindowStates ws = windowState();
7562#ifndef Q_OS_WIN
7563 setGeometry(restoredNormalGeometry);
7564#else
7565 if (ws & Qt::WindowFullScreen) {
7566 // Full screen is not a real window state on Windows.
7567 move(availableGeometry.topLeft());
7568 } else if (ws & Qt::WindowMaximized) {
7569 // Setting a geometry on an already maximized window causes this to be
7570 // restored into a broken, half-maximized state, non-resizable state (QTBUG-4397).
7571 // Move the window in normal state if needed.
7572 if (restoredScreen != screen()) {
7573 setWindowState(Qt::WindowNoState);
7574 setGeometry(restoredNormalGeometry);
7575 }
7576 } else {
7577 setGeometry(restoredNormalGeometry);
7578 }
7579#endif // Q_OS_WIN
7580 if (maximized)
7581 ws |= Qt::WindowMaximized;
7582 if (fullScreen)
7583 ws |= Qt::WindowFullScreen;
7584 setWindowState(ws);
7585 d_func()->topData()->normalGeometry = restoredNormalGeometry;
7586 } else {
7587 setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen));
7588
7589 // FIXME: Why fall back to restoredNormalGeometry if majorVersion <= 2?
7590 if (majorVersion > 2)
7591 setGeometry(restoredGeometry);
7592 else
7593 setGeometry(restoredNormalGeometry);
7594 }
7595 return true;
7596}
7597
7598/*!\fn void QWidget::setGeometry(int x, int y, int w, int h)
7599 \overload
7600
7601 This corresponds to setGeometry(QRect(\a x, \a y, \a w, \a h)).
7602*/
7603
7604/*!
7605 Sets the margins around the contents of the widget to have the sizes
7606 \a left, \a top, \a right, and \a bottom. The margins are used by
7607 the layout system, and may be used by subclasses to specify the area
7608 to draw in (e.g. excluding the frame).
7609
7610 Changing the margins will trigger a resizeEvent().
7611
7612 \sa contentsRect(), contentsMargins()
7613*/
7614void QWidget::setContentsMargins(int left, int top, int right, int bottom)
7615{
7616 Q_D(QWidget);
7617 if (left == d->leftmargin && top == d->topmargin
7618 && right == d->rightmargin && bottom == d->bottommargin)
7619 return;
7620 d->leftmargin = left;
7621 d->topmargin = top;
7622 d->rightmargin = right;
7623 d->bottommargin = bottom;
7624
7625 d->updateContentsRect();
7626}
7627
7628/*!
7629 \overload
7630 \since 4.6
7631
7632 \brief The setContentsMargins function sets the margins around the
7633 widget's contents.
7634
7635 Sets the margins around the contents of the widget to have the
7636 sizes determined by \a margins. The margins are
7637 used by the layout system, and may be used by subclasses to
7638 specify the area to draw in (e.g. excluding the frame).
7639
7640 Changing the margins will trigger a resizeEvent().
7641
7642 \sa contentsRect(), contentsMargins()
7643*/
7644void QWidget::setContentsMargins(const QMargins &margins)
7645{
7646 setContentsMargins(margins.left(), margins.top(),
7647 margins.right(), margins.bottom());
7648}
7649
7650void QWidgetPrivate::updateContentsRect()
7651{
7652 Q_Q(QWidget);
7653
7654 if (layout)
7655 layout->update(); //force activate; will do updateGeometry
7656 else
7657 q->updateGeometry();
7658
7659 if (q->isVisible()) {
7660 q->update();
7661 QResizeEvent e(q->data->crect.size(), q->data->crect.size());
7662 QCoreApplication::sendEvent(q, &e);
7663 } else {
7664 q->setAttribute(Qt::WA_PendingResizeEvent, true);
7665 }
7666
7667 QEvent e(QEvent::ContentsRectChange);
7668 QCoreApplication::sendEvent(q, &e);
7669}
7670
7671/*!
7672 \since 4.6
7673
7674 \brief The contentsMargins function returns the widget's contents margins.
7675
7676 \sa setContentsMargins(), contentsRect()
7677 */
7678QMargins QWidget::contentsMargins() const
7679{
7680 Q_D(const QWidget);
7681 QMargins userMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin);
7682 return testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea) ?
7683 userMargins | d->safeAreaMargins() : userMargins;
7684}
7685
7686/*!
7687 Returns the area inside the widget's margins.
7688
7689 \sa setContentsMargins(), contentsMargins()
7690*/
7691QRect QWidget::contentsRect() const
7692{
7693 return rect() - contentsMargins();
7694}
7695
7696QMargins QWidgetPrivate::safeAreaMargins() const
7697{
7698 Q_Q(const QWidget);
7699 QWidget *nativeWidget = q->window();
7700 if (!nativeWidget->windowHandle())
7701 return QMargins();
7702
7703 QPlatformWindow *platformWindow = nativeWidget->windowHandle()->handle();
7704 if (!platformWindow)
7705 return QMargins();
7706
7707 QMargins safeAreaMargins = platformWindow->safeAreaMargins();
7708
7709 if (!q->isWindow()) {
7710 // In theory the native parent widget already has a contents rect reflecting
7711 // the safe area of that widget, but we can't be sure that the widget or child
7712 // widgets of that widget have respected the contents rect when setting their
7713 // geometry, so we need to manually compute the safe area.
7714
7715 // Unless the native widget doesn't have any margins, in which case there's
7716 // nothing for us to compute.
7717 if (safeAreaMargins.isNull())
7718 return QMargins();
7719
7720 // Or, if one of our ancestors are in a layout that does not have WA_LayoutOnEntireRect
7721 // set, and the widget respects the safe area, then we know that the layout has already
7722 // taken care of placing us inside the safe area, by taking the contents rect of its
7723 // parent widget into account.
7724 const QWidget *assumedSafeWidget = nullptr;
7725 for (const QWidget *w = q; w != nativeWidget; w = w->parentWidget()) {
7726 QWidget *parentWidget = w->parentWidget();
7727 if (!parentWidget->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea))
7728 continue; // Layout can't help us
7729
7730 if (parentWidget->testAttribute(Qt::WA_LayoutOnEntireRect))
7731 continue; // Layout not going to help us
7732
7733 QLayout *layout = parentWidget->layout();
7734 if (!layout)
7735 continue;
7736
7737 if (layout->geometry().isNull())
7738 continue; // Layout hasn't been activated yet
7739
7740 if (layout->indexOf(w) < 0)
7741 continue; // Widget is not in layout
7742
7743 assumedSafeWidget = w;
7744 break;
7745 }
7746
7747#if !defined(QT_DEBUG)
7748 if (assumedSafeWidget) {
7749 // We found a layout that we assume will take care of keeping us within the safe area
7750 // For debug builds we still map the safe area using the fallback logic, so that we
7751 // can detect any misbehaving layouts.
7752 return QMargins();
7753 }
7754#endif
7755
7756 // In all other cases we need to map the safe area of the native parent to the widget.
7757 // This depends on the widget being positioned and sized already, which means the initial
7758 // layout will be wrong, but the layout will then adjust itself.
7759 QPoint topLeftMargins = q->mapFrom(nativeWidget, QPoint(safeAreaMargins.left(), safeAreaMargins.top()));
7760 QRect widgetRect = q->isVisible() ? q->visibleRegion().boundingRect() : q->rect();
7761 QPoint bottomRightMargins = widgetRect.bottomRight() - q->mapFrom(nativeWidget,
7762 nativeWidget->rect().bottomRight() - QPoint(safeAreaMargins.right(), safeAreaMargins.bottom()));
7763
7764 // Margins should never be negative
7765 safeAreaMargins = QMargins(qMax(0, topLeftMargins.x()), qMax(0, topLeftMargins.y()),
7766 qMax(0, bottomRightMargins.x()), qMax(0, bottomRightMargins.y()));
7767
7768 if (!safeAreaMargins.isNull() && assumedSafeWidget) {
7769 QLayout *layout = assumedSafeWidget->parentWidget()->layout();
7770 qWarning() << layout << "is laying out" << assumedSafeWidget
7771 << "outside of the contents rect of" << layout->parentWidget();
7772 return QMargins(); // Return empty margin to visually highlight the error
7773 }
7774 }
7775
7776 return safeAreaMargins;
7777}
7778
7779/*!
7780 \fn void QWidget::customContextMenuRequested(const QPoint &pos)
7781
7782 This signal is emitted when the widget's \l contextMenuPolicy is
7783 Qt::CustomContextMenu, and the user has requested a context menu on
7784 the widget. The position \a pos is the position of the context menu
7785 event that the widget receives. Normally this is in widget
7786 coordinates. The exception to this rule is QAbstractScrollArea and
7787 its subclasses that map the context menu event to coordinates of the
7788 \l{QAbstractScrollArea::viewport()}{viewport()}.
7789
7790
7791 \sa mapToGlobal(), QMenu, contextMenuPolicy
7792*/
7793
7794
7795/*!
7796 \property QWidget::contextMenuPolicy
7797 \brief how the widget shows a context menu
7798
7799 The default value of this property is Qt::DefaultContextMenu,
7800 which means the contextMenuEvent() handler is called. Other values
7801 are Qt::NoContextMenu, Qt::PreventContextMenu,
7802 Qt::ActionsContextMenu, and Qt::CustomContextMenu. With
7803 Qt::CustomContextMenu, the signal customContextMenuRequested() is
7804 emitted.
7805
7806 \sa contextMenuEvent(), customContextMenuRequested(), actions()
7807*/
7808
7809Qt::ContextMenuPolicy QWidget::contextMenuPolicy() const
7810{
7811 return (Qt::ContextMenuPolicy)data->context_menu_policy;
7812}
7813
7814void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
7815{
7816 data->context_menu_policy = (uint) policy;
7817}
7818
7819/*!
7820 \property QWidget::focusPolicy
7821 \brief the way the widget accepts keyboard focus
7822
7823 The policy is Qt::TabFocus if the widget accepts keyboard
7824 focus by tabbing, Qt::ClickFocus if the widget accepts
7825 focus by clicking, Qt::StrongFocus if it accepts both, and
7826 Qt::NoFocus (the default) if it does not accept focus at
7827 all.
7828
7829 You must enable keyboard focus for a widget if it processes
7830 keyboard events. This is normally done from the widget's
7831 constructor. For instance, the QLineEdit constructor calls
7832 setFocusPolicy(Qt::StrongFocus).
7833
7834 If the widget has a focus proxy, then the focus policy will
7835 be propagated to it.
7836
7837 \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
7838*/
7839
7840
7841Qt::FocusPolicy QWidget::focusPolicy() const
7842{
7843 return (Qt::FocusPolicy)data->focus_policy;
7844}
7845
7846void QWidget::setFocusPolicy(Qt::FocusPolicy policy)
7847{
7848 data->focus_policy = (uint) policy;
7849 Q_D(QWidget);
7850 if (d->extra && d->extra->focus_proxy)
7851 d->extra->focus_proxy->setFocusPolicy(policy);
7852}
7853
7854/*!
7855 \property QWidget::updatesEnabled
7856 \brief whether updates are enabled
7857
7858 An updates enabled widget receives paint events and has a system
7859 background; a disabled widget does not. This also implies that
7860 calling update() and repaint() has no effect if updates are
7861 disabled.
7862
7863 By default, this property is \c true.
7864
7865 setUpdatesEnabled() is normally used to disable updates for a
7866 short period of time, for instance to avoid screen flicker during
7867 large changes. In Qt, widgets normally do not generate screen
7868 flicker, but on X11 the server might erase regions on the screen
7869 when widgets get hidden before they can be replaced by other
7870 widgets. Disabling updates solves this.
7871
7872 Example:
7873 \snippet code/src_gui_kernel_qwidget.cpp 13
7874
7875 Disabling a widget implicitly disables all its children. Enabling a widget
7876 enables all child widgets \e except top-level widgets or those that
7877 have been explicitly disabled. Re-enabling updates implicitly calls
7878 update() on the widget.
7879
7880 \sa paintEvent()
7881*/
7882void QWidget::setUpdatesEnabled(bool enable)
7883{
7884 Q_D(QWidget);
7885 setAttribute(Qt::WA_ForceUpdatesDisabled, !enable);
7886 d->setUpdatesEnabled_helper(enable);
7887}
7888
7889/*!
7890 Shows the widget and its child widgets.
7891
7892 For child windows, this is equivalent to calling setVisible(true).
7893 Otherwise, it is equivalent to calling showFullScreen(), showMaximized(),
7894 or setVisible(true), depending on the platform's default behavior for the window flags.
7895
7896 \sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(),
7897 showNormal(), isVisible(), windowFlags()
7898*/
7899void QWidget::show()
7900{
7901 // Note: We don't call showNormal() as not to clobber Qt::Window(Max/Min)imized
7902
7903 if (!isWindow()) {
7904 setVisible(true);
7905 } else {
7906 const auto *platformIntegration = QGuiApplicationPrivate::platformIntegration();
7907 Qt::WindowState defaultState = platformIntegration->defaultWindowState(data->window_flags);
7908 if (defaultState == Qt::WindowFullScreen)
7909 showFullScreen();
7910 else if (defaultState == Qt::WindowMaximized)
7911 showMaximized();
7912 else
7913 setVisible(true);
7914 }
7915}
7916
7917/*! \internal
7918
7919 Makes the widget visible in the isVisible() meaning of the word.
7920 It is only called for toplevels or widgets with visible parents.
7921 */
7922void QWidgetPrivate::show_recursive()
7923{
7924 Q_Q(QWidget);
7925 // polish if necessary
7926
7927 if (!q->testAttribute(Qt::WA_WState_Created))
7928 createRecursively();
7929 q->ensurePolished();
7930
7931 if (!q->isWindow() && q->parentWidget()->d_func()->layout && !q->parentWidget()->data->in_show)
7932 q->parentWidget()->d_func()->layout->activate();
7933 // activate our layout before we and our children become visible
7934 if (layout)
7935 layout->activate();
7936
7937 show_helper();
7938}
7939
7940void QWidgetPrivate::sendPendingMoveAndResizeEvents(bool recursive, bool disableUpdates)
7941{
7942 Q_Q(QWidget);
7943
7944 disableUpdates = disableUpdates && q->updatesEnabled();
7945 if (disableUpdates)
7946 q->setAttribute(Qt::WA_UpdatesDisabled);
7947
7948 if (q->testAttribute(Qt::WA_PendingMoveEvent)) {
7949 QMoveEvent e(data.crect.topLeft(), data.crect.topLeft());
7950 QCoreApplication::sendEvent(q, &e);
7951 q->setAttribute(Qt::WA_PendingMoveEvent, false);
7952 }
7953
7954 if (q->testAttribute(Qt::WA_PendingResizeEvent)) {
7955 QResizeEvent e(data.crect.size(), QSize());
7956 QCoreApplication::sendEvent(q, &e);
7957 q->setAttribute(Qt::WA_PendingResizeEvent, false);
7958 }
7959
7960 if (disableUpdates)
7961 q->setAttribute(Qt::WA_UpdatesDisabled, false);
7962
7963 if (!recursive)
7964 return;
7965
7966 for (int i = 0; i < children.size(); ++i) {
7967 if (QWidget *child = qobject_cast<QWidget *>(children.at(i)))
7968 child->d_func()->sendPendingMoveAndResizeEvents(recursive, disableUpdates);
7969 }
7970}
7971
7972void QWidgetPrivate::activateChildLayoutsRecursively()
7973{
7974 sendPendingMoveAndResizeEvents(false, true);
7975
7976 for (int i = 0; i < children.size(); ++i) {
7977 QWidget *child = qobject_cast<QWidget *>(children.at(i));
7978 if (!child || child->isHidden() || child->isWindow())
7979 continue;
7980
7981 child->ensurePolished();
7982
7983 // Activate child's layout
7984 QWidgetPrivate *childPrivate = child->d_func();
7985 if (childPrivate->layout)
7986 childPrivate->layout->activate();
7987
7988 // Pretend we're visible.
7989 const bool wasVisible = child->isVisible();
7990 if (!wasVisible)
7991 child->setAttribute(Qt::WA_WState_Visible);
7992
7993 // Do the same for all my children.
7994 childPrivate->activateChildLayoutsRecursively();
7995
7996 // We're not cheating anymore.
7997 if (!wasVisible)
7998 child->setAttribute(Qt::WA_WState_Visible, false);
7999 }
8000}
8001
8002void QWidgetPrivate::show_helper()
8003{
8004 Q_Q(QWidget);
8005 data.in_show = true; // qws optimization
8006 // make sure we receive pending move and resize events
8007 sendPendingMoveAndResizeEvents();
8008
8009 // become visible before showing all children
8010 q->setAttribute(Qt::WA_WState_Visible);
8011
8012 // finally show all children recursively
8013 showChildren(false);
8014
8015
8016
8017 const bool isWindow = q->isWindow();
8018#if QT_CONFIG(graphicsview)
8019 bool isEmbedded = isWindow && q->graphicsProxyWidget() != nullptr;
8020#else
8021 bool isEmbedded = false;
8022#endif
8023
8024 // popup handling: new popups and tools need to be raised, and
8025 // existing popups must be closed. Also propagate the current
8026 // windows's KeyboardFocusChange status.
8027 if (isWindow && !isEmbedded) {
8028 if ((q->windowType() == Qt::Tool) || (q->windowType() == Qt::Popup) || q->windowType() == Qt::ToolTip) {
8029 q->raise();
8030 if (q->parentWidget() && q->parentWidget()->window()->testAttribute(Qt::WA_KeyboardFocusChange))
8031 q->setAttribute(Qt::WA_KeyboardFocusChange);
8032 } else {
8033 while (QApplication::activePopupWidget()) {
8034 if (!QApplication::activePopupWidget()->close())
8035 break;
8036 }
8037 }
8038 }
8039
8040 // Automatic embedding of child windows of widgets already embedded into
8041 // QGraphicsProxyWidget when they are shown the first time.
8042#if QT_CONFIG(graphicsview)
8043 if (isWindow) {
8044 if (!isEmbedded && !bypassGraphicsProxyWidget(q)) {
8045 QGraphicsProxyWidget *ancestorProxy = nearestGraphicsProxyWidget(q->parentWidget());
8046 if (ancestorProxy) {
8047 isEmbedded = true;
8048 ancestorProxy->d_func()->embedSubWindow(q);
8049 }
8050 }
8051 }
8052#else
8053 Q_UNUSED(isEmbedded);
8054#endif
8055
8056 // send the show event before showing the window
8057 QShowEvent showEvent;
8058 QCoreApplication::sendEvent(q, &showEvent);
8059
8060 show_sys();
8061
8062 if (!isEmbedded && q->windowType() == Qt::Popup)
8063 qApp->d_func()->openPopup(q);
8064
8065#if QT_CONFIG(accessibility)
8066 if (q->windowType() != Qt::ToolTip) { // Tooltips are read aloud twice in MS narrator.
8067 QAccessibleEvent event(q, QAccessible::ObjectShow);
8068 QAccessible::updateAccessibility(&event);
8069 }
8070#endif
8071
8072 if (QApplicationPrivate::hidden_focus_widget == q) {
8073 QApplicationPrivate::hidden_focus_widget = nullptr;
8074 q->setFocus(Qt::OtherFocusReason);
8075 }
8076
8077 // Process events when showing a Qt::SplashScreen widget before the event loop
8078 // is spinnning; otherwise it might not show up on particular platforms.
8079 // This makes QSplashScreen behave the same on all platforms.
8080 if (!qApp->d_func()->in_exec && q->windowType() == Qt::SplashScreen)
8081 QCoreApplication::processEvents();
8082
8083 data.in_show = false; // reset qws optimization
8084}
8085
8086void QWidgetPrivate::show_sys()
8087{
8088 Q_Q(QWidget);
8089
8090 auto window = qobject_cast<QWidgetWindow *>(windowHandle());
8091
8092 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
8093 invalidateBackingStore(q->rect());
8094 q->setAttribute(Qt::WA_Mapped);
8095 // add our window the modal window list (native dialogs)
8096 if (window && q->isWindow()
8097#if QT_CONFIG(graphicsview)
8098 && (!extra || !extra->proxyWidget)
8099#endif
8100 && q->windowModality() != Qt::NonModal) {
8101 QGuiApplicationPrivate::showModalWindow(window);
8102 }
8103 return;
8104 }
8105
8106 if (renderToTexture && !q->isWindow())
8107 QCoreApplication::postEvent(q->parentWidget(), new QUpdateLaterEvent(q->geometry()));
8108 else
8109 QCoreApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
8110
8111 if ((!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
8112 || q->testAttribute(Qt::WA_OutsideWSRange)) {
8113 return;
8114 }
8115
8116 if (window) {
8117 if (q->isWindow())
8118 fixPosIncludesFrame();
8119 QRect geomRect = q->geometry();
8120 if (!q->isWindow()) {
8121 QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
8122 geomRect.moveTopLeft(topLeftOfWindow);
8123 }
8124 const QRect windowRect = window->geometry();
8125 if (windowRect != geomRect) {
8126 if (q->testAttribute(Qt::WA_Moved)
8127 || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
8128 window->setGeometry(geomRect);
8129 else
8130 window->resize(geomRect.size());
8131 }
8132
8133#ifndef QT_NO_CURSOR
8134 qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
8135#endif
8136 invalidateBackingStore(q->rect());
8137 window->setNativeWindowVisibility(true);
8138 // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ?
8139 if (window->isTopLevel()) {
8140 const QPoint crectTopLeft = q->data->crect.topLeft();
8141 const QPoint windowTopLeft = window->geometry().topLeft();
8142 if (crectTopLeft == QPoint(0, 0) && windowTopLeft != crectTopLeft)
8143 q->data->crect.moveTopLeft(windowTopLeft);
8144 }
8145 }
8146}
8147
8148/*!
8149 Hides the widget. This function is equivalent to
8150 setVisible(false).
8151
8152
8153 \note If you are working with QDialog or its subclasses and you invoke
8154 the show() function after this function, the dialog will be displayed in
8155 its original position.
8156
8157 \sa hideEvent(), isHidden(), show(), setVisible(), isVisible(), close()
8158*/
8159void QWidget::hide()
8160{
8161 setVisible(false);
8162}
8163
8164/*!\internal
8165 */
8166void QWidgetPrivate::hide_helper()
8167{
8168 Q_Q(QWidget);
8169
8170 bool isEmbedded = false;
8171#if QT_CONFIG(graphicsview)
8172 isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(q) && nearestGraphicsProxyWidget(q->parentWidget()) != nullptr;
8173#else
8174 Q_UNUSED(isEmbedded);
8175#endif
8176
8177 if (!isEmbedded && (q->windowType() == Qt::Popup))
8178 qApp->d_func()->closePopup(q);
8179
8180 q->setAttribute(Qt::WA_Mapped, false);
8181 hide_sys();
8182
8183 bool wasVisible = q->testAttribute(Qt::WA_WState_Visible);
8184
8185 if (wasVisible) {
8186 q->setAttribute(Qt::WA_WState_Visible, false);
8187
8188 }
8189
8190 QHideEvent hideEvent;
8191 QCoreApplication::sendEvent(q, &hideEvent);
8192 hideChildren(false);
8193
8194 // next bit tries to move the focus if the focus widget is now
8195 // hidden.
8196 if (wasVisible) {
8197 qApp->d_func()->sendSyntheticEnterLeave(q);
8198 QWidget *fw = QApplication::focusWidget();
8199 while (fw && !fw->isWindow()) {
8200 if (fw == q) {
8201 q->focusNextPrevChild(true);
8202 break;
8203 }
8204 fw = fw->parentWidget();
8205 }
8206 }
8207
8208 if (QWidgetRepaintManager *repaintManager = maybeRepaintManager())
8209 repaintManager->removeDirtyWidget(q);
8210
8211#if QT_CONFIG(accessibility)
8212 if (wasVisible) {
8213 QAccessibleEvent event(q, QAccessible::ObjectHide);
8214 QAccessible::updateAccessibility(&event);
8215 }
8216#endif
8217}
8218
8219void QWidgetPrivate::hide_sys()
8220{
8221 Q_Q(QWidget);
8222
8223 auto window = qobject_cast<QWidgetWindow *>(windowHandle());
8224
8225 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
8226 q->setAttribute(Qt::WA_Mapped, false);
8227 // remove our window from the modal window list (native dialogs)
8228 if (window && q->isWindow()
8229#if QT_CONFIG(graphicsview)
8230 && (!extra || !extra->proxyWidget)
8231#endif
8232 && q->windowModality() != Qt::NonModal) {
8233 QGuiApplicationPrivate::hideModalWindow(window);
8234 }
8235 // do not return here, if window non-zero, we must hide it
8236 }
8237
8238 deactivateWidgetCleanup();
8239
8240 if (!q->isWindow()) {
8241 QWidget *p = q->parentWidget();
8242 if (p &&p->isVisible()) {
8243 if (renderToTexture)
8244 p->d_func()->invalidateBackingStore(q->geometry());
8245 else
8246 invalidateBackingStore(q->rect());
8247 }
8248 } else {
8249 invalidateBackingStore(q->rect());
8250 }
8251
8252 if (window)
8253 window->setNativeWindowVisibility(false);
8254}
8255
8256/*!
8257 \fn bool QWidget::isHidden() const
8258
8259 Returns \c true if the widget is hidden, otherwise returns \c false.
8260
8261 A hidden widget will only become visible when show() is called on
8262 it. It will not be automatically shown when the parent is shown.
8263
8264 To check visibility, use !isVisible() instead (notice the exclamation mark).
8265
8266 isHidden() implies !isVisible(), but a widget can be not visible
8267 and not hidden at the same time. This is the case for widgets that are children of
8268 widgets that are not visible.
8269
8270
8271 Widgets are hidden if:
8272 \list
8273 \li they were created as independent windows,
8274 \li they were created as children of visible widgets,
8275 \li hide() or setVisible(false) was called.
8276 \endlist
8277*/
8278
8279void QWidget::setVisible(bool visible)
8280{
8281 Q_D(QWidget);
8282 qCDebug(lcWidgetShowHide) << "Setting visibility of" << this
8283 << "with attributes" << WidgetAttributes{this}
8284 << "to" << visible << "via QWidget";
8285
8286 if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) == !visible)
8287 return;
8288
8289 if (d->dontSetExplicitShowHide) {
8290 d->dontSetExplicitShowHide = false;
8291 } else {
8292 // Remember that setVisible was called explicitly
8293 setAttribute(Qt::WA_WState_ExplicitShowHide);
8294 }
8295
8296 d->setVisible(visible);
8297}
8298
8299// This method is called from QWidgetWindow in response to QWindow::setVisible,
8300// and should match the semantics of QWindow::setVisible. QWidget::setVisible on
8301// the other hand keeps track of WA_WState_ExplicitShowHide in addition.
8302void QWidgetPrivate::setVisible(bool visible)
8303{
8304 Q_Q(QWidget);
8305 qCDebug(lcWidgetShowHide) << "Setting visibility of" << q
8306 << "with attributes" << WidgetAttributes{q}
8307 << "to" << visible << "via QWidgetPrivate";
8308
8309 if (visible) { // show
8310 // Designer uses a trick to make grabWidget work without showing
8311 if (!q->isWindow() && q->parentWidget() && q->parentWidget()->isVisible()
8312 && !q->parentWidget()->testAttribute(Qt::WA_WState_Created))
8313 q->parentWidget()->window()->d_func()->createRecursively();
8314
8315 //create toplevels but not children of non-visible parents
8316 QWidget *pw = q->parentWidget();
8317 if (!q->testAttribute(Qt::WA_WState_Created)
8318 && (q->isWindow() || pw->testAttribute(Qt::WA_WState_Created))) {
8319 q->create();
8320 }
8321
8322 bool wasResized = q->testAttribute(Qt::WA_Resized);
8323 Qt::WindowStates initialWindowState = q->windowState();
8324
8325 // polish if necessary
8326 q->ensurePolished();
8327
8328 // whether we need to inform the parent widget immediately
8329 bool needUpdateGeometry = !q->isWindow() && q->testAttribute(Qt::WA_WState_Hidden);
8330 // we are no longer hidden
8331 q->setAttribute(Qt::WA_WState_Hidden, false);
8332
8333 if (needUpdateGeometry)
8334 updateGeometry_helper(true);
8335
8336 // activate our layout before we and our children become visible
8337 if (layout)
8338 layout->activate();
8339
8340 if (!q->isWindow()) {
8341 QWidget *parent = q->parentWidget();
8342 while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) {
8343 parent->d_func()->layout->activate();
8344 if (parent->isWindow())
8345 break;
8346 parent = parent->parentWidget();
8347 }
8348 if (parent)
8349 parent->d_func()->setDirtyOpaqueRegion();
8350 }
8351
8352 // adjust size if necessary
8353 if (!wasResized
8354 && (q->isWindow() || !q->parentWidget()->d_func()->layout)) {
8355 if (q->isWindow()) {
8356 q->adjustSize();
8357 if (q->windowState() != initialWindowState)
8358 q->setWindowState(initialWindowState);
8359 } else {
8360 q->adjustSize();
8361 }
8362 q->setAttribute(Qt::WA_Resized, false);
8363 }
8364
8365 q->setAttribute(Qt::WA_KeyboardFocusChange, false);
8366
8367 if (q->isWindow() || q->parentWidget()->isVisible()) {
8368 show_helper();
8369
8370 qApp->d_func()->sendSyntheticEnterLeave(q);
8371 }
8372
8373 QEvent showToParentEvent(QEvent::ShowToParent);
8374 QCoreApplication::sendEvent(q, &showToParentEvent);
8375 } else { // hide
8376 if (QApplicationPrivate::hidden_focus_widget == q)
8377 QApplicationPrivate::hidden_focus_widget = nullptr;
8378
8379 // hw: The test on getOpaqueRegion() needs to be more intelligent
8380 // currently it doesn't work if the widget is hidden (the region will
8381 // be clipped). The real check should be testing the cached region
8382 // (and dirty flag) directly.
8383 if (!q->isWindow() && q->parentWidget()) // && !d->getOpaqueRegion().isEmpty())
8384 q->parentWidget()->d_func()->setDirtyOpaqueRegion();
8385
8386 if (!q->testAttribute(Qt::WA_WState_Hidden)) {
8387 q->setAttribute(Qt::WA_WState_Hidden);
8388 hide_helper();
8389 }
8390
8391 // invalidate layout similar to updateGeometry()
8392 if (!q->isWindow() && q->parentWidget()) {
8393 if (q->parentWidget()->d_func()->layout)
8394 q->parentWidget()->d_func()->layout->invalidate();
8395 else if (q->parentWidget()->isVisible())
8396 QCoreApplication::postEvent(q->parentWidget(), new QEvent(QEvent::LayoutRequest));
8397 }
8398
8399 QEvent hideToParentEvent(QEvent::HideToParent);
8400 QCoreApplication::sendEvent(q, &hideToParentEvent);
8401 }
8402}
8403
8404/*!
8405 Convenience function, equivalent to setVisible(!\a hidden).
8406*/
8407void QWidget::setHidden(bool hidden)
8408{
8409 setVisible(!hidden);
8410}
8411
8412bool QWidgetPrivate::isExplicitlyHidden() const
8413{
8414 Q_Q(const QWidget);
8415 return q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
8416}
8417
8418void QWidgetPrivate::_q_showIfNotHidden()
8419{
8420 Q_Q(QWidget);
8421 if (!isExplicitlyHidden())
8422 q->setVisible(true);
8423}
8424
8425void QWidgetPrivate::showChildren(bool spontaneous)
8426{
8427 Q_Q(QWidget);
8428 qCDebug(lcWidgetShowHide) << "Showing children of" << q
8429 << "spontaneously" << spontaneous;
8430
8431 QList<QObject*> childList = children;
8432 for (int i = 0; i < childList.size(); ++i) {
8433 QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
8434 if (!widget)
8435 continue;
8436 qCDebug(lcWidgetShowHide) << "Considering" << widget
8437 << "with attributes" << WidgetAttributes{widget};
8438 if (widget->windowHandle() && !widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
8439 widget->setAttribute(Qt::WA_WState_Hidden, false);
8440 if (widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
8441 continue;
8442 if (spontaneous) {
8443 widget->setAttribute(Qt::WA_Mapped);
8444 widget->d_func()->showChildren(true);
8445 QShowEvent e;
8446 QApplication::sendSpontaneousEvent(widget, &e);
8447 } else {
8448 if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) {
8449 widget->d_func()->show_recursive();
8450 } else {
8451 // Call QWidget::setVisible() here, so that subclasses
8452 // that (wrongly) override setVisible to do initialization
8453 // will still be notified that they are made visible, but
8454 // do so without triggering ExplicitShowHide.
8455 widget->d_func()->dontSetExplicitShowHide = true;
8456 widget->setVisible(true);
8457 widget->d_func()->dontSetExplicitShowHide = false;
8458 }
8459 }
8460 }
8461}
8462
8463void QWidgetPrivate::hideChildren(bool spontaneous)
8464{
8465 Q_Q(QWidget);
8466 qCDebug(lcWidgetShowHide) << "Hiding children of" << q
8467 << "spontaneously" << spontaneous;
8468
8469 QList<QObject*> childList = children;
8470 for (int i = 0; i < childList.size(); ++i) {
8471 QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
8472 if (!widget)
8473 continue;
8474 qCDebug(lcWidgetShowHide) << "Considering" << widget
8475 << "with attributes" << WidgetAttributes{widget};
8476 if (widget->isWindow() || !widget->isVisible())
8477 continue;
8478
8479 if (spontaneous)
8480 widget->setAttribute(Qt::WA_Mapped, false);
8481 else
8482 widget->setAttribute(Qt::WA_WState_Visible, false);
8483 widget->d_func()->hideChildren(spontaneous);
8484 QHideEvent e;
8485 if (spontaneous) {
8486 QApplication::sendSpontaneousEvent(widget, &e);
8487 } else {
8488 QCoreApplication::sendEvent(widget, &e);
8489 if (widget->internalWinId()
8490 && widget->testAttribute(Qt::WA_DontCreateNativeAncestors)) {
8491 // hide_sys() on an ancestor won't have any affect on this
8492 // widget, so it needs an explicit hide_sys() of its own
8493 widget->d_func()->hide_sys();
8494 }
8495 }
8496 qApp->d_func()->sendSyntheticEnterLeave(widget);
8497#if QT_CONFIG(accessibility)
8498 if (!spontaneous) {
8499 QAccessibleEvent event(widget, QAccessible::ObjectHide);
8500 QAccessible::updateAccessibility(&event);
8501 }
8502#endif
8503 }
8504
8505 // If the window of this widget is not closed, then the leave event
8506 // will eventually handle the widget under mouse use case.
8507 // Otherwise, we need to explicitly handle it here.
8508 if (QWidget* widgetWindow = q->window();
8509 widgetWindow && widgetWindow->data->is_closing) {
8510 q->setAttribute(Qt::WA_UnderMouse, false);
8511 }
8512}
8513
8514/*!
8515 \internal
8516
8517 For windows, this is called from the QWidgetWindow::handleCloseEvent implementation,
8518 which QWidget::close indirectly calls by closing the QWindow. \a mode will be
8519 CloseWithEvent if QWidgetWindow::handleCloseEvent is called indirectly by
8520 QWindow::close, and CloseWithSpontaneousEvent if the close event originates from the
8521 system (i.e. the user clicked the close button in the title bar).
8522
8523 QDialog calls this method directly in its hide() implementation, which might be
8524 called from the QDialog::closeEvent override. \a mode will be set to CloseNoEvent
8525 to prevent recursion.
8526
8527 For non-windows, this is called directly by QWidget::close, and \a mode will be
8528 CloseWithEvent.
8529
8530 The function is also called by the QWidget destructor, with \a mode set to CloseNoEvent.
8531*/
8532bool QWidgetPrivate::handleClose(CloseMode mode)
8533{
8534 Q_Q(QWidget);
8535 qCDebug(lcWidgetShowHide) << "Handling close event for" << q;
8536
8537 if (data.is_closing)
8538 return true;
8539
8540 // We might not have initiated the close, so update the state now that we know
8541 data.is_closing = true;
8542
8543 QPointer<QWidget> that = q;
8544
8545 if (data.in_destructor)
8546 mode = CloseNoEvent;
8547
8548 if (mode != CloseNoEvent) {
8549 QCloseEvent e;
8550 if (mode == CloseWithSpontaneousEvent)
8551 QApplication::sendSpontaneousEvent(q, &e);
8552 else
8553 QCoreApplication::sendEvent(q, &e);
8554 if (!that.isNull() && !e.isAccepted()) {
8555 data.is_closing = false;
8556 return false;
8557 }
8558 }
8559
8560 // even for windows, make sure we deliver a hide event and that all children get hidden
8561 if (!that.isNull() && !q->isHidden())
8562 q->hide();
8563
8564 if (!that.isNull()) {
8565 data.is_closing = false;
8566 if (q->testAttribute(Qt::WA_DeleteOnClose)) {
8567 q->setAttribute(Qt::WA_DeleteOnClose, false);
8568 q->deleteLater();
8569 }
8570 }
8571 return true;
8572}
8573
8574
8575/*!
8576 Closes this widget. Returns \c true if the widget was closed;
8577 otherwise returns \c false.
8578
8579 First it sends the widget a QCloseEvent. The widget is
8580 \l{hide()}{hidden} if it \l{QEvent::accept()}{accepts}
8581 the close event. If it \l{QEvent::ignore()}{ignores}
8582 the event, nothing happens. The default
8583 implementation of QWidget::closeEvent() accepts the close event.
8584
8585 If the widget has the Qt::WA_DeleteOnClose flag, the widget
8586 is also deleted. A close events is delivered to the widget no
8587 matter if the widget is visible or not.
8588
8589 The \l QGuiApplication::lastWindowClosed() signal is emitted when the
8590 last visible primary window (i.e. window with no parent) with the
8591 Qt::WA_QuitOnClose attribute set is closed. By default this
8592 attribute is set for all widgets except transient windows such as
8593 splash screens, tool windows, and popup menus.
8594
8595*/
8596
8597bool QWidget::close()
8598{
8599 return d_func()->close();
8600}
8601
8602bool QWidgetPrivate::close()
8603{
8604 // FIXME: We're not setting is_closing here, even though that would
8605 // make sense, as the code below will not end up in handleClose to
8606 // reset is_closing when there's a QWindow, but no QPlatformWindow,
8607 // and we can't assume close is synchronous so we can't reset it here.
8608
8609 // Close native widgets via QWindow::close() in order to run QWindow
8610 // close code. The QWidget-specific close code in handleClose() will
8611 // in this case be called from the Close event handler in QWidgetWindow.
8612 if (QWindow *widgetWindow = windowHandle()) {
8613 if (widgetWindow->isTopLevel())
8614 return widgetWindow->close();
8615 }
8616
8617 return handleClose(QWidgetPrivate::CloseWithEvent);
8618}
8619
8620/*!
8621 \property QWidget::visible
8622 \brief whether the widget is visible
8623
8624 Calling setVisible(true) or show() sets the widget to visible
8625 status if all its parent widgets up to the window are visible. If
8626 an ancestor is not visible, the widget won't become visible until
8627 all its ancestors are shown. If its size or position has changed,
8628 Qt guarantees that a widget gets move and resize events just
8629 before it is shown. If the widget has not been resized yet, Qt
8630 will adjust the widget's size to a useful default using
8631 adjustSize().
8632
8633 Calling setVisible(false) or hide() hides a widget explicitly. An
8634 explicitly hidden widget will never become visible, even if all
8635 its ancestors become visible, unless you show it.
8636
8637 A widget receives show and hide events when its visibility status
8638 changes. Between a hide and a show event, there is no need to
8639 waste CPU cycles preparing or displaying information to the user.
8640 A video application, for example, might simply stop generating new
8641 frames.
8642
8643 A widget that happens to be obscured by other windows on the
8644 screen is considered to be visible. The same applies to iconified
8645 windows and windows that exist on another virtual
8646 desktop (on platforms that support this concept). A widget
8647 receives spontaneous show and hide events when its mapping status
8648 is changed by the window system, e.g. a spontaneous hide event
8649 when the user minimizes the window, and a spontaneous show event
8650 when the window is restored again.
8651
8652 You seldom have to reimplement the setVisible() function. If
8653 you need to change some settings before a widget is shown, use
8654 showEvent() instead. If you need to do some delayed initialization
8655 use the Polish event delivered to the event() function.
8656
8657 \sa show(), hide(), isHidden(), isVisibleTo(), isMinimized(),
8658 showEvent(), hideEvent()
8659*/
8660
8661
8662/*!
8663 Returns \c true if this widget would become visible if \a ancestor is
8664 shown; otherwise returns \c false.
8665
8666 The true case occurs if neither the widget itself nor any parent
8667 up to but excluding \a ancestor has been explicitly hidden.
8668
8669 This function will still return true if the widget is obscured by
8670 other windows on the screen, but could be physically visible if it
8671 or they were to be moved.
8672
8673 isVisibleTo(0) is identical to isVisible().
8674
8675 \sa show(), hide(), isVisible()
8676*/
8677
8678bool QWidget::isVisibleTo(const QWidget *ancestor) const
8679{
8680 if (!ancestor)
8681 return isVisible();
8682 const QWidget * w = this;
8683 while (!w->isHidden()
8684 && !w->isWindow()
8685 && w->parentWidget()
8686 && w->parentWidget() != ancestor)
8687 w = w->parentWidget();
8688 return !w->isHidden();
8689}
8690
8691
8692/*!
8693 Returns the unobscured region where paint events can occur.
8694
8695 For visible widgets, this is an approximation of the area not
8696 covered by other widgets; otherwise, this is an empty region.
8697
8698 The repaint() function calls this function if necessary, so in
8699 general you do not need to call it.
8700
8701*/
8702QRegion QWidget::visibleRegion() const
8703{
8704 Q_D(const QWidget);
8705
8706 QRect clipRect = d->clipRect();
8707 if (clipRect.isEmpty())
8708 return QRegion();
8709 QRegion r(clipRect);
8710 d->subtractOpaqueChildren(r, clipRect);
8711 d->subtractOpaqueSiblings(r);
8712 return r;
8713}
8714
8715
8716QSize QWidgetPrivate::adjustedSize() const
8717{
8718 Q_Q(const QWidget);
8719
8720 QSize s = q->sizeHint();
8721
8722 if (q->isWindow()) {
8723 Qt::Orientations exp;
8724 if (layout) {
8725 if (layout->hasHeightForWidth())
8726 s.setHeight(layout->totalHeightForWidth(s.width()));
8727 exp = layout->expandingDirections();
8728 } else
8729 {
8730 if (q->sizePolicy().hasHeightForWidth())
8731 s.setHeight(q->heightForWidth(s.width()));
8732 exp = q->sizePolicy().expandingDirections();
8733 }
8734 if (exp & Qt::Horizontal)
8735 s.setWidth(qMax(s.width(), 200));
8736 if (exp & Qt::Vertical)
8737 s.setHeight(qMax(s.height(), 100));
8738
8739 QRect screen;
8740 if (const QScreen *screenAtPoint = QGuiApplication::screenAt(q->pos()))
8741 screen = screenAtPoint->geometry();
8742 else
8743 screen = QGuiApplication::primaryScreen()->geometry();
8744
8745 s.setWidth(qMin(s.width(), screen.width()*2/3));
8746 s.setHeight(qMin(s.height(), screen.height()*2/3));
8747
8748 if (QTLWExtra *extra = maybeTopData())
8749 extra->sizeAdjusted = true;
8750 }
8751
8752 if (!s.isValid()) {
8753 QRect r = q->childrenRect(); // get children rectangle
8754 if (r.isNull())
8755 return s;
8756 s = r.size() + QSize(2 * r.x(), 2 * r.y());
8757 }
8758
8759 return s;
8760}
8761
8762/*!
8763 Adjusts the size of the widget to fit its contents.
8764
8765 This function uses sizeHint() if it is valid, i.e., the size hint's width
8766 and height are >= 0. Otherwise, it sets the size to the children
8767 rectangle that covers all child widgets (the union of all child widget
8768 rectangles).
8769
8770 For windows, the screen size is also taken into account. If the sizeHint()
8771 is less than (200, 100) and the size policy is \l{QSizePolicy::Expanding}
8772 {expanding}, the window will be at least (200, 100). The maximum size of
8773 a window is 2/3 of the screen's width and height.
8774
8775 \sa sizeHint(), childrenRect()
8776*/
8777
8778void QWidget::adjustSize()
8779{
8780 Q_D(QWidget);
8781 ensurePolished();
8782 QSize s = d->adjustedSize();
8783
8784 if (d->layout)
8785 d->layout->activate();
8786
8787 if (s.isValid())
8788 resize(s);
8789}
8790
8791
8792/*!
8793 \property QWidget::sizeHint
8794 \brief the recommended size for the widget
8795
8796 If the value of this property is an invalid size, no size is
8797 recommended.
8798
8799 The default implementation of sizeHint() returns an invalid size
8800 if there is no layout for this widget, and returns the layout's
8801 preferred size otherwise.
8802
8803 \sa QSize::isValid(), minimumSizeHint(), sizePolicy(),
8804 setMinimumSize(), updateGeometry()
8805*/
8806
8807QSize QWidget::sizeHint() const
8808{
8809 Q_D(const QWidget);
8810 if (d->layout)
8811 return d->layout->totalSizeHint();
8812 return QSize(-1, -1);
8813}
8814
8815/*!
8816 \property QWidget::minimumSizeHint
8817 \brief the recommended minimum size for the widget
8818
8819 If the value of this property is an invalid size, no minimum size
8820 is recommended.
8821
8822 The default implementation of minimumSizeHint() returns an invalid
8823 size if there is no layout for this widget, and returns the
8824 layout's minimum size otherwise. Most built-in widgets reimplement
8825 minimumSizeHint().
8826
8827 \l QLayout will never resize a widget to a size smaller than the
8828 minimum size hint unless minimumSize() is set or the size policy is
8829 set to QSizePolicy::Ignore. If minimumSize() is set, the minimum
8830 size hint will be ignored.
8831
8832 \sa QSize::isValid(), resize(), setMinimumSize(), sizePolicy()
8833*/
8834QSize QWidget::minimumSizeHint() const
8835{
8836 Q_D(const QWidget);
8837 if (d->layout)
8838 return d->layout->totalMinimumSize();
8839 return QSize(-1, -1);
8840}
8841
8842
8843/*!
8844 \fn QWidget *QWidget::parentWidget() const
8845
8846 Returns the parent of this widget, or \nullptr if it does not have any
8847 parent widget.
8848*/
8849
8850
8851/*!
8852 Returns \c true if this widget is a parent, (or grandparent and so on
8853 to any level), of the given \a child, and both widgets are within
8854 the same window; otherwise returns \c false.
8855*/
8856
8857bool QWidget::isAncestorOf(const QWidget *child) const
8858{
8859 while (child) {
8860 if (child == this)
8861 return true;
8862 if (child->isWindow())
8863 return false;
8864 child = child->parentWidget();
8865 }
8866 return false;
8867}
8868
8869/*****************************************************************************
8870 QWidget event handling
8871 *****************************************************************************/
8872
8873/*!
8874 This is the main event handler; it handles event \a event. You can
8875 reimplement this function in a subclass, but we recommend using
8876 one of the specialized event handlers instead.
8877
8878 Key press and release events are treated differently from other
8879 events. event() checks for Tab and Shift+Tab and tries to move the
8880 focus appropriately. If there is no widget to move the focus to
8881 (or the key press is not Tab or Shift+Tab), event() calls
8882 keyPressEvent().
8883
8884 Mouse and tablet event handling is also slightly special: only
8885 when the widget is \l enabled, event() will call the specialized
8886 handlers such as mousePressEvent(); otherwise it will discard the
8887 event.
8888
8889 This function returns \c true if the event was recognized, otherwise
8890 it returns \c false. If the recognized event was accepted (see \l
8891 QEvent::accepted), any further processing such as event
8892 propagation to the parent widget stops.
8893
8894 \sa closeEvent(), focusInEvent(), focusOutEvent(), enterEvent(),
8895 keyPressEvent(), keyReleaseEvent(), leaveEvent(),
8896 mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(),
8897 mouseReleaseEvent(), moveEvent(), paintEvent(), resizeEvent(),
8898 QObject::event(), QObject::timerEvent()
8899*/
8900
8901bool QWidget::event(QEvent *event)
8902{
8903 Q_D(QWidget);
8904
8905 // ignore mouse and key events when disabled
8906 if (!isEnabled()) {
8907 switch(event->type()) {
8908 case QEvent::TabletPress:
8909 case QEvent::TabletRelease:
8910 case QEvent::TabletMove:
8911 case QEvent::MouseButtonPress:
8912 case QEvent::MouseButtonRelease:
8913 case QEvent::MouseButtonDblClick:
8914 case QEvent::MouseMove:
8915 case QEvent::TouchBegin:
8916 case QEvent::TouchUpdate:
8917 case QEvent::TouchEnd:
8918 case QEvent::TouchCancel:
8919 case QEvent::ContextMenu:
8920 case QEvent::KeyPress:
8921 case QEvent::KeyRelease:
8922#if QT_CONFIG(wheelevent)
8923 case QEvent::Wheel:
8924#endif
8925 return false;
8926 default:
8927 break;
8928 }
8929 }
8930 switch (event->type()) {
8931 case QEvent::PlatformSurface: {
8932 // Sync up QWidget's view of whether or not the widget has been created
8933 switch (static_cast<QPlatformSurfaceEvent*>(event)->surfaceEventType()) {
8934 case QPlatformSurfaceEvent::SurfaceCreated:
8935 if (!testAttribute(Qt::WA_WState_Created))
8936 create();
8937 break;
8938 case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
8939 if (testAttribute(Qt::WA_WState_Created)) {
8940 // Child windows have already been destroyed by QWindow,
8941 // so we skip them here.
8942 destroy(false, false);
8943 }
8944 break;
8945 }
8946 break;
8947 }
8948 case QEvent::MouseMove:
8949 mouseMoveEvent((QMouseEvent*)event);
8950 break;
8951
8952 case QEvent::MouseButtonPress:
8953 mousePressEvent((QMouseEvent*)event);
8954 break;
8955
8956 case QEvent::MouseButtonRelease:
8957 mouseReleaseEvent((QMouseEvent*)event);
8958 break;
8959
8960 case QEvent::MouseButtonDblClick:
8961 mouseDoubleClickEvent((QMouseEvent*)event);
8962 break;
8963#if QT_CONFIG(wheelevent)
8964 case QEvent::Wheel:
8965 wheelEvent((QWheelEvent*)event);
8966 break;
8967#endif
8968#if QT_CONFIG(tabletevent)
8969 case QEvent::TabletMove:
8970 if (static_cast<QTabletEvent *>(event)->buttons() == Qt::NoButton && !testAttribute(Qt::WA_TabletTracking))
8971 break;
8972 Q_FALLTHROUGH();
8973 case QEvent::TabletPress:
8974 case QEvent::TabletRelease:
8975 tabletEvent((QTabletEvent*)event);
8976 break;
8977#endif
8978 case QEvent::KeyPress: {
8979 QKeyEvent *k = static_cast<QKeyEvent *>(event);
8980 bool res = false;
8981 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
8982 if (k->key() == Qt::Key_Backtab
8983 || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
8984 res = focusNextPrevChild(false);
8985 else if (k->key() == Qt::Key_Tab)
8986 res = focusNextPrevChild(true);
8987 if (res)
8988 break;
8989 }
8990 keyPressEvent(k);
8991#ifdef QT_KEYPAD_NAVIGATION
8992 if (!k->isAccepted() && QApplication::keypadNavigationEnabled()
8993 && !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier))) {
8994 if (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder) {
8995 if (k->key() == Qt::Key_Up)
8996 res = focusNextPrevChild(false);
8997 else if (k->key() == Qt::Key_Down)
8998 res = focusNextPrevChild(true);
8999 } else if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
9000 if (k->key() == Qt::Key_Up)
9001 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionNorth);
9002 else if (k->key() == Qt::Key_Right)
9003 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionEast);
9004 else if (k->key() == Qt::Key_Down)
9005 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionSouth);
9006 else if (k->key() == Qt::Key_Left)
9007 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionWest);
9008 }
9009 if (res) {
9010 k->accept();
9011 break;
9012 }
9013 }
9014#endif
9015#if QT_CONFIG(whatsthis)
9016 if (!k->isAccepted()
9017 && k->modifiers() & Qt::ShiftModifier && k->key() == Qt::Key_F1
9018 && d->whatsThis.size()) {
9019 QWhatsThis::showText(mapToGlobal(inputMethodQuery(Qt::ImCursorRectangle).toRect().center()), d->whatsThis, this);
9020 k->accept();
9021 }
9022#endif
9023 }
9024 break;
9025
9026 case QEvent::KeyRelease:
9027 keyReleaseEvent((QKeyEvent*)event);
9028 Q_FALLTHROUGH();
9029 case QEvent::ShortcutOverride:
9030 break;
9031
9032 case QEvent::InputMethod:
9033 inputMethodEvent((QInputMethodEvent *) event);
9034 break;
9035
9036 case QEvent::InputMethodQuery: {
9037 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(event);
9038 Qt::InputMethodQueries queries = query->queries();
9039 for (uint i = 0; i < 32; ++i) {
9040 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
9041 if (q) {
9042 QVariant v = inputMethodQuery(q);
9043 if (q == Qt::ImEnabled && !v.isValid() && isEnabled()) {
9044 // Qt:ImEnabled was added in Qt 5.3. So not all widgets support it, even
9045 // if they implement IM otherwise (by overriding inputMethodQuery()). Instead
9046 // they set the widget attribute Qt::WA_InputMethodEnabled. But this attribute
9047 // will only be set if the widget supports IM _and_ is not read-only. So for
9048 // read-only widgets, not all IM features will be supported when ImEnabled is
9049 // not implemented explicitly (e.g selection handles for read-only widgets on iOS).
9050 v = QVariant(testAttribute(Qt::WA_InputMethodEnabled));
9051 }
9052 query->setValue(q, v);
9053 }
9054 }
9055 query->accept();
9056 }
9057 break;
9058
9059 case QEvent::PolishRequest:
9060 ensurePolished();
9061 break;
9062
9063 case QEvent::Polish: {
9064 style()->polish(this);
9065 setAttribute(Qt::WA_WState_Polished);
9066 if (!QApplication::font(this).isCopyOf(QApplication::font()))
9067 d->resolveFont();
9068 if (!QApplication::palette(this).isCopyOf(QGuiApplication::palette()))
9069 d->resolvePalette();
9070 }
9071 break;
9072
9073 case QEvent::ApplicationWindowIconChange:
9074 if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon)) {
9075 d->setWindowIcon_sys();
9076 d->setWindowIcon_helper();
9077 }
9078 break;
9079 case QEvent::FocusIn:
9080 focusInEvent((QFocusEvent*)event);
9081 d->updateWidgetTransform(event);
9082 break;
9083
9084 case QEvent::FocusOut:
9085 focusOutEvent((QFocusEvent*)event);
9086 break;
9087
9088 case QEvent::Enter:
9089#if QT_CONFIG(statustip)
9090 if (d->statusTip.size()) {
9091 QStatusTipEvent tip(d->statusTip);
9092 QCoreApplication::sendEvent(const_cast<QWidget *>(this), &tip);
9093 }
9094#endif
9095 enterEvent(static_cast<QEnterEvent*>(event));
9096 break;
9097
9098 case QEvent::Leave:
9099#if QT_CONFIG(statustip)
9100 if (d->statusTip.size()) {
9101 QString empty;
9102 QStatusTipEvent tip(empty);
9103 QCoreApplication::sendEvent(const_cast<QWidget *>(this), &tip);
9104 }
9105#endif
9106 leaveEvent(event);
9107 break;
9108
9109 case QEvent::HoverEnter:
9110 case QEvent::HoverLeave:
9111 update();
9112 break;
9113
9114 case QEvent::Paint:
9115 // At this point the event has to be delivered, regardless
9116 // whether the widget isVisible() or not because it
9117 // already went through the filters
9118 paintEvent((QPaintEvent*)event);
9119 break;
9120
9121 case QEvent::Move:
9122 moveEvent((QMoveEvent*)event);
9123 d->updateWidgetTransform(event);
9124 break;
9125
9126 case QEvent::Resize:
9127 resizeEvent((QResizeEvent*)event);
9128 d->updateWidgetTransform(event);
9129 break;
9130
9131 case QEvent::Close:
9132 closeEvent((QCloseEvent *)event);
9133 break;
9134
9135#ifndef QT_NO_CONTEXTMENU
9136 case QEvent::ContextMenu:
9137 switch (data->context_menu_policy) {
9138 case Qt::PreventContextMenu:
9139 break;
9140 case Qt::DefaultContextMenu:
9141 contextMenuEvent(static_cast<QContextMenuEvent *>(event));
9142 break;
9143 case Qt::CustomContextMenu:
9144 emit customContextMenuRequested(static_cast<QContextMenuEvent *>(event)->pos());
9145 break;
9146#if QT_CONFIG(menu)
9147 case Qt::ActionsContextMenu:
9148 if (d->actions.size()) {
9149 QMenu::exec(d->actions, static_cast<QContextMenuEvent *>(event)->globalPos(),
9150 nullptr, this);
9151 break;
9152 }
9153 Q_FALLTHROUGH();
9154#endif
9155 default:
9156 event->ignore();
9157 break;
9158 }
9159 break;
9160#endif // QT_NO_CONTEXTMENU
9161
9162#if QT_CONFIG(draganddrop)
9163 case QEvent::Drop:
9164 dropEvent((QDropEvent*) event);
9165 break;
9166
9167 case QEvent::DragEnter:
9168 dragEnterEvent((QDragEnterEvent*) event);
9169 break;
9170
9171 case QEvent::DragMove:
9172 dragMoveEvent((QDragMoveEvent*) event);
9173 break;
9174
9175 case QEvent::DragLeave:
9176 dragLeaveEvent((QDragLeaveEvent*) event);
9177 break;
9178#endif
9179
9180 case QEvent::Show:
9181 showEvent((QShowEvent*) event);
9182 break;
9183
9184 case QEvent::Hide:
9185 hideEvent((QHideEvent*) event);
9186 break;
9187
9188 case QEvent::ShowWindowRequest:
9189 if (!isHidden())
9190 d->show_sys();
9191 break;
9192
9193 case QEvent::ApplicationFontChange:
9194 d->resolveFont();
9195 break;
9196 case QEvent::ApplicationPaletteChange:
9197 if (!(windowType() == Qt::Desktop))
9198 d->resolvePalette();
9199 break;
9200
9201 case QEvent::ToolBarChange:
9202 case QEvent::ActivationChange:
9203 case QEvent::EnabledChange:
9204 case QEvent::FontChange:
9205 case QEvent::StyleChange:
9206 case QEvent::PaletteChange:
9207 case QEvent::WindowTitleChange:
9208 case QEvent::IconTextChange:
9209 case QEvent::ModifiedChange:
9210 case QEvent::MouseTrackingChange:
9211 case QEvent::TabletTrackingChange:
9212 case QEvent::ParentChange:
9213 case QEvent::LocaleChange:
9214 case QEvent::MacSizeChange:
9215 case QEvent::ContentsRectChange:
9216 case QEvent::ThemeChange:
9217 case QEvent::ReadOnlyChange:
9218 changeEvent(event);
9219 break;
9220
9221 case QEvent::WindowStateChange: {
9222 const bool wasMinimized = static_cast<const QWindowStateChangeEvent *>(event)->oldState() & Qt::WindowMinimized;
9223 if (wasMinimized != isMinimized()) {
9224 QWidget *widget = const_cast<QWidget *>(this);
9225 if (wasMinimized) {
9226 // Always send the spontaneous events here, otherwise it can break the application!
9227 if (!d->childrenShownByExpose) {
9228 // Show widgets only when they are not yet shown by the expose event
9229 d->showChildren(true);
9230 QShowEvent showEvent;
9231 QCoreApplication::sendSpontaneousEvent(widget, &showEvent);
9232 }
9233 d->childrenHiddenByWState = false; // Set it always to "false" when window is restored
9234 } else {
9235 QHideEvent hideEvent;
9236 QCoreApplication::sendSpontaneousEvent(widget, &hideEvent);
9237 d->hideChildren(true);
9238 d->childrenHiddenByWState = true;
9239 }
9240 d->childrenShownByExpose = false; // Set it always to "false" when window state changes
9241 }
9242 changeEvent(event);
9243 }
9244 break;
9245
9246 case QEvent::WindowActivate:
9247 case QEvent::WindowDeactivate: {
9248 if (isVisible() && !palette().isEqual(QPalette::Active, QPalette::Inactive))
9249 update();
9250 QList<QObject*> childList = d->children;
9251 for (int i = 0; i < childList.size(); ++i) {
9252 QWidget *w = qobject_cast<QWidget *>(childList.at(i));
9253 if (w && w->isVisible() && !w->isWindow())
9254 QCoreApplication::sendEvent(w, event);
9255 }
9256 break; }
9257
9258 case QEvent::LanguageChange:
9259 changeEvent(event);
9260 {
9261 QList<QObject*> childList = d->children;
9262 for (int i = 0; i < childList.size(); ++i) {
9263 QObject *o = childList.at(i);
9264 if (o)
9265 QCoreApplication::sendEvent(o, event);
9266 }
9267 }
9268 update();
9269 break;
9270
9271 case QEvent::ApplicationLayoutDirectionChange:
9272 d->resolveLayoutDirection();
9273 break;
9274
9275 case QEvent::LayoutDirectionChange:
9276 if (d->layout)
9277 d->layout->invalidate();
9278 update();
9279 changeEvent(event);
9280 break;
9281 case QEvent::UpdateRequest:
9282 d->syncBackingStore();
9283 break;
9284 case QEvent::UpdateLater:
9285 update(static_cast<QUpdateLaterEvent*>(event)->region());
9286 break;
9287 case QEvent::StyleAnimationUpdate:
9288 if (isVisible() && !window()->isMinimized()) {
9289 event->accept();
9290 update();
9291 }
9292 break;
9293
9294 case QEvent::WindowBlocked:
9295 case QEvent::WindowUnblocked:
9296 if (!d->children.isEmpty()) {
9297 QWidget *modalWidget = QApplication::activeModalWidget();
9298 for (int i = 0; i < d->children.size(); ++i) {
9299 QObject *o = d->children.at(i);
9300 if (o && o != modalWidget && o->isWidgetType()) {
9301 QWidget *w = static_cast<QWidget *>(o);
9302 // do not forward the event to child windows; QApplication does this for us
9303 if (!w->isWindow())
9304 QCoreApplication::sendEvent(w, event);
9305 }
9306 }
9307 }
9308 break;
9309#if QT_CONFIG(tooltip)
9310 case QEvent::ToolTip:
9311 if (!d->toolTip.isEmpty())
9312 QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this, QRect(), d->toolTipDuration);
9313 else
9314 event->ignore();
9315 break;
9316#endif
9317#if QT_CONFIG(whatsthis)
9318 case QEvent::WhatsThis:
9319 if (d->whatsThis.size())
9320 QWhatsThis::showText(static_cast<QHelpEvent *>(event)->globalPos(), d->whatsThis, this);
9321 else
9322 event->ignore();
9323 break;
9324 case QEvent::QueryWhatsThis:
9325 if (d->whatsThis.isEmpty())
9326 event->ignore();
9327 break;
9328#endif
9329 case QEvent::EmbeddingControl:
9330 d->topData()->frameStrut.setCoords(0 ,0, 0, 0);
9331 data->fstrut_dirty = false;
9332 break;
9333#ifndef QT_NO_ACTION
9334 case QEvent::ActionAdded:
9335 case QEvent::ActionRemoved:
9336 case QEvent::ActionChanged:
9337 actionEvent((QActionEvent*)event);
9338 break;
9339#endif
9340
9341 case QEvent::KeyboardLayoutChange:
9342 {
9343 changeEvent(event);
9344
9345 // inform children of the change
9346 QList<QObject*> childList = d->children;
9347 for (int i = 0; i < childList.size(); ++i) {
9348 QWidget *w = qobject_cast<QWidget *>(childList.at(i));
9349 if (w && w->isVisible() && !w->isWindow())
9350 QCoreApplication::sendEvent(w, event);
9351 }
9352 break;
9353 }
9354 case QEvent::TouchBegin:
9355 case QEvent::TouchUpdate:
9356 case QEvent::TouchEnd:
9357 case QEvent::TouchCancel:
9358 {
9359 event->ignore();
9360 break;
9361 }
9362#ifndef QT_NO_GESTURES
9363 case QEvent::Gesture:
9364 event->ignore();
9365 break;
9366#endif
9367 case QEvent::ScreenChangeInternal:
9368 if (const QTLWExtra *te = d->maybeTopData()) {
9369 const QWindow *win = te->window;
9370 d->setWinId((win && win->handle()) ? win->handle()->winId() : 0);
9371 }
9372 break;
9373 case QEvent::DevicePixelRatioChange:
9374 if (d->data.fnt.d->dpi != logicalDpiY())
9375 d->updateFont(d->data.fnt);
9376 d->renderToTextureReallyDirty = 1;
9377 break;
9378 case QEvent::DynamicPropertyChange: {
9379 const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
9380 if (propName.size() == 13 && !qstrncmp(propName, "_q_customDpi", 12)) {
9381 uint value = property(propName.constData()).toUInt();
9382 if (!d->extra)
9383 d->createExtra();
9384 const char axis = propName.at(12);
9385 if (axis == 'X')
9386 d->extra->customDpiX = value;
9387 else if (axis == 'Y')
9388 d->extra->customDpiY = value;
9389 d->updateFont(d->data.fnt);
9390 }
9391 if (windowHandle() && !qstrncmp(propName, "_q_platform_", 12))
9392 windowHandle()->setProperty(propName, property(propName));
9393 Q_FALLTHROUGH();
9394 }
9395 default:
9396 return QObject::event(event);
9397 }
9398 return true;
9399}
9400
9401/*!
9402 This event handler can be reimplemented to handle state changes.
9403
9404 The state being changed in this event can be retrieved through the \a event
9405 supplied.
9406
9407 Change events include: QEvent::ToolBarChange,
9408 QEvent::ActivationChange, QEvent::EnabledChange, QEvent::FontChange,
9409 QEvent::StyleChange, QEvent::PaletteChange,
9410 QEvent::WindowTitleChange, QEvent::IconTextChange,
9411 QEvent::ModifiedChange, QEvent::MouseTrackingChange,
9412 QEvent::ParentChange, QEvent::WindowStateChange,
9413 QEvent::LanguageChange, QEvent::LocaleChange,
9414 QEvent::LayoutDirectionChange, QEvent::ReadOnlyChange.
9415
9416*/
9417void QWidget::changeEvent(QEvent * event)
9418{
9419 switch(event->type()) {
9420 case QEvent::EnabledChange: {
9421 update();
9422#if QT_CONFIG(accessibility)
9423 QAccessible::State s;
9424 s.disabled = true;
9425 QAccessibleStateChangeEvent event(this, s);
9426 QAccessible::updateAccessibility(&event);
9427#endif
9428 break;
9429 }
9430
9431 case QEvent::FontChange:
9432 case QEvent::StyleChange: {
9433 Q_D(QWidget);
9434 update();
9435 updateGeometry();
9436 if (d->layout)
9437 d->layout->invalidate();
9438 break;
9439 }
9440
9441 case QEvent::PaletteChange:
9442 update();
9443 break;
9444
9445 case QEvent::ThemeChange:
9446 if (QGuiApplication::desktopSettingsAware() && windowType() != Qt::Desktop
9447 && qApp && !QCoreApplication::closingDown()) {
9448 if (testAttribute(Qt::WA_WState_Polished))
9449 QApplication::style()->unpolish(this);
9450 if (testAttribute(Qt::WA_WState_Polished))
9451 QApplication::style()->polish(this);
9452 QEvent styleChangedEvent(QEvent::StyleChange);
9453 QCoreApplication::sendEvent(this, &styleChangedEvent);
9454 if (isVisible())
9455 update();
9456 }
9457 break;
9458
9459#ifdef Q_OS_MAC
9460 case QEvent::MacSizeChange:
9461 updateGeometry();
9462 break;
9463#endif
9464
9465 default:
9466 break;
9467 }
9468}
9469
9470/*!
9471 This event handler, for event \a event, can be reimplemented in a
9472 subclass to receive mouse move events for the widget.
9473
9474 If mouse tracking is switched off, mouse move events only occur if
9475 a mouse button is pressed while the mouse is being moved. If mouse
9476 tracking is switched on, mouse move events occur even if no mouse
9477 button is pressed.
9478
9479 QMouseEvent::pos() reports the position of the mouse cursor,
9480 relative to this widget. For press and release events, the
9481 position is usually the same as the position of the last mouse
9482 move event, but it might be different if the user's hand shakes.
9483 This is a feature of the underlying window system, not Qt.
9484
9485 If you want to show a tooltip immediately, while the mouse is
9486 moving (e.g., to get the mouse coordinates with QMouseEvent::pos()
9487 and show them as a tooltip), you must first enable mouse tracking
9488 as described above. Then, to ensure that the tooltip is updated
9489 immediately, you must call QToolTip::showText() instead of
9490 setToolTip() in your implementation of mouseMoveEvent().
9491
9492 \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
9493 mouseDoubleClickEvent(), event(), QMouseEvent, {Scribble Example}
9494*/
9495
9496void QWidget::mouseMoveEvent(QMouseEvent *event)
9497{
9498 event->ignore();
9499}
9500
9501/*!
9502 This event handler, for event \a event, can be reimplemented in a
9503 subclass to receive mouse press events for the widget.
9504
9505 If you create new widgets in the mousePressEvent() the
9506 mouseReleaseEvent() may not end up where you expect, depending on
9507 the underlying window system (or X11 window manager), the widgets'
9508 location and maybe more.
9509
9510 The default implementation implements the closing of popup widgets
9511 when you click outside the window. For other widget types it does
9512 nothing.
9513
9514 \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
9515 mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
9516*/
9517
9518void QWidget::mousePressEvent(QMouseEvent *event)
9519{
9520 event->ignore();
9521 if ((windowType() == Qt::Popup)) {
9522 event->accept();
9523 QWidget* w;
9524 while ((w = QApplication::activePopupWidget()) && w != this){
9525 w->close();
9526 if (QApplication::activePopupWidget() == w) // widget does not want to disappear
9527 w->hide(); // hide at least
9528 }
9529 if (!rect().contains(event->position().toPoint())){
9530 close();
9531 }
9532 }
9533}
9534
9535/*!
9536 This event handler, for event \a event, can be reimplemented in a
9537 subclass to receive mouse release events for the widget.
9538
9539 \sa mousePressEvent(), mouseDoubleClickEvent(),
9540 mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
9541*/
9542
9543void QWidget::mouseReleaseEvent(QMouseEvent *event)
9544{
9545 event->ignore();
9546}
9547
9548/*!
9549 This event handler, for event \a event, can be reimplemented in a
9550 subclass to receive mouse double click events for the widget.
9551
9552 The default implementation calls mousePressEvent().
9553
9554 \note The widget will also receive mouse press and mouse release
9555 events in addition to the double click event. And if another widget
9556 that overlaps this widget disappears in response to press or
9557 release events, then this widget will only receive the double click
9558 event. It is up to the developer to ensure that the application
9559 interprets these events correctly.
9560
9561 \sa mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(),
9562 event(), QMouseEvent
9563*/
9564
9565void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
9566{
9567 mousePressEvent(event);
9568}
9569
9570#if QT_CONFIG(wheelevent)
9571/*!
9572 This event handler, for event \a event, can be reimplemented in a
9573 subclass to receive wheel events for the widget.
9574
9575 If you reimplement this handler, it is very important that you
9576 \l{QEvent}{ignore()} the event if you do not handle
9577 it, so that the widget's parent can interpret it.
9578
9579 The default implementation ignores the event.
9580
9581 \sa QEvent::ignore(), QEvent::accept(), event(),
9582 QWheelEvent
9583*/
9584
9585void QWidget::wheelEvent(QWheelEvent *event)
9586{
9587 event->ignore();
9588}
9589#endif // QT_CONFIG(wheelevent)
9590
9591#if QT_CONFIG(tabletevent)
9592/*!
9593 This event handler, for event \a event, can be reimplemented in a
9594 subclass to receive tablet events for the widget.
9595
9596 If you reimplement this handler, it is very important that you
9597 \l{QEvent}{ignore()} the event if you do not handle
9598 it, so that the widget's parent can interpret it.
9599
9600 The default implementation ignores the event.
9601
9602 If tablet tracking is switched off, tablet move events only occur if the
9603 stylus is in contact with the tablet, or at least one stylus button is
9604 pressed, while the stylus is being moved. If tablet tracking is switched on,
9605 tablet move events occur even while the stylus is hovering in proximity of
9606 the tablet, with no buttons pressed.
9607
9608 \sa QEvent::ignore(), QEvent::accept(), event(), setTabletTracking(),
9609 QTabletEvent
9610*/
9611
9612void QWidget::tabletEvent(QTabletEvent *event)
9613{
9614 event->ignore();
9615}
9616#endif // QT_CONFIG(tabletevent)
9617
9618/*!
9619 This event handler, for event \a event, can be reimplemented in a
9620 subclass to receive key press events for the widget.
9621
9622 A widget must call setFocusPolicy() to accept focus initially and
9623 have focus in order to receive a key press event.
9624
9625 If you reimplement this handler, it is very important that you
9626 call the base class implementation if you do not act upon the key.
9627
9628 The default implementation closes popup widgets if the user
9629 presses the key sequence for QKeySequence::Cancel (typically the
9630 Escape key). Otherwise the event is ignored, so that the widget's
9631 parent can interpret it.
9632
9633 Note that QKeyEvent starts with isAccepted() == true, so you do not
9634 need to call QKeyEvent::accept() - just do not call the base class
9635 implementation if you act upon the key.
9636
9637 \sa keyReleaseEvent(), setFocusPolicy(),
9638 focusInEvent(), focusOutEvent(), event(), QKeyEvent
9639*/
9640
9641void QWidget::keyPressEvent(QKeyEvent *event)
9642{
9643#ifndef QT_NO_SHORTCUT
9644 if ((windowType() == Qt::Popup) && event->matches(QKeySequence::Cancel)) {
9645 event->accept();
9646 close();
9647 } else
9648#endif
9649 {
9650 event->ignore();
9651 }
9652}
9653
9654/*!
9655 This event handler, for event \a event, can be reimplemented in a
9656 subclass to receive key release events for the widget.
9657
9658 A widget must \l{setFocusPolicy()}{accept focus}
9659 initially and \l{hasFocus()}{have focus} in order to
9660 receive a key release event.
9661
9662 If you reimplement this handler, it is very important that you
9663 call the base class implementation if you do not act upon the key.
9664
9665 The default implementation ignores the event, so that the widget's
9666 parent can interpret it.
9667
9668 Note that QKeyEvent starts with isAccepted() == true, so you do not
9669 need to call QKeyEvent::accept() - just do not call the base class
9670 implementation if you act upon the key.
9671
9672 \sa keyPressEvent(), QEvent::ignore(), setFocusPolicy(),
9673 focusInEvent(), focusOutEvent(), event(), QKeyEvent
9674*/
9675
9676void QWidget::keyReleaseEvent(QKeyEvent *event)
9677{
9678 event->ignore();
9679}
9680
9681/*!
9682 \fn void QWidget::focusInEvent(QFocusEvent *event)
9683
9684 This event handler can be reimplemented in a subclass to receive
9685 keyboard focus events (focus received) for the widget. The event
9686 is passed in the \a event parameter
9687
9688 A widget normally must setFocusPolicy() to something other than
9689 Qt::NoFocus to receive focus events. (Note that the
9690 application programmer can call setFocus() on any widget, even
9691 those that do not normally accept focus.)
9692
9693 The default implementation updates the widget (except for windows
9694 that do not specify a focusPolicy()).
9695
9696 \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
9697 keyReleaseEvent(), event(), QFocusEvent
9698*/
9699
9700void QWidget::focusInEvent(QFocusEvent *)
9701{
9702 if (focusPolicy() != Qt::NoFocus || !isWindow()) {
9703 update();
9704 }
9705}
9706
9707/*!
9708 \fn void QWidget::focusOutEvent(QFocusEvent *event)
9709
9710 This event handler can be reimplemented in a subclass to receive
9711 keyboard focus events (focus lost) for the widget. The events is
9712 passed in the \a event parameter.
9713
9714 A widget normally must setFocusPolicy() to something other than
9715 Qt::NoFocus to receive focus events. (Note that the
9716 application programmer can call setFocus() on any widget, even
9717 those that do not normally accept focus.)
9718
9719 The default implementation updates the widget (except for windows
9720 that do not specify a focusPolicy()).
9721
9722 \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
9723 keyReleaseEvent(), event(), QFocusEvent
9724*/
9725
9726void QWidget::focusOutEvent(QFocusEvent *)
9727{
9728 if (focusPolicy() != Qt::NoFocus || !isWindow())
9729 update();
9730
9731#if !defined(QT_PLATFORM_UIKIT)
9732 // FIXME: revisit autoSIP logic, QTBUG-42906
9733 if (qApp->autoSipEnabled() && testAttribute(Qt::WA_InputMethodEnabled))
9734 QGuiApplication::inputMethod()->hide();
9735#endif
9736}
9737
9738/*!
9739 \fn void QWidget::enterEvent(QEnterEvent *event)
9740
9741 This event handler can be reimplemented in a subclass to receive
9742 widget enter events which are passed in the \a event parameter.
9743
9744 An event is sent to the widget when the mouse cursor enters the
9745 widget.
9746
9747 \sa leaveEvent(), mouseMoveEvent(), event()
9748*/
9749
9750void QWidget::enterEvent(QEnterEvent *)
9751{
9752}
9753
9754/*!
9755 \fn void QWidget::leaveEvent(QEvent *event)
9756
9757 This event handler can be reimplemented in a subclass to receive
9758 widget leave events which are passed in the \a event parameter.
9759
9760 A leave event is sent to the widget when the mouse cursor leaves
9761 the widget.
9762
9763 \sa enterEvent(), mouseMoveEvent(), event()
9764*/
9765
9766void QWidget::leaveEvent(QEvent *)
9767{
9768}
9769
9770/*!
9771 \fn void QWidget::paintEvent(QPaintEvent *event)
9772
9773 This event handler can be reimplemented in a subclass to receive paint
9774 events passed in \a event.
9775
9776 A paint event is a request to repaint all or part of a widget. It can
9777 happen for one of the following reasons:
9778
9779 \list
9780 \li repaint() or update() was invoked,
9781 \li the widget was obscured and has now been uncovered, or
9782 \li many other reasons.
9783 \endlist
9784
9785 Many widgets can simply repaint their entire surface when asked to, but
9786 some slow widgets need to optimize by painting only the requested region:
9787 QPaintEvent::region(). This speed optimization does not change the result,
9788 as painting is clipped to that region during event processing. QListView
9789 and QTableView do this, for example.
9790
9791 Qt also tries to speed up painting by merging multiple paint events into
9792 one. When update() is called several times or the window system sends
9793 several paint events, Qt merges these events into one event with a larger
9794 region (see QRegion::united()). The repaint() function does not permit this
9795 optimization, so we suggest using update() whenever possible.
9796
9797 When the paint event occurs, the update region has normally been erased, so
9798 you are painting on the widget's background.
9799
9800 The background can be set using setBackgroundRole() and setPalette().
9801
9802 Since Qt 4.0, QWidget automatically double-buffers its painting, so there
9803 is no need to write double-buffering code in paintEvent() to avoid flicker.
9804
9805 \note Generally, you should refrain from calling update() or repaint()
9806 \b{inside} a paintEvent(). For example, calling update() or repaint() on
9807 children inside a paintEvent() results in undefined behavior; the child may
9808 or may not get a paint event.
9809
9810 \warning If you are using a custom paint engine without Qt's backingstore,
9811 Qt::WA_PaintOnScreen must be set. Otherwise, QWidget::paintEngine() will
9812 never be called; the backingstore will be used instead.
9813
9814 \sa event(), repaint(), update(), QPainter, QPixmap, QPaintEvent,
9815 {Analog Clock}
9816*/
9817
9818void QWidget::paintEvent(QPaintEvent *)
9819{
9820}
9821
9822
9823/*!
9824 \fn void QWidget::moveEvent(QMoveEvent *event)
9825
9826 This event handler can be reimplemented in a subclass to receive
9827 widget move events which are passed in the \a event parameter.
9828 When the widget receives this event, it is already at the new
9829 position.
9830
9831 The old position is accessible through QMoveEvent::oldPos().
9832
9833 \sa resizeEvent(), event(), move(), QMoveEvent
9834*/
9835
9836void QWidget::moveEvent(QMoveEvent *)
9837{
9838}
9839
9840
9841/*!
9842 This event handler can be reimplemented in a subclass to receive
9843 widget resize events which are passed in the \a event parameter.
9844 When resizeEvent() is called, the widget already has its new
9845 geometry. The old size is accessible through
9846 QResizeEvent::oldSize().
9847
9848 The widget will be erased and receive a paint event immediately
9849 after processing the resize event. No drawing need be (or should
9850 be) done inside this handler.
9851
9852
9853 \sa moveEvent(), event(), resize(), QResizeEvent, paintEvent(),
9854 {Scribble Example}
9855*/
9856
9857void QWidget::resizeEvent(QResizeEvent * /* event */)
9858{
9859}
9860
9861#ifndef QT_NO_ACTION
9862/*!
9863 \fn void QWidget::actionEvent(QActionEvent *event)
9864
9865 This event handler is called with the given \a event whenever the
9866 widget's actions are changed.
9867
9868 \sa addAction(), insertAction(), removeAction(), actions(), QActionEvent
9869*/
9870void QWidget::actionEvent(QActionEvent *)
9871{
9872
9873}
9874#endif
9875
9876/*!
9877 This event handler is called with the given \a event when Qt receives a window
9878 close request for a top-level widget from the window system.
9879
9880 By default, the event is accepted and the widget is closed. You can reimplement
9881 this function to change the way the widget responds to window close requests.
9882 For example, you can prevent the window from closing by calling \l{QEvent::}{ignore()}
9883 on all events.
9884
9885 Main window applications typically use reimplementations of this function to check
9886 whether the user's work has been saved and ask for permission before closing.
9887
9888 \sa event(), hide(), close(), QCloseEvent
9889*/
9890
9891void QWidget::closeEvent(QCloseEvent *event)
9892{
9893 event->accept();
9894}
9895
9896#ifndef QT_NO_CONTEXTMENU
9897/*!
9898 This event handler, for event \a event, can be reimplemented in a
9899 subclass to receive widget context menu events.
9900
9901 The handler is called when the widget's \l contextMenuPolicy is
9902 Qt::DefaultContextMenu.
9903
9904 The default implementation ignores the context event.
9905 See the \l QContextMenuEvent documentation for more details.
9906
9907 \sa event(), QContextMenuEvent, customContextMenuRequested()
9908*/
9909
9910void QWidget::contextMenuEvent(QContextMenuEvent *event)
9911{
9912 event->ignore();
9913}
9914#endif // QT_NO_CONTEXTMENU
9915
9916
9917/*!
9918 This event handler, for event \a event, can be reimplemented in a
9919 subclass to receive Input Method composition events. This handler
9920 is called when the state of the input method changes.
9921
9922 Note that when creating custom text editing widgets, the
9923 Qt::WA_InputMethodEnabled window attribute must be set explicitly
9924 (using the setAttribute() function) in order to receive input
9925 method events.
9926
9927 The default implementation calls event->ignore(), which rejects the
9928 Input Method event. See the \l QInputMethodEvent documentation for more
9929 details.
9930
9931 \sa event(), QInputMethodEvent
9932*/
9933void QWidget::inputMethodEvent(QInputMethodEvent *event)
9934{
9935 event->ignore();
9936}
9937
9938/*!
9939 This method is only relevant for input widgets. It is used by the
9940 input method to query a set of properties of the widget to be
9941 able to support complex input method operations as support for
9942 surrounding text and reconversions.
9943
9944 \a query specifies which property is queried.
9945
9946 \sa inputMethodEvent(), QInputMethodEvent, QInputMethodQueryEvent, inputMethodHints
9947*/
9948QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const
9949{
9950 switch(query) {
9951 case Qt::ImCursorRectangle:
9952 return QRect(width()/2, 0, 1, height());
9953 case Qt::ImFont:
9954 return font();
9955 case Qt::ImAnchorPosition:
9956 // Fallback.
9957 return inputMethodQuery(Qt::ImCursorPosition);
9958 case Qt::ImHints:
9959 return (int)inputMethodHints();
9960 case Qt::ImInputItemClipRectangle:
9961 return d_func()->clipRect();
9962 default:
9963 return QVariant();
9964 }
9965}
9966
9967/*!
9968 \property QWidget::inputMethodHints
9969 \brief What input method specific hints the widget has.
9970
9971 This is only relevant for input widgets. It is used by
9972 the input method to retrieve hints as to how the input method
9973 should operate. For example, if the Qt::ImhFormattedNumbersOnly flag
9974 is set, the input method may change its visual components to reflect
9975 that only numbers can be entered.
9976
9977 \warning Some widgets require certain flags to work as
9978 intended. To set a flag, do \c{w->setInputMethodHints(w->inputMethodHints()|f)}
9979 instead of \c{w->setInputMethodHints(f)}.
9980
9981 \note The flags are only hints, so the particular input method
9982 implementation is free to ignore them. If you want to be
9983 sure that a certain type of characters are entered,
9984 you should also set a QValidator on the widget.
9985
9986 The default value is Qt::ImhNone.
9987
9988 \since 4.6
9989
9990 \sa inputMethodQuery()
9991*/
9992Qt::InputMethodHints QWidget::inputMethodHints() const
9993{
9994#if QT_CONFIG(im)
9995 const QWidgetPrivate *priv = d_func();
9996 while (priv->inheritsInputMethodHints) {
9997 priv = priv->q_func()->parentWidget()->d_func();
9998 Q_ASSERT(priv);
9999 }
10000 return priv->imHints;
10001#else
10002 return Qt::ImhNone;
10003#endif
10004}
10005
10006void QWidget::setInputMethodHints(Qt::InputMethodHints hints)
10007{
10008#ifndef QT_NO_IM
10009 Q_D(QWidget);
10010 if (d->imHints == hints)
10011 return;
10012 d->imHints = hints;
10013 if (this == QGuiApplication::focusObject())
10014 QGuiApplication::inputMethod()->update(Qt::ImHints);
10015#else
10016 Q_UNUSED(hints);
10017#endif //QT_NO_IM
10018}
10019
10020
10021#if QT_CONFIG(draganddrop)
10022
10023/*!
10024 \fn void QWidget::dragEnterEvent(QDragEnterEvent *event)
10025
10026 This event handler is called when a drag is in progress and the
10027 mouse enters this widget. The event is passed in the \a event parameter.
10028
10029 If the event is ignored, the widget won't receive any \l{dragMoveEvent()}{drag
10030 move events}.
10031
10032 See the \l{dnd.html}{Drag-and-drop documentation} for an
10033 overview of how to provide drag-and-drop in your application.
10034
10035 \sa QDrag, QDragEnterEvent
10036*/
10037void QWidget::dragEnterEvent(QDragEnterEvent *)
10038{
10039}
10040
10041/*!
10042 \fn void QWidget::dragMoveEvent(QDragMoveEvent *event)
10043
10044 This event handler is called if a drag is in progress, and when
10045 any of the following conditions occur: the cursor enters this widget,
10046 the cursor moves within this widget, or a modifier key is pressed on
10047 the keyboard while this widget has the focus. The event is passed
10048 in the \a event parameter.
10049
10050 See the \l{dnd.html}{Drag-and-drop documentation} for an
10051 overview of how to provide drag-and-drop in your application.
10052
10053 \sa QDrag, QDragMoveEvent
10054*/
10055void QWidget::dragMoveEvent(QDragMoveEvent *)
10056{
10057}
10058
10059/*!
10060 \fn void QWidget::dragLeaveEvent(QDragLeaveEvent *event)
10061
10062 This event handler is called when a drag is in progress and the
10063 mouse leaves this widget. The event is passed in the \a event
10064 parameter.
10065
10066 See the \l{dnd.html}{Drag-and-drop documentation} for an
10067 overview of how to provide drag-and-drop in your application.
10068
10069 \sa QDrag, QDragLeaveEvent
10070*/
10071void QWidget::dragLeaveEvent(QDragLeaveEvent *)
10072{
10073}
10074
10075/*!
10076 \fn void QWidget::dropEvent(QDropEvent *event)
10077
10078 This event handler is called when the drag is dropped on this
10079 widget. The event is passed in the \a event parameter.
10080
10081 See the \l{dnd.html}{Drag-and-drop documentation} for an
10082 overview of how to provide drag-and-drop in your application.
10083
10084 \sa QDrag, QDropEvent
10085*/
10086void QWidget::dropEvent(QDropEvent *)
10087{
10088}
10089
10090#endif // QT_CONFIG(draganddrop)
10091
10092/*!
10093 \fn void QWidget::showEvent(QShowEvent *event)
10094
10095 This event handler can be reimplemented in a subclass to receive
10096 widget show events which are passed in the \a event parameter.
10097
10098 Non-spontaneous show events are sent to widgets immediately
10099 before they are shown. The spontaneous show events of windows are
10100 delivered afterwards.
10101
10102 Note: A widget receives spontaneous show and hide events when its
10103 mapping status is changed by the window system, e.g. a spontaneous
10104 hide event when the user minimizes the window, and a spontaneous
10105 show event when the window is restored again. After receiving a
10106 spontaneous hide event, a widget is still considered visible in
10107 the sense of isVisible().
10108
10109 \sa visible, event(), QShowEvent
10110*/
10111void QWidget::showEvent(QShowEvent *)
10112{
10113}
10114
10115/*!
10116 \fn void QWidget::hideEvent(QHideEvent *event)
10117
10118 This event handler can be reimplemented in a subclass to receive
10119 widget hide events. The event is passed in the \a event parameter.
10120
10121 Hide events are sent to widgets immediately after they have been
10122 hidden.
10123
10124 Note: A widget receives spontaneous show and hide events when its
10125 mapping status is changed by the window system, e.g. a spontaneous
10126 hide event when the user minimizes the window, and a spontaneous
10127 show event when the window is restored again. After receiving a
10128 spontaneous hide event, a widget is still considered visible in
10129 the sense of isVisible().
10130
10131 \sa visible, event(), QHideEvent
10132*/
10133void QWidget::hideEvent(QHideEvent *)
10134{
10135}
10136
10137/*!
10138 This special event handler can be reimplemented in a subclass to
10139 receive native platform events identified by \a eventType
10140 which are passed in the \a message parameter.
10141
10142 In your reimplementation of this function, if you want to stop the
10143 event being handled by Qt, return true and set \a result. The \a result
10144 parameter has meaning only on Windows. If you return false, this native
10145 event is passed back to Qt, which translates the event into a Qt event
10146 and sends it to the widget.
10147
10148 \note Events are only delivered to this event handler if the widget
10149 has a native window handle.
10150
10151 \note This function superseedes the event filter functions
10152 x11Event(), winEvent() and macEvent() of Qt 4.
10153
10154 \sa QAbstractNativeEventFilter
10155
10156 \table
10157 \header \li Platform \li Event Type Identifier \li Message Type \li Result Type
10158 \row \li Windows \li "windows_generic_MSG" \li MSG * \li LRESULT
10159 \row \li macOS \li "NSEvent" \li NSEvent * \li
10160 \row \li XCB \li "xcb_generic_event_t" \li xcb_generic_event_t * \li
10161 \endtable
10162*/
10163
10164bool QWidget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
10165{
10166 Q_UNUSED(eventType);
10167 Q_UNUSED(message);
10168 Q_UNUSED(result);
10169 return false;
10170}
10171
10172/*!
10173 Ensures that the widget and its children have been polished by
10174 QStyle (i.e., have a proper font and palette).
10175
10176 QWidget calls this function after it has been fully constructed
10177 but before it is shown the very first time. You can call this
10178 function if you want to ensure that the widget is polished before
10179 doing an operation, e.g., the correct font size might be needed in
10180 the widget's sizeHint() reimplementation. Note that this function
10181 \e is called from the default implementation of sizeHint().
10182
10183 Polishing is useful for final initialization that must happen after
10184 all constructors (from base classes as well as from subclasses)
10185 have been called.
10186
10187 If you need to change some settings when a widget is polished,
10188 reimplement event() and handle the QEvent::Polish event type.
10189
10190 \b{Note:} The function is declared const so that it can be called from
10191 other const functions (e.g., sizeHint()).
10192
10193 \sa event()
10194*/
10195void QWidget::ensurePolished() const
10196{
10197 Q_D(const QWidget);
10198
10199 const QMetaObject *m = metaObject();
10200 if (m == d->polished)
10201 return;
10202 d->polished = m;
10203
10204 QEvent e(QEvent::Polish);
10205 QCoreApplication::sendEvent(const_cast<QWidget *>(this), &e);
10206
10207 // polish children after 'this'
10208 QList<QObject*> children = d->children;
10209 for (int i = 0; i < children.size(); ++i) {
10210 QObject *o = children.at(i);
10211 if (!o->isWidgetType())
10212 continue;
10213 if (QWidget *w = qobject_cast<QWidget *>(o))
10214 w->ensurePolished();
10215 }
10216
10217 if (d->parent && d->sendChildEvents) {
10218 QChildEvent e(QEvent::ChildPolished, const_cast<QWidget *>(this));
10219 QCoreApplication::sendEvent(d->parent, &e);
10220 }
10221}
10222
10223/*!
10224 Returns the mask currently set on a widget. If no mask is set the
10225 return value will be an empty region.
10226
10227 \sa setMask(), clearMask(), QRegion::isEmpty()
10228*/
10229QRegion QWidget::mask() const
10230{
10231 Q_D(const QWidget);
10232 return d->extra ? d->extra->mask : QRegion();
10233}
10234
10235/*!
10236 Returns the layout manager that is installed on this widget, or \nullptr
10237 if no layout manager is installed.
10238
10239 The layout manager sets the geometry of the widget's children
10240 that have been added to the layout.
10241
10242 \sa setLayout(), sizePolicy(), {Layout Management}
10243*/
10244QLayout *QWidget::layout() const
10245{
10246 return d_func()->layout;
10247}
10248
10249
10250/*!
10251 \fn void QWidget::setLayout(QLayout *layout)
10252
10253 Sets the layout manager for this widget to \a layout.
10254
10255 If there already is a layout manager installed on this widget,
10256 QWidget won't let you install another. You must first delete the
10257 existing layout manager (returned by layout()) before you can
10258 call setLayout() with the new layout.
10259
10260 If \a layout is the layout manager on a different widget, setLayout()
10261 will reparent the layout and make it the layout manager for this widget.
10262
10263 Example:
10264
10265 \snippet layouts/layouts.cpp 24
10266
10267 An alternative to calling this function is to pass this widget to
10268 the layout's constructor.
10269
10270 The QWidget will take ownership of \a layout.
10271
10272 \sa layout(), {Layout Management}
10273*/
10274
10275void QWidget::setLayout(QLayout *l)
10276{
10277 if (Q_UNLIKELY(!l)) {
10278 qWarning("QWidget::setLayout: Cannot set layout to 0");
10279 return;
10280 }
10281 if (layout()) {
10282 if (Q_UNLIKELY(layout() != l))
10283 qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", which already has a"
10284 " layout", l->objectName().toLocal8Bit().data(), metaObject()->className(),
10285 objectName().toLocal8Bit().data());
10286 return;
10287 }
10288
10289 QObject *oldParent = l->parent();
10290 if (oldParent && oldParent != this) {
10291 if (oldParent->isWidgetType()) {
10292 // Steal the layout off a widget parent. Takes effect when
10293 // morphing laid-out container widgets in Designer.
10294 QWidget *oldParentWidget = static_cast<QWidget *>(oldParent);
10295 oldParentWidget->takeLayout();
10296 } else {
10297 qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
10298 l->objectName().toLocal8Bit().data(), metaObject()->className(),
10299 objectName().toLocal8Bit().data());
10300 return;
10301 }
10302 }
10303
10304 Q_D(QWidget);
10305 l->d_func()->topLevel = true;
10306 d->layout = l;
10307 if (oldParent != this) {
10308 l->setParent(this);
10309 l->d_func()->reparentChildWidgets(this);
10310 l->invalidate();
10311 }
10312
10313 if (isWindow() && d->maybeTopData())
10314 d->topData()->sizeAdjusted = false;
10315}
10316
10317/*!
10318 \fn QLayout *QWidget::takeLayout()
10319
10320 Remove the layout from the widget.
10321 \since 4.5
10322*/
10323
10324QLayout *QWidget::takeLayout()
10325{
10326 Q_D(QWidget);
10327 QLayout *l = layout();
10328 if (!l)
10329 return nullptr;
10330 d->layout = nullptr;
10331 l->setParent(nullptr);
10332 return l;
10333}
10334
10335/*!
10336 \property QWidget::sizePolicy
10337 \brief the default layout behavior of the widget
10338
10339 If there is a QLayout that manages this widget's children, the
10340 size policy specified by that layout is used. If there is no such
10341 QLayout, the result of this function is used.
10342
10343 The default policy is Preferred/Preferred, which means that the
10344 widget can be freely resized, but prefers to be the size
10345 sizeHint() returns. Button-like widgets set the size policy to
10346 specify that they may stretch horizontally, but are fixed
10347 vertically. The same applies to lineedit controls (such as
10348 QLineEdit, QSpinBox or an editable QComboBox) and other
10349 horizontally orientated widgets (such as QProgressBar).
10350 QToolButton's are normally square, so they allow growth in both
10351 directions. Widgets that support different directions (such as
10352 QSlider, QScrollBar or QHeader) specify stretching in the
10353 respective direction only. Widgets that can provide scroll bars
10354 (usually subclasses of QScrollArea) tend to specify that they can
10355 use additional space, and that they can make do with less than
10356 sizeHint().
10357
10358 \sa sizeHint(), QLayout, QSizePolicy, updateGeometry()
10359*/
10360QSizePolicy QWidget::sizePolicy() const
10361{
10362 Q_D(const QWidget);
10363 return d->size_policy;
10364}
10365
10366void QWidget::setSizePolicy(QSizePolicy policy)
10367{
10368 Q_D(QWidget);
10369 setAttribute(Qt::WA_WState_OwnSizePolicy);
10370 if (policy == d->size_policy)
10371 return;
10372
10373 if (d->size_policy.retainSizeWhenHidden() != policy.retainSizeWhenHidden())
10374 d->retainSizeWhenHiddenChanged = 1;
10375
10376 d->size_policy = policy;
10377
10378#if QT_CONFIG(graphicsview)
10379 if (const auto &extra = d->extra) {
10380 if (extra->proxyWidget)
10381 extra->proxyWidget->setSizePolicy(policy);
10382 }
10383#endif
10384
10385 updateGeometry();
10386 d->retainSizeWhenHiddenChanged = 0;
10387
10388 if (isWindow() && d->maybeTopData())
10389 d->topData()->sizeAdjusted = false;
10390}
10391
10392/*!
10393 \fn void QWidget::setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
10394 \overload
10395
10396 Sets the size policy of the widget to \a horizontal and \a
10397 vertical, with standard stretch and no height-for-width.
10398
10399 \sa QSizePolicy::QSizePolicy()
10400*/
10401
10402/*!
10403 Returns the preferred height for this widget, given the width \a w.
10404
10405 If this widget has a layout, the default implementation returns
10406 the layout's preferred height. if there is no layout, the default
10407 implementation returns -1 indicating that the preferred height
10408 does not depend on the width.
10409*/
10410
10411int QWidget::heightForWidth(int w) const
10412{
10413 if (layout() && layout()->hasHeightForWidth())
10414 return layout()->totalHeightForWidth(w);
10415 return -1;
10416}
10417
10418
10419/*!
10420 \since 5.0
10421
10422 Returns \c true if the widget's preferred height depends on its width; otherwise returns \c false.
10423*/
10424bool QWidget::hasHeightForWidth() const
10425{
10426 Q_D(const QWidget);
10427 return d->layout ? d->layout->hasHeightForWidth() : d->size_policy.hasHeightForWidth();
10428}
10429
10430/*!
10431 \fn QWidget *QWidget::childAt(int x, int y) const
10432
10433 Returns the visible child widget at the position (\a{x}, \a{y})
10434 in the widget's coordinate system. If there is no visible child
10435 widget at the specified position, the function returns \nullptr.
10436*/
10437
10438/*!
10439 \overload
10440
10441 Returns the visible child widget at point \a p in the widget's own
10442 coordinate system.
10443*/
10444
10445QWidget *QWidget::childAt(const QPoint &p) const
10446{
10447 return d_func()->childAt_helper(QPointF(p), false);
10448}
10449
10450/*!
10451 \overload
10452 \since 6.8
10453
10454 Returns the visible child widget at point \a p in the widget's own
10455 coordinate system.
10456*/
10457
10458QWidget *QWidget::childAt(const QPointF &p) const
10459{
10460 return d_func()->childAt_helper(p, false);
10461}
10462
10463QWidget *QWidgetPrivate::childAt_helper(const QPointF &p, bool ignoreChildrenInDestructor) const
10464{
10465 if (children.isEmpty())
10466 return nullptr;
10467
10468 if (!pointInsideRectAndMask(p))
10469 return nullptr;
10470 return childAtRecursiveHelper(p, ignoreChildrenInDestructor);
10471}
10472
10473QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPointF &p, bool ignoreChildrenInDestructor) const
10474{
10475 for (int i = children.size() - 1; i >= 0; --i) {
10476 QWidget *child = qobject_cast<QWidget *>(children.at(i));
10477 if (!child || child->isWindow() || child->isHidden() || child->testAttribute(Qt::WA_TransparentForMouseEvents)
10478 || (ignoreChildrenInDestructor && child->data->in_destructor)) {
10479 continue;
10480 }
10481
10482 // Map the point 'p' from parent coordinates to child coordinates.
10483 QPointF childPoint = p;
10484 childPoint -= child->data->crect.topLeft();
10485
10486 // Check if the point hits the child.
10487 if (!child->d_func()->pointInsideRectAndMask(childPoint))
10488 continue;
10489
10490 // Do the same for the child's descendants.
10491 if (QWidget *w = child->d_func()->childAtRecursiveHelper(childPoint, ignoreChildrenInDestructor))
10492 return w;
10493
10494 // We have found our target; namely the child at position 'p'.
10495 return child;
10496 }
10497 return nullptr;
10498}
10499
10500void QWidgetPrivate::updateGeometry_helper(bool forceUpdate)
10501{
10502 Q_Q(QWidget);
10503 if (widgetItem)
10504 widgetItem->invalidateSizeCache();
10505 QWidget *parent;
10506 if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) {
10507 const int isHidden = q->isHidden() && !size_policy.retainSizeWhenHidden() && !retainSizeWhenHiddenChanged;
10508
10509 if (!q->isWindow() && !isHidden && (parent = q->parentWidget())) {
10510 if (parent->d_func()->layout)
10511 parent->d_func()->layout->invalidate();
10512 else if (parent->isVisible())
10513 QCoreApplication::postEvent(parent, new QEvent(QEvent::LayoutRequest));
10514 }
10515 }
10516}
10517
10518/*!
10519 Notifies the layout system that this widget has changed and may
10520 need to change geometry.
10521
10522 Call this function if the sizeHint() or sizePolicy() have changed.
10523
10524 For explicitly hidden widgets, updateGeometry() is a no-op. The
10525 layout system will be notified as soon as the widget is shown.
10526*/
10527
10528void QWidget::updateGeometry()
10529{
10530 Q_D(QWidget);
10531 d->updateGeometry_helper(false);
10532}
10533
10534/*! \property QWidget::windowFlags
10535
10536 Window flags are a combination of a type (e.g. Qt::Dialog) and
10537 zero or more hints to the window system (e.g.
10538 Qt::FramelessWindowHint).
10539
10540 If the widget had type Qt::Widget or Qt::SubWindow and becomes a
10541 window (Qt::Window, Qt::Dialog, etc.), it is put at position (0,
10542 0) on the desktop. If the widget is a window and becomes a
10543 Qt::Widget or Qt::SubWindow, it is put at position (0, 0)
10544 relative to its parent widget.
10545
10546 \note This function calls setParent() when changing the flags for
10547 a window, causing the widget to be hidden. You must call show() to make
10548 the widget visible again..
10549
10550 \sa windowType(), setWindowFlag(), {Window Flags Example}
10551*/
10552void QWidget::setWindowFlags(Qt::WindowFlags flags)
10553{
10554 Q_D(QWidget);
10555 d->setWindowFlags(flags);
10556}
10557
10558/*!
10559 \since 5.9
10560
10561 Sets the window flag \a flag on this widget if \a on is true;
10562 otherwise clears the flag.
10563
10564 \sa setWindowFlags(), windowFlags(), windowType()
10565*/
10566void QWidget::setWindowFlag(Qt::WindowType flag, bool on)
10567{
10568 Q_D(QWidget);
10569 if (on)
10570 d->setWindowFlags(data->window_flags | flag);
10571 else
10572 d->setWindowFlags(data->window_flags & ~flag);
10573}
10574
10575/*! \internal
10576
10577 Implemented in QWidgetPrivate so that QMdiSubWindowPrivate can reimplement it.
10578*/
10579void QWidgetPrivate::setWindowFlags(Qt::WindowFlags flags)
10580{
10581 Q_Q(QWidget);
10582 if (q->data->window_flags == flags)
10583 return;
10584
10585 if ((q->data->window_flags | flags) & Qt::Window) {
10586 // the old type was a window and/or the new type is a window
10587 QPoint oldPos = q->pos();
10588 bool visible = q->isVisible();
10589 const bool windowFlagChanged = (q->data->window_flags ^ flags) & Qt::Window;
10590 q->setParent(q->parentWidget(), flags);
10591
10592 // if both types are windows or neither of them are, we restore
10593 // the old position
10594 if (!windowFlagChanged && (visible || q->testAttribute(Qt::WA_Moved)))
10595 q->move(oldPos);
10596 // for backward-compatibility we change Qt::WA_QuitOnClose attribute value only when the window was recreated.
10597 adjustQuitOnCloseAttribute();
10598 } else {
10599 q->data->window_flags = flags;
10600 }
10601}
10602
10603/*!
10604 Sets the window flags for the widget to \a flags,
10605 \e without telling the window system.
10606
10607 \warning Do not call this function unless you really know what
10608 you're doing.
10609
10610 \sa setWindowFlags()
10611*/
10612void QWidget::overrideWindowFlags(Qt::WindowFlags flags)
10613{
10614 data->window_flags = flags;
10615}
10616
10617/*!
10618 \fn Qt::WindowType QWidget::windowType() const
10619
10620 Returns the window type of this widget. This is identical to
10621 windowFlags() & Qt::WindowType_Mask.
10622
10623 \sa windowFlags
10624*/
10625
10626/*!
10627 Sets the parent of the widget to \a parent, and resets the window
10628 flags. The widget is moved to position (0, 0) in its new parent.
10629
10630 If the new parent widget is in a different window, the
10631 reparented widget and its children are appended to the end of the
10632 \l{setFocusPolicy()}{tab chain} of the new parent
10633 widget, in the same internal order as before. If one of the moved
10634 widgets had keyboard focus, setParent() calls clearFocus() for that
10635 widget.
10636
10637 If the new parent widget is in the same window as the
10638 old parent, setting the parent doesn't change the tab order or
10639 keyboard focus.
10640
10641 If the "new" parent widget is the old parent widget, this function
10642 does nothing.
10643
10644 \note The widget becomes invisible as part of changing its parent,
10645 even if it was previously visible. You must call show() to make the
10646 widget visible again.
10647
10648 \warning It is very unlikely that you will ever need this
10649 function. If you have a widget that changes its content
10650 dynamically, it is far easier to use \l QStackedWidget.
10651
10652 \sa setWindowFlags()
10653*/
10654void QWidget::setParent(QWidget *parent)
10655{
10656 if (parent == parentWidget())
10657 return;
10658 setParent((QWidget*)parent, windowFlags() & ~Qt::WindowType_Mask);
10659}
10660
10661void qSendWindowChangeToTextureChildrenRecursively(QWidget *widget, QEvent::Type eventType)
10662{
10663 QWidgetPrivate *d = QWidgetPrivate::get(widget);
10664 if (d->renderToTexture) {
10665 QEvent e(eventType);
10666 QCoreApplication::sendEvent(widget, &e);
10667 }
10668
10669 for (int i = 0; i < d->children.size(); ++i) {
10670 QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
10671 if (w && !w->isWindow())
10672 qSendWindowChangeToTextureChildrenRecursively(w, eventType);
10673 }
10674
10675 // Notify QWidgetWindow after we've notified all child QWidgets
10676 if (auto *window = d->windowHandle(QWidgetPrivate::WindowHandleMode::Direct)) {
10677 QEvent e(eventType);
10678 QCoreApplication::sendEvent(window, &e);
10679 }
10680}
10681
10682/*!
10683 \overload
10684
10685 This function also takes widget flags, \a f as an argument.
10686*/
10687
10688void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
10689{
10690 Q_D(QWidget);
10691 Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QWidget to itself");
10692#ifdef QT_DEBUG
10693 const auto checkForParentChildLoops = qScopeGuard([&](){
10694 int depth = 0;
10695 auto p = parentWidget();
10696 while (p) {
10697 if (++depth == QObjectPrivate::CheckForParentChildLoopsWarnDepth) {
10698 qWarning("QWidget %p (class: '%s', object name: '%s') may have a loop in its parent-child chain; "
10699 "this is undefined behavior",
10700 this, metaObject()->className(), qPrintable(objectName()));
10701 }
10702 p = p->parentWidget();
10703 }
10704 });
10705#endif
10706
10707 const bool resized = testAttribute(Qt::WA_Resized);
10708 const bool wasCreated = testAttribute(Qt::WA_WState_Created);
10709 QWidget *oldtlw = window();
10710 Q_ASSERT(oldtlw);
10711 QWidget *oldParentWithWindow = d->closestParentWidgetWithWindowHandle();
10712
10713 if (f & Qt::Window) // Frame geometry likely changes, refresh.
10714 d->data.fstrut_dirty = true;
10715
10716 QWidget *desktopWidget = nullptr;
10717 if (parent && parent->windowType() == Qt::Desktop)
10718 desktopWidget = parent;
10719 bool newParent = (parent != parentWidget()) || desktopWidget;
10720
10721 if (newParent && parent && !desktopWidget) {
10722 if (testAttribute(Qt::WA_NativeWindow) && !QCoreApplication::testAttribute(Qt::AA_DontCreateNativeWidgetSiblings))
10723 parent->d_func()->enforceNativeChildren();
10724 else if (parent->d_func()->nativeChildrenForced() || parent->testAttribute(Qt::WA_PaintOnScreen))
10725 setAttribute(Qt::WA_NativeWindow);
10726 }
10727
10728 if (wasCreated) {
10729 if (!testAttribute(Qt::WA_WState_Hidden)) {
10730 // Hiding the widget will set WA_WState_Hidden as well, which would
10731 // normally require the widget to be explicitly shown again to become
10732 // visible, even as a child widget. But we refine this value later in
10733 // setParent_sys(), applying WA_WState_Hidden based on whether the
10734 // widget is a top level or not.
10735 hide();
10736
10737 // We reset WA_WState_ExplicitShowHide here, likely as a remnant of
10738 // when we only had QWidget::setVisible(), which is treated as an
10739 // explicit show/hide. Nowadays we have QWidgetPrivate::setVisible(),
10740 // that allows us to hide a widget without affecting ExplicitShowHide.
10741 // Though it can be argued that ExplicitShowHide should reflect the
10742 // last update of the widget's state, so if we hide the widget as a
10743 // side effect of changing parent, perhaps we _should_ reset it?
10744 setAttribute(Qt::WA_WState_ExplicitShowHide, false);
10745 }
10746 if (newParent) {
10747 QEvent e(QEvent::ParentAboutToChange);
10748 QCoreApplication::sendEvent(this, &e);
10749 }
10750 }
10751
10752 // texture-based widgets need a pre-notification when their associated top-level window changes
10753 // This is not under the wasCreated/newParent conditions above in order to also play nice with QDockWidget.
10754 const bool oldWidgetUsesRhiFlush = oldParentWithWindow ? oldParentWithWindow->d_func()->usesRhiFlush
10755 : oldtlw->d_func()->usesRhiFlush;
10756 if (oldWidgetUsesRhiFlush && ((!parent && parentWidget()) || (parent && parent->window() != oldtlw)))
10757 qSendWindowChangeToTextureChildrenRecursively(this, QEvent::WindowAboutToChangeInternal);
10758
10759 // If we get parented into another window, children will be folded
10760 // into the new parent's focus chain, so clear focus now.
10761 if (newParent && isAncestorOf(focusWidget()) && !(f & Qt::Window))
10762 focusWidget()->clearFocus();
10763
10764 d->setParent_sys(parent, f);
10765
10766 if (desktopWidget)
10767 parent = nullptr;
10768
10769 if (d->textureChildSeen && parent) {
10770 // set the textureChildSeen flag up the whole parent chain
10771 QWidgetPrivate::get(parent)->setTextureChildSeen();
10772 }
10773
10774 if (QWidgetRepaintManager *oldPaintManager = oldtlw->d_func()->maybeRepaintManager()) {
10775 if (newParent)
10776 oldPaintManager->removeDirtyWidget(this);
10777 // Move the widget and all its static children from
10778 // the old backing store to the new one.
10779 oldPaintManager->moveStaticWidgets(this);
10780 }
10781
10782 d->reparentFocusWidgets(oldtlw);
10783 setAttribute(Qt::WA_Resized, resized);
10784
10785 const bool useStyleSheetPropagationInWidgetStyles =
10786 QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
10787
10788 if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(Qt::WA_StyleSheet)
10789 && (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
10790 // if the parent has a font set or inherited, then propagate the mask to the new child
10791 if (parent) {
10792 const auto pd = parent->d_func();
10793 d->inheritedFontResolveMask = pd->directFontResolveMask | pd->inheritedFontResolveMask;
10794 d->inheritedPaletteResolveMask = pd->directPaletteResolveMask | pd->inheritedPaletteResolveMask;
10795 }
10796 d->resolveFont();
10797 d->resolvePalette();
10798 }
10799 d->resolveLayoutDirection();
10800 d->resolveLocale();
10801
10802 // Note: GL widgets under WGL or EGL will always need a ParentChange
10803 // event to handle recreation/rebinding of the GL context, hence the
10804 // (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all
10805 // platforms).
10806 if (newParent || !wasCreated
10807#if QT_CONFIG(opengles2)
10808 || (f & Qt::MSWindowsOwnDC)
10809#endif
10810 ) {
10811 // propagate enabled updates enabled state to non-windows
10812 if (!isWindow()) {
10813 if (!testAttribute(Qt::WA_ForceDisabled))
10814 d->setEnabled_helper(parent ? parent->isEnabled() : true);
10815 if (!testAttribute(Qt::WA_ForceUpdatesDisabled))
10816 d->setUpdatesEnabled_helper(parent ? parent->updatesEnabled() : true);
10817 }
10818 d->inheritStyle();
10819
10820 // send and post remaining QObject events
10821 if (parent && d->sendChildEvents) {
10822 QChildEvent e(QEvent::ChildAdded, this);
10823 QCoreApplication::sendEvent(parent, &e);
10824 }
10825
10826 if (parent && d->sendChildEvents && d->polished) {
10827 QChildEvent e(QEvent::ChildPolished, this);
10828 QCoreApplication::sendEvent(parent, &e);
10829 }
10830
10831 QEvent e(QEvent::ParentChange);
10832 QCoreApplication::sendEvent(this, &e);
10833 }
10834
10835 // texture-based widgets need another event when their top-level window
10836 // changes (more precisely, has already changed at this point)
10837 if (oldWidgetUsesRhiFlush && oldtlw != window())
10838 qSendWindowChangeToTextureChildrenRecursively(this, QEvent::WindowChangeInternal);
10839
10840 if (!wasCreated) {
10841 if (isWindow() || parentWidget()->isVisible())
10842 setAttribute(Qt::WA_WState_Hidden, true);
10843 else if (!testAttribute(Qt::WA_WState_ExplicitShowHide))
10844 setAttribute(Qt::WA_WState_Hidden, false);
10845 }
10846
10847 d->updateIsOpaque();
10848
10849#if QT_CONFIG(graphicsview)
10850 // Embed the widget into a proxy if the parent is embedded.
10851 // ### Doesn't handle reparenting out of an embedded widget.
10852 if (oldtlw->graphicsProxyWidget()) {
10853 if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(oldtlw))
10854 ancestorProxy->d_func()->unembedSubWindow(this);
10855 }
10856 if (isWindow() && parent && !graphicsProxyWidget() && !bypassGraphicsProxyWidget(this)) {
10857 if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(parent))
10858 ancestorProxy->d_func()->embedSubWindow(this);
10859 }
10860#endif
10861
10862 if (d->extra && d->extra->hasWindowContainer)
10863 QWindowContainer::parentWasChanged(this);
10864
10865 QWidget *newParentWithWindow = d->closestParentWidgetWithWindowHandle();
10866 if (newParentWithWindow && newParentWithWindow != oldParentWithWindow) {
10867 // Check if the native parent now needs to switch to RHI
10868 qCDebug(lcWidgetPainting) << "Evaluating whether reparenting of" << this
10869 << "into" << parent << "requires RHI enablement for" << newParentWithWindow;
10870
10871 QPlatformBackingStoreRhiConfig rhiConfig;
10872 QSurface::SurfaceType surfaceType = QSurface::RasterSurface;
10873
10874 // First evaluate whether the reparented widget uses RHI.
10875 // We do this as a separate step because the performance
10876 // implications of always checking the native parent are
10877 // problematic when it comes to large widget trees.
10878 if (q_evaluateRhiConfig(this, &rhiConfig, &surfaceType)) {
10879 // Then check whether the native parent requires RHI
10880 // as a result. It may not, if this widget is a native
10881 // window, and can handle its own RHI flushing.
10882 if (q_evaluateRhiConfig(newParentWithWindow, nullptr, nullptr)) {
10883 // Finally, check whether we need to recreate the
10884 // native parent to enable RHI flushing.
10885 auto *existingWindow = newParentWithWindow->windowHandle();
10886 auto existingSurfaceType = existingWindow->surfaceType();
10887 if (existingSurfaceType != surfaceType) {
10888 qCDebug(lcWidgetPainting)
10889 << "Recreating" << existingWindow
10890 << "with current type" << existingSurfaceType
10891 << "to support" << surfaceType;
10892 const auto windowStateBeforeDestroy = newParentWithWindow->windowState();
10893 const auto visibilityBeforeDestroy = newParentWithWindow->isVisible();
10894 const auto positionBeforeDestroy = newParentWithWindow->pos();
10895 newParentWithWindow->destroy();
10896 newParentWithWindow->create();
10897 Q_ASSERT(newParentWithWindow->windowHandle());
10898 newParentWithWindow->windowHandle()->setWindowStates(windowStateBeforeDestroy);
10899 newParentWithWindow->move(positionBeforeDestroy);
10900 QWidgetPrivate::get(newParentWithWindow)->setVisible(visibilityBeforeDestroy);
10901 } else if (auto *backingStore = newParentWithWindow->backingStore()) {
10902 // If we don't recreate we still need to make sure the native parent
10903 // widget has a RHI config that the reparented widget can use.
10904 backingStore->handle()->createRhi(existingWindow, rhiConfig);
10905 // And that it knows it's now flushing with RHI
10906 QWidgetPrivate::get(newParentWithWindow)->usesRhiFlush = true;
10907 }
10908 }
10909 }
10910 }
10911}
10912
10913void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
10914{
10915 Q_Q(QWidget);
10916
10917 Qt::WindowFlags oldFlags = data.window_flags;
10918 bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
10919
10920 QScreen *targetScreen = nullptr;
10921 // Handle a request to move the widget to a particular screen
10922 if (newparent && newparent->windowType() == Qt::Desktop) {
10923 // make sure the widget is created on the same screen as the
10924 // programmer specified desktop widget
10925 targetScreen = newparent->screen();
10926 newparent = nullptr;
10927 }
10928
10929 setWinId(0);
10930
10931 if (!newparent) {
10932 f |= Qt::Window;
10933 if (parent)
10934 targetScreen = q->parentWidget()->window()->screen();
10935 }
10936
10937 const bool destroyWindow = (
10938 // Reparenting top level to child
10939 (oldFlags & Qt::Window) && !(f & Qt::Window)
10940 // And we can dispose of the window
10941 && wasCreated && !q->testAttribute(Qt::WA_NativeWindow)
10942 );
10943
10944 if (parent != newparent) {
10945 // Update object parent now, so we can resolve new parent window below
10946 QObjectPrivate::setParent_helper(newparent);
10947
10948 if (q->windowHandle())
10949 q->windowHandle()->setFlags(f);
10950
10951 // If the widget itself or any of its children have been created,
10952 // we need to reparent their QWindows as well.
10953 QWidget *parentWithWindow = closestParentWidgetWithWindowHandle();
10954 // But if the widget is about to be destroyed we must skip the
10955 // widget itself, and only reparent children.
10956 if (destroyWindow) {
10957 reparentWidgetWindowChildren(parentWithWindow);
10958 } else {
10959 // During reparentWidgetWindows() we need to know whether the reparented
10960 // QWindow should be a top level (with a transient parent) or not. This
10961 // widget has not updated its window flags yet, so we can't ask the widget
10962 // directly at that point. Nor can we use the QWindow flags, as unlike QWidgets
10963 // the QWindow flags always reflect Qt::Window, even for child windows. And
10964 // we can't use QWindow::isTopLevel() either, as that depends on the parent,
10965 // which we are in the process of updating. So we propagate the
10966 // new flags of the reparented window here.
10967 reparentWidgetWindows(parentWithWindow, f);
10968 }
10969 }
10970
10971 bool explicitlyHidden = isExplicitlyHidden();
10972
10973 if (destroyWindow) {
10974 if (extra && extra->hasWindowContainer)
10975 QWindowContainer::toplevelAboutToBeDestroyed(q);
10976
10977 // There shouldn't be any QWindow children left, but if there
10978 // are, re-parent them now, before we destroy.
10979 if (!q->windowHandle()->children().isEmpty()) {
10980 QWidget *parentWithWindow = closestParentWidgetWithWindowHandle();
10981 QWindow *newParentWindow = parentWithWindow ? parentWithWindow->windowHandle() : nullptr;
10982 for (QObject *child : q->windowHandle()->children()) {
10983 if (QWindow *childWindow = qobject_cast<QWindow *>(child)) {
10984 qCWarning(lcWidgetWindow) << "Reparenting" << childWindow
10985 << "before destroying" << this;
10986 childWindow->setParent(newParentWindow);
10987 }
10988 }
10989 }
10990
10991 // We have reparented any child windows of the widget we are
10992 // about to destroy to the new parent window handle, so we can
10993 // safely destroy this widget without destroying sub windows.
10994 q->destroy(true, false);
10995 }
10996
10997 adjustFlags(f, q);
10998 data.window_flags = f;
10999 q->setAttribute(Qt::WA_WState_Created, false);
11000 q->setAttribute(Qt::WA_WState_Visible, false);
11001 q->setAttribute(Qt::WA_WState_Hidden, false);
11002
11003 if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window)))
11004 q->createWinId();
11005
11006 if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
11007 q->setAttribute(Qt::WA_WState_Hidden);
11008 q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
11009
11010 // move the window to the selected screen
11011 if (!newparent && targetScreen) {
11012 // only if it is already created
11013 if (q->testAttribute(Qt::WA_WState_Created))
11014 q->windowHandle()->setScreen(targetScreen);
11015 else
11016 topData()->initialScreen = targetScreen;
11017 }
11018}
11019
11020void QWidgetPrivate::reparentWidgetWindows(QWidget *parentWithWindow, Qt::WindowFlags windowFlags)
11021{
11022 if (QWindow *window = windowHandle()) {
11023 // Reparent this QWindow, and all QWindow children will follow
11024 if (parentWithWindow) {
11025 if (windowFlags & Qt::Window) {
11026 // Top level windows can only have transient parents,
11027 // and the transient parent must be another top level.
11028 QWidget *topLevel = parentWithWindow->window();
11029 auto *transientParent = topLevel->windowHandle();
11030 Q_ASSERT(transientParent);
11031 qCDebug(lcWidgetWindow) << "Setting" << window << "transient parent to" << transientParent;
11032 window->setTransientParent(transientParent);
11033 window->setParent(nullptr);
11034 } else {
11035 auto *parentWindow = parentWithWindow->windowHandle();
11036 qCDebug(lcWidgetWindow) << "Reparenting" << window << "into" << parentWindow;
11037 window->setTransientParent(nullptr);
11038 window->setParent(parentWindow);
11039 }
11040 } else {
11041 qCDebug(lcWidgetWindow) << "Making" << window << "top level window";
11042 window->setTransientParent(nullptr);
11043 window->setParent(nullptr);
11044 }
11045 } else {
11046 reparentWidgetWindowChildren(parentWithWindow);
11047 }
11048}
11049
11050void QWidgetPrivate::reparentWidgetWindowChildren(QWidget *parentWithWindow)
11051{
11052 for (auto *child : std::as_const(children)) {
11053 if (auto *childWidget = qobject_cast<QWidget*>(child)) {
11054 auto *childPrivate = QWidgetPrivate::get(childWidget);
11055 // Child widgets with QWindows should always continue to be child
11056 // windows, so we pass on the child's current window flags here.
11057 childPrivate->reparentWidgetWindows(parentWithWindow, childWidget->windowFlags());
11058 }
11059 }
11060}
11061
11062/*!
11063 Scrolls the widget including its children \a dx pixels to the
11064 right and \a dy downward. Both \a dx and \a dy may be negative.
11065
11066 After scrolling, the widgets will receive paint events for
11067 the areas that need to be repainted. For widgets that Qt knows to
11068 be opaque, this is only the newly exposed parts.
11069 For example, if an opaque widget is scrolled 8 pixels to the left,
11070 only an 8-pixel wide stripe at the right edge needs updating.
11071
11072 Since widgets propagate the contents of their parents by default,
11073 you need to set the \l autoFillBackground property, or use
11074 setAttribute() to set the Qt::WA_OpaquePaintEvent attribute, to make
11075 a widget opaque.
11076
11077 For widgets that use contents propagation, a scroll will cause an
11078 update of the entire scroll area.
11079
11080 \sa {Transparency and Double Buffering}
11081*/
11082
11083void QWidget::scroll(int dx, int dy)
11084{
11085 if ((!updatesEnabled() && children().size() == 0) || !isVisible())
11086 return;
11087 if (dx == 0 && dy == 0)
11088 return;
11089 Q_D(QWidget);
11090#if QT_CONFIG(graphicsview)
11091 if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) {
11092 // Graphics View maintains its own dirty region as a list of rects;
11093 // until we can connect item updates directly to the view, we must
11094 // separately add a translated dirty region.
11095 for (const QRect &rect : d->dirty)
11096 proxy->update(rect.translated(dx, dy));
11097 proxy->scroll(dx, dy, proxy->subWidgetRect(this));
11098 return;
11099 }
11100#endif
11101 d->setDirtyOpaqueRegion();
11102 d->scroll_sys(dx, dy);
11103}
11104
11105void QWidgetPrivate::scroll_sys(int dx, int dy)
11106{
11107 Q_Q(QWidget);
11108 scrollChildren(dx, dy);
11109 scrollRect(q->rect(), dx, dy);
11110}
11111
11112/*!
11113 \overload
11114
11115 This version only scrolls \a r and does not move the children of
11116 the widget.
11117
11118 If \a r is empty or invalid, the result is undefined.
11119
11120 \sa QScrollArea
11121*/
11122void QWidget::scroll(int dx, int dy, const QRect &r)
11123{
11124
11125 if ((!updatesEnabled() && children().size() == 0) || !isVisible())
11126 return;
11127 if (dx == 0 && dy == 0)
11128 return;
11129 Q_D(QWidget);
11130#if QT_CONFIG(graphicsview)
11131 if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) {
11132 // Graphics View maintains its own dirty region as a list of rects;
11133 // until we can connect item updates directly to the view, we must
11134 // separately add a translated dirty region.
11135 if (!d->dirty.isEmpty()) {
11136 for (const QRect &rect : d->dirty.translated(dx, dy) & r)
11137 proxy->update(rect);
11138 }
11139 proxy->scroll(dx, dy, r.translated(proxy->subWidgetRect(this).topLeft().toPoint()));
11140 return;
11141 }
11142#endif
11143 d->scroll_sys(dx, dy, r);
11144}
11145
11146void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
11147{
11148 scrollRect(r, dx, dy);
11149}
11150
11151/*!
11152 Repaints the widget directly by calling paintEvent() immediately,
11153 unless updates are disabled or the widget is hidden.
11154
11155 We suggest only using repaint() if you need an immediate repaint,
11156 for example during animation. In most circumstances update()
11157 is better, as it permits Qt to optimize for speed and minimize
11158 flicker.
11159
11160 \warning If you call repaint() in a function which may itself be
11161 called from paintEvent(), you may get infinite recursion. The
11162 update() function never causes recursion.
11163
11164 \sa update(), paintEvent(), setUpdatesEnabled()
11165*/
11166
11167void QWidget::repaint()
11168{
11169 repaint(rect());
11170}
11171
11172/*! \overload
11173
11174 This version repaints a rectangle (\a x, \a y, \a w, \a h) inside
11175 the widget.
11176
11177 If \a w is negative, it is replaced with \c{width() - x}, and if
11178 \a h is negative, it is replaced width \c{height() - y}.
11179*/
11180void QWidget::repaint(int x, int y, int w, int h)
11181{
11182 if (x > data->crect.width() || y > data->crect.height())
11183 return;
11184
11185 if (w < 0)
11186 w = data->crect.width() - x;
11187 if (h < 0)
11188 h = data->crect.height() - y;
11189
11190 repaint(QRect(x, y, w, h));
11191}
11192
11193/*! \overload
11194
11195 This version repaints a rectangle \a rect inside the widget.
11196*/
11197void QWidget::repaint(const QRect &rect)
11198{
11199 Q_D(QWidget);
11200 d->repaint(rect);
11201}
11202
11203/*!
11204 \overload
11205
11206 This version repaints a region \a rgn inside the widget.
11207*/
11208void QWidget::repaint(const QRegion &rgn)
11209{
11210 Q_D(QWidget);
11211 d->repaint(rgn);
11212}
11213
11214template <typename T>
11215void QWidgetPrivate::repaint(T r)
11216{
11217 Q_Q(QWidget);
11218
11219 if (!q->isVisible() || !q->updatesEnabled() || r.isEmpty())
11220 return;
11221
11222 QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
11223 if (tlwExtra && tlwExtra->backingStore && tlwExtra->repaintManager)
11224 tlwExtra->repaintManager->markDirty(r, q, QWidgetRepaintManager::UpdateNow);
11225}
11226
11227/*!
11228 Updates the widget unless updates are disabled or the widget is
11229 hidden.
11230
11231 This function does not cause an immediate repaint; instead it
11232 schedules a paint event for processing when Qt returns to the main
11233 event loop. This permits Qt to optimize for more speed and less
11234 flicker than a call to repaint() does.
11235
11236 Calling update() several times normally results in just one
11237 paintEvent() call.
11238
11239 Qt normally erases the widget's area before the paintEvent() call.
11240 If the Qt::WA_OpaquePaintEvent widget attribute is set, the widget is
11241 responsible for painting all its pixels with an opaque color.
11242
11243 \sa repaint(), paintEvent(), setUpdatesEnabled(), {Analog Clock}
11244*/
11245void QWidget::update()
11246{
11247 update(rect());
11248}
11249
11250/*! \fn void QWidget::update(int x, int y, int w, int h)
11251 \overload
11252
11253 This version updates a rectangle (\a x, \a y, \a w, \a h) inside
11254 the widget.
11255*/
11256
11257/*!
11258 \overload
11259
11260 This version updates a rectangle \a rect inside the widget.
11261*/
11262void QWidget::update(const QRect &rect)
11263{
11264 Q_D(QWidget);
11265 d->update(rect);
11266}
11267
11268/*!
11269 \overload
11270
11271 This version repaints a region \a rgn inside the widget.
11272*/
11273void QWidget::update(const QRegion &rgn)
11274{
11275 Q_D(QWidget);
11276 d->update(rgn);
11277}
11278
11279template <typename T>
11280void QWidgetPrivate::update(T r)
11281{
11282 Q_Q(QWidget);
11283
11284 if (renderToTexture && !q->isVisible()) {
11285 renderToTextureReallyDirty = 1;
11286 return;
11287 }
11288
11289 if (!q->isVisible() || !q->updatesEnabled())
11290 return;
11291
11292 T clipped = r & q->rect();
11293
11294 if (clipped.isEmpty())
11295 return;
11296
11297 if (q->testAttribute(Qt::WA_WState_InPaintEvent)) {
11298 QCoreApplication::postEvent(q, new QUpdateLaterEvent(clipped));
11299 return;
11300 }
11301
11302 QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
11303 if (tlwExtra && tlwExtra->backingStore && tlwExtra->repaintManager)
11304 tlwExtra->repaintManager->markDirty(clipped, q);
11305}
11306
11307 /*!
11308 \internal
11309
11310 This just sets the corresponding attribute bit to 1 or 0
11311 */
11312static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data,
11313 QWidgetPrivate *d)
11314{
11315 if (attribute < int(8*sizeof(uint))) {
11316 if (on)
11317 data->widget_attributes |= (1<<attribute);
11318 else
11319 data->widget_attributes &= ~(1<<attribute);
11320 } else {
11321 const int x = attribute - 8*sizeof(uint);
11322 const int int_off = x / (8*sizeof(uint));
11323 if (on)
11324 d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint))));
11325 else
11326 d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint))));
11327 }
11328}
11329
11330#ifdef Q_OS_MAC
11331void QWidgetPrivate::macUpdateSizeAttribute()
11332{
11333 Q_Q(QWidget);
11334 QEvent event(QEvent::MacSizeChange);
11335 QCoreApplication::sendEvent(q, &event);
11336 for (int i = 0; i < children.size(); ++i) {
11337 QWidget *w = qobject_cast<QWidget *>(children.at(i));
11338 if (w && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
11339 && !w->testAttribute(Qt::WA_MacMiniSize) // no attribute set? inherit from parent
11340 && !w->testAttribute(Qt::WA_MacSmallSize)
11341 && !w->testAttribute(Qt::WA_MacNormalSize))
11342 w->d_func()->macUpdateSizeAttribute();
11343 }
11344 resolveFont();
11345}
11346#endif
11347
11348/*!
11349 Sets the attribute \a attribute on this widget if \a on is true;
11350 otherwise clears the attribute.
11351
11352 \sa testAttribute()
11353*/
11354void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
11355{
11356 if (testAttribute(attribute) == on)
11357 return;
11358
11359 Q_D(QWidget);
11360 static_assert(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8),
11361 "QWidget::setAttribute(WidgetAttribute, bool): "
11362 "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
11363#ifdef Q_OS_WIN
11364 // ### Don't use PaintOnScreen+paintEngine() to do native painting in some future release
11365 if (attribute == Qt::WA_PaintOnScreen && on && windowType() != Qt::Desktop && !inherits("QGLWidget")) {
11366 // see ::paintEngine for details
11367 paintEngine();
11368 if (d->noPaintOnScreen)
11369 return;
11370 }
11371#endif
11372
11373 // Don't set WA_NativeWindow on platforms that don't support it -- except for QGLWidget, which depends on it
11374 if (attribute == Qt::WA_NativeWindow && !d->mustHaveWindowHandle) {
11375 QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
11376 if (!platformIntegration->hasCapability(QPlatformIntegration::NativeWidgets))
11377 return;
11378 }
11379
11380 setAttribute_internal(attribute, on, data, d);
11381
11382 switch (attribute) {
11383
11384#if QT_CONFIG(draganddrop)
11385 case Qt::WA_AcceptDrops: {
11386 if (on && !testAttribute(Qt::WA_DropSiteRegistered))
11387 setAttribute(Qt::WA_DropSiteRegistered, true);
11388 else if (!on && (isWindow() || !parentWidget() || !parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
11389 setAttribute(Qt::WA_DropSiteRegistered, false);
11390 QEvent e(QEvent::AcceptDropsChange);
11391 QCoreApplication::sendEvent(this, &e);
11392 break;
11393 }
11394 case Qt::WA_DropSiteRegistered: {
11395 for (int i = 0; i < d->children.size(); ++i) {
11396 QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
11397 if (w && !w->isWindow() && !w->testAttribute(Qt::WA_AcceptDrops) && w->testAttribute(Qt::WA_DropSiteRegistered) != on)
11398 w->setAttribute(Qt::WA_DropSiteRegistered, on);
11399 }
11400 break;
11401 }
11402#endif
11403
11404 case Qt::WA_NoChildEventsForParent:
11405 d->sendChildEvents = !on;
11406 break;
11407 case Qt::WA_NoChildEventsFromChildren:
11408 d->receiveChildEvents = !on;
11409 break;
11410 case Qt::WA_MacNormalSize:
11411 case Qt::WA_MacSmallSize:
11412 case Qt::WA_MacMiniSize:
11413#ifdef Q_OS_MAC
11414 {
11415 // We can only have one of these set at a time
11416 const Qt::WidgetAttribute MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize,
11417 Qt::WA_MacMiniSize };
11418 for (int i = 0; i < 3; ++i) {
11419 if (MacSizes[i] != attribute)
11420 setAttribute_internal(MacSizes[i], false, data, d);
11421 }
11422 d->macUpdateSizeAttribute();
11423 }
11424#endif
11425 break;
11426 case Qt::WA_ShowModal:
11427 if (!on) {
11428 // reset modality type to NonModal when clearing WA_ShowModal
11429 data->window_modality = Qt::NonModal;
11430 } else if (data->window_modality == Qt::NonModal) {
11431 // If modality hasn't been set prior to setting WA_ShowModal, use
11432 // ApplicationModal.
11433 data->window_modality = Qt::ApplicationModal;
11434 // Some window managers do not allow us to enter modality after the
11435 // window is visible.The window must be hidden before changing the
11436 // windowModality property and then reshown.
11437 }
11438 if (testAttribute(Qt::WA_WState_Created)) {
11439 // don't call setModal_sys() before create()
11440 d->setModal_sys();
11441 }
11442 break;
11443 case Qt::WA_MouseTracking: {
11444 QEvent e(QEvent::MouseTrackingChange);
11445 QCoreApplication::sendEvent(this, &e);
11446 break; }
11447 case Qt::WA_TabletTracking: {
11448 QEvent e(QEvent::TabletTrackingChange);
11449 QCoreApplication::sendEvent(this, &e);
11450 break; }
11451 case Qt::WA_NativeWindow: {
11452 d->createTLExtra();
11453 if (on)
11454 d->createTLSysExtra();
11455#ifndef QT_NO_IM
11456 QWidget *focusWidget = d->effectiveFocusWidget();
11457 if (on && !internalWinId() && this == QGuiApplication::focusObject()
11458 && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
11459 QGuiApplication::inputMethod()->commit();
11460 QGuiApplication::inputMethod()->update(Qt::ImEnabled);
11461 }
11462 if (!QCoreApplication::testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget())
11463 parentWidget()->d_func()->enforceNativeChildren();
11464 if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
11465 d->createWinId();
11466 if (isEnabled() && focusWidget->isEnabled() && this == QGuiApplication::focusObject()
11467 && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
11468 QGuiApplication::inputMethod()->update(Qt::ImEnabled);
11469 }
11470#endif //QT_NO_IM
11471 break;
11472 }
11473 case Qt::WA_PaintOnScreen:
11474 d->updateIsOpaque();
11475 Q_FALLTHROUGH();
11476 case Qt::WA_OpaquePaintEvent:
11477 d->updateIsOpaque();
11478 break;
11479 case Qt::WA_NoSystemBackground:
11480 d->updateIsOpaque();
11481 Q_FALLTHROUGH();
11482 case Qt::WA_UpdatesDisabled:
11483 d->updateSystemBackground();
11484 break;
11485 case Qt::WA_TransparentForMouseEvents:
11486 break;
11487 case Qt::WA_InputMethodEnabled: {
11488#ifndef QT_NO_IM
11489 if (QGuiApplication::focusObject() == this) {
11490 if (!on)
11491 QGuiApplication::inputMethod()->commit();
11492 QGuiApplication::inputMethod()->update(Qt::ImEnabled);
11493 }
11494#endif //QT_NO_IM
11495 break;
11496 }
11497 case Qt::WA_WindowPropagation:
11498 d->resolvePalette();
11499 d->resolveFont();
11500 d->resolveLocale();
11501 break;
11502 case Qt::WA_DontShowOnScreen: {
11503 if (on && isVisible()) {
11504 // Make sure we keep the current state and only hide the widget
11505 // from the desktop. show_sys will only update platform specific
11506 // attributes at this point.
11507 d->hide_sys();
11508 d->show_sys();
11509 }
11510 break;
11511 }
11512
11513 case Qt::WA_X11NetWmWindowTypeDesktop:
11514 case Qt::WA_X11NetWmWindowTypeDock:
11515 case Qt::WA_X11NetWmWindowTypeToolBar:
11516 case Qt::WA_X11NetWmWindowTypeMenu:
11517 case Qt::WA_X11NetWmWindowTypeUtility:
11518 case Qt::WA_X11NetWmWindowTypeSplash:
11519 case Qt::WA_X11NetWmWindowTypeDialog:
11520 case Qt::WA_X11NetWmWindowTypeDropDownMenu:
11521 case Qt::WA_X11NetWmWindowTypePopupMenu:
11522 case Qt::WA_X11NetWmWindowTypeToolTip:
11523 case Qt::WA_X11NetWmWindowTypeNotification:
11524 case Qt::WA_X11NetWmWindowTypeCombo:
11525 case Qt::WA_X11NetWmWindowTypeDND:
11526 d->setNetWmWindowTypes();
11527 break;
11528
11529 case Qt::WA_StaticContents:
11530 if (QWidgetRepaintManager *repaintManager = d->maybeRepaintManager()) {
11531 if (on)
11532 repaintManager->addStaticWidget(this);
11533 else
11534 repaintManager->removeStaticWidget(this);
11535 }
11536 break;
11537 case Qt::WA_TranslucentBackground:
11538 if (on)
11539 setAttribute(Qt::WA_NoSystemBackground);
11540 d->updateIsTranslucent();
11541
11542 break;
11543 case Qt::WA_AcceptTouchEvents:
11544 break;
11545 default:
11546 break;
11547 }
11548}
11549
11550/*! \fn bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const
11551
11552 Returns \c true if attribute \a attribute is set on this widget;
11553 otherwise returns \c false.
11554
11555 \sa setAttribute()
11556 */
11557bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const
11558{
11559 Q_D(const QWidget);
11560 const int x = attribute - 8*sizeof(uint);
11561 const int int_off = x / (8*sizeof(uint));
11562 return (d->high_attributes[int_off] & (1<<(x-(int_off*8*sizeof(uint)))));
11563}
11564
11565/*!
11566 \property QWidget::windowOpacity
11567
11568 \brief The level of opacity for the window.
11569
11570 The valid range of opacity is from 1.0 (completely opaque) to
11571 0.0 (completely transparent).
11572
11573 By default the value of this property is 1.0.
11574
11575 This feature is available on Embedded Linux, \macos, Windows,
11576 and X11 platforms that support the Composite extension.
11577
11578 \note On X11 you need to have a composite manager running,
11579 and the X11 specific _NET_WM_WINDOW_OPACITY atom needs to be
11580 supported by the window manager you are using.
11581
11582 \warning Changing this property from opaque to transparent might issue a
11583 paint event that needs to be processed before the window is displayed
11584 correctly. This affects mainly the use of QScreen::grabWindow(). Also note
11585 that semi-transparent windows update and resize significantly slower than
11586 opaque windows.
11587
11588 \sa setMask()
11589*/
11590qreal QWidget::windowOpacity() const
11591{
11592 Q_D(const QWidget);
11593 return (isWindow() && d->maybeTopData()) ? d->maybeTopData()->opacity / 255. : 1.0;
11594}
11595
11596void QWidget::setWindowOpacity(qreal opacity)
11597{
11598 Q_D(QWidget);
11599 if (!isWindow())
11600 return;
11601
11602 opacity = qBound(qreal(0.0), opacity, qreal(1.0));
11603 QTLWExtra *extra = d->topData();
11604 extra->opacity = uint(opacity * 255);
11605 setAttribute(Qt::WA_WState_WindowOpacitySet);
11606 d->setWindowOpacity_sys(opacity);
11607
11608 if (!testAttribute(Qt::WA_WState_Created))
11609 return;
11610
11611#if QT_CONFIG(graphicsview)
11612 if (QGraphicsProxyWidget *proxy = graphicsProxyWidget()) {
11613 // Avoid invalidating the cache if set.
11614 if (proxy->cacheMode() == QGraphicsItem::NoCache)
11615 proxy->update();
11616 else if (QGraphicsScene *scene = proxy->scene())
11617 scene->update(proxy->sceneBoundingRect());
11618 return;
11619 }
11620#endif
11621}
11622
11623void QWidgetPrivate::setWindowOpacity_sys(qreal level)
11624{
11625 Q_Q(QWidget);
11626 if (q->windowHandle())
11627 q->windowHandle()->setOpacity(level);
11628}
11629
11630/*!
11631 \property QWidget::windowModified
11632 \brief whether the document shown in the window has unsaved changes
11633
11634 A modified window is a window whose content has changed but has
11635 not been saved to disk. This flag will have different effects
11636 varied by the platform. On \macos the close button will have a
11637 modified look; on other platforms, the window title will have an
11638 '*' (asterisk).
11639
11640 The window title must contain a "[*]" placeholder, which
11641 indicates where the '*' should appear. Normally, it should appear
11642 right after the file name (e.g., "document1.txt[*] - Text
11643 Editor"). If the window isn't modified, the placeholder is simply
11644 removed.
11645
11646 Note that if a widget is set as modified, all its ancestors will
11647 also be set as modified. However, if you call \c
11648 {setWindowModified(false)} on a widget, this will not propagate to
11649 its parent because other children of the parent might have been
11650 modified.
11651
11652 \sa windowTitle
11653*/
11654bool QWidget::isWindowModified() const
11655{
11656 return testAttribute(Qt::WA_WindowModified);
11657}
11658
11659void QWidget::setWindowModified(bool mod)
11660{
11661 Q_D(QWidget);
11662 setAttribute(Qt::WA_WindowModified, mod);
11663
11664 d->setWindowModified_helper();
11665
11666 QEvent e(QEvent::ModifiedChange);
11667 QCoreApplication::sendEvent(this, &e);
11668}
11669
11670void QWidgetPrivate::setWindowModified_helper()
11671{
11672 Q_Q(QWidget);
11673 QWindow *window = q->windowHandle();
11674 if (!window)
11675 return;
11676 QPlatformWindow *platformWindow = window->handle();
11677 if (!platformWindow)
11678 return;
11679 bool on = q->testAttribute(Qt::WA_WindowModified);
11680 if (!platformWindow->setWindowModified(on)) {
11681 if (Q_UNLIKELY(on && !q->windowTitle().contains("[*]"_L1)))
11682 qWarning("QWidget::setWindowModified: The window title does not contain a '[*]' placeholder");
11683 setWindowTitle_helper(q->windowTitle());
11684 setWindowIconText_helper(q->windowIconText());
11685 }
11686}
11687
11688#if QT_CONFIG(tooltip)
11689/*!
11690 \property QWidget::toolTip
11691
11692 \brief the widget's tooltip
11693
11694 Note that by default tooltips are only shown for widgets that are
11695 children of the active window. You can change this behavior by
11696 setting the attribute Qt::WA_AlwaysShowToolTips on the \e window,
11697 not on the widget with the tooltip.
11698
11699 If you want to control a tooltip's behavior, you can intercept the
11700 event() function and catch the QEvent::ToolTip event (e.g., if you
11701 want to customize the area for which the tooltip should be shown).
11702
11703 By default, this property contains an empty string.
11704
11705 \sa QToolTip, statusTip, whatsThis
11706*/
11707void QWidget::setToolTip(const QString &s)
11708{
11709 Q_D(QWidget);
11710 d->toolTip = s;
11711
11712 QEvent event(QEvent::ToolTipChange);
11713 QCoreApplication::sendEvent(this, &event);
11714}
11715
11716QString QWidget::toolTip() const
11717{
11718 Q_D(const QWidget);
11719 return d->toolTip;
11720}
11721
11722/*!
11723 \property QWidget::toolTipDuration
11724 \brief the widget's tooltip duration
11725 \since 5.2
11726
11727 Specifies how long time the tooltip will be displayed, in milliseconds.
11728 If the value is -1 (default) the duration is calculated depending on the length of the tooltip.
11729
11730 \sa toolTip
11731*/
11732
11733void QWidget::setToolTipDuration(int msec)
11734{
11735 Q_D(QWidget);
11736 d->toolTipDuration = msec;
11737}
11738
11739int QWidget::toolTipDuration() const
11740{
11741 Q_D(const QWidget);
11742 return d->toolTipDuration;
11743}
11744
11745#endif // QT_CONFIG(tooltip)
11746
11747
11748#if QT_CONFIG(statustip)
11749/*!
11750 \property QWidget::statusTip
11751 \brief the widget's status tip
11752
11753 By default, this property contains an empty string.
11754
11755 \sa toolTip, whatsThis
11756*/
11757void QWidget::setStatusTip(const QString &s)
11758{
11759 Q_D(QWidget);
11760 d->statusTip = s;
11761}
11762
11763QString QWidget::statusTip() const
11764{
11765 Q_D(const QWidget);
11766 return d->statusTip;
11767}
11768#endif // QT_CONFIG(statustip)
11769
11770#if QT_CONFIG(whatsthis)
11771/*!
11772 \property QWidget::whatsThis
11773
11774 \brief the widget's What's This help text.
11775
11776 By default, this property contains an empty string.
11777
11778 \sa QWhatsThis, QWidget::toolTip, QWidget::statusTip
11779*/
11780void QWidget::setWhatsThis(const QString &s)
11781{
11782 Q_D(QWidget);
11783 d->whatsThis = s;
11784}
11785
11786QString QWidget::whatsThis() const
11787{
11788 Q_D(const QWidget);
11789 return d->whatsThis;
11790}
11791#endif // QT_CONFIG(whatsthis)
11792
11793#if QT_CONFIG(accessibility)
11794/*!
11795 \property QWidget::accessibleName
11796
11797 \brief the widget's name as seen by assistive technologies
11798
11799 This is the primary name by which assistive technology such as screen readers
11800 announce this widget. For most widgets setting this property is not required.
11801 For example for QPushButton the button's text will be used.
11802
11803 It is important to set this property when the widget does not provide any
11804 text. For example a button that only contains an icon needs to set this
11805 property to work with screen readers.
11806 The name should be short and equivalent to the visual information conveyed
11807 by the widget.
11808
11809 This property has to be \l{Internationalization with Qt}{localized}.
11810
11811 By default, this property contains an empty string.
11812
11813 \sa QWidget::accessibleDescription, QAccessibleInterface::text()
11814*/
11815void QWidget::setAccessibleName(const QString &name)
11816{
11817 Q_D(QWidget);
11818 if (d->accessibleName == name)
11819 return;
11820
11821 d->accessibleName = name;
11822 QAccessibleEvent event(this, QAccessible::NameChanged);
11823 QAccessible::updateAccessibility(&event);
11824}
11825
11826QString QWidget::accessibleName() const
11827{
11828 Q_D(const QWidget);
11829 return d->accessibleName;
11830}
11831
11832/*!
11833 \property QWidget::accessibleDescription
11834
11835 \brief the widget's description as seen by assistive technologies
11836
11837 The accessible description of a widget should convey what a widget does.
11838 While the \l accessibleName should be a short and concise string (e.g. \gui{Save}),
11839 the description should give more context, such as \gui{Saves the current document}.
11840
11841 This property has to be \l{Internationalization with Qt}{localized}.
11842
11843 By default, this property contains an empty string and Qt falls back
11844 to using the tool tip to provide this information.
11845
11846 \sa QWidget::accessibleName, QAccessibleInterface::text()
11847*/
11848void QWidget::setAccessibleDescription(const QString &description)
11849{
11850 Q_D(QWidget);
11851 if (d->accessibleDescription == description)
11852 return;
11853
11854 d->accessibleDescription = description;
11855 QAccessibleEvent event(this, QAccessible::DescriptionChanged);
11856 QAccessible::updateAccessibility(&event);
11857}
11858
11859QString QWidget::accessibleDescription() const
11860{
11861 Q_D(const QWidget);
11862 return d->accessibleDescription;
11863}
11864
11865/*!
11866 \property QWidget::accessibleIdentifier
11867
11868 \brief the widget's identifier as seen by assistive technologies
11869
11870 If set, the accessible identifier of a widget can be used by assistive
11871 technologies in order to identify a specific widget, e.g. in automated
11872 tests.
11873
11874 \since 6.9
11875*/
11876void QWidget::setAccessibleIdentifier(const QString &identifier)
11877{
11878 Q_D(QWidget);
11879 if (d->accessibleIdentifier == identifier)
11880 return;
11881
11882 d->accessibleIdentifier = identifier;
11883 QAccessibleEvent event(this, QAccessible::IdentifierChanged);
11884 QAccessible::updateAccessibility(&event);
11885}
11886
11887QString QWidget::accessibleIdentifier() const
11888{
11889 Q_D(const QWidget);
11890 return d->accessibleIdentifier;
11891}
11892
11893#endif // QT_CONFIG(accessibility)
11894
11895#ifndef QT_NO_SHORTCUT
11896/*!
11897 Adds a shortcut to Qt's shortcut system that watches for the given
11898 \a key sequence in the given \a context. If the \a context is
11899 Qt::ApplicationShortcut, the shortcut applies to the application as a
11900 whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
11901 or to the window itself, Qt::WindowShortcut.
11902
11903 If the same \a key sequence has been grabbed by several widgets,
11904 when the \a key sequence occurs a QEvent::Shortcut event is sent
11905 to all the widgets to which it applies in a non-deterministic
11906 order, but with the ``ambiguous'' flag set to true.
11907
11908 \warning You should not normally need to use this function;
11909 instead create \l{QAction}s with the shortcut key sequences you
11910 require (if you also want equivalent menu options and toolbar
11911 buttons), or create \l{QShortcut}s if you just need key sequences.
11912 Both QAction and QShortcut handle all the event filtering for you,
11913 and provide signals which are triggered when the user triggers the
11914 key sequence, so are much easier to use than this low-level
11915 function.
11916
11917 \sa releaseShortcut(), setShortcutEnabled()
11918*/
11919int QWidget::grabShortcut(const QKeySequence &key, Qt::ShortcutContext context)
11920{
11921 Q_ASSERT(qApp);
11922 if (key.isEmpty())
11923 return 0;
11924 setAttribute(Qt::WA_GrabbedShortcut);
11925 return QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, key, context, qWidgetShortcutContextMatcher);
11926}
11927
11928/*!
11929 Removes the shortcut with the given \a id from Qt's shortcut
11930 system. The widget will no longer receive QEvent::Shortcut events
11931 for the shortcut's key sequence (unless it has other shortcuts
11932 with the same key sequence).
11933
11934 \warning You should not normally need to use this function since
11935 Qt's shortcut system removes shortcuts automatically when their
11936 parent widget is destroyed. It is best to use QAction or
11937 QShortcut to handle shortcuts, since they are easier to use than
11938 this low-level function. Note also that this is an expensive
11939 operation.
11940
11941 \sa grabShortcut(), setShortcutEnabled()
11942*/
11943void QWidget::releaseShortcut(int id)
11944{
11945 Q_ASSERT(qApp);
11946 if (id)
11947 QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id, this, 0);
11948}
11949
11950/*!
11951 If \a enable is true, the shortcut with the given \a id is
11952 enabled; otherwise the shortcut is disabled.
11953
11954 \warning You should not normally need to use this function since
11955 Qt's shortcut system enables/disables shortcuts automatically as
11956 widgets become hidden/visible and gain or lose focus. It is best
11957 to use QAction or QShortcut to handle shortcuts, since they are
11958 easier to use than this low-level function.
11959
11960 \sa grabShortcut(), releaseShortcut()
11961*/
11962void QWidget::setShortcutEnabled(int id, bool enable)
11963{
11964 Q_ASSERT(qApp);
11965 if (id)
11966 QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, id, this, 0);
11967}
11968
11969/*!
11970 \since 4.2
11971
11972 If \a enable is true, auto repeat of the shortcut with the
11973 given \a id is enabled; otherwise it is disabled.
11974
11975 \sa grabShortcut(), releaseShortcut()
11976*/
11977void QWidget::setShortcutAutoRepeat(int id, bool enable)
11978{
11979 Q_ASSERT(qApp);
11980 if (id)
11981 QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(enable, id, this, 0);
11982}
11983#endif // QT_NO_SHORTCUT
11984
11985/*!
11986 Updates the widget's micro focus and informs input methods
11987 that the state specified by \a query has changed.
11988*/
11989void QWidget::updateMicroFocus(Qt::InputMethodQuery query)
11990{
11991 if (this == QGuiApplication::focusObject())
11992 QGuiApplication::inputMethod()->update(query);
11993}
11994
11995/*!
11996 Raises this widget to the top of the parent widget's stack.
11997
11998 After this call the widget will be visually in front of any
11999 overlapping sibling widgets.
12000
12001 \note When using activateWindow(), you can call this function to
12002 ensure that the window is stacked on top.
12003
12004 \sa lower(), stackUnder()
12005*/
12006
12007void QWidget::raise()
12008{
12009 Q_D(QWidget);
12010 if (!isWindow()) {
12011 QWidget *p = parentWidget();
12012 const int parentChildCount = p->d_func()->children.size();
12013 if (parentChildCount < 2)
12014 return;
12015 const int from = p->d_func()->children.indexOf(this);
12016 Q_ASSERT(from >= 0);
12017 // Do nothing if the widget is already in correct stacking order _and_ created.
12018 if (from != parentChildCount -1)
12019 p->d_func()->children.move(from, parentChildCount - 1);
12020 if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
12021 create();
12022 else if (from == parentChildCount - 1)
12023 return;
12024
12025 QRegion region(rect());
12026 d->subtractOpaqueSiblings(region);
12027 d->invalidateBackingStore(region);
12028 }
12029 if (testAttribute(Qt::WA_WState_Created))
12030 d->raise_sys();
12031
12032 if (d->extra && d->extra->hasWindowContainer)
12033 QWindowContainer::parentWasRaised(this);
12034
12035 QEvent e(QEvent::ZOrderChange);
12036 QCoreApplication::sendEvent(this, &e);
12037}
12038
12039void QWidgetPrivate::raise_sys()
12040{
12041 Q_Q(QWidget);
12042 if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
12043 q->windowHandle()->raise();
12044 } else if (renderToTexture) {
12045 if (QWidget *p = q->parentWidget()) {
12046 setDirtyOpaqueRegion();
12047 p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry()));
12048 }
12049 }
12050}
12051
12052/*!
12053 Lowers the widget to the bottom of the parent widget's stack.
12054
12055 After this call the widget will be visually behind (and therefore
12056 obscured by) any overlapping sibling widgets.
12057
12058 \sa raise(), stackUnder()
12059*/
12060
12061void QWidget::lower()
12062{
12063 Q_D(QWidget);
12064 if (!isWindow()) {
12065 QWidget *p = parentWidget();
12066 const int parentChildCount = p->d_func()->children.size();
12067 if (parentChildCount < 2)
12068 return;
12069 const int from = p->d_func()->children.indexOf(this);
12070 Q_ASSERT(from >= 0);
12071 // Do nothing if the widget is already in correct stacking order _and_ created.
12072 if (from != 0)
12073 p->d_func()->children.move(from, 0);
12074 if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
12075 create();
12076 else if (from == 0)
12077 return;
12078 }
12079 if (testAttribute(Qt::WA_WState_Created))
12080 d->lower_sys();
12081
12082 if (d->extra && d->extra->hasWindowContainer)
12083 QWindowContainer::parentWasLowered(this);
12084
12085 QEvent e(QEvent::ZOrderChange);
12086 QCoreApplication::sendEvent(this, &e);
12087}
12088
12089void QWidgetPrivate::lower_sys()
12090{
12091 Q_Q(QWidget);
12092 if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
12093 Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
12094 q->windowHandle()->lower();
12095 } else if (QWidget *p = q->parentWidget()) {
12096 setDirtyOpaqueRegion();
12097 p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry()));
12098 }
12099}
12100
12101/*!
12102 Places the widget under \a w in the parent widget's stack.
12103
12104 To make this work, the widget itself and \a w must be siblings.
12105
12106 \sa raise(), lower()
12107*/
12108void QWidget::stackUnder(QWidget* w)
12109{
12110 Q_D(QWidget);
12111 QWidget *p = parentWidget();
12112 if (!w || isWindow() || p != w->parentWidget() || this == w)
12113 return;
12114 if (p) {
12115 int from = p->d_func()->children.indexOf(this);
12116 int to = p->d_func()->children.indexOf(w);
12117 Q_ASSERT(from >= 0);
12118 Q_ASSERT(to >= 0);
12119 if (from < to)
12120 --to;
12121 // Do nothing if the widget is already in correct stacking order _and_ created.
12122 if (from != to)
12123 p->d_func()->children.move(from, to);
12124 if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
12125 create();
12126 else if (from == to)
12127 return;
12128 }
12129 if (testAttribute(Qt::WA_WState_Created))
12130 d->stackUnder_sys(w);
12131
12132 QEvent e(QEvent::ZOrderChange);
12133 QCoreApplication::sendEvent(this, &e);
12134}
12135
12136void QWidgetPrivate::stackUnder_sys(QWidget*)
12137{
12138 Q_Q(QWidget);
12139 if (QWidget *p = q->parentWidget()) {
12140 setDirtyOpaqueRegion();
12141 p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry()));
12142 }
12143}
12144
12145/*!
12146 \fn bool QWidget::isTopLevel() const
12147 \deprecated
12148
12149 Use isWindow() instead.
12150*/
12151
12152/*!
12153 \fn bool QWidget::isRightToLeft() const
12154 \internal
12155*/
12156
12157/*!
12158 \fn bool QWidget::isLeftToRight() const
12159 \internal
12160*/
12161
12162/*!
12163 \macro QWIDGETSIZE_MAX
12164 \relates QWidget
12165
12166 Defines the maximum size for a QWidget object.
12167
12168 The largest allowed size for a widget is QSize(QWIDGETSIZE_MAX,
12169 QWIDGETSIZE_MAX), i.e. QSize (16777215,16777215).
12170
12171 \sa QWidget::setMaximumSize()
12172*/
12173
12174/*!
12175 \fn QWidget::setupUi(QWidget *widget)
12176
12177 Sets up the user interface for the specified \a widget.
12178
12179 \note This function is available with widgets that derive from user
12180 interface descriptions created using \l{uic}.
12181
12182 \sa {Using a Designer UI File in Your Application}
12183*/
12184
12185QRect QWidgetPrivate::frameStrut() const
12186{
12187 Q_Q(const QWidget);
12188 if (!q->isWindow() || (q->windowType() == Qt::Desktop) || q->testAttribute(Qt::WA_DontShowOnScreen)) {
12189 // x2 = x1 + w - 1, so w/h = 1
12190 return QRect(0, 0, 1, 1);
12191 }
12192
12193 if (data.fstrut_dirty
12194 // ### Fix properly for 4.3
12195 && q->isVisible()
12196 && q->testAttribute(Qt::WA_WState_Created))
12197 const_cast<QWidgetPrivate *>(this)->updateFrameStrut();
12198
12199 return maybeTopData() ? maybeTopData()->frameStrut : QRect();
12200}
12201
12202void QWidgetPrivate::updateFrameStrut()
12203{
12204 Q_Q(QWidget);
12205 if (q->data->fstrut_dirty) {
12206 if (QTLWExtra *te = maybeTopData()) {
12207 if (te->window && te->window->handle()) {
12208 const QMargins margins = te->window->frameMargins();
12209 if (!margins.isNull()) {
12210 te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
12211 q->data->fstrut_dirty = false;
12212 }
12213 }
12214 }
12215 }
12216}
12217
12218#ifdef QT_KEYPAD_NAVIGATION
12219/*!
12220 \internal
12221
12222 Changes the focus from the current focusWidget to a widget in
12223 the \a direction.
12224
12225 Returns \c true, if there was a widget in that direction
12226*/
12227bool QWidgetPrivate::navigateToDirection(Direction direction)
12228{
12229 QWidget *targetWidget = widgetInNavigationDirection(direction);
12230 if (targetWidget)
12231 targetWidget->setFocus();
12232 return (targetWidget != 0);
12233}
12234
12235/*!
12236 \internal
12237
12238 Searches for a widget that is positioned in the \a direction, starting
12239 from the current focusWidget.
12240
12241 Returns the pointer to a found widget or \nullptr, if there was no widget
12242 in that direction.
12243*/
12244QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
12245{
12246 const QWidget *sourceWidget = QApplication::focusWidget();
12247 if (!sourceWidget)
12248 return nullptr;
12249 const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint()));
12250 const int sourceX =
12251 (direction == DirectionNorth || direction == DirectionSouth) ?
12252 (sourceRect.left() + (sourceRect.right() - sourceRect.left()) / 2)
12253 :(direction == DirectionEast ? sourceRect.right() : sourceRect.left());
12254 const int sourceY =
12255 (direction == DirectionEast || direction == DirectionWest) ?
12256 (sourceRect.top() + (sourceRect.bottom() - sourceRect.top()) / 2)
12257 :(direction == DirectionSouth ? sourceRect.bottom() : sourceRect.top());
12258 const QPoint sourcePoint(sourceX, sourceY);
12259 const QPoint sourceCenter = sourceRect.center();
12260 const QWidget *sourceWindow = sourceWidget->window();
12261
12262 QWidget *targetWidget = nullptr;
12263 int shortestDistance = INT_MAX;
12264
12265 const auto targetCandidates = QApplication::allWidgets();
12266 for (QWidget *targetCandidate : targetCandidates) {
12267
12268 const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint()));
12269
12270 // For focus proxies, the child widget handling the focus can have keypad navigation focus,
12271 // but the owner of the proxy cannot.
12272 // Additionally, empty widgets should be ignored.
12273 if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty())
12274 continue;
12275
12276 // Only navigate to a target widget that...
12277 if ( targetCandidate != sourceWidget
12278 // ...takes the focus,
12279 && targetCandidate->focusPolicy() & Qt::TabFocus
12280 // ...is above if DirectionNorth,
12281 && !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top())
12282 // ...is on the right if DirectionEast,
12283 && !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right())
12284 // ...is below if DirectionSouth,
12285 && !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom())
12286 // ...is on the left if DirectionWest,
12287 && !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left())
12288 // ...is enabled,
12289 && targetCandidate->isEnabled()
12290 // ...is visible,
12291 && targetCandidate->isVisible()
12292 // ...is in the same window,
12293 && targetCandidate->window() == sourceWindow) {
12294 const int targetCandidateDistance = [](const QPoint &sourcePoint,
12295 const QRect &targetCandidateRect) {
12296 int dx = 0;
12297 int dy = 0;
12298 if (p.x() < r.left())
12299 dx = r.left() - p.x();
12300 else if (p.x() > r.right())
12301 dx = p.x() - r.right();
12302 if (p.y() < r.top())
12303 dy = r.top() - p.y();
12304 else if (p.y() > r.bottom())
12305 dy = p.y() - r.bottom();
12306 return dx + dy;
12307 }();
12308 if (targetCandidateDistance < shortestDistance) {
12309 shortestDistance = targetCandidateDistance;
12310 targetWidget = targetCandidate;
12311 }
12312 }
12313 }
12314 return targetWidget;
12315}
12316
12317/*!
12318 \internal
12319
12320 Tells us if it there is currently a reachable widget by keypad navigation in
12321 a certain \a orientation.
12322 If no navigation is possible, occurring key events in that \a orientation may
12323 be used to interact with the value in the focused widget, even though it
12324 currently has not the editFocus.
12325
12326 \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
12327*/
12328bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation)
12329{
12330 return orientation == Qt::Horizontal?
12331 (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
12332 || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
12333 :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
12334 || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
12335}
12336/*!
12337 \internal
12338
12339 Checks, if the \a widget is inside a QTabWidget. If is is inside
12340 one, left/right key events will be used to switch between tabs in keypad
12341 navigation. If there is no QTabWidget, the horizontal key events can be used
12342to
12343 interact with the value in the focused widget, even though it currently has
12344 not the editFocus.
12345
12346 \sa QWidget::hasEditFocus()
12347*/
12348bool QWidgetPrivate::inTabWidget(QWidget *widget)
12349{
12350 for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
12351 if (qobject_cast<const QTabWidget*>(tabWidget))
12352 return true;
12353 return false;
12354}
12355#endif
12356
12357/*!
12358 \since 5.0
12359 \internal
12360
12361 Sets the backing store to be the \a store specified.
12362 The QWidget will take ownership of the \a store.
12363*/
12364void QWidget::setBackingStore(QBackingStore *store)
12365{
12366 // ### createWinId() ??
12367
12368 if (!isWindow())
12369 return;
12370
12371 Q_D(QWidget);
12372
12373 QTLWExtra *topData = d->topData();
12374 if (topData->backingStore == store)
12375 return;
12376
12377 QBackingStore *oldStore = topData->backingStore;
12378 delete topData->backingStore;
12379 topData->backingStore = store;
12380
12381 QWidgetRepaintManager *repaintManager = d->maybeRepaintManager();
12382 if (!repaintManager)
12383 return;
12384
12385 if (isWindow()) {
12386 if (repaintManager->backingStore() != oldStore && repaintManager->backingStore() != store)
12387 delete repaintManager->backingStore();
12388 repaintManager->setBackingStore(store);
12389 }
12390}
12391
12392/*!
12393 \since 5.0
12394
12395 Returns the QBackingStore this widget will be drawn into.
12396*/
12397QBackingStore *QWidget::backingStore() const
12398{
12399 Q_D(const QWidget);
12400 QTLWExtra *extra = d->maybeTopData();
12401 if (extra && extra->backingStore)
12402 return extra->backingStore;
12403
12404 if (!isWindow())
12405 return window()->backingStore();
12406
12407 return nullptr;
12408}
12409
12410void QWidgetPrivate::getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const
12411{
12412 if (left)
12413 *left = (int)leftLayoutItemMargin;
12414 if (top)
12415 *top = (int)topLayoutItemMargin;
12416 if (right)
12417 *right = (int)rightLayoutItemMargin;
12418 if (bottom)
12419 *bottom = (int)bottomLayoutItemMargin;
12420}
12421
12422void QWidgetPrivate::setLayoutItemMargins(int left, int top, int right, int bottom)
12423{
12424 if (leftLayoutItemMargin == left
12425 && topLayoutItemMargin == top
12426 && rightLayoutItemMargin == right
12427 && bottomLayoutItemMargin == bottom)
12428 return;
12429
12430 Q_Q(QWidget);
12431 leftLayoutItemMargin = (signed char)left;
12432 topLayoutItemMargin = (signed char)top;
12433 rightLayoutItemMargin = (signed char)right;
12434 bottomLayoutItemMargin = (signed char)bottom;
12435 q->updateGeometry();
12436}
12437
12438void QWidgetPrivate::setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt)
12439{
12440 Q_Q(QWidget);
12441 QStyleOption myOpt;
12442 if (!opt) {
12443 myOpt.initFrom(q);
12444 myOpt.rect.setRect(0, 0, 32768, 32768); // arbitrary
12445 opt = &myOpt;
12446 }
12447
12448 QRect liRect = q->style()->subElementRect(element, opt, q);
12449 if (liRect.isValid()) {
12450 leftLayoutItemMargin = (signed char)(opt->rect.left() - liRect.left());
12451 topLayoutItemMargin = (signed char)(opt->rect.top() - liRect.top());
12452 rightLayoutItemMargin = (signed char)(liRect.right() - opt->rect.right());
12453 bottomLayoutItemMargin = (signed char)(liRect.bottom() - opt->rect.bottom());
12454 } else {
12455 leftLayoutItemMargin = 0;
12456 topLayoutItemMargin = 0;
12457 rightLayoutItemMargin = 0;
12458 bottomLayoutItemMargin = 0;
12459 }
12460}
12461// resets the Qt::WA_QuitOnClose attribute to the default value for transient widgets.
12462void QWidgetPrivate::adjustQuitOnCloseAttribute()
12463{
12464 Q_Q(QWidget);
12465
12466 if (!q->parentWidget()) {
12467 Qt::WindowType type = q->windowType();
12468 if (type == Qt::Widget || type == Qt::SubWindow)
12469 type = Qt::Window;
12470 if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
12471 q->setAttribute(Qt::WA_QuitOnClose, false);
12472 }
12473}
12474
12475void QWidgetPrivate::sendComposeStatus(QWidget *w, bool end)
12476{
12477 QWidgetPrivate *wd = QWidgetPrivate::get(w);
12478 if (!wd->textureChildSeen)
12479 return;
12480 if (end)
12481 wd->endCompose();
12482 else
12483 wd->beginCompose();
12484 for (int i = 0; i < wd->children.size(); ++i) {
12485 w = qobject_cast<QWidget *>(wd->children.at(i));
12486 if (w && !w->isWindow() && !w->isHidden() && QWidgetPrivate::get(w)->textureChildSeen)
12487 sendComposeStatus(w, end);
12488 }
12489}
12490
12491Q_WIDGETS_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget)
12492{
12493 return widget->data;
12494}
12495
12496Q_WIDGETS_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget)
12497{
12498 return widget->d_func();
12499}
12500
12501
12502#if QT_CONFIG(graphicsview)
12503/*!
12504 \since 4.5
12505
12506 Returns the proxy widget for the corresponding embedded widget in a graphics
12507 view; otherwise returns \nullptr.
12508
12509 \sa QGraphicsProxyWidget::createProxyForChildWidget(),
12510 QGraphicsScene::addWidget()
12511 */
12512QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const
12513{
12514 Q_D(const QWidget);
12515 if (d->extra) {
12516 return d->extra->proxyWidget;
12517 }
12518 return nullptr;
12519}
12520#endif
12521
12522#ifndef QT_NO_GESTURES
12523/*!
12524 Subscribes the widget to a given \a gesture with specific \a flags.
12525
12526 \sa ungrabGesture(), QGestureEvent
12527 \since 4.6
12528*/
12529void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
12530{
12531 Q_D(QWidget);
12532 d->gestureContext.insert(gesture, flags);
12533 (void)QGestureManager::instance(); // create a gesture manager
12534}
12535
12536/*!
12537 Unsubscribes the widget from a given \a gesture type
12538
12539 \sa grabGesture(), QGestureEvent
12540 \since 4.6
12541*/
12542void QWidget::ungrabGesture(Qt::GestureType gesture)
12543{
12544 // if you modify this function, check the inlined version in ~QWidget, too
12545 Q_D(QWidget);
12546 if (d->gestureContext.remove(gesture)) {
12547 if (QGestureManager *manager = QGestureManager::instance())
12548 manager->cleanupCachedGestures(this, gesture);
12549 }
12550}
12551#endif // QT_NO_GESTURES
12552
12553/*!
12554 \fn void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
12555
12556 Frees up window system resources. Destroys the widget window if \a
12557 destroyWindow is true.
12558
12559 destroy() calls itself recursively for all the child widgets,
12560 passing \a destroySubWindows for the \a destroyWindow parameter.
12561 To have more control over destruction of subwidgets, destroy
12562 subwidgets selectively first.
12563
12564 This function is usually called from the QWidget destructor.
12565*/
12566void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
12567{
12568 Q_D(QWidget);
12569
12570 d->aboutToDestroy();
12571 if (!isWindow() && parentWidget())
12572 parentWidget()->d_func()->invalidateBackingStore(d->effectiveRectFor(geometry()));
12573 d->deactivateWidgetCleanup();
12574
12575 if ((windowType() == Qt::Popup) && qApp)
12576 qApp->d_func()->closePopup(this);
12577
12578 if (this == qApp->activeWindow())
12579 QApplicationPrivate::setActiveWindow(nullptr);
12580 if (QWidget::mouseGrabber() == this)
12581 releaseMouse();
12582 if (QWidget::keyboardGrabber() == this)
12583 releaseKeyboard();
12584
12585 setAttribute(Qt::WA_WState_Created, false);
12586
12587 if (windowType() != Qt::Desktop) {
12588 if (destroySubWindows) {
12589 QObjectList childList(children());
12590 for (int i = 0; i < childList.size(); i++) {
12591 QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
12592 if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
12593 if (widget->windowHandle()) {
12594 widget->destroy();
12595 }
12596 }
12597 }
12598 }
12599 if (destroyWindow) {
12600 d->deleteTLSysExtra();
12601 } else {
12602 if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
12603 d->hide_sys();
12604 }
12605 }
12606
12607 d->setWinId(0);
12608 }
12609}
12610
12611/*!
12612 \fn QPaintEngine *QWidget::paintEngine() const
12613
12614 Returns the widget's paint engine.
12615
12616 Note that this function should not be called explicitly by the
12617 user, since it's meant for reimplementation purposes only. The
12618 function is called by Qt internally, and the default
12619 implementation may not always return a valid pointer.
12620*/
12621QPaintEngine *QWidget::paintEngine() const
12622{
12623 qWarning("QWidget::paintEngine: Should no longer be called");
12624
12625#ifdef Q_OS_WIN
12626 // We set this bit which is checked in setAttribute for
12627 // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
12628 //
12629 // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
12630 // Windows which would mean suddenly their widgets stop working.
12631 //
12632 // 2. Users set paint on screen and subclass paintEngine() to
12633 // return 0, in which case we have a "hole" in the backingstore
12634 // allowing use of GDI or DirectX directly.
12635 //
12636 // 1 is WRONG, but to minimize silent failures, we have set this
12637 // bit to ignore the setAttribute call. 2. needs to be
12638 // supported because its our only means of embedding native
12639 // graphics stuff.
12640 const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
12641#endif
12642
12643 return nullptr; //##### @@@
12644}
12645
12646// Do not call QWindow::mapToGlobal() until QPlatformWindow is properly showing.
12647static inline bool canMapPosition(QWindow *window)
12648{
12649 return window->handle() && !qt_window_private(window)->resizeEventPending;
12650}
12651
12652#if QT_CONFIG(graphicsview)
12653static inline QGraphicsProxyWidget *graphicsProxyWidget(const QWidget *w)
12654{
12655 QGraphicsProxyWidget *result = nullptr;
12656 const QWidgetPrivate *d = qt_widget_private(const_cast<QWidget *>(w));
12657 if (d->extra)
12658 result = d->extra->proxyWidget;
12659 return result;
12660}
12661#endif // QT_CONFIG(graphicsview)
12662
12664 QTransform transform;
12665 QWindow *window;
12666};
12667
12669{
12671 result.window = nullptr;
12672 for ( ; w ; w = w->parentWidget()) {
12673#if QT_CONFIG(graphicsview)
12674 if (QGraphicsProxyWidget *qgpw = graphicsProxyWidget(w)) {
12675 if (const QGraphicsScene *scene = qgpw->scene()) {
12676 const QList <QGraphicsView *> views = scene->views();
12677 if (!views.isEmpty()) {
12678 auto *viewP = static_cast<QGraphicsViewPrivate *>(qt_widget_private(views.constFirst()));
12679 result.transform *= viewP->mapToViewTransform(qgpw);
12680 w = views.first()->viewport();
12681 }
12682 }
12683 }
12684#endif // QT_CONFIG(graphicsview)
12685 QWindow *window = w->windowHandle();
12686 if (window && canMapPosition(window)) {
12687 result.window = window;
12688 break;
12689 }
12690
12691 const auto &geometry = w->geometry();
12692 result.transform *= QTransform::fromTranslate(geometry.x(), geometry.y());
12693 if (w->isWindow())
12694 break;
12695 }
12696 return result;
12697}
12698
12699/*!
12700 \fn QPointF QWidget::mapToGlobal(const QPointF &pos) const
12701
12702 Translates the widget coordinate \a pos to global screen
12703 coordinates. For example, \c{mapToGlobal(QPointF(0,0))} would give
12704 the global coordinates of the top-left pixel of the widget.
12705
12706 \sa mapFromGlobal(), mapTo(), mapToParent()
12707 \since 6.0
12708*/
12709QPointF QWidget::mapToGlobal(const QPointF &pos) const
12710{
12711 const MapToGlobalTransformResult t = mapToGlobalTransform(this);
12712 const QPointF g = t.transform.map(pos);
12713 return t.window ? t.window->mapToGlobal(g) : g;
12714}
12715
12716/*!
12717 \overload
12718*/
12719QPoint QWidget::mapToGlobal(const QPoint &pos) const
12720{
12721 return mapToGlobal(QPointF(pos)).toPoint();
12722}
12723
12724/*!
12725 \fn QPointF QWidget::mapFromGlobal(const QPointF &pos) const
12726
12727 Translates the global screen coordinate \a pos to widget
12728 coordinates.
12729
12730 \sa mapToGlobal(), mapFrom(), mapFromParent()
12731 \since 6.0
12732*/
12733QPointF QWidget::mapFromGlobal(const QPointF &pos) const
12734{
12735 const MapToGlobalTransformResult t = mapToGlobalTransform(this);
12736 const QPointF windowLocal = t.window ? t.window->mapFromGlobal(pos) : pos;
12737 return t.transform.inverted().map(windowLocal);
12738}
12739
12740/*!
12741 \overload
12742*/
12743QPoint QWidget::mapFromGlobal(const QPoint &pos) const
12744{
12745 return mapFromGlobal(QPointF(pos)).toPoint();
12746}
12747
12749static bool mouseGrabWithCursor = false;
12750static QWidget *keyboardGrb = nullptr;
12751
12752static inline QWindow *grabberWindow(const QWidget *w)
12753{
12754 QWindow *window = w->windowHandle();
12755 if (!window)
12756 if (const QWidget *nativeParent = w->nativeParentWidget())
12757 window = nativeParent->windowHandle();
12758 return window;
12759}
12760
12761#ifndef QT_NO_CURSOR
12762static void grabMouseForWidget(QWidget *widget, const QCursor *cursor = nullptr)
12763#else
12764static void grabMouseForWidget(QWidget *widget)
12765#endif
12766{
12767 if (qt_mouseGrb)
12768 qt_mouseGrb->releaseMouse();
12769
12770 mouseGrabWithCursor = false;
12771 if (QWindow *window = grabberWindow(widget)) {
12772#ifndef QT_NO_CURSOR
12773 if (cursor) {
12774 mouseGrabWithCursor = true;
12775 QGuiApplication::setOverrideCursor(*cursor);
12776 }
12777#endif // !QT_NO_CURSOR
12778 window->setMouseGrabEnabled(true);
12779 }
12780
12781 qt_mouseGrb = widget;
12782}
12783
12785{
12786 if (qt_mouseGrb == widget) {
12787 if (QWindow *window = grabberWindow(widget)) {
12788#ifndef QT_NO_CURSOR
12789 if (mouseGrabWithCursor) {
12790 QGuiApplication::restoreOverrideCursor();
12791 mouseGrabWithCursor = false;
12792 }
12793#endif // !QT_NO_CURSOR
12794 window->setMouseGrabEnabled(false);
12795 }
12796 }
12797 qt_mouseGrb = nullptr;
12798}
12799
12800/*!
12801 \fn void QWidget::grabMouse()
12802
12803 Grabs the mouse input.
12804
12805 This widget receives all mouse events until releaseMouse() is
12806 called; other widgets get no mouse events at all. Keyboard
12807 events are not affected. Use grabKeyboard() if you want to grab
12808 that.
12809
12810 \warning Bugs in mouse-grabbing applications very often lock the
12811 terminal. Use this function with extreme caution, and consider
12812 using the \c -nograb command line option while debugging.
12813
12814 It is seldom necessary to grab the mouse when using Qt, as
12815 Qt grabs and releases it sensibly. In particular, Qt grabs the
12816 mouse when a mouse button is pressed and keeps it until the last
12817 button is released.
12818
12819 \note Only visible widgets can grab mouse input. If isVisible()
12820 returns \c false for a widget, that widget cannot call grabMouse().
12821
12822 \note On Windows, grabMouse() only works when the mouse is inside a window
12823 owned by the process.
12824 On \macos, grabMouse() only works when the mouse is inside the frame of that widget.
12825
12826 \sa releaseMouse(), grabKeyboard(), releaseKeyboard()
12827*/
12828void QWidget::grabMouse()
12829{
12830 grabMouseForWidget(this);
12831}
12832
12833/*!
12834 \fn void QWidget::grabMouse(const QCursor &cursor)
12835 \overload grabMouse()
12836
12837 Grabs the mouse input and changes the cursor shape.
12838
12839 The cursor will assume shape \a cursor (for as long as the mouse
12840 focus is grabbed) and this widget will be the only one to receive
12841 mouse events until releaseMouse() is called().
12842
12843 \warning Grabbing the mouse might lock the terminal.
12844
12845 \note See the note in QWidget::grabMouse().
12846
12847 \sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
12848*/
12849#ifndef QT_NO_CURSOR
12850void QWidget::grabMouse(const QCursor &cursor)
12851{
12852 grabMouseForWidget(this, &cursor);
12853}
12854#endif
12855
12856bool QWidgetPrivate::stealMouseGrab(bool grab)
12857{
12858 // This is like a combination of grab/releaseMouse() but with error checking
12859 // and it has no effect on the result of mouseGrabber().
12860 Q_Q(QWidget);
12861 QWindow *window = grabberWindow(q);
12862 return window ? window->setMouseGrabEnabled(grab) : false;
12863}
12864
12865/*!
12866 \fn void QWidget::releaseMouse()
12867
12868 Releases the mouse grab.
12869
12870 \sa grabMouse(), grabKeyboard(), releaseKeyboard()
12871*/
12872void QWidget::releaseMouse()
12873{
12874 releaseMouseGrabOfWidget(this);
12875}
12876
12877/*!
12878 \fn void QWidget::grabKeyboard()
12879
12880 Grabs the keyboard input.
12881
12882 This widget receives all keyboard events until releaseKeyboard()
12883 is called; other widgets get no keyboard events at all. Mouse
12884 events are not affected. Use grabMouse() if you want to grab that.
12885
12886 The focus widget is not affected, except that it doesn't receive
12887 any keyboard events. setFocus() moves the focus as usual, but the
12888 new focus widget receives keyboard events only after
12889 releaseKeyboard() is called.
12890
12891 If a different widget is currently grabbing keyboard input, that
12892 widget's grab is released first.
12893
12894 \sa releaseKeyboard(), grabMouse(), releaseMouse(), focusWidget()
12895*/
12896void QWidget::grabKeyboard()
12897{
12898 if (keyboardGrb)
12899 keyboardGrb->releaseKeyboard();
12900 if (QWindow *window = grabberWindow(this))
12901 window->setKeyboardGrabEnabled(true);
12902 keyboardGrb = this;
12903}
12904
12905bool QWidgetPrivate::stealKeyboardGrab(bool grab)
12906{
12907 // This is like a combination of grab/releaseKeyboard() but with error
12908 // checking and it has no effect on the result of keyboardGrabber().
12909 Q_Q(QWidget);
12910 QWindow *window = grabberWindow(q);
12911 return window ? window->setKeyboardGrabEnabled(grab) : false;
12912}
12913
12914/*!
12915 \fn void QWidget::releaseKeyboard()
12916
12917 Releases the keyboard grab.
12918
12919 \sa grabKeyboard(), grabMouse(), releaseMouse()
12920*/
12921void QWidget::releaseKeyboard()
12922{
12923 if (keyboardGrb == this) {
12924 if (QWindow *window = grabberWindow(this))
12925 window->setKeyboardGrabEnabled(false);
12926 keyboardGrb = nullptr;
12927 }
12928}
12929
12930/*!
12931 \fn QWidget *QWidget::mouseGrabber()
12932
12933 Returns the widget that is currently grabbing the mouse input.
12934
12935 If no widget in this application is currently grabbing the mouse,
12936 \nullptr is returned.
12937
12938 \sa grabMouse(), keyboardGrabber()
12939*/
12940QWidget *QWidget::mouseGrabber()
12941{
12942 return qt_mouseGrb;
12943}
12944
12945/*!
12946 \fn QWidget *QWidget::keyboardGrabber()
12947
12948 Returns the widget that is currently grabbing the keyboard input.
12949
12950 If no widget in this application is currently grabbing the
12951 keyboard, \nullptr is returned.
12952
12953 \sa grabMouse(), mouseGrabber()
12954*/
12955QWidget *QWidget::keyboardGrabber()
12956{
12957 return keyboardGrb;
12958}
12959
12960/*!
12961 \fn void QWidget::activateWindow()
12962
12963 Sets the top-level widget containing this widget to be the active
12964 window.
12965
12966 An active window is a visible top-level window that has the
12967 keyboard input focus.
12968
12969 This function performs the same operation as clicking the mouse on
12970 the title bar of a top-level window. On X11, the result depends on
12971 the Window Manager. If you want to ensure that the window is
12972 stacked on top as well you should also call raise(). Note that the
12973 window must be visible, otherwise activateWindow() has no effect.
12974
12975 On Windows, if you are calling this when the application is not
12976 currently the active one then it will not make it the active
12977 window. It will change the color of the taskbar entry to indicate
12978 that the window has changed in some way. This is because Microsoft
12979 does not allow an application to interrupt what the user is currently
12980 doing in another application.
12981
12982 \sa isActiveWindow(), window(), show()
12983*/
12984void QWidget::activateWindow()
12985{
12986 QWindow *const wnd = window()->windowHandle();
12987
12988 if (wnd)
12989 wnd->requestActivate();
12990}
12991
12992/*!
12993
12994 Internal implementation of the virtual QPaintDevice::metric()
12995 function.
12996
12997 \a m is the metric to get.
12998*/
12999int QWidget::metric(PaintDeviceMetric m) const
13000{
13001 QScreen *screen = this->screen();
13002
13003 if (!screen) {
13004 if (m == PdmDpiX || m == PdmDpiY)
13005 return 72;
13006 return QPaintDevice::metric(m);
13007 }
13008
13009 auto resolveDevicePixelRatio = [this, screen]() -> qreal {
13010
13011 // Note: keep in sync with QBackingStorePrivate::backingStoreDevicePixelRatio()!
13012 static bool downscale = qEnvironmentVariableIntValue("QT_WIDGETS_HIGHDPI_DOWNSCALE") > 0;
13013 QWindow *window = this->window()->windowHandle();
13014 if (window)
13015 return downscale ? std::ceil(window->devicePixelRatio()) : window->devicePixelRatio();
13016 return screen->devicePixelRatio();
13017 };
13018
13019 switch (m) {
13020 case PdmWidth:
13021 return data->crect.width();
13022 case PdmWidthMM:
13023 return data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
13024 case PdmHeight:
13025 return data->crect.height();
13026 case PdmHeightMM:
13027 return data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
13028 case PdmDepth:
13029 return screen->depth();
13030 case PdmDpiX:
13031 for (const QWidget *p = this; p; p = p->parentWidget()) {
13032 if (p->d_func()->extra && p->d_func()->extra->customDpiX)
13033 return p->d_func()->extra->customDpiX;
13034 }
13035 return qRound(screen->logicalDotsPerInchX());
13036 case PdmDpiY:
13037 for (const QWidget *p = this; p; p = p->parentWidget()) {
13038 if (p->d_func()->extra && p->d_func()->extra->customDpiY)
13039 return p->d_func()->extra->customDpiY;
13040 }
13041 return qRound(screen->logicalDotsPerInchY());
13042 case PdmPhysicalDpiX:
13043 return qRound(screen->physicalDotsPerInchX());
13044 case PdmPhysicalDpiY:
13045 return qRound(screen->physicalDotsPerInchY());
13046 case PdmDevicePixelRatio:
13047 return resolveDevicePixelRatio();
13048 case PdmDevicePixelRatioScaled:
13049 return QPaintDevice::devicePixelRatioFScale() * resolveDevicePixelRatio();
13050 case PdmDevicePixelRatioF_EncodedA:
13051 Q_FALLTHROUGH();
13052 case PdmDevicePixelRatioF_EncodedB:
13053 return QPaintDevice::encodeMetricF(m, resolveDevicePixelRatio());
13054 default:
13055 break;
13056 }
13057 return QPaintDevice::metric(m);
13058}
13059
13060/*!
13061 Initializes the \a painter pen, background and font to the same as
13062 the given widget's. This function is called automatically when the
13063 painter is opened on a QWidget.
13064*/
13065void QWidget::initPainter(QPainter *painter) const
13066{
13067 const QPalette &pal = palette();
13068 painter->d_func()->state->pen = QPen(pal.brush(foregroundRole()), 1);
13069 painter->d_func()->state->bgBrush = pal.brush(backgroundRole());
13070 QFont f(font(), const_cast<QWidget *>(this));
13071 painter->d_func()->state->deviceFont = f;
13072 painter->d_func()->state->font = f;
13073}
13074
13075/*!
13076 \internal
13077
13078 Do PaintDevice rendering with the specified \a offset.
13079*/
13080QPaintDevice *QWidget::redirected(QPoint *offset) const
13081{
13082 return d_func()->redirected(offset);
13083}
13084
13085/*!
13086 \internal
13087
13088 A painter that is shared among other instances of QPainter.
13089*/
13090QPainter *QWidget::sharedPainter() const
13091{
13092 // Someone sent a paint event directly to the widget
13093 if (!d_func()->redirectDev)
13094 return nullptr;
13095
13096 QPainter *sp = d_func()->sharedPainter();
13097 if (!sp || !sp->isActive())
13098 return nullptr;
13099
13100 if (sp->paintEngine()->paintDevice() != d_func()->redirectDev)
13101 return nullptr;
13102
13103 return sp;
13104}
13105
13106/*!
13107 \fn void QWidget::setMask(const QRegion &region)
13108 \overload
13109
13110 Causes only the parts of the widget which overlap \a region to be
13111 visible. If the region includes pixels outside the rect() of the
13112 widget, window system controls in that area may or may not be
13113 visible, depending on the platform.
13114
13115 Since QRegion allows arbitrarily complex regions to be created, widget
13116 masks can be made to suit the most unconventionally-shaped windows, and
13117 even allow widgets to be displayed with holes in them. Note that this
13118 effect can be slow if the region is particularly complex.
13119
13120 Widget masks are used to hint to the window system that the application
13121 does not want mouse events for areas outside the mask. On most systems,
13122 they also result in coarse visual clipping. To get smooth window edges, use
13123 translucent background and anti-aliased painting instead, as shown in the
13124 \l{Translucent Background} example.
13125
13126 \sa windowOpacity
13127*/
13128void QWidget::setMask(const QRegion &newMask)
13129{
13130 Q_D(QWidget);
13131
13132 d->createExtra();
13133 if (newMask == d->extra->mask)
13134 return;
13135
13136#ifndef QT_NO_BACKINGSTORE
13137 const QRegion oldMask(d->extra->mask);
13138#endif
13139
13140 d->extra->mask = newMask;
13141 d->extra->hasMask = !newMask.isEmpty();
13142
13143 if (!testAttribute(Qt::WA_WState_Created))
13144 return;
13145
13146 d->setMask_sys(newMask);
13147
13148#ifndef QT_NO_BACKINGSTORE
13149 if (!isVisible())
13150 return;
13151
13152 if (!d->extra->hasMask) {
13153 // Mask was cleared; update newly exposed area.
13154 QRegion expose(rect());
13155 expose -= oldMask;
13156 if (!expose.isEmpty()) {
13157 d->setDirtyOpaqueRegion();
13158 update(expose);
13159 }
13160 return;
13161 }
13162
13163 if (!isWindow()) {
13164 // Update newly exposed area on the parent widget.
13165 QRegion parentExpose(rect());
13166 parentExpose -= newMask;
13167 if (!parentExpose.isEmpty()) {
13168 d->setDirtyOpaqueRegion();
13169 parentExpose.translate(data->crect.topLeft());
13170 parentWidget()->update(parentExpose);
13171 }
13172
13173 // Update newly exposed area on this widget
13174 if (!oldMask.isEmpty())
13175 update(newMask - oldMask);
13176 }
13177#endif
13178}
13179
13180void QWidgetPrivate::setMask_sys(const QRegion &region)
13181{
13182 Q_Q(QWidget);
13183 if (QWindow *window = q->windowHandle())
13184 window->setMask(region);
13185}
13186
13187/*!
13188 \fn void QWidget::setMask(const QBitmap &bitmap)
13189
13190 Causes only the pixels of the widget for which \a bitmap has a
13191 corresponding 1 bit to be visible. If the region includes pixels
13192 outside the rect() of the widget, window system controls in that
13193 area may or may not be visible, depending on the platform.
13194
13195 Note that this effect can be slow if the region is particularly
13196 complex.
13197
13198 The following code shows how an image with an alpha channel can be
13199 used to generate a mask for a widget:
13200
13201 \snippet widget-mask/main.cpp 0
13202
13203 The label shown by this code is masked using the image it contains,
13204 giving the appearance that an irregularly-shaped image is being drawn
13205 directly onto the screen.
13206
13207 Masked widgets receive mouse events only on their visible
13208 portions.
13209
13210 \sa clearMask(), windowOpacity()
13211*/
13212void QWidget::setMask(const QBitmap &bitmap)
13213{
13214 setMask(QRegion(bitmap));
13215}
13216
13217/*!
13218 \fn void QWidget::clearMask()
13219
13220 Removes any mask set by setMask().
13221
13222 \sa setMask()
13223*/
13224void QWidget::clearMask()
13225{
13226 Q_D(QWidget);
13227 if (!d->extra || !d->extra->hasMask)
13228 return;
13229 setMask(QRegion());
13230}
13231
13232void QWidgetPrivate::setWidgetParentHelper(QObject *widgetAsObject, QObject *newParent)
13233{
13234 Q_ASSERT(widgetAsObject->isWidgetType());
13235 Q_ASSERT(!newParent || newParent->isWidgetType());
13236 QWidget *widget = static_cast<QWidget*>(widgetAsObject);
13237 widget->setParent(static_cast<QWidget*>(newParent));
13238}
13239
13240std::string QWidgetPrivate::flagsForDumping() const
13241{
13242 Q_Q(const QWidget);
13243 std::string flags = QObjectPrivate::flagsForDumping();
13244 if (QApplication::focusWidget() == q)
13245 flags += 'F';
13246 if (q->isVisible()) {
13247 std::stringstream s;
13248 s << '<'
13249 << q->width() << 'x' << q->height()
13250 << std::showpos << q->x() << q->y()
13251 << '>';
13252 flags += s.str();
13253 } else {
13254 flags += 'I';
13255 }
13256 return flags;
13257}
13258
13259void QWidgetPrivate::setNetWmWindowTypes(bool skipIfMissing)
13260{
13261#if QT_CONFIG(xcb)
13262 Q_Q(QWidget);
13263
13264 if (!q->windowHandle())
13265 return;
13266
13267 QXcbWindow::WindowTypes wmWindowType = QXcbWindow::None;
13268 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop))
13269 wmWindowType |= QXcbWindow::Desktop;
13270 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock))
13271 wmWindowType |= QXcbWindow::Dock;
13272 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar))
13273 wmWindowType |= QXcbWindow::Toolbar;
13274 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu))
13275 wmWindowType |= QXcbWindow::Menu;
13276 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility))
13277 wmWindowType |= QXcbWindow::Utility;
13278 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash))
13279 wmWindowType |= QXcbWindow::Splash;
13280 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog))
13281 wmWindowType |= QXcbWindow::Dialog;
13282 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu))
13283 wmWindowType |= QXcbWindow::DropDownMenu;
13284 if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu))
13285 wmWindowType |= QXcbWindow::PopupMenu;
13286 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip))
13287 wmWindowType |= QXcbWindow::Tooltip;
13288 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification))
13289 wmWindowType |= QXcbWindow::Notification;
13290 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo))
13291 wmWindowType |= QXcbWindow::Combo;
13292 if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND))
13293 wmWindowType |= QXcbWindow::Dnd;
13294
13295 if (wmWindowType == QXcbWindow::None && skipIfMissing)
13296 return;
13297
13298 if (auto *xcbWindow = dynamic_cast<QXcbWindow*>(q->windowHandle()->handle()))
13299 xcbWindow->setWindowType(wmWindowType);
13300#else
13301 Q_UNUSED(skipIfMissing);
13302#endif
13303}
13304
13305/*!
13306 \internal
13307 \return \c true, if a child with \param policy exists and isn't a child of \param excludeChildrenOf.
13308 Return false otherwise.
13309 */
13310bool QWidgetPrivate::hasChildWithFocusPolicy(Qt::FocusPolicy policy, const QWidget *excludeChildrenOf) const
13311{
13312 Q_Q(const QWidget);
13313 const QWidgetList &children = q->findChildren<QWidget *>(Qt::FindChildrenRecursively);
13314 for (const auto *child : children) {
13315 if (child->focusPolicy() == policy && child->isEnabled()
13316 && (!excludeChildrenOf || !excludeChildrenOf->isAncestorOf(child))) {
13317 return true;
13318 }
13319 }
13320 return false;
13321}
13322
13323#ifndef QT_NO_DEBUG_STREAM
13324
13325namespace {
13326QDebug operator<<(QDebug debug, const WidgetAttributes &attributes)
13327{
13328 const QDebugStateSaver saver(debug);
13329 debug.nospace();
13330 debug << '[';
13331 if (const QWidget *widget = attributes.widget) {
13332 const QMetaObject *qtMo = qt_getEnumMetaObject(Qt::WA_AttributeCount);
13333 const QMetaEnum me = qtMo->enumerator(qtMo->indexOfEnumerator("WidgetAttribute"));
13334 int count = 0;
13335 for (int a = 0; a < Qt::WA_AttributeCount; ++a) {
13336 if (widget->testAttribute(static_cast<Qt::WidgetAttribute>(a))) {
13337 if (count++)
13338 debug << ',';
13339 debug << me.valueToKey(a);
13340 }
13341 }
13342 }
13343 debug << ']';
13344 return debug;
13345}
13346}
13347
13348QDebug operator<<(QDebug debug, const QWidget *widget)
13349{
13350 const QDebugStateSaver saver(debug);
13351 debug.nospace();
13352 if (widget) {
13353 debug << widget->metaObject()->className() << '(' << (const void *)widget;
13354 if (!widget->objectName().isEmpty())
13355 debug << ", name=" << widget->objectName();
13356 if (debug.verbosity() > 2) {
13357 const QRect geometry = widget->geometry();
13358 const QRect frameGeometry = widget->frameGeometry();
13359 if (widget->isVisible())
13360 debug << ", visible";
13361 if (!widget->isEnabled())
13362 debug << ", disabled";
13363 debug << ", states=" << widget->windowState()
13364 << ", type=" << widget->windowType() << ", flags=" << widget->windowFlags();
13365 debug << ", attributes=" << WidgetAttributes{widget};
13366 if (widget->isWindow())
13367 debug << ", window";
13368 debug << ", " << geometry.width() << 'x' << geometry.height()
13369 << Qt::forcesign << geometry.x() << geometry.y() << Qt::noforcesign;
13370 if (frameGeometry != geometry) {
13371 const QMargins margins(geometry.x() - frameGeometry.x(),
13372 geometry.y() - frameGeometry.y(),
13373 frameGeometry.right() - geometry.right(),
13374 frameGeometry.bottom() - geometry.bottom());
13375 debug << ", margins=" << margins;
13376 }
13377 debug << ", devicePixelRatio=" << widget->devicePixelRatio();
13378 if (const WId wid = widget->internalWinId())
13379 debug << ", winId=0x" << Qt::hex << wid << Qt::dec;
13380 }
13381 debug << ')';
13382 } else {
13383 debug << "QWidget(0x0)";
13384 }
13385 return debug;
13386}
13387#endif // !QT_NO_DEBUG_STREAM
13388
13389
13390// *************************** Focus abstraction ************************************
13391
13392#define FOCUS_NEXT(w) w->d_func()->focus_next
13393#define FOCUS_PREV(w) w->d_func()->focus_prev
13394
13395/*!
13396 \internal
13397 \return next or previous element in the focus chain, depending on
13398 \param direction, irrespective of focus proxies or widgets with Qt::NoFocus.
13399 */
13400QWidget *QWidgetPrivate::nextPrevElementInFocusChain(FocusDirection direction) const
13401{
13402 Q_Q(const QWidget);
13403 return direction == FocusDirection::Next ? FOCUS_NEXT(q) : FOCUS_PREV(q);
13404}
13405
13406/*!
13407 \internal
13408 Removes a widget from the focus chain, respecting the flags set in \param rules.
13409 \list
13410 \li EnsureFocusOut: If the widget has input focus, transfer focus to the next or previous widget
13411 in the focus chain, depending on \param direction.
13412 \li RemoveInconsistent: Remove the widget, even if its focus chain is inconsistent.
13413 \li AssertConsistency: qFatal, if the focus chain is inconsistent. This is used in the QWidget destructor.
13414 \endlist
13415 \return \c true if the widget has been removed, otherwise \c false.
13416 */
13417bool QWidgetPrivate::removeFromFocusChain(FocusChainRemovalRules rules, FocusDirection direction)
13418{
13419 Q_Q(QWidget);
13420 if (!isFocusChainConsistent()) {
13421#ifdef QT_DEBUG
13422 if (rules.testFlag(FocusChainRemovalRule::AssertConsistency))
13423 qFatal() << q << "has inconsistent focus chain.";
13424#endif
13425 qCDebug(lcWidgetFocus) << q << "wasn't removed, because of inconsistent focus chain.";
13426 return false;
13427 }
13428
13429 if (!isInFocusChain()) {
13430 qCDebug(lcWidgetFocus) << q << "wasn't removed, because it is not part of a focus chain.";
13431 return false;
13432 }
13433
13434 if (rules.testFlag(FocusChainRemovalRule::EnsureFocusOut))
13435 q->focusNextPrevChild(direction == FocusDirection::Next);
13436
13439 initFocusChain();
13440 qCDebug(lcWidgetFocus) << q << "removed from focus chain.";
13441 return true;
13442}
13443
13444/*!
13445 \internal
13446 Initialises the focus chain by making the widget point to itself.
13447 */
13448void QWidgetPrivate::initFocusChain()
13449{
13450 Q_Q(QWidget);
13451 qCDebug(lcWidgetFocus) << "Initializing focus chain of" << q;
13452 FOCUS_PREV(q) = q;
13453 FOCUS_NEXT(q) = q;
13454}
13455
13456/*!
13457 \internal
13458 Reads QWidget children, which are not part of a focus chain yet.
13459 Inserts them into the focus chain before or after the widget,
13460 depending on \param direction and in the order of their creation.
13461 This is used, when QWidget::setParent() causes a widget to change toplevel windows.
13462 */
13463void QWidgetPrivate::reparentFocusChildren(FocusDirection direction)
13464{
13465 Q_Q(QWidget);
13466
13467 // separate the focus chain into new (children of myself) and old (the rest)
13468 QWidget *firstOld = nullptr;
13469 QWidget *lastOld = nullptr; // last in the old list
13470 QWidget *lastNew = q; // last in the new list
13471 bool prevWasNew = true;
13472 QWidget *widget = nextPrevElementInFocusChain(direction);
13473
13474 // For efficiency, do not maintain the list invariant inside the loop.
13475 // Append items to the relevant list, and we optimize by not changing pointers,
13476 // when subsequent items are going into the same list.
13477 while (widget != q) {
13478 bool currentIsNew = q->isAncestorOf(widget);
13479 if (currentIsNew) {
13480 if (!prevWasNew) {
13481 // previous was old => append to new list
13482 FOCUS_NEXT(lastNew) = widget;
13483 FOCUS_PREV(widget) = lastNew;
13484 }
13485 lastNew = widget;
13486 } else {
13487 if (prevWasNew) {
13488 // prev was new => append to old list, if it exists
13489 if (lastOld) {
13490 FOCUS_NEXT(lastOld) = widget;
13491 FOCUS_PREV(widget) = lastOld;
13492 } else {
13493 // start the old list
13494 firstOld = widget;
13495 }
13496 }
13497 lastOld = widget;
13498 }
13499 widget = widget->d_func()->nextPrevElementInFocusChain(direction);
13500 prevWasNew = currentIsNew;
13501 }
13502
13503 // repair old list:
13504 if (firstOld) {
13505 FOCUS_NEXT(lastOld) = firstOld;
13506 FOCUS_PREV(firstOld) = lastOld;
13507 }
13508
13509 if (!q->isWindow()) {
13510 QWidget *topLevel = q->window();
13511 // insert new chain into toplevel's chain
13512 QWidget *prev = FOCUS_PREV(topLevel);
13513 FOCUS_PREV(topLevel) = lastNew;
13514 FOCUS_NEXT(prev) = q;
13515 FOCUS_PREV(q) = prev;
13516 FOCUS_NEXT(lastNew) = topLevel;
13517 } else {
13518 // repair new list
13519 FOCUS_NEXT(lastNew) = q;
13520 FOCUS_PREV(q) = lastNew;
13521 }
13522}
13523
13524/*!
13525 \internal
13526 Inserts a widget into the focus chain before or after \param position, depending on
13527 \param direction.
13528 \return \c true, if the insertion has changed the focus chain, otherwise \c false.
13529 */
13530bool QWidgetPrivate::insertIntoFocusChain(FocusDirection direction, QWidget *position)
13531{
13532 Q_Q(QWidget);
13533 Q_ASSERT(position);
13534 QWidget *next = FOCUS_NEXT(q);
13535 QWidget *previous = FOCUS_PREV(q);
13536
13537 switch (direction) {
13538 case FocusDirection::Next:
13539 if (previous == position) {
13540 qCDebug(lcWidgetFocus) << "No-op insertion." << q << "is already before" << position;
13541 return false;
13542 }
13543
13544 removeFromFocusChain(FocusChainRemovalRule::AssertConsistency);
13545
13546 FOCUS_NEXT(q) = FOCUS_NEXT(position);
13547 FOCUS_PREV(FOCUS_NEXT(position)) = q;
13548 FOCUS_NEXT(position) = q;
13549 FOCUS_PREV(q) = position;
13550 qCDebug(lcWidgetFocus) << q << "inserted after" << position;
13551 break;
13552
13553 case FocusDirection::Previous:
13554 if (next == position) {
13555 qCDebug(lcWidgetFocus) << "No-op insertion." << q << "is already after" << position;
13556 return false;
13557 }
13558
13559 removeFromFocusChain(FocusChainRemovalRule::AssertConsistency);
13560
13561 FOCUS_PREV(q) = FOCUS_PREV(position);
13562 FOCUS_NEXT(FOCUS_PREV(position)) = q;
13563 FOCUS_PREV(position) = q;
13564 FOCUS_NEXT(q) = position;
13565 qCDebug(lcWidgetFocus) << q << "inserted before" << position;
13566 break;
13567 }
13568
13569 Q_ASSERT(isFocusChainConsistent());
13570 return true;
13571}
13572
13573/*!
13574 \internal
13575 Convenience override to insert a QWidgetList \param toBeInserted into the focus chain
13576 before or after \param position, depending on \param direction.
13577 \return \c true, if the insertion has changed the focus chain, otherwise \c false.
13578 \note
13579 \param toBeInserted must be a consistent focus chain.
13580 */
13581bool QWidgetPrivate::insertIntoFocusChain(const QWidgetList &toBeInserted,
13582 FocusDirection direction, QWidget *position)
13583{
13584 if (toBeInserted.isEmpty()) {
13585 qCDebug(lcWidgetFocus) << "No-op insertion of an empty list";
13586 return false;
13587 }
13588
13589 Q_ASSERT_X(!toBeInserted.contains(position),
13590 Q_FUNC_INFO,
13591 "Coding error: toBeInserted contains position");
13592
13593 QWidget *first = toBeInserted.constFirst();
13594 QWidget *last = toBeInserted.constLast();
13595
13596 // Call QWidget override to log accordingly
13597 if (toBeInserted.count() == 1)
13598 return first->d_func()->insertIntoFocusChain(direction, position);
13599
13600 Q_ASSERT(first != last);
13601 switch (direction) {
13602 case FocusDirection::Previous:
13603 if (FOCUS_PREV(position) == last) {
13604 qCDebug(lcWidgetFocus) << "No-op insertion." << toBeInserted << "is already before"
13605 << position;
13606 return false;
13607 }
13608 FOCUS_NEXT(FOCUS_PREV(position)) = first;
13609 FOCUS_PREV(first) = FOCUS_PREV(position);
13610 FOCUS_NEXT(last) = position;
13611 FOCUS_PREV(position) = last;
13612 qCDebug(lcWidgetFocus) << toBeInserted << "inserted before" << position;
13613 break;
13614 case FocusDirection::Next:
13615 if (FOCUS_PREV(position) == last) {
13616 qCDebug(lcWidgetFocus) << "No-op insertion." << toBeInserted << "is already after"
13617 << position;
13618 return false;
13619 }
13620 FOCUS_PREV(FOCUS_NEXT(position)) = last;
13621 FOCUS_NEXT(last) = FOCUS_NEXT(position);
13622 FOCUS_PREV(first) = position;
13623 FOCUS_NEXT(position) = first;
13624 qCDebug(lcWidgetFocus) << toBeInserted << "inserted after" << position;
13625 break;
13626 }
13627
13628 Q_ASSERT(position->d_func()->isFocusChainConsistent());
13629 return true;
13630}
13631
13632/*!
13633 \internal
13634 \return a QWidgetList, representing the part of the focus chain,
13635 starting with \param from and ending with \param to, in \param direction.
13636 */
13637QWidgetList focusPath(QWidget *from, QWidget *to, QWidgetPrivate::FocusDirection direction)
13638{
13639 QWidgetList path({from});
13640 if (from == to)
13641 return path;
13642
13643 QWidget *current = from;
13644 do {
13645 switch (direction) {
13646 case QWidgetPrivate::FocusDirection::Previous:
13647 current = current->previousInFocusChain();
13648 break;
13649 case QWidgetPrivate::FocusDirection::Next:
13650 current = current->nextInFocusChain();
13651 break;
13652 }
13653 if (path.contains(current))
13654 return QWidgetList();
13655 path << current;
13656 } while (current != to);
13657
13658 return path;
13659}
13660
13661/*!
13662 \internal
13663 Removes the part from the focus chain starting with \param from and ending with \param to,
13664 in \param direction.
13665 \return removed part as a QWidgetList.
13666 */
13667QWidgetList QWidgetPrivate::takeFromFocusChain(QWidget *from,
13668 QWidget *to,
13669 FocusDirection direction)
13670{
13671 // Check if there is a path from->to in direction
13672 const QWidgetList path = focusPath(from, to , direction);
13673 if (path.isEmpty()) {
13674 qCDebug(lcWidgetFocus) << "No-op removal. Focus chain from" << from << "doesn't lead to " << to;
13675 return QWidgetList();
13676 }
13677
13678 QWidget *first = path.constFirst();
13679 QWidget *last = path.constLast();
13680 if (first == last) {
13681 first->d_func()->removeFromFocusChain();
13682 return QWidgetList({first});
13683 }
13684
13685 FOCUS_NEXT(FOCUS_PREV(first)) = FOCUS_NEXT(last);
13686 FOCUS_PREV(FOCUS_NEXT(last)) = FOCUS_PREV(first);
13687 FOCUS_PREV(first) = last;
13688 FOCUS_NEXT(last) = first;
13689 qCDebug(lcWidgetFocus) << path << "removed from focus chain";
13690 return path;
13691}
13692
13693/*!
13694 \internal
13695 \return The last focus child of the widget, traversing the focus chain no further than
13696 \param noFurtherThan.
13697 */
13698QWidget *QWidgetPrivate::determineLastFocusChild(QWidget *noFurtherThan)
13699{
13700 Q_Q(QWidget);
13701 // Since we need to repeat the same logic for both 'first' and 'second', we add a function
13702 // that determines the last focus child for a widget, taking proxies and compound widgets into
13703 // account. If the target is not a compound widget (it doesn't have a focus proxy that points
13704 // to a child), 'lastFocusChild' will be set to the target itself.
13705 QWidget *lastFocusChild = q;
13706
13707 QWidget *focusProxy = deepestFocusProxy();
13708 if (!focusProxy) {
13709 // QTBUG-81097: Another case is possible here. We can have a child
13710 // widget, that sets its focusProxy() to the parent (target).
13711 // An example of such widget is a QLineEdit, nested into
13712 // a QAbstractSpinBox. In this case such widget should be considered
13713 // the last focus child.
13714 for (auto *object : std::as_const(q->children())) {
13715 QWidget *w = qobject_cast<QWidget *>(object);
13716 if (w && w->focusProxy() == q) {
13717 lastFocusChild = w;
13718 break;
13719 }
13720 }
13721 } else if (q->isAncestorOf(focusProxy)) {
13722 lastFocusChild = focusProxy;
13723 for (QWidget *focusNext = lastFocusChild->nextInFocusChain();
13724 focusNext != focusProxy && q->isAncestorOf(focusNext)
13725 && focusNext->window() == focusProxy->window();
13726 focusNext = focusNext->nextInFocusChain()) {
13727 if (focusNext == noFurtherThan)
13728 break;
13729 if (focusNext->focusPolicy() != Qt::NoFocus)
13730 lastFocusChild = focusNext;
13731 }
13732 }
13733 return lastFocusChild;
13734};
13735
13736/*!
13737 \internal
13738 \return \c true, if the widget is part of a focus chain and \c false otherwise.
13739 A widget is considered to be part of a focus chain, neither FOCUS_NEXT, nor FOCUS_PREV
13740 are pointing to the widget itself.
13741
13742 \note
13743 This method doesn't check the consistency of the focus chain.
13744 If multiple widgets have been removed from the focus chain by takeFromFocusChain(),
13745 isInFocusChain() will return \c true for all of those widgets, even if they represent
13746 an inconsistent focus chain.
13747 */
13748bool QWidgetPrivate::isInFocusChain() const
13749{
13750 Q_Q(const QWidget);
13751 return !(FOCUS_NEXT(q) == q && FOCUS_PREV(q) == q);
13752}
13753
13754/*!
13755 \internal
13756 A focus chain is consistent, when it is circular: Following the chain in either direction
13757 has to return to the beginning. This is why a newly constructed widget points to itself,
13758 when the focus chain has been initialized. A newly constructed widget is considered to have
13759 a consistent focus chain, while not being part of a focus chain.
13760
13761 The method always returns \c true, when the logging category "qt.widgets.focus" is disabled.
13762 When it is enabled, the method returns \c true early, if a widget is pointing to itself.
13763 It returns \c false, if one of the following is detected:
13764 \list
13765 \li nullptr found in a previous/next pointer.
13766 \li broken chain: widget A is B's previous, but B isn't A's next.
13767 \li chain isn't closed: starting at A doesn't lead back to A.
13768 \endlist
13769 It return \c true, if none of the above is observed.
13770
13771 \note
13772 The focus chain is checked only in forward direction.
13773 This is sufficient, because the check for a broken chain asserts consistent paths
13774 in both directions.
13775 */
13776bool QWidgetPrivate::isFocusChainConsistent() const
13777{
13778 Q_Q(const QWidget);
13779 const bool skip = !QLoggingCategory("qt.widgets.focus").isDebugEnabled();
13780 if (skip)
13781 return true;
13782
13783 if (!isInFocusChain())
13784 return true;
13785
13786 const QWidget *position = q;
13787
13788 for (int i = 0; i < QApplication::allWidgets().count(); ++i) {
13789 if (!FOCUS_PREV(position) || !FOCUS_NEXT(position)) {
13790 qCDebug(lcWidgetFocus) << "Nullptr found at:" << position
13791 << "Previous pointing to" << FOCUS_PREV(position)
13792 << "Next pointing to" << FOCUS_NEXT(position);
13793 return false;
13794 }
13795 if (!(FOCUS_PREV(FOCUS_NEXT(position)) == position
13796 && FOCUS_NEXT(FOCUS_PREV(position)) == position)) {
13797 qCDebug(lcWidgetFocus) << "Inconsistent focus chain at:" << position
13798 << "Previous pointing to" << FOCUS_PREV(FOCUS_NEXT(position))
13799 << "Next pointing to" << FOCUS_NEXT(FOCUS_PREV(position));
13800 return false;
13801 }
13802 position = FOCUS_NEXT(position);
13803 if (position == q)
13804 return true;
13805
13806 }
13807
13808 qCDebug(lcWidgetFocus) << "Focus chain leading from" << q << "to" << position << "is not closed.";
13809 return false;
13810}
13811
13812#undef FOCUS_NEXT
13813#undef FOCUS_PREV
13814
13815
13816QT_END_NAMESPACE
13817
13818#include "moc_qwidget.cpp"
13819#include "moc_qwidget_p.cpp"
friend class QWidgetPrivate
friend class QWidget
Definition qpainter.h:423
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")
void qt_qpa_set_cursor(QWidget *w, bool force)
Definition qwidget.cpp:5022
#define qApp
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
static bool canMapPosition(QWindow *window)
static void unsetCursor(QWidget *w)
Definition qwidget.cpp:5016
void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
Definition qwidget.cpp:1237
QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget)
Returns a modified window title with the [*] place holder replaced according to the rules described i...
Definition qwidget.cpp:6000
static void sendResizeEvents(QWidget *target)
Definition qwidget.cpp:5196
static void applyCursor(QWidget *w, const QCursor &c)
Definition qwidget.cpp:5010
#define FOCUS_PREV(w)
static bool isEmbedded(const QWindow *w)
Definition qwidget.cpp:6637
static void releaseMouseGrabOfWidget(QWidget *widget)
#define FOCUS_NEXT(w)
static void grabMouseForWidget(QWidget *widget, const QCursor *cursor=nullptr)
QWidget * qt_button_down
Definition qwidget.cpp:2307
static MapToGlobalTransformResult mapToGlobalTransform(const QWidget *w)
static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data, QWidgetPrivate *d)
void qSendWindowChangeToTextureChildrenRecursively(QWidget *widget, QEvent::Type eventType)
static bool qRectIntersects(const QRect &r1, const QRect &r2)
Definition qwidget.cpp:98
bool qt_sendSpontaneousEvent(QObject *, QEvent *)
QWidgetList focusPath(QWidget *from, QWidget *to, QWidgetPrivate::FocusDirection direction)
bool q_evaluateRhiConfig(const QWidget *w, QPlatformBackingStoreRhiConfig *outConfig, QSurface::SurfaceType *outType)
Definition qwidget.cpp:1117
static QWidget * keyboardGrb
QWidget * qt_mouseGrb
static bool mouseGrabWithCursor
static QWindow * grabberWindow(const QWidget *w)
static void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
Definition qwidget.cpp:2226
static bool q_evaluateRhiConfigRecursive(const QWidget *w, QPlatformBackingStoreRhiConfig *outConfig, QSurface::SurfaceType *outType)
Definition qwidget.cpp:1091
#define QWIDGETSIZE_MAX
Definition qwidget.h:921
static void cleanup(QWidget *that, QWidgetPrivate *d)
Definition qwidget.cpp:808