1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtWidgets module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qapplication.h"
42#include "qapplication_p.h"
43#include "qbrush.h"
44#include "qcursor.h"
45#include "qdesktopwidget_p.h"
46#include "qevent.h"
47#include "qlayout.h"
48#if QT_CONFIG(menu)
49#include "qmenu.h"
50#endif
51#include "qmetaobject.h"
52#include "qpixmap.h"
53#include "qpointer.h"
54#include "qstack.h"
55#include "qstyle.h"
56#include "qstylefactory.h"
57#include "qvariant.h"
58#include "qwidget.h"
59#include "qstyleoption.h"
60#include "qstylehints.h"
61#ifndef QT_NO_ACCESSIBILITY
62# include "qaccessible.h"
63#endif
64#include <qpa/qplatformwindow.h>
65#include "private/qwidgetwindow_p.h"
66#include "qpainter.h"
67#include "qtooltip.h"
68#if QT_CONFIG(whatsthis)
69#include "qwhatsthis.h"
70#endif
71#include "qdebug.h"
72#include "private/qstylesheetstyle_p.h"
73#include "private/qstyle_p.h"
74#include "qfileinfo.h"
75#include "qscopeguard.h"
76#include <QtGui/private/qhighdpiscaling_p.h>
77#include <QtGui/qinputmethod.h>
78#include <QtGui/qopenglcontext.h>
79#include <QtGui/private/qopenglcontext_p.h>
80#include <QtGui/qoffscreensurface.h>
81
82#if QT_CONFIG(graphicseffect)
83#include <private/qgraphicseffect_p.h>
84#endif
85#include <qbackingstore.h>
86#include <private/qwidgetrepaintmanager_p.h>
87#include <private/qpaintengine_raster_p.h>
88
89#include "qwidget_p.h"
90#include <QtGui/private/qwindow_p.h>
91#include "qaction_p.h"
92#include "qlayout_p.h"
93#if QT_CONFIG(graphicsview)
94#include "QtWidgets/qgraphicsproxywidget.h"
95#include "QtWidgets/qgraphicsscene.h"
96#include "private/qgraphicsproxywidget_p.h"
97#endif
98#include "QtWidgets/qabstractscrollarea.h"
99#include "private/qabstractscrollarea_p.h"
100#include "private/qevent_p.h"
101
102#include "private/qgesturemanager_p.h"
103
104#ifdef QT_KEYPAD_NAVIGATION
105#if QT_CONFIG(tabwidget)
106#include "qtabwidget.h" // Needed in inTabWidget()
107#endif
108#endif // QT_KEYPAD_NAVIGATION
109
110#include "qwindowcontainer_p.h"
111
112#include <QtPlatformHeaders/qxcbwindowfunctions.h>
113
114#include <private/qmemory_p.h>
115
116// widget/widget data creation count
117//#define QWIDGET_EXTRA_DEBUG
118//#define ALIEN_DEBUG
119
120QT_BEGIN_NAMESPACE
121
122Q_LOGGING_CATEGORY(lcWidgetPainting, "qt.widgets.painting", QtWarningMsg);
123
124static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
125{
126 return (qMax(a: r1.left(), b: r2.left()) <= qMin(a: r1.right(), b: r2.right()) &&
127 qMax(a: r1.top(), b: r2.top()) <= qMin(a: r1.bottom(), b: r2.bottom()));
128}
129
130extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
131extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
132
133QWidgetPrivate::QWidgetPrivate(int version)
134 : QObjectPrivate(version)
135 , focus_next(nullptr)
136 , focus_prev(nullptr)
137 , focus_child(nullptr)
138 , layout(nullptr)
139 , needsFlush(nullptr)
140 , redirectDev(nullptr)
141 , widgetItem(nullptr)
142 , extraPaintEngine(nullptr)
143 , polished(nullptr)
144 , graphicsEffect(nullptr)
145#if !defined(QT_NO_IM)
146 , imHints(Qt::ImhNone)
147#endif
148#ifndef QT_NO_TOOLTIP
149 , toolTipDuration(-1)
150#endif
151 , directFontResolveMask(0)
152 , inheritedFontResolveMask(0)
153 , directPaletteResolveMask(0)
154 , inheritedPaletteResolveMask(0)
155 , leftmargin(0)
156 , topmargin(0)
157 , rightmargin(0)
158 , bottommargin(0)
159 , leftLayoutItemMargin(0)
160 , topLayoutItemMargin(0)
161 , rightLayoutItemMargin(0)
162 , bottomLayoutItemMargin(0)
163 , hd(nullptr)
164 , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
165 , fg_role(QPalette::NoRole)
166 , bg_role(QPalette::NoRole)
167 , dirtyOpaqueChildren(1)
168 , isOpaque(0)
169 , retainSizeWhenHiddenChanged(0)
170 , inDirtyList(0)
171 , isScrolled(0)
172 , isMoved(0)
173 , usesDoubleBufferedGLContext(0)
174 , mustHaveWindowHandle(0)
175 , renderToTexture(0)
176 , textureChildSeen(0)
177#ifndef QT_NO_IM
178 , inheritsInputMethodHints(0)
179#endif
180#ifndef QT_NO_OPENGL
181 , renderToTextureReallyDirty(1)
182 , renderToTextureComposeActive(0)
183#endif
184 , childrenHiddenByWState(0)
185 , childrenShownByExpose(0)
186#if defined(Q_OS_WIN)
187 , noPaintOnScreen(0)
188#endif
189{
190 if (Q_UNLIKELY(!qApp)) {
191 qFatal(msg: "QWidget: Must construct a QApplication before a QWidget");
192 return;
193 }
194
195 checkForIncompatibleLibraryVersion(version);
196
197 isWidget = true;
198 memset(s: high_attributes, c: 0, n: sizeof(high_attributes));
199
200#ifdef QWIDGET_EXTRA_DEBUG
201 static int count = 0;
202 qDebug() << "widgets" << ++count;
203#endif
204}
205
206
207QWidgetPrivate::~QWidgetPrivate()
208{
209 if (widgetItem)
210 widgetItem->wid = nullptr;
211
212 if (extra)
213 deleteExtra();
214}
215
216/*!
217 \internal
218*/
219void QWidgetPrivate::scrollChildren(int dx, int dy)
220{
221 Q_Q(QWidget);
222 if (q->children().size() > 0) { // scroll children
223 QPoint pd(dx, dy);
224 QObjectList childObjects = q->children();
225 for (int i = 0; i < childObjects.size(); ++i) { // move all children
226 QWidget *w = qobject_cast<QWidget*>(o: childObjects.at(i));
227 if (w && !w->isWindow()) {
228 QPoint oldp = w->pos();
229 QRect r(w->pos() + pd, w->size());
230 w->data->crect = r;
231 if (w->testAttribute(attribute: Qt::WA_WState_Created))
232 w->d_func()->setWSGeometry();
233 w->d_func()->setDirtyOpaqueRegion();
234 QMoveEvent e(r.topLeft(), oldp);
235 QCoreApplication::sendEvent(receiver: w, event: &e);
236 }
237 }
238 }
239}
240
241void QWidgetPrivate::setWSGeometry()
242{
243 Q_Q(QWidget);
244 if (QWindow *window = q->windowHandle())
245 window->setGeometry(data.crect);
246}
247
248void QWidgetPrivate::updateWidgetTransform(QEvent *event)
249{
250 Q_Q(QWidget);
251 if (q == QGuiApplication::focusObject() || event->type() == QEvent::FocusIn) {
252 QTransform t;
253 QPoint p = q->mapTo(q->topLevelWidget(), QPoint(0,0));
254 t.translate(dx: p.x(), dy: p.y());
255 QGuiApplication::inputMethod()->setInputItemTransform(t);
256 QGuiApplication::inputMethod()->setInputItemRectangle(q->rect());
257 QGuiApplication::inputMethod()->update(queries: Qt::ImInputItemClipRectangle);
258 }
259}
260
261#ifdef QT_KEYPAD_NAVIGATION
262QPointer<QWidget> QWidgetPrivate::editingWidget;
263
264/*!
265 Returns \c true if this widget currently has edit focus; otherwise false.
266
267 This feature is only available in Qt for Embedded Linux.
268
269 \sa setEditFocus(), QApplication::navigationMode()
270*/
271bool QWidget::hasEditFocus() const
272{
273 const QWidget* w = this;
274 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
275 w = w->d_func()->extra->focus_proxy;
276 return QWidgetPrivate::editingWidget == w;
277}
278
279/*!
280 \fn void QWidget::setEditFocus(bool enable)
281
282 If \a enable is true, make this widget have edit focus, in which
283 case Qt::Key_Up and Qt::Key_Down will be delivered to the widget
284 normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to
285 change focus.
286
287 This feature is only available in Qt for Embedded Linux.
288
289 \sa hasEditFocus(), QApplication::navigationMode()
290*/
291void QWidget::setEditFocus(bool on)
292{
293 QWidget *f = this;
294 while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
295 f = f->d_func()->extra->focus_proxy;
296
297 if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f)
298 QWidgetPrivate::editingWidget->setEditFocus(false);
299
300 if (on && !f->hasFocus())
301 f->setFocus();
302
303 if ((!on && !QWidgetPrivate::editingWidget)
304 || (on && QWidgetPrivate::editingWidget == f)) {
305 return;
306 }
307
308 if (!on && QWidgetPrivate::editingWidget == f) {
309 QWidgetPrivate::editingWidget = 0;
310 QEvent event(QEvent::LeaveEditFocus);
311 QCoreApplication::sendEvent(f, &event);
312 QCoreApplication::sendEvent(f->style(), &event);
313 } else if (on) {
314 QWidgetPrivate::editingWidget = f;
315 QEvent event(QEvent::EnterEditFocus);
316 QCoreApplication::sendEvent(f, &event);
317 QCoreApplication::sendEvent(f->style(), &event);
318 }
319}
320#endif
321
322/*!
323 \property QWidget::autoFillBackground
324 \brief whether the widget background is filled automatically
325 \since 4.1
326
327 If enabled, this property will cause Qt to fill the background of the
328 widget before invoking the paint event. The color used is defined by the
329 QPalette::Window color role from the widget's \l{QPalette}{palette}.
330
331 In addition, Windows are always filled with QPalette::Window, unless the
332 WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
333
334 This property cannot be turned off (i.e., set to false) if a widget's
335 parent has a static gradient for its background.
336
337 \warning Use this property with caution in conjunction with
338 \l{Qt Style Sheets}. When a widget has a style sheet with a valid
339 background or a border-image, this property is automatically disabled.
340
341 By default, this property is \c false.
342
343 \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
344 {QWidget#Transparency and Double Buffering}{Transparency and Double Buffering}
345*/
346bool QWidget::autoFillBackground() const
347{
348 Q_D(const QWidget);
349 return d->extra && d->extra->autoFillBackground;
350}
351
352void QWidget::setAutoFillBackground(bool enabled)
353{
354 Q_D(QWidget);
355 if (!d->extra)
356 d->createExtra();
357 if (d->extra->autoFillBackground == enabled)
358 return;
359
360 d->extra->autoFillBackground = enabled;
361 d->updateIsOpaque();
362 update();
363 d->updateIsOpaque();
364}
365
366/*!
367 \class QWidget
368 \brief The QWidget class is the base class of all user interface objects.
369
370 \ingroup basicwidgets
371 \inmodule QtWidgets
372
373 The widget is the atom of the user interface: it receives mouse, keyboard
374 and other events from the window system, and paints a representation of
375 itself on the screen. Every widget is rectangular, and they are sorted in a
376 Z-order. A widget is clipped by its parent and by the widgets in front of
377 it.
378
379 A widget that is not embedded in a parent widget is called a window.
380 Usually, windows have a frame and a title bar, although it is also possible
381 to create windows without such decoration using suitable
382 \l{Qt::WindowFlags}{window flags}). In Qt, QMainWindow and the various
383 subclasses of QDialog are the most common window types.
384
385 Every widget's constructor accepts one or two standard arguments:
386
387 \list 1
388 \li \c{QWidget *parent = nullptr} is the parent of the new widget.
389 If it is \nullptr (the default), the new widget will be a window.
390 If not, it will be a child of \e parent, and be constrained by
391 \e parent's geometry (unless you specify Qt::Window as window flag).
392 \li \c{Qt::WindowFlags f = { }} (where available) sets the window flags;
393 the default is suitable for almost all widgets, but to get, for
394 example, a window without a window system frame, you must use
395 special flags.
396 \endlist
397
398 QWidget has many member functions, but some of them have little direct
399 functionality; for example, QWidget has a font property, but never uses
400 this itself. There are many subclasses which provide real functionality,
401 such as QLabel, QPushButton, QListWidget, and QTabWidget.
402
403
404 \section1 Top-Level and Child Widgets
405
406 A widget without a parent widget is always an independent window (top-level
407 widget). For these widgets, setWindowTitle() and setWindowIcon() set the
408 title bar and icon respectively.
409
410 Non-window widgets are child widgets, displayed within their parent
411 widgets. Most widgets in Qt are mainly useful as child widgets. For
412 example, it is possible to display a button as a top-level window, but most
413 people prefer to put their buttons inside other widgets, such as QDialog.
414
415 \image parent-child-widgets.png A parent widget containing various child widgets.
416
417 The diagram above shows a QGroupBox widget being used to hold various child
418 widgets in a layout provided by QGridLayout. The QLabel child widgets have
419 been outlined to indicate their full sizes.
420
421 If you want to use a QWidget to hold child widgets you will usually want to
422 add a layout to the parent QWidget. See \l{Layout Management} for more
423 information.
424
425
426 \section1 Composite Widgets
427
428 When a widget is used as a container to group a number of child widgets, it
429 is known as a composite widget. These can be created by constructing a
430 widget with the required visual properties - a QFrame, for example - and
431 adding child widgets to it, usually managed by a layout. The above diagram
432 shows such a composite widget that was created using Qt Designer.
433
434 Composite widgets can also be created by subclassing a standard widget,
435 such as QWidget or QFrame, and adding the necessary layout and child
436 widgets in the constructor of the subclass. Many of the \l{Qt Widgets Examples}
437 {examples provided with Qt} use this approach, and it is also covered in
438 the Qt \l{Tutorials}.
439
440
441 \section1 Custom Widgets and Painting
442
443 Since QWidget is a subclass of QPaintDevice, subclasses can be used to
444 display custom content that is composed using a series of painting
445 operations with an instance of the QPainter class. This approach contrasts
446 with the canvas-style approach used by the \l{Graphics View}
447 {Graphics View Framework} where items are added to a scene by the
448 application and are rendered by the framework itself.
449
450 Each widget performs all painting operations from within its paintEvent()
451 function. This is called whenever the widget needs to be redrawn, either
452 as a result of some external change or when requested by the application.
453
454 The \l{widgets/analogclock}{Analog Clock example} shows how a simple widget
455 can handle paint events.
456
457
458 \section1 Size Hints and Size Policies
459
460 When implementing a new widget, it is almost always useful to reimplement
461 sizeHint() to provide a reasonable default size for the widget and to set
462 the correct size policy with setSizePolicy().
463
464 By default, composite widgets which do not provide a size hint will be
465 sized according to the space requirements of their child widgets.
466
467 The size policy lets you supply good default behavior for the layout
468 management system, so that other widgets can contain and manage yours
469 easily. The default size policy indicates that the size hint represents
470 the preferred size of the widget, and this is often good enough for many
471 widgets.
472
473 \note The size of top-level widgets are constrained to 2/3 of the desktop's
474 height and width. You can resize() the widget manually if these bounds are
475 inadequate.
476
477
478 \section1 Events
479
480 Widgets respond to events that are typically caused by user actions. Qt
481 delivers events to widgets by calling specific event handler functions with
482 instances of QEvent subclasses containing information about each event.
483
484 If your widget only contains child widgets, you probably do not need to
485 implement any event handlers. If you want to detect a mouse click in a
486 child widget call the child's underMouse() function inside the widget's
487 mousePressEvent().
488
489 The \l{widgets/scribble}{Scribble example} implements a wider set of
490 events to handle mouse movement, button presses, and window resizing.
491
492 You will need to supply the behavior and content for your own widgets, but
493 here is a brief overview of the events that are relevant to QWidget,
494 starting with the most common ones:
495
496 \list
497 \li paintEvent() is called whenever the widget needs to be repainted.
498 Every widget displaying custom content must implement it. Painting
499 using a QPainter can only take place in a paintEvent() or a
500 function called by a paintEvent().
501 \li resizeEvent() is called when the widget has been resized.
502 \li mousePressEvent() is called when a mouse button is pressed while
503 the mouse cursor is inside the widget, or when the widget has
504 grabbed the mouse using grabMouse(). Pressing the mouse without
505 releasing it is effectively the same as calling grabMouse().
506 \li mouseReleaseEvent() is called when a mouse button is released. A
507 widget receives mouse release events when it has received the
508 corresponding mouse press event. This means that if the user
509 presses the mouse inside \e your widget, then drags the mouse
510 somewhere else before releasing the mouse button, \e your widget
511 receives the release event. There is one exception: if a popup menu
512 appears while the mouse button is held down, this popup immediately
513 steals the mouse events.
514 \li mouseDoubleClickEvent() is called when the user double-clicks in
515 the widget. If the user double-clicks, the widget receives a mouse
516 press event, a mouse release event, (a mouse click event,) a second
517 mouse press, this event and finally a second mouse release event.
518 (Some mouse move events may also be
519 received if the mouse is not held steady during this operation.) It
520 is \e{not possible} to distinguish a click from a double-click
521 until the second click arrives. (This is one reason why most GUI
522 books recommend that double-clicks be an extension of
523 single-clicks, rather than trigger a different action.)
524 \endlist
525
526 Widgets that accept keyboard input need to reimplement a few more event
527 handlers:
528
529 \list
530 \li keyPressEvent() is called whenever a key is pressed, and again when
531 a key has been held down long enough for it to auto-repeat. The
532 \uicontrol Tab and \uicontrol Shift+Tab keys are only passed to the widget if
533 they are not used by the focus-change mechanisms. To force those
534 keys to be processed by your widget, you must reimplement
535 QWidget::event().
536 \li focusInEvent() is called when the widget gains keyboard focus
537 (assuming you have called setFocusPolicy()). Well-behaved widgets
538 indicate that they own the keyboard focus in a clear but discreet
539 way.
540 \li focusOutEvent() is called when the widget loses keyboard focus.
541 \endlist
542
543 You may be required to also reimplement some of the less common event
544 handlers:
545
546 \list
547 \li mouseMoveEvent() is called whenever the mouse moves while a mouse
548 button is held down. This can be useful during drag and drop
549 operations. If you call \l{setMouseTracking()}{setMouseTracking}(true),
550 you get mouse move events even when no buttons are held down.
551 (See also the \l{Drag and Drop} guide.)
552 \li keyReleaseEvent() is called whenever a key is released and while it
553 is held down (if the key is auto-repeating). In that case, the
554 widget will receive a pair of key release and key press event for
555 every repeat. The \uicontrol Tab and \uicontrol Shift+Tab keys are only passed
556 to the widget if they are not used by the focus-change mechanisms.
557 To force those keys to be processed by your widget, you must
558 reimplement QWidget::event().
559 \li wheelEvent() is called whenever the user turns the mouse wheel
560 while the widget has the focus.
561 \li enterEvent() is called when the mouse enters the widget's screen
562 space. (This excludes screen space owned by any of the widget's
563 children.)
564 \li leaveEvent() is called when the mouse leaves the widget's screen
565 space. If the mouse enters a child widget it will not cause a
566 leaveEvent().
567 \li moveEvent() is called when the widget has been moved relative to
568 its parent.
569 \li closeEvent() is called when the user closes the widget (or when
570 close() is called).
571 \endlist
572
573 There are also some rather obscure events described in the documentation
574 for QEvent::Type. To handle these events, you need to reimplement event()
575 directly.
576
577 The default implementation of event() handles \uicontrol Tab and \uicontrol Shift+Tab
578 (to move the keyboard focus), and passes on most of the other events to
579 one of the more specialized handlers above.
580
581 Events and the mechanism used to deliver them are covered in
582 \l{The Event System}.
583
584 \section1 Groups of Functions and Properties
585
586 \table
587 \header \li Context \li Functions and Properties
588
589 \row \li Window functions \li
590 show(),
591 hide(),
592 raise(),
593 lower(),
594 close().
595
596 \row \li Top-level windows \li
597 \l windowModified, \l windowTitle, \l windowIcon,
598 \l isActiveWindow, activateWindow(), \l minimized, showMinimized(),
599 \l maximized, showMaximized(), \l fullScreen, showFullScreen(),
600 showNormal().
601
602 \row \li Window contents \li
603 update(),
604 repaint(),
605 scroll().
606
607 \row \li Geometry \li
608 \l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(),
609 \l sizePolicy, sizeHint(), minimumSizeHint(),
610 updateGeometry(), layout(),
611 \l frameGeometry, \l geometry, \l childrenRect, \l childrenRegion,
612 adjustSize(),
613 mapFromGlobal(), mapToGlobal(),
614 mapFromParent(), mapToParent(),
615 \l maximumSize, \l minimumSize, \l sizeIncrement,
616 \l baseSize, setFixedSize()
617
618 \row \li Mode \li
619 \l visible, isVisibleTo(),
620 \l enabled, isEnabledTo(),
621 \l modal,
622 isWindow(),
623 \l mouseTracking,
624 \l updatesEnabled,
625 visibleRegion().
626
627 \row \li Look and feel \li
628 style(),
629 setStyle(),
630 \l styleSheet,
631 \l cursor,
632 \l font,
633 \l palette,
634 backgroundRole(), setBackgroundRole(),
635 fontInfo(), fontMetrics().
636
637 \row \li Keyboard focus functions \li
638 \l focus, \l focusPolicy,
639 setFocus(), clearFocus(), setTabOrder(), setFocusProxy(),
640 focusNextChild(), focusPreviousChild().
641
642 \row \li Mouse and keyboard grabbing \li
643 grabMouse(), releaseMouse(),
644 grabKeyboard(), releaseKeyboard(),
645 mouseGrabber(), keyboardGrabber().
646
647 \row \li Event handlers \li
648 event(),
649 mousePressEvent(),
650 mouseReleaseEvent(),
651 mouseDoubleClickEvent(),
652 mouseMoveEvent(),
653 keyPressEvent(),
654 keyReleaseEvent(),
655 focusInEvent(),
656 focusOutEvent(),
657 wheelEvent(),
658 enterEvent(),
659 leaveEvent(),
660 paintEvent(),
661 moveEvent(),
662 resizeEvent(),
663 closeEvent(),
664 dragEnterEvent(),
665 dragMoveEvent(),
666 dragLeaveEvent(),
667 dropEvent(),
668 childEvent(),
669 showEvent(),
670 hideEvent(),
671 customEvent().
672 changeEvent(),
673
674 \row \li System functions \li
675 parentWidget(), window(), setParent(), winId(),
676 find(), metric().
677
678 \row \li Context menu \li
679 contextMenuPolicy, contextMenuEvent(),
680 customContextMenuRequested(), actions()
681
682 \row \li Interactive help \li
683 setToolTip(), setWhatsThis()
684
685 \endtable
686
687
688 \section1 Widget Style Sheets
689
690 In addition to the standard widget styles for each platform, widgets can
691 also be styled according to rules specified in a \l{styleSheet}
692 {style sheet}. This feature enables you to customize the appearance of
693 specific widgets to provide visual cues to users about their purpose. For
694 example, a button could be styled in a particular way to indicate that it
695 performs a destructive action.
696
697 The use of widget style sheets is described in more detail in the
698 \l{Qt Style Sheets} document.
699
700
701 \section1 Transparency and Double Buffering
702
703 Since Qt 4.0, QWidget automatically double-buffers its painting, so there
704 is no need to write double-buffering code in paintEvent() to avoid
705 flicker.
706
707 Since Qt 4.1, the contents of parent widgets are propagated by
708 default to each of their children as long as Qt::WA_PaintOnScreen is not
709 set. Custom widgets can be written to take advantage of this feature by
710 updating irregular regions (to create non-rectangular child widgets), or
711 painting with colors that have less than full alpha component. The
712 following diagram shows how attributes and properties of a custom widget
713 can be fine-tuned to achieve different effects.
714
715 \image propagation-custom.png
716
717 In the above diagram, a semi-transparent rectangular child widget with an
718 area removed is constructed and added to a parent widget (a QLabel showing
719 a pixmap). Then, different properties and widget attributes are set to
720 achieve different effects:
721
722 \list
723 \li The left widget has no additional properties or widget attributes
724 set. This default state suits most custom widgets using
725 transparency, are irregularly-shaped, or do not paint over their
726 entire area with an opaque brush.
727 \li The center widget has the \l autoFillBackground property set. This
728 property is used with custom widgets that rely on the widget to
729 supply a default background, and do not paint over their entire
730 area with an opaque brush.
731 \li The right widget has the Qt::WA_OpaquePaintEvent widget attribute
732 set. This indicates that the widget will paint over its entire area
733 with opaque colors. The widget's area will initially be
734 \e{uninitialized}, represented in the diagram with a red diagonal
735 grid pattern that shines through the overpainted area. The
736 Qt::WA_OpaquePaintArea attribute is useful for widgets that need to
737 paint their own specialized contents quickly and do not need a
738 default filled background.
739 \endlist
740
741 To rapidly update custom widgets with simple background colors, such as
742 real-time plotting or graphing widgets, it is better to define a suitable
743 background color (using setBackgroundRole() with the
744 QPalette::Window role), set the \l autoFillBackground property, and only
745 implement the necessary drawing functionality in the widget's paintEvent().
746
747 To rapidly update custom widgets that constantly paint over their entire
748 areas with opaque content, e.g., video streaming widgets, it is better to
749 set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead
750 associated with repainting the widget's background.
751
752 If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and}
753 the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent
754 attribute takes precedence. Depending on your requirements, you should
755 choose either one of them.
756
757 Since Qt 4.1, the contents of parent widgets are also propagated to
758 standard Qt widgets. This can lead to some unexpected results if the
759 parent widget is decorated in a non-standard way, as shown in the diagram
760 below.
761
762 \image propagation-standard.png
763
764 The scope for customizing the painting behavior of standard Qt widgets,
765 without resorting to subclassing, is slightly less than that possible for
766 custom widgets. Usually, the desired appearance of a standard widget can be
767 achieved by setting its \l autoFillBackground property.
768
769
770 \section1 Creating Translucent Windows
771
772 Since Qt 4.5, it has been possible to create windows with translucent regions
773 on window systems that support compositing.
774
775 To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground
776 attribute with setAttribute() and ensure that its background is painted with
777 non-opaque colors in the regions you want to be partially transparent.
778
779 Platform notes:
780
781 \list
782 \li X11: This feature relies on the use of an X server that supports ARGB visuals
783 and a compositing window manager.
784 \li Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
785 for the translucency to work.
786 \li \macos: The widget needs to have the Qt::FramelessWindowHint window flag set
787 for the translucency to work.
788 \endlist
789
790
791 \section1 Native Widgets vs Alien Widgets
792
793 Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
794 system. They do not have a native window handle associated with them. This
795 feature significantly speeds up widget painting, resizing, and removes flicker.
796
797 Should you require the old behavior with native windows, you can choose
798 one of the following options:
799
800 \list 1
801 \li Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
802 \li Set the Qt::AA_NativeWindows attribute on your application. All
803 widgets will be native widgets.
804 \li Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
805 and all of its ancestors will become native (unless
806 Qt::WA_DontCreateNativeAncestors is set).
807 \li Call QWidget::winId to enforce a native window (this implies 3).
808 \li Set the Qt::WA_PaintOnScreen attribute to enforce a native window
809 (this implies 3).
810 \endlist
811
812 \sa QEvent, QPainter, QGridLayout, QBoxLayout
813
814*/
815
816QWidgetMapper *QWidgetPrivate::mapper = nullptr; // widget with wid
817QWidgetSet *QWidgetPrivate::allWidgets = nullptr; // widgets with no wid
818
819
820/*****************************************************************************
821 QWidget member functions
822 *****************************************************************************/
823
824/*
825 Widget state flags:
826 \list
827 \li Qt::WA_WState_Created The widget has a valid winId().
828 \li Qt::WA_WState_Visible The widget is currently visible.
829 \li Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
830 become visible unless you call show() on it. Qt::WA_WState_Hidden
831 implies !Qt::WA_WState_Visible.
832 \li Qt::WA_WState_CompressKeys Compress keyboard events.
833 \li Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
834 \li Qt::WA_WState_InPaintEvent Currently processing a paint event.
835 \li Qt::WA_WState_Reparented The widget has been reparented.
836 \li Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
837 \li Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
838 \endlist
839*/
840
841struct QWidgetExceptionCleaner
842{
843 /* this cleans up when the constructor throws an exception */
844 static inline void cleanup(QWidget *that, QWidgetPrivate *d)
845 {
846#ifdef QT_NO_EXCEPTIONS
847 Q_UNUSED(that);
848 Q_UNUSED(d);
849#else
850 QWidgetPrivate::allWidgets->remove(that);
851 if (d->focus_next != that) {
852 if (d->focus_next)
853 d->focus_next->d_func()->focus_prev = d->focus_prev;
854 if (d->focus_prev)
855 d->focus_prev->d_func()->focus_next = d->focus_next;
856 }
857#endif
858 }
859};
860
861/*!
862 Constructs a widget which is a child of \a parent, with widget
863 flags set to \a f.
864
865 If \a parent is \nullptr, the new widget becomes a window. If
866 \a parent is another widget, this widget becomes a child window
867 inside \a parent. The new widget is deleted when its \a parent is
868 deleted.
869
870 The widget flags argument, \a f, is normally 0, but it can be set
871 to customize the frame of a window (i.e. \a parent must be
872 \nullptr). To customize the frame, use a value composed
873 from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}.
874
875 If you add a child widget to an already visible widget you must
876 explicitly show the child to make it visible.
877
878 Note that the X11 version of Qt may not be able to deliver all
879 combinations of style flags on all systems. This is because on
880 X11, Qt can only ask the window manager, and the window manager
881 can override the application's settings. On Windows, Qt can set
882 whatever flags you want.
883
884 \sa windowFlags
885*/
886QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
887 : QObject(*new QWidgetPrivate, nullptr), QPaintDevice()
888{
889 QT_TRY {
890 d_func()->init(desktopWidget: parent, f);
891 } QT_CATCH(...) {
892 QWidgetExceptionCleaner::cleanup(that: this, d: d_func());
893 QT_RETHROW;
894 }
895}
896
897
898/*! \internal
899*/
900QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
901 : QObject(dd, nullptr), QPaintDevice()
902{
903 Q_D(QWidget);
904 QT_TRY {
905 d->init(desktopWidget: parent, f);
906 } QT_CATCH(...) {
907 QWidgetExceptionCleaner::cleanup(that: this, d: d_func());
908 QT_RETHROW;
909 }
910}
911
912/*!
913 \internal
914*/
915int QWidget::devType() const
916{
917 return QInternal::Widget;
918}
919
920
921//### w is a "this" ptr, passed as a param because QWorkspace needs special logic
922void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
923{
924 bool customize = (flags & (Qt::CustomizeWindowHint
925 | Qt::FramelessWindowHint
926 | Qt::WindowTitleHint
927 | Qt::WindowSystemMenuHint
928 | Qt::WindowMinimizeButtonHint
929 | Qt::WindowMaximizeButtonHint
930 | Qt::WindowCloseButtonHint
931 | Qt::WindowContextHelpButtonHint));
932
933 uint type = (flags & Qt::WindowType_Mask);
934
935 if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
936 type = Qt::Window;
937 flags |= Qt::Window;
938 }
939
940 if (flags & Qt::CustomizeWindowHint) {
941 // modify window flags to make them consistent.
942 // Only enable this on non-Mac platforms. Since the old way of doing this would
943 // interpret WindowSystemMenuHint as a close button and we can't change that behavior
944 // we can't just add this in.
945 if ((flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint))
946# ifdef Q_OS_WIN
947 && type != Qt::Dialog // QTBUG-2027, allow for menu-less dialogs.
948# endif
949 ) {
950 flags |= Qt::WindowSystemMenuHint;
951 flags |= Qt::WindowTitleHint;
952 flags &= ~Qt::FramelessWindowHint;
953 }
954 } else if (customize && !(flags & Qt::FramelessWindowHint)) {
955 // if any of the window hints that affect the titlebar are set
956 // and the window is supposed to have frame, we add a titlebar
957 // and system menu by default.
958 flags |= Qt::WindowSystemMenuHint;
959 flags |= Qt::WindowTitleHint;
960 }
961 if (customize)
962 ; // don't modify window flags if the user explicitly set them.
963 else if (type == Qt::Dialog || type == Qt::Sheet) {
964 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
965 // ### fixme: Qt 6: Never set Qt::WindowContextHelpButtonHint flag automatically
966 if (!QApplicationPrivate::testAttribute(flag: Qt::AA_DisableWindowContextHelpButton))
967 flags |= Qt::WindowContextHelpButtonHint;
968 } else if (type == Qt::Tool)
969 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
970 else
971 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint |
972 Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint;
973 if (w->testAttribute(attribute: Qt::WA_TransparentForMouseEvents))
974 flags |= Qt::WindowTransparentForInput;
975}
976
977void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
978{
979 Q_Q(QWidget);
980 Q_ASSERT_X(q != parentWidget, Q_FUNC_INFO, "Cannot parent a QWidget to itself");
981
982 if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance())))
983 qFatal(msg: "QWidget: Cannot create a QWidget without QApplication");
984
985 Q_ASSERT(allWidgets);
986 if (allWidgets)
987 allWidgets->insert(value: q);
988
989 int targetScreen = -1;
990 if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
991 const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(object: parentWidget);
992 targetScreen = sw ? sw->screenNumber() : 0;
993 parentWidget = nullptr;
994 }
995
996 q->data = &data;
997
998#if QT_CONFIG(thread)
999 if (!parent) {
1000 Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
1001 "Widgets must be created in the GUI thread.");
1002 }
1003#endif
1004
1005 if (targetScreen >= 0) {
1006 topData()->initialScreenIndex = targetScreen;
1007 if (QWindow *window = q->windowHandle())
1008 window->setScreen(QGuiApplication::screens().value(i: targetScreen, defaultValue: nullptr));
1009 }
1010
1011 data.fstrut_dirty = true;
1012
1013 data.winid = 0;
1014 data.widget_attributes = 0;
1015 data.window_flags = f;
1016 data.window_state = 0;
1017 data.focus_policy = 0;
1018 data.context_menu_policy = Qt::DefaultContextMenu;
1019 data.window_modality = Qt::NonModal;
1020
1021 data.sizehint_forced = 0;
1022 data.is_closing = 0;
1023 data.in_show = 0;
1024 data.in_set_window_state = 0;
1025 data.in_destructor = false;
1026
1027 // Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle.
1028 if (f & Qt::MSWindowsOwnDC) {
1029 mustHaveWindowHandle = 1;
1030 q->setAttribute(Qt::WA_NativeWindow);
1031 }
1032
1033 q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
1034 adjustQuitOnCloseAttribute();
1035
1036 q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea);
1037 q->setAttribute(Qt::WA_WState_Hidden);
1038
1039 //give potential windows a bigger "pre-initial" size; create() will give them a new size later
1040 data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
1041 focus_next = focus_prev = q;
1042
1043 if ((f & Qt::WindowType_Mask) == Qt::Desktop)
1044 q->create();
1045 else if (parentWidget)
1046 q->setParent(parent: parentWidget, f: data.window_flags);
1047 else {
1048 adjustFlags(flags&: data.window_flags, w: q);
1049 resolveLayoutDirection();
1050 // opaque system background?
1051 const QBrush &background = q->palette().brush(cr: QPalette::Window);
1052 setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque());
1053 }
1054 data.fnt = QFont(data.fnt, q);
1055
1056 q->setAttribute(Qt::WA_PendingMoveEvent);
1057 q->setAttribute(Qt::WA_PendingResizeEvent);
1058
1059 if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
1060 QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
1061
1062 if (QApplicationPrivate::testAttribute(flag: Qt::AA_ImmediateWidgetCreation)) // ### fixme: Qt 6: Remove AA_ImmediateWidgetCreation.
1063 q->create();
1064
1065 QEvent e(QEvent::Create);
1066 QCoreApplication::sendEvent(receiver: q, event: &e);
1067 QCoreApplication::postEvent(receiver: q, event: new QEvent(QEvent::PolishRequest));
1068
1069 extraPaintEngine = nullptr;
1070}
1071
1072void QWidgetPrivate::createRecursively()
1073{
1074 Q_Q(QWidget);
1075 q->create(0, initializeWindow: true, destroyOldWindow: true);
1076 for (int i = 0; i < children.size(); ++i) {
1077 QWidget *child = qobject_cast<QWidget *>(o: children.at(i));
1078 if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(attribute: Qt::WA_WState_Created))
1079 child->d_func()->createRecursively();
1080 }
1081}
1082
1083QWindow *QWidgetPrivate::windowHandle(WindowHandleMode mode) const
1084{
1085 if (mode == WindowHandleMode::Direct || mode == WindowHandleMode::Closest) {
1086 if (QTLWExtra *x = maybeTopData()) {
1087 if (x->window != nullptr || mode == WindowHandleMode::Direct)
1088 return x->window;
1089 }
1090 }
1091 if (mode == WindowHandleMode::Closest) {
1092 if (auto nativeParent = q_func()->nativeParentWidget()) {
1093 if (auto window = nativeParent->windowHandle())
1094 return window;
1095 }
1096 }
1097 if (mode == WindowHandleMode::TopLevel || mode == WindowHandleMode::Closest) {
1098 if (auto topLevel = q_func()->topLevelWidget()) {
1099 if (auto window = topLevel ->windowHandle())
1100 return window;
1101 }
1102 }
1103 return nullptr;
1104}
1105
1106QScreen *QWidgetPrivate::associatedScreen() const
1107{
1108 if (auto window = windowHandle(mode: WindowHandleMode::Closest))
1109 return window->screen();
1110 return nullptr;
1111}
1112
1113// ### fixme: Qt 6: Remove parameter window from QWidget::create()
1114
1115/*!
1116 Creates a new widget window.
1117
1118 The parameters \a window, \a initializeWindow, and \a destroyOldWindow
1119 are ignored in Qt 5. Please use QWindow::fromWinId() to create a
1120 QWindow wrapping a foreign window and pass it to
1121 QWidget::createWindowContainer() instead.
1122
1123 \sa createWindowContainer(), QWindow::fromWinId()
1124*/
1125
1126void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
1127{
1128 Q_UNUSED(initializeWindow);
1129 Q_UNUSED(destroyOldWindow);
1130
1131 Q_D(QWidget);
1132 if (Q_UNLIKELY(window))
1133 qWarning(msg: "QWidget::create(): Parameter 'window' does not have any effect.");
1134 if (testAttribute(attribute: Qt::WA_WState_Created) && window == 0 && internalWinId())
1135 return;
1136
1137 if (d->data.in_destructor)
1138 return;
1139
1140 Qt::WindowType type = windowType();
1141 Qt::WindowFlags &flags = data->window_flags;
1142
1143 if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
1144 type = Qt::Window;
1145 flags |= Qt::Window;
1146 }
1147
1148 if (QWidget *parent = parentWidget()) {
1149 if (type & Qt::Window) {
1150 if (!parent->testAttribute(attribute: Qt::WA_WState_Created))
1151 parent->createWinId();
1152 } else if (testAttribute(attribute: Qt::WA_NativeWindow) && !parent->internalWinId()
1153 && !testAttribute(attribute: Qt::WA_DontCreateNativeAncestors)) {
1154 // We're about to create a native child widget that doesn't have a native parent;
1155 // enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors
1156 // attribute is set.
1157 d->createWinId();
1158 // Nothing more to do.
1159 Q_ASSERT(testAttribute(Qt::WA_WState_Created));
1160 Q_ASSERT(internalWinId());
1161 return;
1162 }
1163 }
1164
1165
1166 static const bool paintOnScreenEnv = qEnvironmentVariableIntValue(varName: "QT_ONSCREEN_PAINT") > 0;
1167 if (paintOnScreenEnv)
1168 setAttribute(Qt::WA_PaintOnScreen);
1169
1170 if (QApplicationPrivate::testAttribute(flag: Qt::AA_NativeWindows))
1171 setAttribute(Qt::WA_NativeWindow);
1172
1173#ifdef ALIEN_DEBUG
1174 qDebug() << "QWidget::create:" << this << "parent:" << parentWidget()
1175 << "Alien?" << !testAttribute(Qt::WA_NativeWindow);
1176#endif
1177
1178 d->updateIsOpaque();
1179
1180 setAttribute(Qt::WA_WState_Created); // set created flag
1181 d->create();
1182
1183 // A real toplevel window needs a paint manager
1184 if (isWindow() && windowType() != Qt::Desktop)
1185 d->topData()->repaintManager.reset(p: new QWidgetRepaintManager(this));
1186
1187 d->setModal_sys();
1188
1189 if (!isWindow() && parentWidget() && parentWidget()->testAttribute(attribute: Qt::WA_DropSiteRegistered))
1190 setAttribute(Qt::WA_DropSiteRegistered, on: true);
1191
1192 // need to force the resting of the icon after changing parents
1193 if (testAttribute(attribute: Qt::WA_SetWindowIcon))
1194 d->setWindowIcon_sys();
1195
1196 if (isWindow() && !d->topData()->iconText.isEmpty())
1197 d->setWindowIconText_helper(d->topData()->iconText);
1198 if (isWindow() && !d->topData()->caption.isEmpty())
1199 d->setWindowTitle_helper(d->topData()->caption);
1200 if (isWindow() && !d->topData()->filePath.isEmpty())
1201 d->setWindowFilePath_helper(d->topData()->filePath);
1202 if (windowType() != Qt::Desktop) {
1203 d->updateSystemBackground();
1204
1205 if (isWindow() && !testAttribute(attribute: Qt::WA_SetWindowIcon))
1206 d->setWindowIcon_sys();
1207 }
1208
1209 // Frame strut update needed in cases where there are native widgets such as QGLWidget,
1210 // as those force native window creation on their ancestors before they are shown.
1211 // If the strut is not updated, any subsequent move of the top level window before show
1212 // will cause window frame to be ignored when positioning the window.
1213 // Note that this only helps on platforms that handle window creation synchronously.
1214 d->updateFrameStrut();
1215}
1216
1217void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
1218{
1219 QObjectList children = parentWidget->children();
1220 for (int i = 0; i < children.size(); i++) {
1221 if (children.at(i)->isWidgetType()) {
1222 const QWidget *childWidget = qobject_cast<const QWidget *>(object: children.at(i));
1223 if (childWidget) { // should not be necessary
1224 if (childWidget->testAttribute(attribute: Qt::WA_NativeWindow)) {
1225 if (!childWidget->internalWinId())
1226 childWidget->winId();
1227 if (childWidget->windowHandle()) {
1228 if (childWidget->isWindow()) {
1229 childWidget->windowHandle()->setTransientParent(parentWidget->window()->windowHandle());
1230 } else {
1231 childWidget->windowHandle()->setParent(childWidget->nativeParentWidget()->windowHandle());
1232 }
1233 }
1234 } else {
1235 q_createNativeChildrenAndSetParent(parentWidget: childWidget);
1236 }
1237 }
1238 }
1239 }
1240
1241}
1242
1243void QWidgetPrivate::create()
1244{
1245 Q_Q(QWidget);
1246
1247 if (!q->testAttribute(attribute: Qt::WA_NativeWindow) && !q->isWindow())
1248 return; // we only care about real toplevels
1249
1250 QWidgetWindow *win = topData()->window;
1251 // topData() ensures the extra is created but does not ensure 'window' is non-null
1252 // in case the extra was already valid.
1253 if (!win) {
1254 createTLSysExtra();
1255 win = topData()->window;
1256 }
1257
1258 const auto dynamicPropertyNames = q->dynamicPropertyNames();
1259 for (const QByteArray &propertyName : dynamicPropertyNames) {
1260 if (!qstrncmp(str1: propertyName, str2: "_q_platform_", len: 12))
1261 win->setProperty(name: propertyName, value: q->property(name: propertyName));
1262 }
1263
1264 Qt::WindowFlags &flags = data.window_flags;
1265
1266#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
1267 if (q->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea))
1268 flags |= Qt::MaximizeUsingFullscreenGeometryHint;
1269#endif
1270
1271 if (q->testAttribute(attribute: Qt::WA_ShowWithoutActivating))
1272 win->setProperty(name: "_q_showWithoutActivating", value: QVariant(true));
1273 if (q->testAttribute(attribute: Qt::WA_MacAlwaysShowToolWindow))
1274 win->setProperty(name: "_q_macAlwaysShowToolWindow", value: QVariant(true));
1275 setNetWmWindowTypes(true); // do nothing if none of WA_X11NetWmWindowType* is set
1276 win->setFlags(flags);
1277 fixPosIncludesFrame();
1278 if (q->testAttribute(attribute: Qt::WA_Moved)
1279 || !QGuiApplicationPrivate::platformIntegration()->hasCapability(cap: QPlatformIntegration::WindowManagement))
1280 win->setGeometry(q->geometry());
1281 else
1282 win->resize(newSize: q->size());
1283 if (win->isTopLevel()) {
1284 int screenNumber = topData()->initialScreenIndex;
1285 topData()->initialScreenIndex = -1;
1286 if (screenNumber < 0) {
1287 screenNumber = q->windowType() != Qt::Desktop
1288 ? QDesktopWidgetPrivate::screenNumber(widget: q) : 0;
1289 }
1290 win->setScreen(QGuiApplication::screens().value(i: screenNumber, defaultValue: nullptr));
1291 }
1292
1293 QSurfaceFormat format = win->requestedFormat();
1294 if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface
1295 && q->testAttribute(attribute: Qt::WA_TranslucentBackground)) {
1296 format.setAlphaBufferSize(8);
1297 }
1298 win->setFormat(format);
1299
1300 if (QWidget *nativeParent = q->nativeParentWidget()) {
1301 if (nativeParent->windowHandle()) {
1302 if (flags & Qt::Window) {
1303 win->setTransientParent(nativeParent->window()->windowHandle());
1304 win->setParent(nullptr);
1305 } else {
1306 win->setTransientParent(nullptr);
1307 win->setParent(nativeParent->windowHandle());
1308 }
1309 }
1310 }
1311
1312 qt_window_private(window: win)->positionPolicy = topData()->posIncludesFrame ?
1313 QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
1314
1315 if (q->windowType() != Qt::Desktop || q->testAttribute(attribute: Qt::WA_NativeWindow)) {
1316 win->create();
1317 // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing.
1318 if (QPlatformWindow *platformWindow = win->handle())
1319 platformWindow->setFrameStrutEventsEnabled(true);
1320 }
1321
1322 data.window_flags = win->flags();
1323 if (!win->isTopLevel()) // In a Widget world foreign windows can only be top level
1324 data.window_flags &= ~Qt::ForeignWindow;
1325
1326 if (!topData()->role.isNull())
1327 QXcbWindowFunctions::setWmWindowRole(window: win, role: topData()->role.toLatin1());
1328
1329 QBackingStore *store = q->backingStore();
1330
1331 if (!store) {
1332 if (q->windowType() != Qt::Desktop) {
1333 if (q->isTopLevel())
1334 q->setBackingStore(new QBackingStore(win));
1335 } else {
1336 q->setAttribute(Qt::WA_PaintOnScreen, on: true);
1337 }
1338 }
1339
1340 setWindowModified_helper();
1341
1342 if (win->handle()) {
1343 WId id = win->winId();
1344 // See the QPlatformWindow::winId() documentation
1345 Q_ASSERT(id != WId(0));
1346 setWinId(id);
1347 }
1348
1349 // Check children and create windows for them if necessary
1350 q_createNativeChildrenAndSetParent(parentWidget: q);
1351
1352 if (extra && !extra->mask.isEmpty())
1353 setMask_sys(extra->mask);
1354
1355 if (data.crect.width() == 0 || data.crect.height() == 0) {
1356 q->setAttribute(Qt::WA_OutsideWSRange, on: true);
1357 } else if (q->isVisible()) {
1358 // If widget is already shown, set window visible, too
1359 win->setNativeWindowVisibility(true);
1360 }
1361}
1362
1363#ifdef Q_OS_WIN
1364static const char activeXNativeParentHandleProperty[] = "_q_embedded_native_parent_handle";
1365#endif
1366
1367void QWidgetPrivate::createTLSysExtra()
1368{
1369 Q_Q(QWidget);
1370 if (!extra->topextra->window && (q->testAttribute(attribute: Qt::WA_NativeWindow) || q->isWindow())) {
1371 extra->topextra->window = new QWidgetWindow(q);
1372 if (extra->minw || extra->minh)
1373 extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh));
1374 if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX)
1375 extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
1376 if (extra->topextra->opacity != 255 && q->isWindow())
1377 extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255));
1378
1379 const bool isTipLabel = q->inherits(classname: "QTipLabel");
1380 const bool isAlphaWidget = !isTipLabel && q->inherits(classname: "QAlphaWidget");
1381#ifdef Q_OS_WIN
1382 // Pass on native parent handle for Widget embedded into Active X.
1383 const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty);
1384 if (activeXNativeParentHandle.isValid())
1385 extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle);
1386 if (isTipLabel || isAlphaWidget)
1387 extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true));
1388#endif
1389 if (isTipLabel || isAlphaWidget || q->inherits(classname: "QRollEffect"))
1390 qt_window_private(window: extra->topextra->window)->setAutomaticPositionAndResizeEnabled(false);
1391 }
1392
1393}
1394
1395/*!
1396 Destroys the widget.
1397
1398 All this widget's children are deleted first. The application
1399 exits if this widget is the main widget.
1400*/
1401
1402QWidget::~QWidget()
1403{
1404 Q_D(QWidget);
1405 d->data.in_destructor = true;
1406
1407#if defined (QT_CHECK_STATE)
1408 if (Q_UNLIKELY(paintingActive()))
1409 qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
1410#endif
1411
1412#ifndef QT_NO_GESTURES
1413 if (QGestureManager *manager = QGestureManager::instance(ic: QGestureManager::DontForceCreation)) {
1414 // \forall Qt::GestureType type : ungrabGesture(type) (inlined)
1415 for (auto it = d->gestureContext.keyBegin(), end = d->gestureContext.keyEnd(); it != end; ++it)
1416 manager->cleanupCachedGestures(target: this, type: *it);
1417 }
1418 d->gestureContext.clear();
1419#endif
1420
1421#ifndef QT_NO_ACTION
1422 // remove all actions from this widget
1423 for (int i = 0; i < d->actions.size(); ++i) {
1424 QActionPrivate *apriv = d->actions.at(i)->d_func();
1425 apriv->widgets.removeAll(t: this);
1426 }
1427 d->actions.clear();
1428#endif
1429
1430#ifndef QT_NO_SHORTCUT
1431 // Remove all shortcuts grabbed by this
1432 // widget, unless application is closing
1433 if (!QApplicationPrivate::is_app_closing && testAttribute(attribute: Qt::WA_GrabbedShortcut))
1434 QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id: 0, owner: this, key: QKeySequence());
1435#endif
1436
1437 // delete layout while we still are a valid widget
1438 delete d->layout;
1439 d->layout = nullptr;
1440 // Remove myself from focus list
1441
1442 Q_ASSERT(d->focus_next->d_func()->focus_prev == this);
1443 Q_ASSERT(d->focus_prev->d_func()->focus_next == this);
1444
1445 if (d->focus_next != this) {
1446 d->focus_next->d_func()->focus_prev = d->focus_prev;
1447 d->focus_prev->d_func()->focus_next = d->focus_next;
1448 d->focus_next = d->focus_prev = nullptr;
1449 }
1450
1451
1452 QT_TRY {
1453#if QT_CONFIG(graphicsview)
1454 const QWidget* w = this;
1455 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
1456 w = w->d_func()->extra->focus_proxy;
1457 QWidget *window = w->window();
1458 QWExtra *e = window ? window->d_func()->extra.get() : nullptr ;
1459 if (!e || !e->proxyWidget || (w->parentWidget() && w->parentWidget()->d_func()->focus_child == this))
1460#endif
1461 clearFocus();
1462 } QT_CATCH(...) {
1463 // swallow this problem because we are in a destructor
1464 }
1465
1466 d->setDirtyOpaqueRegion();
1467
1468 if (isWindow() && isVisible() && internalWinId()) {
1469 QT_TRY {
1470 d->close_helper(mode: QWidgetPrivate::CloseNoEvent);
1471 } QT_CATCH(...) {
1472 // if we're out of memory, at least hide the window.
1473 QT_TRY {
1474 hide();
1475 } QT_CATCH(...) {
1476 // and if that also doesn't work, then give up
1477 }
1478 }
1479 } else if (isVisible()) {
1480 qApp->d_func()->sendSyntheticEnterLeave(widget: this);
1481 }
1482
1483 if (QWidgetRepaintManager *repaintManager = d->maybeRepaintManager()) {
1484 repaintManager->removeDirtyWidget(w: this);
1485 if (testAttribute(attribute: Qt::WA_StaticContents))
1486 repaintManager->removeStaticWidget(widget: this);
1487 }
1488
1489 delete d->needsFlush;
1490 d->needsFlush = nullptr;
1491
1492 // The next 20 lines are duplicated from QObject, but required here
1493 // since QWidget deletes is children itself
1494 bool blocked = d->blockSig;
1495 d->blockSig = 0; // unblock signals so we always emit destroyed()
1496
1497 if (d->isSignalConnected(signalIdx: 0)) {
1498 QT_TRY {
1499 emit destroyed(this);
1500 } QT_CATCH(...) {
1501 // all the signal/slots connections are still in place - if we don't
1502 // quit now, we will crash pretty soon.
1503 qWarning(msg: "Detected an unexpected exception in ~QWidget while emitting destroyed().");
1504 QT_RETHROW;
1505 }
1506 }
1507
1508 if (d->declarativeData) {
1509 d->wasDeleted = true; // needed, so that destroying the declarative data does the right thing
1510 if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
1511 if (QAbstractDeclarativeData::destroyed_qml1)
1512 QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
1513 } else {
1514 if (QAbstractDeclarativeData::destroyed)
1515 QAbstractDeclarativeData::destroyed(d->declarativeData, this);
1516 }
1517 d->declarativeData = nullptr; // don't activate again in ~QObject
1518 d->wasDeleted = false;
1519 }
1520
1521 d->blockSig = blocked;
1522
1523 if (!d->children.isEmpty())
1524 d->deleteChildren();
1525
1526 QCoreApplication::removePostedEvents(receiver: this);
1527
1528 QT_TRY {
1529 destroy(); // platform-dependent cleanup
1530 } QT_CATCH(...) {
1531 // if this fails we can't do anything about it but at least we are not allowed to throw.
1532 }
1533 --QWidgetPrivate::instanceCounter;
1534
1535 if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
1536 QWidgetPrivate::allWidgets->remove(value: this);
1537
1538 QT_TRY {
1539 QEvent e(QEvent::Destroy);
1540 QCoreApplication::sendEvent(receiver: this, event: &e);
1541 } QT_CATCH(const std::exception&) {
1542 // if this fails we can't do anything about it but at least we are not allowed to throw.
1543 }
1544
1545#if QT_CONFIG(graphicseffect)
1546 delete d->graphicsEffect;
1547#endif
1548}
1549
1550int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances
1551int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances
1552
1553void QWidgetPrivate::setWinId(WId id) // set widget identifier
1554{
1555 Q_Q(QWidget);
1556 // the user might create a widget with Qt::Desktop window
1557 // attribute (or create another QDesktopWidget instance), which
1558 // will have the same windowid (the root window id) as the
1559 // qt_desktopWidget. We should not add the second desktop widget
1560 // to the mapper.
1561 bool userDesktopWidget = qt_desktopWidget != nullptr && qt_desktopWidget != q && q->windowType() == Qt::Desktop;
1562 if (mapper && data.winid && !userDesktopWidget) {
1563 mapper->remove(key: data.winid);
1564 }
1565
1566 const WId oldWinId = data.winid;
1567
1568 data.winid = id;
1569 if (mapper && id && !userDesktopWidget) {
1570 mapper->insert(key: data.winid, value: q);
1571 }
1572
1573 if(oldWinId != id) {
1574 QEvent e(QEvent::WinIdChange);
1575 QCoreApplication::sendEvent(receiver: q, event: &e);
1576 }
1577}
1578
1579void QWidgetPrivate::createTLExtra()
1580{
1581 if (!extra)
1582 createExtra();
1583 if (!extra->topextra) {
1584 extra->topextra = qt_make_unique<QTLWExtra>();
1585 QTLWExtra* x = extra->topextra.get();
1586 x->backingStore = nullptr;
1587 x->sharedPainter = nullptr;
1588 x->incw = x->inch = 0;
1589 x->basew = x->baseh = 0;
1590 x->frameStrut.setCoords(xp1: 0, yp1: 0, xp2: 0, yp2: 0);
1591 x->normalGeometry = QRect(0,0,-1,-1);
1592 x->savedFlags = { };
1593 x->opacity = 255;
1594 x->posIncludesFrame = 0;
1595 x->sizeAdjusted = false;
1596 x->embedded = 0;
1597 x->window = nullptr;
1598 x->initialScreenIndex = -1;
1599
1600#ifdef QWIDGET_EXTRA_DEBUG
1601 static int count = 0;
1602 qDebug() << "tlextra" << ++count;
1603#endif
1604 }
1605}
1606
1607/*!
1608 \internal
1609 Creates the widget extra data.
1610*/
1611
1612void QWidgetPrivate::createExtra()
1613{
1614 if (!extra) { // if not exists
1615 extra = qt_make_unique<QWExtra>();
1616 extra->glContext = nullptr;
1617#if QT_CONFIG(graphicsview)
1618 extra->proxyWidget = nullptr;
1619#endif
1620 extra->minw = 0;
1621 extra->minh = 0;
1622 extra->maxw = QWIDGETSIZE_MAX;
1623 extra->maxh = QWIDGETSIZE_MAX;
1624 extra->customDpiX = 0;
1625 extra->customDpiY = 0;
1626 extra->explicitMinSize = 0;
1627 extra->explicitMaxSize = 0;
1628 extra->autoFillBackground = 0;
1629 extra->nativeChildrenForced = 0;
1630 extra->inRenderWithPainter = 0;
1631 extra->hasWindowContainer = false;
1632 extra->hasMask = 0;
1633 createSysExtra();
1634#ifdef QWIDGET_EXTRA_DEBUG
1635 static int count = 0;
1636 qDebug() << "extra" << ++count;
1637#endif
1638 }
1639}
1640
1641void QWidgetPrivate::createSysExtra()
1642{
1643}
1644
1645/*!
1646 \internal
1647 Deletes the widget extra data.
1648*/
1649
1650void QWidgetPrivate::deleteExtra()
1651{
1652 if (extra) { // if exists
1653 deleteSysExtra();
1654#ifndef QT_NO_STYLE_STYLESHEET
1655 // dereference the stylesheet style
1656 if (QStyleSheetStyle *proxy = qt_styleSheet(style: extra->style))
1657 proxy->deref();
1658#endif
1659 if (extra->topextra) {
1660 deleteTLSysExtra();
1661 // extra->topextra->backingStore destroyed in QWidgetPrivate::deleteTLSysExtra()
1662 }
1663 // extra->xic destroyed in QWidget::destroy()
1664 extra.reset();
1665 }
1666}
1667
1668void QWidgetPrivate::deleteSysExtra()
1669{
1670}
1671
1672static void deleteBackingStore(QWidgetPrivate *d)
1673{
1674 QTLWExtra *topData = d->topData();
1675
1676 delete topData->backingStore;
1677 topData->backingStore = nullptr;
1678}
1679
1680void QWidgetPrivate::deleteTLSysExtra()
1681{
1682 if (extra && extra->topextra) {
1683 //the qplatformbackingstore may hold a reference to the window, so the backingstore
1684 //needs to be deleted first.
1685
1686 extra->topextra->repaintManager.reset(p: nullptr);
1687 deleteBackingStore(d: this);
1688#ifndef QT_NO_OPENGL
1689 extra->topextra->widgetTextures.clear();
1690 extra->topextra->shareContext.reset();
1691#endif
1692
1693 //the toplevel might have a context with a "qglcontext associated with it. We need to
1694 //delete the qglcontext before we delete the qplatformopenglcontext.
1695 //One unfortunate thing about this is that we potentially create a glContext just to
1696 //delete it straight afterwards.
1697 if (extra->topextra->window) {
1698 extra->topextra->window->destroy();
1699 }
1700 delete extra->topextra->window;
1701 extra->topextra->window = nullptr;
1702
1703 }
1704}
1705
1706/*
1707 Returns \c region of widgets above this which overlap with
1708 \a rect, which is in parent's coordinate system (same as crect).
1709*/
1710
1711QRegion QWidgetPrivate::overlappedRegion(const QRect &rect, bool breakAfterFirst) const
1712{
1713 Q_Q(const QWidget);
1714
1715 const QWidget *w = q;
1716 QRect r = rect;
1717 QPoint p;
1718 QRegion region;
1719 while (w) {
1720 if (w->isWindow())
1721 break;
1722 QWidgetPrivate *pd = w->parentWidget()->d_func();
1723 bool above = false;
1724 for (int i = 0; i < pd->children.size(); ++i) {
1725 QWidget *sibling = qobject_cast<QWidget *>(o: pd->children.at(i));
1726 if (!sibling || !sibling->isVisible() || sibling->isWindow())
1727 continue;
1728 if (!above) {
1729 above = (sibling == w);
1730 continue;
1731 }
1732
1733 const QRect siblingRect = sibling->d_func()->effectiveRectFor(rect: sibling->data->crect);
1734 if (qRectIntersects(r1: siblingRect, r2: r)) {
1735 const auto &siblingExtra = sibling->d_func()->extra;
1736 if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
1737 && !siblingExtra->mask.translated(p: sibling->data->crect.topLeft()).intersects(r)) {
1738 continue;
1739 }
1740 region += siblingRect.translated(p: -p);
1741 if (breakAfterFirst)
1742 break;
1743 }
1744 }
1745 w = w->parentWidget();
1746 r.translate(p: pd->data.crect.topLeft());
1747 p += pd->data.crect.topLeft();
1748 }
1749 return region;
1750}
1751
1752void QWidgetPrivate::syncBackingStore()
1753{
1754 if (shouldPaintOnScreen()) {
1755 paintOnScreen(rgn: dirty);
1756 dirty = QRegion();
1757 } else if (QWidgetRepaintManager *repaintManager = maybeRepaintManager()) {
1758 repaintManager->sync();
1759 }
1760}
1761
1762void QWidgetPrivate::syncBackingStore(const QRegion &region)
1763{
1764 if (shouldPaintOnScreen())
1765 paintOnScreen(rgn: region);
1766 else if (QWidgetRepaintManager *repaintManager = maybeRepaintManager()) {
1767 repaintManager->sync(exposedWidget: q_func(), exposedRegion: region);
1768 }
1769}
1770
1771void QWidgetPrivate::paintOnScreen(const QRegion &rgn)
1772{
1773 if (data.in_destructor)
1774 return;
1775
1776 if (shouldDiscardSyncRequest())
1777 return;
1778
1779 Q_Q(QWidget);
1780 if (q->testAttribute(attribute: Qt::WA_StaticContents)) {
1781 if (!extra)
1782 createExtra();
1783 extra->staticContentsSize = data.crect.size();
1784 }
1785
1786 QPaintEngine *engine = q->paintEngine();
1787
1788 // QGLWidget does not support partial updates if:
1789 // 1) The context is double buffered
1790 // 2) The context is single buffered and auto-fill background is enabled.
1791 const bool noPartialUpdateSupport = (engine && (engine->type() == QPaintEngine::OpenGL
1792 || engine->type() == QPaintEngine::OpenGL2))
1793 && (usesDoubleBufferedGLContext || q->autoFillBackground());
1794 QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn);
1795
1796 toBePainted &= clipRect();
1797 clipToEffectiveMask(region&: toBePainted);
1798 if (toBePainted.isEmpty())
1799 return; // Nothing to repaint.
1800
1801 drawWidget(pdev: q, rgn: toBePainted, offset: QPoint(), flags: QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen, sharedPainter: nullptr);
1802
1803 if (Q_UNLIKELY(q->paintingActive()))
1804 qWarning(msg: "QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
1805}
1806
1807void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
1808{
1809 Q_Q(QWidget);
1810
1811 if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled())
1812 return; // nothing we can do
1813
1814 if (enable != q->testAttribute(attribute: Qt::WA_UpdatesDisabled))
1815 return; // nothing to do
1816
1817 q->setAttribute(Qt::WA_UpdatesDisabled, on: !enable);
1818 if (enable)
1819 q->update();
1820
1821 Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
1822 for (int i = 0; i < children.size(); ++i) {
1823 QWidget *w = qobject_cast<QWidget *>(o: children.at(i));
1824 if (w && !w->isWindow() && !w->testAttribute(attribute))
1825 w->d_func()->setUpdatesEnabled_helper(enable);
1826 }
1827}
1828
1829/*!
1830 \internal
1831
1832 Propagate this widget's palette to all children, except style sheet
1833 widgets, and windows that don't enable window propagation (palettes don't
1834 normally propagate to windows).
1835*/
1836void QWidgetPrivate::propagatePaletteChange()
1837{
1838 Q_Q(QWidget);
1839 // Propagate a new inherited mask to all children.
1840#if QT_CONFIG(graphicsview)
1841 if (!q->parentWidget() && extra && extra->proxyWidget) {
1842 QGraphicsProxyWidget *p = extra->proxyWidget;
1843 inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolve();
1844 } else
1845#endif // QT_CONFIG(graphicsview)
1846 if (q->isWindow() && !q->testAttribute(attribute: Qt::WA_WindowPropagation)) {
1847 inheritedPaletteResolveMask = 0;
1848 }
1849
1850 directPaletteResolveMask = data.pal.resolve();
1851 auto mask = directPaletteResolveMask | inheritedPaletteResolveMask;
1852
1853 const bool useStyleSheetPropagationInWidgetStyles =
1854 QCoreApplication::testAttribute(attribute: Qt::AA_UseStyleSheetPropagationInWidgetStyles);
1855
1856 QEvent pc(QEvent::PaletteChange);
1857 QCoreApplication::sendEvent(receiver: q, event: &pc);
1858 for (int i = 0; i < children.size(); ++i) {
1859 QWidget *w = qobject_cast<QWidget*>(o: children.at(i));
1860 if (w && (!w->testAttribute(attribute: Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
1861 && (!w->isWindow() || w->testAttribute(attribute: Qt::WA_WindowPropagation))) {
1862 QWidgetPrivate *wd = w->d_func();
1863 wd->inheritedPaletteResolveMask = mask;
1864 wd->resolvePalette();
1865 }
1866 }
1867}
1868
1869/*
1870 Returns the widget's clipping rectangle.
1871*/
1872QRect QWidgetPrivate::clipRect() const
1873{
1874 Q_Q(const QWidget);
1875 const QWidget * w = q;
1876 if (!w->isVisible())
1877 return QRect();
1878 QRect r = effectiveRectFor(rect: q->rect());
1879 int ox = 0;
1880 int oy = 0;
1881 while (w
1882 && w->isVisible()
1883 && !w->isWindow()
1884 && w->parentWidget()) {
1885 ox -= w->x();
1886 oy -= w->y();
1887 w = w->parentWidget();
1888 r &= QRect(ox, oy, w->width(), w->height());
1889 }
1890 return r;
1891}
1892
1893/*
1894 Returns the widget's clipping region (without siblings).
1895*/
1896QRegion QWidgetPrivate::clipRegion() const
1897{
1898 Q_Q(const QWidget);
1899 if (!q->isVisible())
1900 return QRegion();
1901 QRegion r(q->rect());
1902 const QWidget * w = q;
1903 const QWidget *ignoreUpTo;
1904 int ox = 0;
1905 int oy = 0;
1906 while (w
1907 && w->isVisible()
1908 && !w->isWindow()
1909 && w->parentWidget()) {
1910 ox -= w->x();
1911 oy -= w->y();
1912 ignoreUpTo = w;
1913 w = w->parentWidget();
1914 r &= QRegion(ox, oy, w->width(), w->height());
1915
1916 int i = 0;
1917 while(w->d_func()->children.at(i: i++) != static_cast<const QObject *>(ignoreUpTo))
1918 ;
1919 for ( ; i < w->d_func()->children.size(); ++i) {
1920 if(QWidget *sibling = qobject_cast<QWidget *>(o: w->d_func()->children.at(i))) {
1921 if(sibling->isVisible() && !sibling->isWindow()) {
1922 QRect siblingRect(ox+sibling->x(), oy+sibling->y(),
1923 sibling->width(), sibling->height());
1924 if (qRectIntersects(r1: siblingRect, r2: q->rect()))
1925 r -= QRegion(siblingRect);
1926 }
1927 }
1928 }
1929 }
1930 return r;
1931}
1932
1933void QWidgetPrivate::setSystemClip(QPaintEngine *paintEngine, qreal devicePixelRatio, const QRegion &region)
1934{
1935// Transform the system clip region from device-independent pixels to device pixels
1936 QTransform scaleTransform;
1937 scaleTransform.scale(sx: devicePixelRatio, sy: devicePixelRatio);
1938
1939 paintEngine->d_func()->baseSystemClip = region;
1940 paintEngine->d_func()->setSystemTransform(scaleTransform);
1941
1942}
1943
1944#if QT_CONFIG(graphicseffect)
1945void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
1946{
1947 Q_Q(QWidget);
1948 QWidget *w = q;
1949 do {
1950 if (w->graphicsEffect()) {
1951 QWidgetEffectSourcePrivate *sourced =
1952 static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
1953 if (!sourced->updateDueToGraphicsEffect)
1954 w->graphicsEffect()->source()->d_func()->invalidateCache();
1955 }
1956 w = w->parentWidget();
1957 } while (w);
1958}
1959#endif // QT_CONFIG(graphicseffect)
1960
1961void QWidgetPrivate::setDirtyOpaqueRegion()
1962{
1963 Q_Q(QWidget);
1964
1965 dirtyOpaqueChildren = true;
1966
1967#if QT_CONFIG(graphicseffect)
1968 invalidateGraphicsEffectsRecursively();
1969#endif // QT_CONFIG(graphicseffect)
1970
1971 if (q->isWindow())
1972 return;
1973
1974 QWidget *parent = q->parentWidget();
1975 if (!parent)
1976 return;
1977
1978 // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly?
1979 QWidgetPrivate *pd = parent->d_func();
1980 if (!pd->dirtyOpaqueChildren)
1981 pd->setDirtyOpaqueRegion();
1982}
1983
1984const QRegion &QWidgetPrivate::getOpaqueChildren() const
1985{
1986 if (!dirtyOpaqueChildren)
1987 return opaqueChildren;
1988
1989 QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
1990 that->opaqueChildren = QRegion();
1991
1992 for (int i = 0; i < children.size(); ++i) {
1993 QWidget *child = qobject_cast<QWidget *>(o: children.at(i));
1994 if (!child || !child->isVisible() || child->isWindow())
1995 continue;
1996
1997 const QPoint offset = child->geometry().topLeft();
1998 QWidgetPrivate *childd = child->d_func();
1999 QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren();
2000 if (childd->extra && childd->extra->hasMask)
2001 r &= childd->extra->mask;
2002 if (r.isEmpty())
2003 continue;
2004 r.translate(p: offset);
2005 that->opaqueChildren += r;
2006 }
2007
2008 that->opaqueChildren &= q_func()->rect();
2009 that->dirtyOpaqueChildren = false;
2010
2011 return that->opaqueChildren;
2012}
2013
2014void QWidgetPrivate::subtractOpaqueChildren(QRegion &source, const QRect &clipRect) const
2015{
2016 if (children.isEmpty() || clipRect.isEmpty())
2017 return;
2018
2019 const QRegion &r = getOpaqueChildren();
2020 if (!r.isEmpty())
2021 source -= (r & clipRect);
2022}
2023
2024//subtract any relatives that are higher up than me --- this is too expensive !!!
2025void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirtySiblingsAbove,
2026 bool alsoNonOpaque) const
2027{
2028 Q_Q(const QWidget);
2029 static int disableSubtractOpaqueSiblings = qEnvironmentVariableIntValue(varName: "QT_NO_SUBTRACTOPAQUESIBLINGS");
2030 if (disableSubtractOpaqueSiblings || q->isWindow())
2031 return;
2032
2033 QRect clipBoundingRect;
2034 bool dirtyClipBoundingRect = true;
2035
2036 QRegion parentClip;
2037 bool dirtyParentClip = true;
2038
2039 QPoint parentOffset = data.crect.topLeft();
2040
2041 const QWidget *w = q;
2042
2043 while (w) {
2044 if (w->isWindow())
2045 break;
2046 QWidgetPrivate *pd = w->parentWidget()->d_func();
2047 const int myIndex = pd->children.indexOf(t: const_cast<QWidget *>(w));
2048 const QRect widgetGeometry = w->d_func()->effectiveRectFor(rect: w->data->crect);
2049 for (int i = myIndex + 1; i < pd->children.size(); ++i) {
2050 QWidget *sibling = qobject_cast<QWidget *>(o: pd->children.at(i));
2051 if (!sibling || !sibling->isVisible() || sibling->isWindow())
2052 continue;
2053
2054 const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(rect: sibling->data->crect);
2055 if (!qRectIntersects(r1: siblingGeometry, r2: widgetGeometry))
2056 continue;
2057
2058 if (dirtyClipBoundingRect) {
2059 clipBoundingRect = sourceRegion.boundingRect();
2060 dirtyClipBoundingRect = false;
2061 }
2062
2063 if (!qRectIntersects(r1: siblingGeometry, r2: clipBoundingRect.translated(p: parentOffset)))
2064 continue;
2065
2066 if (dirtyParentClip) {
2067 parentClip = sourceRegion.translated(p: parentOffset);
2068 dirtyParentClip = false;
2069 }
2070
2071 const QPoint siblingPos(sibling->data->crect.topLeft());
2072 const QRect siblingClipRect(sibling->d_func()->clipRect());
2073 QRegion siblingDirty(parentClip);
2074 siblingDirty &= (siblingClipRect.translated(p: siblingPos));
2075 const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
2076 && !sibling->d_func()->graphicsEffect;
2077 if (hasMask)
2078 siblingDirty &= sibling->d_func()->extra->mask.translated(p: siblingPos);
2079 if (siblingDirty.isEmpty())
2080 continue;
2081
2082 if (sibling->d_func()->isOpaque || alsoNonOpaque) {
2083 if (hasMask) {
2084 siblingDirty.translate(p: -parentOffset);
2085 sourceRegion -= siblingDirty;
2086 } else {
2087 sourceRegion -= siblingGeometry.translated(p: -parentOffset);
2088 }
2089 } else {
2090 if (hasDirtySiblingsAbove)
2091 *hasDirtySiblingsAbove = true;
2092 if (sibling->d_func()->children.isEmpty())
2093 continue;
2094 QRegion opaqueSiblingChildren(sibling->d_func()->getOpaqueChildren());
2095 opaqueSiblingChildren.translate(p: -parentOffset + siblingPos);
2096 sourceRegion -= opaqueSiblingChildren;
2097 }
2098 if (sourceRegion.isEmpty())
2099 return;
2100
2101 dirtyClipBoundingRect = true;
2102 dirtyParentClip = true;
2103 }
2104
2105 w = w->parentWidget();
2106 parentOffset += pd->data.crect.topLeft();
2107 dirtyParentClip = true;
2108 }
2109}
2110
2111void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
2112{
2113 Q_Q(const QWidget);
2114
2115 const QWidget *w = q;
2116 QPoint offset;
2117
2118#if QT_CONFIG(graphicseffect)
2119 if (graphicsEffect) {
2120 w = q->parentWidget();
2121 offset -= data.crect.topLeft();
2122 }
2123#endif // QT_CONFIG(graphicseffect)
2124
2125 while (w) {
2126 const QWidgetPrivate *wd = w->d_func();
2127 if (wd->extra && wd->extra->hasMask)
2128 region &= (w != q) ? wd->extra->mask.translated(p: offset) : wd->extra->mask;
2129 if (w->isWindow())
2130 return;
2131 offset -= wd->data.crect.topLeft();
2132 w = w->parentWidget();
2133 }
2134}
2135
2136bool QWidgetPrivate::shouldPaintOnScreen() const
2137{
2138#if defined(QT_NO_BACKINGSTORE)
2139 return true;
2140#else
2141 Q_Q(const QWidget);
2142 if (q->testAttribute(attribute: Qt::WA_PaintOnScreen)
2143 || (!q->isWindow() && q->window()->testAttribute(attribute: Qt::WA_PaintOnScreen))) {
2144 return true;
2145 }
2146
2147 return false;
2148#endif
2149}
2150
2151void QWidgetPrivate::updateIsOpaque()
2152{
2153 // hw: todo: only needed if opacity actually changed
2154 setDirtyOpaqueRegion();
2155
2156#if QT_CONFIG(graphicseffect)
2157 if (graphicsEffect) {
2158 // ### We should probably add QGraphicsEffect::isOpaque at some point.
2159 setOpaque(false);
2160 return;
2161 }
2162#endif // QT_CONFIG(graphicseffect)
2163
2164 Q_Q(QWidget);
2165 if (q->testAttribute(attribute: Qt::WA_OpaquePaintEvent) || q->testAttribute(attribute: Qt::WA_PaintOnScreen)) {
2166 setOpaque(true);
2167 return;
2168 }
2169
2170 const QPalette &pal = q->palette();
2171
2172 if (q->autoFillBackground()) {
2173 const QBrush &autoFillBrush = pal.brush(cr: q->backgroundRole());
2174 if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
2175 setOpaque(true);
2176 return;
2177 }
2178 }
2179
2180 if (q->isWindow() && !q->testAttribute(attribute: Qt::WA_NoSystemBackground)) {
2181 const QBrush &windowBrush = q->palette().brush(cr: QPalette::Window);
2182 if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
2183 setOpaque(true);
2184 return;
2185 }
2186 }
2187 setOpaque(false);
2188}
2189
2190void QWidgetPrivate::setOpaque(bool opaque)
2191{
2192 if (isOpaque != opaque) {
2193 isOpaque = opaque;
2194 updateIsTranslucent();
2195 }
2196}
2197
2198void QWidgetPrivate::updateIsTranslucent()
2199{
2200 Q_Q(QWidget);
2201 if (QWindow *window = q->windowHandle()) {
2202 QSurfaceFormat format = window->format();
2203 const int oldAlpha = format.alphaBufferSize();
2204 const int newAlpha = q->testAttribute(attribute: Qt::WA_TranslucentBackground)? 8 : 0;
2205 if (oldAlpha != newAlpha) {
2206 format.setAlphaBufferSize(newAlpha);
2207 window->setFormat(format);
2208 }
2209 }
2210}
2211
2212static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
2213{
2214 Q_ASSERT(painter);
2215
2216 if (brush.style() == Qt::TexturePattern) {
2217 const QRect rect(rgn.boundingRect());
2218 painter->setClipRegion(rgn);
2219 painter->drawTiledPixmap(rect, pm: brush.texture(), offset: rect.topLeft());
2220 } else if (brush.gradient()
2221 && (brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode
2222 || brush.gradient()->coordinateMode() == QGradient::ObjectMode)) {
2223 painter->save();
2224 painter->setClipRegion(rgn);
2225 painter->fillRect(x: 0, y: 0, w: painter->device()->width(), h: painter->device()->height(), b: brush);
2226 painter->restore();
2227 } else {
2228 for (const QRect &rect : rgn)
2229 painter->fillRect(rect, brush);
2230 }
2231}
2232
2233bool QWidgetPrivate::updateBrushOrigin(QPainter *painter, const QBrush &brush) const
2234{
2235#if QT_CONFIG(scrollarea)
2236 Q_Q(const QWidget);
2237 //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
2238 if (brush.style() == Qt::NoBrush || brush.style() == Qt::SolidPattern)
2239 return false;
2240 QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(object: parent);
2241 if (scrollArea && scrollArea->viewport() == q) {
2242 QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
2243 QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
2244 painter->setBrushOrigin(-priv->contentsOffset());
2245 }
2246#endif // QT_CONFIG(scrollarea)
2247 return true;
2248}
2249
2250void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, DrawWidgetFlags flags) const
2251{
2252 Q_Q(const QWidget);
2253
2254 bool brushOriginSet = false;
2255 const QBrush autoFillBrush = q->palette().brush(cr: q->backgroundRole());
2256
2257 if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
2258 const QBrush bg = q->palette().brush(cr: QPalette::Window);
2259 if (!brushOriginSet)
2260 brushOriginSet = updateBrushOrigin(painter, brush: bg);
2261 if (!(flags & DontSetCompositionMode)) {
2262 //copy alpha straight in
2263 QPainter::CompositionMode oldMode = painter->compositionMode();
2264 painter->setCompositionMode(QPainter::CompositionMode_Source);
2265 fillRegion(painter, rgn, brush: bg);
2266 painter->setCompositionMode(oldMode);
2267 } else {
2268 fillRegion(painter, rgn, brush: bg);
2269 }
2270 }
2271
2272 if (q->autoFillBackground()) {
2273 if (!brushOriginSet)
2274 brushOriginSet = updateBrushOrigin(painter, brush: autoFillBrush);
2275 fillRegion(painter, rgn, brush: autoFillBrush);
2276 }
2277
2278 if (q->testAttribute(attribute: Qt::WA_StyledBackground)) {
2279 painter->setClipRegion(rgn);
2280 QStyleOption opt;
2281 opt.initFrom(w: q);
2282 q->style()->drawPrimitive(pe: QStyle::PE_Widget, opt: &opt, p: painter, w: q);
2283 }
2284}
2285
2286/*
2287 \internal
2288 This function is called when a widget is hidden or destroyed.
2289 It resets some application global pointers that should only refer active,
2290 visible widgets.
2291*/
2292
2293extern QWidget *qt_button_down;
2294
2295void QWidgetPrivate::deactivateWidgetCleanup()
2296{
2297 Q_Q(QWidget);
2298 // If this was the active application window, reset it
2299 if (QApplication::activeWindow() == q)
2300 QApplication::setActiveWindow(nullptr);
2301 // If the is the active mouse press widget, reset it
2302 if (q == qt_button_down)
2303 qt_button_down = nullptr;
2304}
2305
2306
2307/*!
2308 Returns a pointer to the widget with window identifer/handle \a
2309 id.
2310
2311 The window identifier type depends on the underlying window
2312 system, see \c qwindowdefs.h for the actual definition. If there
2313 is no widget with this identifier, \nullptr is returned.
2314*/
2315
2316QWidget *QWidget::find(WId id)
2317{
2318 return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(key: id, defaultValue: 0) : nullptr;
2319}
2320
2321
2322
2323/*!
2324 \fn WId QWidget::internalWinId() const
2325 \internal
2326 Returns the window system identifier of the widget, or 0 if the widget is not created yet.
2327
2328*/
2329
2330/*!
2331 \fn WId QWidget::winId() const
2332
2333 Returns the window system identifier of the widget.
2334
2335 Portable in principle, but if you use it you are probably about to
2336 do something non-portable. Be careful.
2337
2338 If a widget is non-native (alien) and winId() is invoked on it, that widget
2339 will be provided a native handle.
2340
2341 This value may change at run-time. An event with type QEvent::WinIdChange
2342 will be sent to the widget following a change in window system identifier.
2343
2344 \sa find()
2345*/
2346WId QWidget::winId() const
2347{
2348 if (!data->in_destructor
2349 && (!testAttribute(attribute: Qt::WA_WState_Created) || !internalWinId()))
2350 {
2351#ifdef ALIEN_DEBUG
2352 qDebug() << "QWidget::winId: creating native window for" << this;
2353#endif
2354 QWidget *that = const_cast<QWidget*>(this);
2355 that->setAttribute(Qt::WA_NativeWindow);
2356 that->d_func()->createWinId();
2357 return that->data->winid;
2358 }
2359 return data->winid;
2360}
2361
2362void QWidgetPrivate::createWinId()
2363{
2364 Q_Q(QWidget);
2365
2366#ifdef ALIEN_DEBUG
2367 qDebug() << "QWidgetPrivate::createWinId for" << q;
2368#endif
2369 const bool forceNativeWindow = q->testAttribute(attribute: Qt::WA_NativeWindow);
2370 if (!q->testAttribute(attribute: Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
2371 if (!q->isWindow()) {
2372 QWidget *parent = q->parentWidget();
2373 QWidgetPrivate *pd = parent->d_func();
2374 if (forceNativeWindow && !q->testAttribute(attribute: Qt::WA_DontCreateNativeAncestors))
2375 parent->setAttribute(Qt::WA_NativeWindow);
2376 if (!parent->internalWinId()) {
2377 pd->createWinId();
2378 }
2379
2380 for (int i = 0; i < pd->children.size(); ++i) {
2381 QWidget *w = qobject_cast<QWidget *>(o: pd->children.at(i));
2382 if (w && !w->isWindow() && (!w->testAttribute(attribute: Qt::WA_WState_Created)
2383 || (!w->internalWinId() && w->testAttribute(attribute: Qt::WA_NativeWindow)))) {
2384 w->create();
2385 }
2386 }
2387 } else {
2388 q->create();
2389 }
2390 }
2391}
2392
2393/*!
2394\internal
2395Ensures that the widget is set on the screen point is on. This is handy getting a correct
2396size hint before a resize in e.g QMenu and QToolTip.
2397Returns if the screen was changed.
2398*/
2399
2400bool QWidgetPrivate::setScreenForPoint(const QPoint &pos)
2401{
2402 Q_Q(QWidget);
2403 if (!q->isWindow())
2404 return false;
2405 // Find the screen for pos and make the widget understand it is on that screen.
2406 return setScreen(QGuiApplication::screenAt(point: pos));
2407}
2408
2409/*!
2410\internal
2411Ensures that the widget's QWindow is set to be on the given \a screen.
2412Returns true if the screen was changed.
2413*/
2414
2415bool QWidgetPrivate::setScreen(QScreen *screen)
2416{
2417 Q_Q(QWidget);
2418 if (!screen || !q->isWindow())
2419 return false;
2420 const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
2421 if (currentScreen != screen) {
2422 if (!windowHandle()) // Try to create a window handle if not created.
2423 createWinId();
2424 if (windowHandle())
2425 windowHandle()->setScreen(screen);
2426 return true;
2427 }
2428 return false;
2429}
2430
2431/*!
2432\internal
2433Ensures that the widget has a window system identifier, i.e. that it is known to the windowing system.
2434
2435*/
2436
2437void QWidget::createWinId()
2438{
2439 Q_D(QWidget);
2440#ifdef ALIEN_DEBUG
2441 qDebug() << "QWidget::createWinId" << this;
2442#endif
2443// qWarning("QWidget::createWinId is obsolete, please fix your code.");
2444 d->createWinId();
2445}
2446
2447/*!
2448 \since 4.4
2449
2450 Returns the effective window system identifier of the widget, i.e. the
2451 native parent's window system identifier.
2452
2453 If the widget is native, this function returns the native widget ID.
2454 Otherwise, the window ID of the first native parent widget, i.e., the
2455 top-level widget that contains this widget, is returned.
2456
2457 \note We recommend that you do not store this value as it is likely to
2458 change at run-time.
2459
2460 \sa nativeParentWidget()
2461*/
2462WId QWidget::effectiveWinId() const
2463{
2464 const WId id = internalWinId();
2465 if (id || !testAttribute(attribute: Qt::WA_WState_Created))
2466 return id;
2467 if (const QWidget *realParent = nativeParentWidget())
2468 return realParent->internalWinId();
2469 return 0;
2470}
2471
2472/*!
2473 If this is a native widget, return the associated QWindow.
2474 Otherwise return null.
2475
2476 Native widgets include toplevel widgets, QGLWidget, and child widgets
2477 on which winId() was called.
2478
2479 \since 5.0
2480
2481 \sa winId(), screen()
2482*/
2483QWindow *QWidget::windowHandle() const
2484{
2485 Q_D(const QWidget);
2486 return d->windowHandle();
2487}
2488
2489/*!
2490 Returns the screen the widget is on.
2491
2492 \since 5.14
2493
2494 \sa windowHandle()
2495*/
2496QScreen *QWidget::screen() const
2497{
2498 Q_D(const QWidget);
2499 if (auto associatedScreen = d->associatedScreen())
2500 return associatedScreen;
2501 if (auto topLevel = window()) {
2502 if (auto topData = qt_widget_private(widget: topLevel)->topData()) {
2503 if (auto initialScreen = QGuiApplicationPrivate::screen_list.value(i: topData->initialScreenIndex))
2504 return initialScreen;
2505 }
2506 if (auto screenByPos = QGuiApplication::screenAt(point: topLevel->geometry().center()))
2507 return screenByPos;
2508 }
2509 return QGuiApplication::primaryScreen();
2510}
2511
2512#ifndef QT_NO_STYLE_STYLESHEET
2513
2514/*!
2515 \property QWidget::styleSheet
2516 \brief the widget's style sheet
2517 \since 4.2
2518
2519 The style sheet contains a textual description of customizations to the
2520 widget's style, as described in the \l{Qt Style Sheets} document.
2521
2522 Since Qt 4.5, Qt style sheets fully supports \macos.
2523
2524 \warning Qt style sheets are currently not supported for custom QStyle
2525 subclasses. We plan to address this in some future release.
2526
2527 \sa setStyle(), QApplication::styleSheet, {Qt Style Sheets}
2528*/
2529QString QWidget::styleSheet() const
2530{
2531 Q_D(const QWidget);
2532 if (!d->extra)
2533 return QString();
2534 return d->extra->styleSheet;
2535}
2536
2537void QWidget::setStyleSheet(const QString& styleSheet)
2538{
2539 Q_D(QWidget);
2540 if (data->in_destructor)
2541 return;
2542 d->createExtra();
2543
2544 QStyleSheetStyle *proxy = qt_styleSheet(style: d->extra->style);
2545 d->extra->styleSheet = styleSheet;
2546 if (styleSheet.isEmpty()) { // stylesheet removed
2547 if (!proxy)
2548 return;
2549
2550 d->inheritStyle();
2551 return;
2552 }
2553
2554 if (proxy) { // style sheet update
2555 if (d->polished)
2556 proxy->repolish(widget: this);
2557 return;
2558 }
2559
2560 if (testAttribute(attribute: Qt::WA_SetStyle)) {
2561 d->setStyle_helper(newStyle: new QStyleSheetStyle(d->extra->style), propagate: true);
2562 } else {
2563 d->setStyle_helper(newStyle: new QStyleSheetStyle(nullptr), propagate: true);
2564 }
2565}
2566
2567#endif // QT_NO_STYLE_STYLESHEET
2568
2569/*!
2570 \sa QWidget::setStyle(), QApplication::setStyle(), QApplication::style()
2571*/
2572
2573QStyle *QWidget::style() const
2574{
2575 Q_D(const QWidget);
2576
2577 if (d->extra && d->extra->style)
2578 return d->extra->style;
2579 return QApplication::style();
2580}
2581
2582/*!
2583 Sets the widget's GUI style to \a style. The ownership of the style
2584 object is not transferred.
2585
2586 If no style is set, the widget uses the application's style,
2587 QApplication::style() instead.
2588
2589 Setting a widget's style has no effect on existing or future child
2590 widgets.
2591
2592 \warning This function is particularly useful for demonstration
2593 purposes, where you want to show Qt's styling capabilities. Real
2594 applications should avoid it and use one consistent GUI style
2595 instead.
2596
2597 \warning Qt style sheets are currently not supported for custom QStyle
2598 subclasses. We plan to address this in some future release.
2599
2600 \sa style(), QStyle, QApplication::style(), QApplication::setStyle()
2601*/
2602
2603void QWidget::setStyle(QStyle *style)
2604{
2605 Q_D(QWidget);
2606 setAttribute(Qt::WA_SetStyle, on: style != nullptr);
2607 d->createExtra();
2608#ifndef QT_NO_STYLE_STYLESHEET
2609 if (QStyleSheetStyle *styleSheetStyle = qt_styleSheet(style)) {
2610 //if for some reason someone try to set a QStyleSheetStyle, ref it
2611 //(this may happen for exemple in QButtonDialogBox which propagates its style)
2612 styleSheetStyle->ref();
2613 d->setStyle_helper(newStyle: style, propagate: false);
2614 } else if (qt_styleSheet(style: d->extra->style) || !qApp->styleSheet().isEmpty()) {
2615 // if we have an application stylesheet or have a proxy already, propagate
2616 d->setStyle_helper(newStyle: new QStyleSheetStyle(style), propagate: true);
2617 } else
2618#endif
2619 d->setStyle_helper(newStyle: style, propagate: false);
2620}
2621
2622void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate)
2623{
2624 Q_Q(QWidget);
2625 QStyle *oldStyle = q->style();
2626
2627 createExtra();
2628
2629#ifndef QT_NO_STYLE_STYLESHEET
2630 QPointer<QStyle> origStyle = extra->style;
2631#endif
2632 extra->style = newStyle;
2633
2634 // repolish
2635 if (polished && q->windowType() != Qt::Desktop) {
2636 oldStyle->unpolish(widget: q);
2637 q->style()->polish(widget: q);
2638 }
2639
2640 if (propagate) {
2641 // We copy the list because the order may be modified
2642 const QObjectList childrenList = children;
2643 for (int i = 0; i < childrenList.size(); ++i) {
2644 QWidget *c = qobject_cast<QWidget*>(o: childrenList.at(i));
2645 if (c)
2646 c->d_func()->inheritStyle();
2647 }
2648 }
2649
2650#ifndef QT_NO_STYLE_STYLESHEET
2651 if (!qt_styleSheet(style: newStyle)) {
2652 if (const QStyleSheetStyle* cssStyle = qt_styleSheet(style: origStyle)) {
2653 cssStyle->clearWidgetFont(w: q);
2654 }
2655 }
2656#endif
2657
2658 QEvent e(QEvent::StyleChange);
2659 QCoreApplication::sendEvent(receiver: q, event: &e);
2660
2661#ifndef QT_NO_STYLE_STYLESHEET
2662 // dereference the old stylesheet style
2663 if (QStyleSheetStyle *proxy = qt_styleSheet(style: origStyle))
2664 proxy->deref();
2665#endif
2666}
2667
2668// Inherits style from the current parent and propagates it as necessary
2669void QWidgetPrivate::inheritStyle()
2670{
2671#ifndef QT_NO_STYLE_STYLESHEET
2672 Q_Q(QWidget);
2673
2674 QStyle *extraStyle = extra ? (QStyle*)extra->style : nullptr;
2675
2676 QStyleSheetStyle *proxy = qt_styleSheet(style: extraStyle);
2677
2678 if (!q->styleSheet().isEmpty()) {
2679 Q_ASSERT(proxy);
2680 proxy->repolish(widget: q);
2681 return;
2682 }
2683
2684 QStyle *origStyle = proxy ? proxy->base : extraStyle;
2685 QWidget *parent = q->parentWidget();
2686 QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : nullptr;
2687 // If we have stylesheet on app or parent has stylesheet style, we need
2688 // to be running a proxy
2689 if (!qApp->styleSheet().isEmpty() || qt_styleSheet(style: parentStyle)) {
2690 QStyle *newStyle = parentStyle;
2691 if (q->testAttribute(attribute: Qt::WA_SetStyle))
2692 newStyle = new QStyleSheetStyle(origStyle);
2693 else if (QStyleSheetStyle *newProxy = qt_styleSheet(style: parentStyle))
2694 newProxy->ref();
2695
2696 setStyle_helper(newStyle, propagate: true);
2697 return;
2698 }
2699
2700 // So, we have no stylesheet on parent/app and we have an empty stylesheet
2701 // we just need our original style back
2702 if (origStyle == extraStyle) // is it any different?
2703 return;
2704
2705 // We could have inherited the proxy from our parent (which has a custom style)
2706 // In such a case we need to start following the application style (i.e revert
2707 // the propagation behavior of QStyleSheetStyle)
2708 if (!q->testAttribute(attribute: Qt::WA_SetStyle))
2709 origStyle = nullptr;
2710
2711 setStyle_helper(newStyle: origStyle, propagate: true);
2712#endif // QT_NO_STYLE_STYLESHEET
2713}
2714
2715
2716/*!
2717 \fn bool QWidget::isWindow() const
2718
2719 Returns \c true if the widget is an independent window, otherwise
2720 returns \c false.
2721
2722 A window is a widget that isn't visually the child of any other
2723 widget and that usually has a frame and a
2724 \l{QWidget::setWindowTitle()}{window title}.
2725
2726 A window can have a \l{QWidget::parentWidget()}{parent widget}.
2727 It will then be grouped with its parent and deleted when the
2728 parent is deleted, minimized when the parent is minimized etc. If
2729 supported by the window manager, it will also have a common
2730 taskbar entry with its parent.
2731
2732 QDialog and QMainWindow widgets are by default windows, even if a
2733 parent widget is specified in the constructor. This behavior is
2734 specified by the Qt::Window flag.
2735
2736 \sa window(), isModal(), parentWidget()
2737*/
2738
2739/*!
2740 \property QWidget::modal
2741 \brief whether the widget is a modal widget
2742
2743 This property only makes sense for windows. A modal widget
2744 prevents widgets in all other windows from getting any input.
2745
2746 By default, this property is \c false.
2747
2748 \sa isWindow(), windowModality, QDialog
2749*/
2750
2751/*!
2752 \property QWidget::windowModality
2753 \brief which windows are blocked by the modal widget
2754 \since 4.1
2755
2756 This property only makes sense for windows. A modal widget
2757 prevents widgets in other windows from getting input. The value of
2758 this property controls which windows are blocked when the widget
2759 is visible. Changing this property while the window is visible has
2760 no effect; you must hide() the widget first, then show() it again.
2761
2762 By default, this property is Qt::NonModal.
2763
2764 \sa isWindow(), QWidget::modal, QDialog
2765*/
2766
2767Qt::WindowModality QWidget::windowModality() const
2768{
2769 return static_cast<Qt::WindowModality>(data->window_modality);
2770}
2771
2772void QWidget::setWindowModality(Qt::WindowModality windowModality)
2773{
2774 data->window_modality = windowModality;
2775 // setModal_sys() will be called by setAttribute()
2776 setAttribute(Qt::WA_ShowModal, on: (data->window_modality != Qt::NonModal));
2777 setAttribute(Qt::WA_SetWindowModality, on: true);
2778}
2779
2780void QWidgetPrivate::setModal_sys()
2781{
2782 Q_Q(QWidget);
2783 if (q->windowHandle())
2784 q->windowHandle()->setModality(q->windowModality());
2785}
2786
2787/*!
2788 \fn bool QWidget::underMouse() const
2789
2790 Returns \c true if the widget is under the mouse cursor; otherwise
2791 returns \c false.
2792
2793 This value is not updated properly during drag and drop
2794 operations.
2795
2796 \sa enterEvent(), leaveEvent()
2797*/
2798
2799/*!
2800 \property QWidget::minimized
2801 \brief whether this widget is minimized (iconified)
2802
2803 This property is only relevant for windows.
2804
2805 By default, this property is \c false.
2806
2807 \sa showMinimized(), visible, show(), hide(), showNormal(), maximized
2808*/
2809bool QWidget::isMinimized() const
2810{ return data->window_state & Qt::WindowMinimized; }
2811
2812/*!
2813 Shows the widget minimized, as an icon.
2814
2815 Calling this function only affects \l{isWindow()}{windows}.
2816
2817 \sa showNormal(), showMaximized(), show(), hide(), isVisible(),
2818 isMinimized()
2819*/
2820void QWidget::showMinimized()
2821{
2822 bool isMin = isMinimized();
2823 if (isMin && isVisible())
2824 return;
2825
2826 ensurePolished();
2827
2828 if (!isMin)
2829 setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
2830 setVisible(true);
2831}
2832
2833/*!
2834 \property QWidget::maximized
2835 \brief whether this widget is maximized
2836
2837 This property is only relevant for windows.
2838
2839 \note Due to limitations on some window systems, this does not always
2840 report the expected results (e.g., if the user on X11 maximizes the
2841 window via the window manager, Qt has no way of distinguishing this
2842 from any other resize). This is expected to improve as window manager
2843 protocols evolve.
2844
2845 By default, this property is \c false.
2846
2847 \sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized
2848*/
2849bool QWidget::isMaximized() const
2850{ return data->window_state & Qt::WindowMaximized; }
2851
2852
2853
2854/*!
2855 Returns the current window state. The window state is a OR'ed
2856 combination of Qt::WindowState: Qt::WindowMinimized,
2857 Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
2858
2859 \sa Qt::WindowState, setWindowState()
2860 */
2861Qt::WindowStates QWidget::windowState() const
2862{
2863 return Qt::WindowStates(data->window_state);
2864}
2865
2866/*!\internal
2867
2868 The function sets the window state on child widgets similar to
2869 setWindowState(). The difference is that the window state changed
2870 event has the isOverride() flag set. It exists mainly to keep
2871 QWorkspace working.
2872 */
2873void QWidget::overrideWindowState(Qt::WindowStates newstate)
2874{
2875 QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true);
2876 data->window_state = newstate;
2877 QCoreApplication::sendEvent(receiver: this, event: &e);
2878}
2879
2880/*!
2881 \fn void QWidget::setWindowState(Qt::WindowStates windowState)
2882
2883 Sets the window state to \a windowState. The window state is a OR'ed
2884 combination of Qt::WindowState: Qt::WindowMinimized,
2885 Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
2886
2887 If the window is not visible (i.e. isVisible() returns \c false), the
2888 window state will take effect when show() is called. For visible
2889 windows, the change is immediate. For example, to toggle between
2890 full-screen and normal mode, use the following code:
2891
2892 \snippet code/src_gui_kernel_qwidget.cpp 0
2893
2894 In order to restore and activate a minimized window (while
2895 preserving its maximized and/or full-screen state), use the following:
2896
2897 \snippet code/src_gui_kernel_qwidget.cpp 1
2898
2899 Calling this function will hide the widget. You must call show() to make
2900 the widget visible again.
2901
2902 \note On some window systems Qt::WindowActive is not immediate, and may be
2903 ignored in certain cases.
2904
2905 When the window state changes, the widget receives a changeEvent()
2906 of type QEvent::WindowStateChange.
2907
2908 \sa Qt::WindowState, windowState()
2909*/
2910void QWidget::setWindowState(Qt::WindowStates newstate)
2911{
2912 Q_D(QWidget);
2913 Qt::WindowStates oldstate = windowState();
2914 if (newstate.testFlag(flag: Qt::WindowMinimized)) // QTBUG-46763
2915 newstate.setFlag(flag: Qt::WindowActive, on: false);
2916 if (oldstate == newstate)
2917 return;
2918 if (isWindow() && !testAttribute(attribute: Qt::WA_WState_Created))
2919 create();
2920
2921 data->window_state = newstate;
2922 data->in_set_window_state = 1;
2923 if (isWindow()) {
2924 // Ensure the initial size is valid, since we store it as normalGeometry below.
2925 if (!testAttribute(attribute: Qt::WA_Resized) && !isVisible())
2926 adjustSize();
2927
2928 d->createTLExtra();
2929 if (!(oldstate & (Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)))
2930 d->topData()->normalGeometry = geometry();
2931
2932 Q_ASSERT(windowHandle());
2933 windowHandle()->setWindowStates(newstate & ~Qt::WindowActive);
2934 }
2935 data->in_set_window_state = 0;
2936
2937 if (newstate & Qt::WindowActive)
2938 activateWindow();
2939
2940 QWindowStateChangeEvent e(oldstate);
2941 QCoreApplication::sendEvent(receiver: this, event: &e);
2942}
2943
2944/*!
2945 \property QWidget::fullScreen
2946 \brief whether the widget is shown in full screen mode
2947
2948 A widget in full screen mode occupies the whole screen area and does not
2949 display window decorations, such as a title bar.
2950
2951 By default, this property is \c false.
2952
2953 \sa windowState(), minimized, maximized
2954*/
2955bool QWidget::isFullScreen() const
2956{ return data->window_state & Qt::WindowFullScreen; }
2957
2958/*!
2959 Shows the widget in full-screen mode.
2960
2961 Calling this function only affects \l{isWindow()}{windows}.
2962
2963 To return from full-screen mode, call showNormal() or close().
2964
2965 \note Full-screen mode works fine under Windows, but has certain
2966 problems under X. These problems are due to limitations of the
2967 ICCCM protocol that specifies the communication between X11
2968 clients and the window manager. ICCCM simply does not understand
2969 the concept of non-decorated full-screen windows. Therefore, the
2970 best we can do is to request a borderless window and place and
2971 resize it to fill the entire screen. Depending on the window
2972 manager, this may or may not work. The borderless window is
2973 requested using MOTIF hints, which are at least partially
2974 supported by virtually all modern window managers.
2975
2976 An alternative would be to bypass the window manager entirely and
2977 create a window with the Qt::X11BypassWindowManagerHint flag. This
2978 has other severe problems though, like totally broken keyboard focus
2979 and very strange effects on desktop changes or when the user raises
2980 other windows.
2981
2982 X11 window managers that follow modern post-ICCCM specifications
2983 support full-screen mode properly.
2984
2985 On macOS, showing a window full screen puts the entire application in
2986 full-screen mode, providing it with a dedicated desktop. Showing another
2987 window while the application runs in full-screen mode might automatically
2988 make that window full screen as well. To prevent that, exit full-screen
2989 mode by calling showNormal() or by close() on the full screen window
2990 before showing another window.
2991
2992 \sa showNormal(), showMaximized(), show(), isVisible(), close()
2993*/
2994void QWidget::showFullScreen()
2995{
2996 ensurePolished();
2997
2998 setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
2999 | Qt::WindowFullScreen);
3000 setVisible(true);
3001#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen
3002 // activating it here before libscreen activates it causes problems
3003 activateWindow();
3004#endif
3005}
3006
3007/*!
3008 Shows the widget maximized.
3009
3010 Calling this function only affects \l{isWindow()}{windows}.
3011
3012 On X11, this function may not work properly with certain window
3013 managers. See the \l{Window Geometry} documentation for an explanation.
3014
3015 \sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible()
3016*/
3017void QWidget::showMaximized()
3018{
3019 ensurePolished();
3020
3021 setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen))
3022 | Qt::WindowMaximized);
3023 setVisible(true);
3024}
3025
3026/*!
3027 Restores the widget after it has been maximized or minimized.
3028
3029 Calling this function only affects \l{isWindow()}{windows}.
3030
3031 \sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible()
3032*/
3033void QWidget::showNormal()
3034{
3035 ensurePolished();
3036
3037 setWindowState(windowState() & ~(Qt::WindowMinimized
3038 | Qt::WindowMaximized
3039 | Qt::WindowFullScreen));
3040 setVisible(true);
3041}
3042
3043/*!
3044 Returns \c true if this widget would become enabled if \a ancestor is
3045 enabled; otherwise returns \c false.
3046
3047
3048
3049 This is the case if neither the widget itself nor every parent up
3050 to but excluding \a ancestor has been explicitly disabled.
3051
3052 isEnabledTo(0) returns false if this widget or any if its ancestors
3053 was explicitly disabled.
3054
3055 The word ancestor here means a parent widget within the same window.
3056
3057 Therefore isEnabledTo(0) stops at this widget's window, unlike
3058 isEnabled() which also takes parent windows into considerations.
3059
3060 \sa setEnabled(), enabled
3061*/
3062
3063bool QWidget::isEnabledTo(const QWidget *ancestor) const
3064{
3065 const QWidget * w = this;
3066 while (!w->testAttribute(attribute: Qt::WA_ForceDisabled)
3067 && !w->isWindow()
3068 && w->parentWidget()
3069 && w->parentWidget() != ancestor)
3070 w = w->parentWidget();
3071 return !w->testAttribute(attribute: Qt::WA_ForceDisabled);
3072}
3073
3074#ifndef QT_NO_ACTION
3075/*!
3076 Appends the action \a action to this widget's list of actions.
3077
3078 All QWidgets have a list of \l{QAction}s, however they can be
3079 represented graphically in many different ways. The default use of
3080 the QAction list (as returned by actions()) is to create a context
3081 QMenu.
3082
3083 A QWidget should only have one of each action and adding an action
3084 it already has will not cause the same action to be in the widget twice.
3085
3086 The ownership of \a action is not transferred to this QWidget.
3087
3088 \sa removeAction(), insertAction(), actions(), QMenu
3089*/
3090void QWidget::addAction(QAction *action)
3091{
3092 insertAction(before: nullptr, action);
3093}
3094
3095/*!
3096 Appends the actions \a actions to this widget's list of actions.
3097
3098 \sa removeAction(), QMenu, addAction()
3099*/
3100#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
3101void QWidget::addActions(const QList<QAction *> &actions)
3102#else
3103void QWidget::addActions(QList<QAction*> actions)
3104#endif
3105{
3106 for(int i = 0; i < actions.count(); i++)
3107 insertAction(before: nullptr, action: actions.at(i));
3108}
3109
3110/*!
3111 Inserts the action \a action to this widget's list of actions,
3112 before the action \a before. It appends the action if \a before is \nullptr or
3113 \a before is not a valid action for this widget.
3114
3115 A QWidget should only have one of each action.
3116
3117 \sa removeAction(), addAction(), QMenu, contextMenuPolicy, actions()
3118*/
3119void QWidget::insertAction(QAction *before, QAction *action)
3120{
3121 if (Q_UNLIKELY(!action)) {
3122 qWarning(msg: "QWidget::insertAction: Attempt to insert null action");
3123 return;
3124 }
3125
3126 Q_D(QWidget);
3127 if(d->actions.contains(t: action))
3128 removeAction(action);
3129
3130 int pos = d->actions.indexOf(t: before);
3131 if (pos < 0) {
3132 before = nullptr;
3133 pos = d->actions.size();
3134 }
3135 d->actions.insert(i: pos, t: action);
3136
3137 QActionPrivate *apriv = action->d_func();
3138 apriv->widgets.append(t: this);
3139
3140 QActionEvent e(QEvent::ActionAdded, action, before);
3141 QCoreApplication::sendEvent(receiver: this, event: &e);
3142}
3143
3144/*!
3145 Inserts the actions \a actions to this widget's list of actions,
3146 before the action \a before. It appends the action if \a before is \nullptr or
3147 \a before is not a valid action for this widget.
3148
3149 A QWidget can have at most one of each action.
3150
3151 \sa removeAction(), QMenu, insertAction(), contextMenuPolicy
3152*/
3153#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
3154void QWidget::insertActions(QAction *before, const QList<QAction*> &actions)
3155#else
3156void QWidget::insertActions(QAction *before, QList<QAction*> actions)
3157#endif
3158{
3159 for(int i = 0; i < actions.count(); ++i)
3160 insertAction(before, action: actions.at(i));
3161}
3162
3163/*!
3164 Removes the action \a action from this widget's list of actions.
3165 \sa insertAction(), actions(), insertAction()
3166*/
3167void QWidget::removeAction(QAction *action)
3168{
3169 if (!action)
3170 return;
3171
3172 Q_D(QWidget);
3173
3174 QActionPrivate *apriv = action->d_func();
3175 apriv->widgets.removeAll(t: this);
3176
3177 if (d->actions.removeAll(t: action)) {
3178 QActionEvent e(QEvent::ActionRemoved, action);
3179 QCoreApplication::sendEvent(receiver: this, event: &e);
3180 }
3181}
3182
3183/*!
3184 Returns the (possibly empty) list of this widget's actions.
3185
3186 \sa contextMenuPolicy, insertAction(), removeAction()
3187*/
3188QList<QAction*> QWidget::actions() const
3189{
3190 Q_D(const QWidget);
3191 return d->actions;
3192}
3193#endif // QT_NO_ACTION
3194
3195/*!
3196 \fn bool QWidget::isEnabledToTLW() const
3197 \obsolete
3198
3199 This function is deprecated. It is equivalent to isEnabled()
3200*/
3201
3202/*!
3203 \property QWidget::enabled
3204 \brief whether the widget is enabled
3205
3206 In general an enabled widget handles keyboard and mouse events; a disabled
3207 widget does not. An exception is made with \l{QAbstractButton}.
3208
3209 Some widgets display themselves differently when they are
3210 disabled. For example a button might draw its label grayed out. If
3211 your widget needs to know when it becomes enabled or disabled, you
3212 can use the changeEvent() with type QEvent::EnabledChange.
3213
3214 Disabling a widget implicitly disables all its children. Enabling
3215 respectively enables all child widgets unless they have been
3216 explicitly disabled. It it not possible to explicitly enable a child
3217 widget which is not a window while its parent widget remains disabled.
3218
3219 By default, this property is \c true.
3220
3221 \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3222*/
3223void QWidget::setEnabled(bool enable)
3224{
3225 Q_D(QWidget);
3226 setAttribute(Qt::WA_ForceDisabled, on: !enable);
3227 d->setEnabled_helper(enable);
3228}
3229
3230void QWidgetPrivate::setEnabled_helper(bool enable)
3231{
3232 Q_Q(QWidget);
3233
3234 if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled())
3235 return; // nothing we can do
3236
3237 if (enable != q->testAttribute(attribute: Qt::WA_Disabled))
3238 return; // nothing to do
3239
3240 q->setAttribute(Qt::WA_Disabled, on: !enable);
3241 updateSystemBackground();
3242
3243 if (!enable && q->window()->focusWidget() == q) {
3244 bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled());
3245 if (!parentIsEnabled || !q->focusNextChild())
3246 q->clearFocus();
3247 }
3248
3249 Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled;
3250 for (int i = 0; i < children.size(); ++i) {
3251 QWidget *w = qobject_cast<QWidget *>(o: children.at(i));
3252 if (w && !w->testAttribute(attribute))
3253 w->d_func()->setEnabled_helper(enable);
3254 }
3255#ifndef QT_NO_CURSOR
3256 if (q->testAttribute(attribute: Qt::WA_SetCursor) || q->isWindow()) {
3257 // enforce the windows behavior of clearing the cursor on
3258 // disabled widgets
3259 qt_qpa_set_cursor(w: q, force: false);
3260 }
3261#endif
3262#ifndef QT_NO_IM
3263 if (q->testAttribute(attribute: Qt::WA_InputMethodEnabled) && q->hasFocus()) {
3264 QWidget *focusWidget = effectiveFocusWidget();
3265
3266 if (enable) {
3267 if (focusWidget->testAttribute(attribute: Qt::WA_InputMethodEnabled))
3268 QGuiApplication::inputMethod()->update(queries: Qt::ImEnabled);
3269 } else {
3270 QGuiApplication::inputMethod()->commit();
3271 QGuiApplication::inputMethod()->update(queries: Qt::ImEnabled);
3272 }
3273 }
3274#endif //QT_NO_IM
3275 QEvent e(QEvent::EnabledChange);
3276 QCoreApplication::sendEvent(receiver: q, event: &e);
3277}
3278
3279/*!
3280 \property QWidget::acceptDrops
3281 \brief whether drop events are enabled for this widget
3282
3283 Setting this property to true announces to the system that this
3284 widget \e may be able to accept drop events.
3285
3286 If the widget is the desktop (windowType() == Qt::Desktop), this may
3287 fail if another application is using the desktop; you can call
3288 acceptDrops() to test if this occurs.
3289
3290 \warning Do not modify this property in a drag and drop event handler.
3291
3292 By default, this property is \c false.
3293
3294 \sa {Drag and Drop}
3295*/
3296bool QWidget::acceptDrops() const
3297{
3298 return testAttribute(attribute: Qt::WA_AcceptDrops);
3299}
3300
3301void QWidget::setAcceptDrops(bool on)
3302{
3303 setAttribute(Qt::WA_AcceptDrops, on);
3304
3305}
3306
3307/*!
3308 Disables widget input events if \a disable is true; otherwise
3309 enables input events.
3310
3311 See the \l enabled documentation for more information.
3312
3313 \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3314*/
3315void QWidget::setDisabled(bool disable)
3316{
3317 setEnabled(!disable);
3318}
3319
3320/*!
3321 \property QWidget::frameGeometry
3322 \brief geometry of the widget relative to its parent including any
3323 window frame
3324
3325 See the \l{Window Geometry} documentation for an overview of geometry
3326 issues with windows.
3327
3328 By default, this property contains a value that depends on the user's
3329 platform and screen geometry.
3330
3331 \sa geometry(), x(), y(), pos()
3332*/
3333QRect QWidget::frameGeometry() const
3334{
3335 Q_D(const QWidget);
3336 if (isWindow() && ! (windowType() == Qt::Popup)) {
3337 QRect fs = d->frameStrut();
3338 return QRect(data->crect.x() - fs.left(),
3339 data->crect.y() - fs.top(),
3340 data->crect.width() + fs.left() + fs.right(),
3341 data->crect.height() + fs.top() + fs.bottom());
3342 }
3343 return data->crect;
3344}
3345
3346/*!
3347 \property QWidget::x
3348
3349 \brief the x coordinate of the widget relative to its parent including
3350 any window frame
3351
3352 See the \l{Window Geometry} documentation for an overview of geometry
3353 issues with windows.
3354
3355 By default, this property has a value of 0.
3356
3357 \sa frameGeometry, y, pos
3358*/
3359int QWidget::x() const
3360{
3361 Q_D(const QWidget);
3362 if (isWindow() && ! (windowType() == Qt::Popup))
3363 return data->crect.x() - d->frameStrut().left();
3364 return data->crect.x();
3365}
3366
3367/*!
3368 \property QWidget::y
3369 \brief the y coordinate of the widget relative to its parent and
3370 including any window frame
3371
3372 See the \l{Window Geometry} documentation for an overview of geometry
3373 issues with windows.
3374
3375 By default, this property has a value of 0.
3376
3377 \sa frameGeometry, x, pos
3378*/
3379int QWidget::y() const
3380{
3381 Q_D(const QWidget);
3382 if (isWindow() && ! (windowType() == Qt::Popup))
3383 return data->crect.y() - d->frameStrut().top();
3384 return data->crect.y();
3385}
3386
3387/*!
3388 \property QWidget::pos
3389 \brief the position of the widget within its parent widget
3390
3391 If the widget is a window, the position is that of the widget on
3392 the desktop, including its frame.
3393
3394 When changing the position, the widget, if visible, receives a
3395 move event (moveEvent()) immediately. If the widget is not
3396 currently visible, it is guaranteed to receive an event before it
3397 is shown.
3398
3399 By default, this property contains a position that refers to the
3400 origin.
3401
3402 \warning Calling move() or setGeometry() inside moveEvent() can
3403 lead to infinite recursion.
3404
3405 See the \l{Window Geometry} documentation for an overview of geometry
3406 issues with windows.
3407
3408 \sa frameGeometry, size, x(), y()
3409*/
3410QPoint QWidget::pos() const
3411{
3412 Q_D(const QWidget);
3413 QPoint result = data->crect.topLeft();
3414 if (isWindow() && ! (windowType() == Qt::Popup))
3415 if (!d->maybeTopData() || !d->maybeTopData()->posIncludesFrame)
3416 result -= d->frameStrut().topLeft();
3417 return result;
3418}
3419
3420/*!
3421 \property QWidget::geometry
3422 \brief the geometry of the widget relative to its parent and
3423 excluding the window frame
3424
3425 When changing the geometry, the widget, if visible, receives a
3426 move event (moveEvent()) and/or a resize event (resizeEvent())
3427 immediately. If the widget is not currently visible, it is
3428 guaranteed to receive appropriate events before it is shown.
3429
3430 The size component is adjusted if it lies outside the range
3431 defined by minimumSize() and maximumSize().
3432
3433 \warning Calling setGeometry() inside resizeEvent() or moveEvent()
3434 can lead to infinite recursion.
3435
3436 See the \l{Window Geometry} documentation for an overview of geometry
3437 issues with windows.
3438
3439 By default, this property contains a value that depends on the user's
3440 platform and screen geometry.
3441
3442 \sa frameGeometry(), rect(), move(), resize(), moveEvent(),
3443 resizeEvent(), minimumSize(), maximumSize()
3444*/
3445
3446/*!
3447 \property QWidget::normalGeometry
3448
3449 \brief the geometry of the widget as it will appear when shown as
3450 a normal (not maximized or full screen) top-level widget
3451
3452 For child widgets this property always holds an empty rectangle.
3453
3454 By default, this property contains an empty rectangle.
3455
3456 \sa QWidget::windowState(), QWidget::geometry
3457*/
3458
3459/*!
3460 \property QWidget::size
3461 \brief the size of the widget excluding any window frame
3462
3463 If the widget is visible when it is being resized, it receives a resize event
3464 (resizeEvent()) immediately. If the widget is not currently
3465 visible, it is guaranteed to receive an event before it is shown.
3466
3467 The size is adjusted if it lies outside the range defined by
3468 minimumSize() and maximumSize().
3469
3470 By default, this property contains a value that depends on the user's
3471 platform and screen geometry.
3472
3473 \warning Calling resize() or setGeometry() inside resizeEvent() can
3474 lead to infinite recursion.
3475
3476 \note Setting the size to \c{QSize(0, 0)} will cause the widget to not
3477 appear on screen. This also applies to windows.
3478
3479 \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize()
3480*/
3481
3482/*!
3483 \property QWidget::width
3484 \brief the width of the widget excluding any window frame
3485
3486 See the \l{Window Geometry} documentation for an overview of geometry
3487 issues with windows.
3488
3489 \note Do not use this function to find the width of a screen on
3490 a \l{QDesktopWidget}{multiple screen desktop}. Read
3491 \l{QDesktopWidget#Screen Geometry}{this note} for details.
3492
3493 By default, this property contains a value that depends on the user's
3494 platform and screen geometry.
3495
3496 \sa geometry, height, size
3497*/
3498
3499/*!
3500 \property QWidget::height
3501 \brief the height of the widget excluding any window frame
3502
3503 See the \l{Window Geometry} documentation for an overview of geometry
3504 issues with windows.
3505
3506 \note Do not use this function to find the height of a screen
3507 on a \l{QDesktopWidget}{multiple screen desktop}. Read
3508 \l{QDesktopWidget#Screen Geometry}{this note} for details.
3509
3510 By default, this property contains a value that depends on the user's
3511 platform and screen geometry.
3512
3513 \sa geometry, width, size
3514*/
3515
3516/*!
3517 \property QWidget::rect
3518 \brief the internal geometry of the widget excluding any window
3519 frame
3520
3521 The rect property equals QRect(0, 0, width(), height()).
3522
3523 See the \l{Window Geometry} documentation for an overview of geometry
3524 issues with windows.
3525
3526 By default, this property contains a value that depends on the user's
3527 platform and screen geometry.
3528
3529 \sa size
3530*/
3531
3532
3533QRect QWidget::normalGeometry() const
3534{
3535 Q_D(const QWidget);
3536 if (!d->extra || !d->extra->topextra)
3537 return QRect();
3538
3539 if (!isMaximized() && !isFullScreen())
3540 return geometry();
3541
3542 return d->topData()->normalGeometry;
3543}
3544
3545
3546/*!
3547 \property QWidget::childrenRect
3548 \brief the bounding rectangle of the widget's children
3549
3550 Hidden children are excluded.
3551
3552 By default, for a widget with no children, this property contains a
3553 rectangle with zero width and height located at the origin.
3554
3555 \sa childrenRegion(), geometry()
3556*/
3557
3558QRect QWidget::childrenRect() const
3559{
3560 Q_D(const QWidget);
3561 QRect r(0, 0, 0, 0);
3562 for (int i = 0; i < d->children.size(); ++i) {
3563 QWidget *w = qobject_cast<QWidget *>(o: d->children.at(i));
3564 if (w && !w->isWindow() && !w->isHidden())
3565 r |= w->geometry();
3566 }
3567 return r;
3568}
3569
3570/*!
3571 \property QWidget::childrenRegion
3572 \brief the combined region occupied by the widget's children
3573
3574 Hidden children are excluded.
3575
3576 By default, for a widget with no children, this property contains an
3577 empty region.
3578
3579 \sa childrenRect(), geometry(), mask()
3580*/
3581
3582QRegion QWidget::childrenRegion() const
3583{
3584 Q_D(const QWidget);
3585 QRegion r;
3586 for (int i = 0; i < d->children.size(); ++i) {
3587 QWidget *w = qobject_cast<QWidget *>(o: d->children.at(i));
3588 if (w && !w->isWindow() && !w->isHidden()) {
3589 QRegion mask = w->mask();
3590 if (mask.isEmpty())
3591 r |= w->geometry();
3592 else
3593 r |= mask.translated(p: w->pos());
3594 }
3595 }
3596 return r;
3597}
3598
3599
3600/*!
3601 \property QWidget::minimumSize
3602 \brief the widget's minimum size
3603
3604 The widget cannot be resized to a smaller size than the minimum
3605 widget size. The widget's size is forced to the minimum size if
3606 the current size is smaller.
3607
3608 The minimum size set by this function will override the minimum size
3609 defined by QLayout. In order to unset the minimum size, use a
3610 value of \c{QSize(0, 0)}.
3611
3612 By default, this property contains a size with zero width and height.
3613
3614 \sa minimumWidth, minimumHeight, maximumSize, sizeIncrement
3615*/
3616
3617QSize QWidget::minimumSize() const
3618{
3619 Q_D(const QWidget);
3620 return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0);
3621}
3622
3623/*!
3624 \property QWidget::maximumSize
3625 \brief the widget's maximum size in pixels
3626
3627 The widget cannot be resized to a larger size than the maximum
3628 widget size.
3629
3630 By default, this property contains a size in which both width and height
3631 have values of 16777215.
3632
3633 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3634 of widgets.
3635
3636 \sa maximumWidth, maximumHeight, minimumSize, sizeIncrement
3637*/
3638
3639QSize QWidget::maximumSize() const
3640{
3641 Q_D(const QWidget);
3642 return d->extra ? QSize(d->extra->maxw, d->extra->maxh)
3643 : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
3644}
3645
3646
3647/*!
3648 \property QWidget::minimumWidth
3649 \brief the widget's minimum width in pixels
3650
3651 This property corresponds to the width held by the \l minimumSize property.
3652
3653 By default, this property has a value of 0.
3654
3655 \sa minimumSize, minimumHeight
3656*/
3657
3658/*!
3659 \property QWidget::minimumHeight
3660 \brief the widget's minimum height in pixels
3661
3662 This property corresponds to the height held by the \l minimumSize property.
3663
3664 By default, this property has a value of 0.
3665
3666 \sa minimumSize, minimumWidth
3667*/
3668
3669/*!
3670 \property QWidget::maximumWidth
3671 \brief the widget's maximum width in pixels
3672
3673 This property corresponds to the width held by the \l maximumSize property.
3674
3675 By default, this property contains a value of 16777215.
3676
3677 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3678 of widgets.
3679
3680 \sa maximumSize, maximumHeight
3681*/
3682
3683/*!
3684 \property QWidget::maximumHeight
3685 \brief the widget's maximum height in pixels
3686
3687 This property corresponds to the height held by the \l maximumSize property.
3688
3689 By default, this property contains a value of 16777215.
3690
3691 \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
3692 of widgets.
3693
3694 \sa maximumSize, maximumWidth
3695*/
3696
3697/*!
3698 \property QWidget::sizeIncrement
3699 \brief the size increment of the widget
3700
3701 When the user resizes the window, the size will move in steps of
3702 sizeIncrement().width() pixels horizontally and
3703 sizeIncrement.height() pixels vertically, with baseSize() as the
3704 basis. Preferred widget sizes are for non-negative integers \e i
3705 and \e j:
3706 \snippet code/src_gui_kernel_qwidget.cpp 2
3707
3708 Note that while you can set the size increment for all widgets, it
3709 only affects windows.
3710
3711 By default, this property contains a size with zero width and height.
3712
3713 \warning The size increment has no effect under Windows, and may
3714 be disregarded by the window manager on X11.
3715
3716 \sa size, minimumSize, maximumSize
3717*/
3718QSize QWidget::sizeIncrement() const
3719{
3720 Q_D(const QWidget);
3721 return (d->extra && d->extra->topextra)
3722 ? QSize(d->extra->topextra->incw, d->extra->topextra->inch)
3723 : QSize(0, 0);
3724}
3725
3726/*!
3727 \property QWidget::baseSize
3728 \brief the base size of the widget
3729
3730 The base size is used to calculate a proper widget size if the
3731 widget defines sizeIncrement().
3732
3733 By default, for a newly-created widget, this property contains a size with
3734 zero width and height.
3735
3736 \sa setSizeIncrement()
3737*/
3738
3739QSize QWidget::baseSize() const
3740{
3741 Q_D(const QWidget);
3742 return (d->extra && d->extra->topextra)
3743 ? QSize(d->extra->topextra->basew, d->extra->topextra->baseh)
3744 : QSize(0, 0);
3745}
3746
3747bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
3748{
3749 Q_Q(QWidget);
3750
3751 int mw = minw, mh = minh;
3752 if (mw == QWIDGETSIZE_MAX)
3753 mw = 0;
3754 if (mh == QWIDGETSIZE_MAX)
3755 mh = 0;
3756 if (Q_UNLIKELY(minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX)) {
3757 qWarning(msg: "QWidget::setMinimumSize: (%s/%s) "
3758 "The largest allowed size is (%d,%d)",
3759 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
3760 QWIDGETSIZE_MAX);
3761 minw = mw = qMin<int>(a: minw, QWIDGETSIZE_MAX);
3762 minh = mh = qMin<int>(a: minh, QWIDGETSIZE_MAX);
3763 }
3764 if (Q_UNLIKELY(minw < 0 || minh < 0)) {
3765 qWarning(msg: "QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
3766 "are not possible",
3767 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
3768 minw = mw = qMax(a: minw, b: 0);
3769 minh = mh = qMax(a: minh, b: 0);
3770 }
3771 createExtra();
3772 if (extra->minw == mw && extra->minh == mh)
3773 return false;
3774 extra->minw = mw;
3775 extra->minh = mh;
3776 extra->explicitMinSize = (mw ? Qt::Horizontal : 0) | (mh ? Qt::Vertical : 0);
3777 return true;
3778}
3779
3780void QWidgetPrivate::setConstraints_sys()
3781{
3782 Q_Q(QWidget);
3783 if (extra && q->windowHandle()) {
3784 QWindow *win = q->windowHandle();
3785 QWindowPrivate *winp = qt_window_private(window: win);
3786
3787 winp->minimumSize = QSize(extra->minw, extra->minh);
3788 winp->maximumSize = QSize(extra->maxw, extra->maxh);
3789
3790 if (extra->topextra) {
3791 winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
3792 winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
3793 }
3794
3795 if (winp->platformWindow) {
3796 fixPosIncludesFrame();
3797 winp->platformWindow->propagateSizeHints();
3798 }
3799 }
3800}
3801
3802/*!
3803 \overload
3804
3805 This function corresponds to setMinimumSize(QSize(minw, minh)).
3806 Sets the minimum width to \a minw and the minimum height to \a
3807 minh.
3808*/
3809
3810void QWidget::setMinimumSize(int minw, int minh)
3811{
3812 Q_D(QWidget);
3813 if (!d->setMinimumSize_helper(minw, minh))
3814 return;
3815
3816 if (isWindow())
3817 d->setConstraints_sys();
3818 if (minw > width() || minh > height()) {
3819 bool resized = testAttribute(attribute: Qt::WA_Resized);
3820 bool maximized = isMaximized();
3821 resize(w: qMax(a: minw,b: width()), h: qMax(a: minh,b: height()));
3822 setAttribute(Qt::WA_Resized, on: resized); //not a user resize
3823 if (maximized)
3824 data->window_state = data->window_state | Qt::WindowMaximized;
3825 }
3826#if QT_CONFIG(graphicsview)
3827 if (d->extra) {
3828 if (d->extra->proxyWidget)
3829 d->extra->proxyWidget->setMinimumSize(aw: minw, ah: minh);
3830 }
3831#endif
3832 d->updateGeometry_helper(forceUpdate: d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
3833}
3834
3835bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh)
3836{
3837 Q_Q(QWidget);
3838 if (Q_UNLIKELY(maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX)) {
3839 qWarning(msg: "QWidget::setMaximumSize: (%s/%s) "
3840 "The largest allowed size is (%d,%d)",
3841 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
3842 QWIDGETSIZE_MAX);
3843 maxw = qMin<int>(a: maxw, QWIDGETSIZE_MAX);
3844 maxh = qMin<int>(a: maxh, QWIDGETSIZE_MAX);
3845 }
3846 if (Q_UNLIKELY(maxw < 0 || maxh < 0)) {
3847 qWarning(msg: "QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
3848 "are not possible",
3849 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh);
3850 maxw = qMax(a: maxw, b: 0);
3851 maxh = qMax(a: maxh, b: 0);
3852 }
3853 createExtra();
3854 if (extra->maxw == maxw && extra->maxh == maxh)
3855 return false;
3856 extra->maxw = maxw;
3857 extra->maxh = maxh;
3858 extra->explicitMaxSize = (maxw != QWIDGETSIZE_MAX ? Qt::Horizontal : 0) |
3859 (maxh != QWIDGETSIZE_MAX ? Qt::Vertical : 0);
3860 return true;
3861}
3862
3863/*!
3864 \overload
3865
3866 This function corresponds to setMaximumSize(QSize(\a maxw, \a
3867 maxh)). Sets the maximum width to \a maxw and the maximum height
3868 to \a maxh.
3869*/
3870void QWidget::setMaximumSize(int maxw, int maxh)
3871{
3872 Q_D(QWidget);
3873 if (!d->setMaximumSize_helper(maxw, maxh))
3874 return;
3875
3876 if (isWindow())
3877 d->setConstraints_sys();
3878 if (maxw < width() || maxh < height()) {
3879 bool resized = testAttribute(attribute: Qt::WA_Resized);
3880 resize(w: qMin(a: maxw,b: width()), h: qMin(a: maxh,b: height()));
3881 setAttribute(Qt::WA_Resized, on: resized); //not a user resize
3882 }
3883
3884#if QT_CONFIG(graphicsview)
3885 if (d->extra) {
3886 if (d->extra->proxyWidget)
3887 d->extra->proxyWidget->setMaximumSize(aw: maxw, ah: maxh);
3888 }
3889#endif
3890
3891 d->updateGeometry_helper(forceUpdate: d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
3892}
3893
3894/*!
3895 \overload
3896
3897 Sets the x (width) size increment to \a w and the y (height) size
3898 increment to \a h.
3899*/
3900void QWidget::setSizeIncrement(int w, int h)
3901{
3902 Q_D(QWidget);
3903 d->createTLExtra();
3904 QTLWExtra* x = d->topData();
3905 if (x->incw == w && x->inch == h)
3906 return;
3907 x->incw = w;
3908 x->inch = h;
3909 if (isWindow())
3910 d->setConstraints_sys();
3911}
3912
3913/*!
3914 \overload
3915
3916 This corresponds to setBaseSize(QSize(\a basew, \a baseh)). Sets
3917 the widgets base size to width \a basew and height \a baseh.
3918*/
3919void QWidget::setBaseSize(int basew, int baseh)
3920{
3921 Q_D(QWidget);
3922 d->createTLExtra();
3923 QTLWExtra* x = d->topData();
3924 if (x->basew == basew && x->baseh == baseh)
3925 return;
3926 x->basew = basew;
3927 x->baseh = baseh;
3928 if (isWindow())
3929 d->setConstraints_sys();
3930}
3931
3932/*!
3933 Sets both the minimum and maximum sizes of the widget to \a s,
3934 thereby preventing it from ever growing or shrinking.
3935
3936 This will override the default size constraints set by QLayout.
3937
3938 To remove constraints, set the size to QWIDGETSIZE_MAX.
3939
3940 Alternatively, if you want the widget to have a
3941 fixed size based on its contents, you can call
3942 QLayout::setSizeConstraint(QLayout::SetFixedSize);
3943
3944 \sa maximumSize, minimumSize
3945*/
3946
3947void QWidget::setFixedSize(const QSize & s)
3948{
3949 setFixedSize(w: s.width(), h: s.height());
3950}
3951
3952
3953/*!
3954 \fn void QWidget::setFixedSize(int w, int h)
3955 \overload
3956
3957 Sets the width of the widget to \a w and the height to \a h.
3958*/
3959
3960void QWidget::setFixedSize(int w, int h)
3961{
3962 Q_D(QWidget);
3963 bool minSizeSet = d->setMinimumSize_helper(minw&: w, minh&: h);
3964 bool maxSizeSet = d->setMaximumSize_helper(maxw&: w, maxh&: h);
3965 if (!minSizeSet && !maxSizeSet)
3966 return;
3967
3968 if (isWindow())
3969 d->setConstraints_sys();
3970 else
3971 d->updateGeometry_helper(forceUpdate: true);
3972
3973 if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX)
3974 resize(w, h);
3975}
3976
3977void QWidget::setMinimumWidth(int w)
3978{
3979 Q_D(QWidget);
3980 d->createExtra();
3981 uint expl = d->extra->explicitMinSize | (w ? Qt::Horizontal : 0);
3982 setMinimumSize(minw: w, minh: minimumSize().height());
3983 d->extra->explicitMinSize = expl;
3984}
3985
3986void QWidget::setMinimumHeight(int h)
3987{
3988 Q_D(QWidget);
3989 d->createExtra();
3990 uint expl = d->extra->explicitMinSize | (h ? Qt::Vertical : 0);
3991 setMinimumSize(minw: minimumSize().width(), minh: h);
3992 d->extra->explicitMinSize = expl;
3993}
3994
3995void QWidget::setMaximumWidth(int w)
3996{
3997 Q_D(QWidget);
3998 d->createExtra();
3999 uint expl = d->extra->explicitMaxSize | (w == QWIDGETSIZE_MAX ? 0 : Qt::Horizontal);
4000 setMaximumSize(maxw: w, maxh: maximumSize().height());
4001 d->extra->explicitMaxSize = expl;
4002}
4003
4004void QWidget::setMaximumHeight(int h)
4005{
4006 Q_D(QWidget);
4007 d->createExtra();
4008 uint expl = d->extra->explicitMaxSize | (h == QWIDGETSIZE_MAX ? 0 : Qt::Vertical);
4009 setMaximumSize(maxw: maximumSize().width(), maxh: h);
4010 d->extra->explicitMaxSize = expl;
4011}
4012
4013/*!
4014 Sets both the minimum and maximum width of the widget to \a w
4015 without changing the heights. Provided for convenience.
4016
4017 \sa sizeHint(), minimumSize(), maximumSize(), setFixedSize()
4018*/
4019
4020void QWidget::setFixedWidth(int w)
4021{
4022 Q_D(QWidget);
4023 d->createExtra();
4024 uint explMin = d->extra->explicitMinSize | Qt::Horizontal;
4025 uint explMax = d->extra->explicitMaxSize | Qt::Horizontal;
4026 setMinimumSize(minw: w, minh: minimumSize().height());
4027 setMaximumSize(maxw: w, maxh: maximumSize().height());
4028 d->extra->explicitMinSize = explMin;
4029 d->extra->explicitMaxSize = explMax;
4030}
4031
4032
4033/*!
4034 Sets both the minimum and maximum heights of the widget to \a h
4035 without changing the widths. Provided for convenience.
4036
4037 \sa sizeHint(), minimumSize(), maximumSize(), setFixedSize()
4038*/
4039
4040void QWidget::setFixedHeight(int h)
4041{
4042 Q_D(QWidget);
4043 d->createExtra();
4044 uint explMin = d->extra->explicitMinSize | Qt::Vertical;
4045 uint explMax = d->extra->explicitMaxSize | Qt::Vertical;
4046 setMinimumSize(minw: minimumSize().width(), minh: h);
4047 setMaximumSize(maxw: maximumSize().width(), maxh: h);
4048 d->extra->explicitMinSize = explMin;
4049 d->extra->explicitMaxSize = explMax;
4050}
4051
4052
4053/*!
4054 Translates the widget coordinate \a pos to the coordinate system
4055 of \a parent. The \a parent must not be \nullptr and must be a parent
4056 of the calling widget.
4057
4058 \sa mapFrom(), mapToParent(), mapToGlobal(), underMouse()
4059*/
4060
4061QPoint QWidget::mapTo(const QWidget * parent, const QPoint & pos) const
4062{
4063 QPoint p = pos;
4064 if (parent) {
4065 const QWidget * w = this;
4066 while (w != parent) {
4067 Q_ASSERT_X(w, "QWidget::mapTo(const QWidget *parent, const QPoint &pos)",
4068 "parent must be in parent hierarchy");
4069 p = w->mapToParent(p);
4070 w = w->parentWidget();
4071 }
4072 }
4073 return p;
4074}
4075
4076
4077/*!
4078 Translates the widget coordinate \a pos from the coordinate system
4079 of \a parent to this widget's coordinate system. The \a parent
4080 must not be \nullptr and must be a parent of the calling widget.
4081
4082 \sa mapTo(), mapFromParent(), mapFromGlobal(), underMouse()
4083*/
4084
4085QPoint QWidget::mapFrom(const QWidget * parent, const QPoint & pos) const
4086{
4087 QPoint p(pos);
4088 if (parent) {
4089 const QWidget * w = this;
4090 while (w != parent) {
4091 Q_ASSERT_X(w, "QWidget::mapFrom(const QWidget *parent, const QPoint &pos)",
4092 "parent must be in parent hierarchy");
4093
4094 p = w->mapFromParent(p);
4095 w = w->parentWidget();
4096 }
4097 }
4098 return p;
4099}
4100
4101
4102/*!
4103 Translates the widget coordinate \a pos to a coordinate in the
4104 parent widget.
4105
4106 Same as mapToGlobal() if the widget has no parent.
4107
4108 \sa mapFromParent(), mapTo(), mapToGlobal(), underMouse()
4109*/
4110
4111QPoint QWidget::mapToParent(const QPoint &pos) const
4112{
4113 return pos + data->crect.topLeft();
4114}
4115
4116/*!
4117 Translates the parent widget coordinate \a pos to widget
4118 coordinates.
4119
4120 Same as mapFromGlobal() if the widget has no parent.
4121
4122 \sa mapToParent(), mapFrom(), mapFromGlobal(), underMouse()
4123*/
4124
4125QPoint QWidget::mapFromParent(const QPoint &pos) const
4126{
4127 return pos - data->crect.topLeft();
4128}
4129
4130
4131/*!
4132 Returns the window for this widget, i.e. the next ancestor widget
4133 that has (or could have) a window-system frame.
4134
4135 If the widget is a window, the widget itself is returned.
4136
4137 Typical usage is changing the window title:
4138
4139 \snippet code/src_gui_kernel_qwidget.cpp 3
4140
4141 \sa isWindow()
4142*/
4143
4144QWidget *QWidget::window() const
4145{
4146 QWidget *w = const_cast<QWidget *>(this);
4147 QWidget *p = w->parentWidget();
4148 while (!w->isWindow() && p) {
4149 w = p;
4150 p = p->parentWidget();
4151 }
4152 return w;
4153}
4154
4155/*!
4156 \since 4.4
4157
4158 Returns the native parent for this widget, i.e. the next ancestor widget
4159 that has a system identifier, or \nullptr if it does not have any native
4160 parent.
4161
4162 \sa effectiveWinId()
4163*/
4164QWidget *QWidget::nativeParentWidget() const
4165{
4166 QWidget *parent = parentWidget();
4167 while (parent && !parent->internalWinId())
4168 parent = parent->parentWidget();
4169 return parent;
4170}
4171
4172/*! \fn QWidget *QWidget::topLevelWidget() const
4173 \obsolete
4174
4175 Use window() instead.
4176*/
4177
4178
4179
4180/*!
4181 Returns the background role of the widget.
4182
4183 The background role defines the brush from the widget's \l palette that
4184 is used to render the background.
4185
4186 If no explicit background role is set, the widget inherts its parent
4187 widget's background role.
4188
4189 \sa setBackgroundRole(), foregroundRole()
4190 */
4191QPalette::ColorRole QWidget::backgroundRole() const
4192{
4193
4194 const QWidget *w = this;
4195 do {
4196 QPalette::ColorRole role = w->d_func()->bg_role;
4197 if (role != QPalette::NoRole)
4198 return role;
4199 if (w->isWindow() || w->windowType() == Qt::SubWindow)
4200 break;
4201 w = w->parentWidget();
4202 } while (w);
4203 return QPalette::Window;
4204}
4205
4206/*!
4207 Sets the background role of the widget to \a role.
4208
4209 The background role defines the brush from the widget's \l palette that
4210 is used to render the background.
4211
4212 If \a role is QPalette::NoRole, then the widget inherits its
4213 parent's background role.
4214
4215 Note that styles are free to choose any color from the palette.
4216 You can modify the palette or set a style sheet if you don't
4217 achieve the result you want with setBackgroundRole().
4218
4219 \sa backgroundRole(), foregroundRole()
4220 */
4221
4222void QWidget::setBackgroundRole(QPalette::ColorRole role)
4223{
4224 Q_D(QWidget);
4225 d->bg_role = role;
4226 d->updateSystemBackground();
4227 d->propagatePaletteChange();
4228 d->updateIsOpaque();
4229}
4230
4231/*!
4232 Returns the foreground role.
4233
4234 The foreground role defines the color from the widget's \l palette that
4235 is used to draw the foreground.
4236
4237 If no explicit foreground role is set, the function returns a role
4238 that contrasts with the background role.
4239
4240 \sa setForegroundRole(), backgroundRole()
4241 */
4242QPalette::ColorRole QWidget::foregroundRole() const
4243{
4244 Q_D(const QWidget);
4245 QPalette::ColorRole rl = QPalette::ColorRole(d->fg_role);
4246 if (rl != QPalette::NoRole)
4247 return rl;
4248 QPalette::ColorRole role = QPalette::WindowText;
4249 switch (backgroundRole()) {
4250 case QPalette::Button:
4251 role = QPalette::ButtonText;
4252 break;
4253 case QPalette::Base:
4254 role = QPalette::Text;
4255 break;
4256 case QPalette::Dark:
4257 case QPalette::Shadow:
4258 role = QPalette::Light;
4259 break;
4260 case QPalette::Highlight:
4261 role = QPalette::HighlightedText;
4262 break;
4263 case QPalette::ToolTipBase:
4264 role = QPalette::ToolTipText;
4265 break;
4266 default:
4267 ;
4268 }
4269 return role;
4270}
4271
4272/*!
4273 Sets the foreground role of the widget to \a role.
4274
4275 The foreground role defines the color from the widget's \l palette that
4276 is used to draw the foreground.
4277
4278 If \a role is QPalette::NoRole, the widget uses a foreground role
4279 that contrasts with the background role.
4280
4281 Note that styles are free to choose any color from the palette.
4282 You can modify the palette or set a style sheet if you don't
4283 achieve the result you want with setForegroundRole().
4284
4285 \sa foregroundRole(), backgroundRole()
4286 */
4287void QWidget::setForegroundRole(QPalette::ColorRole role)
4288{
4289 Q_D(QWidget);
4290 d->fg_role = role;
4291 d->updateSystemBackground();
4292 d->propagatePaletteChange();
4293}
4294
4295/*!
4296 \property QWidget::palette
4297 \brief the widget's palette
4298
4299 This property describes the widget's palette. The palette is used by the
4300 widget's style when rendering standard components, and is available as a
4301 means to ensure that custom widgets can maintain consistency with the
4302 native platform's look and feel. It's common that different platforms, or
4303 different styles, have different palettes.
4304
4305 When you assign a new palette to a widget, the color roles from this
4306 palette are combined with the widget's default palette to form the
4307 widget's final palette. The palette entry for the widget's background role
4308 is used to fill the widget's background (see QWidget::autoFillBackground),
4309 and the foreground role initializes QPainter's pen.
4310
4311 The default depends on the system environment. QApplication maintains a
4312 system/theme palette which serves as a default for all widgets. There may
4313 also be special palette defaults for certain types of widgets (e.g., on
4314 Windows Vista, all classes that derive from QMenuBar have a special
4315 default palette). You can also define default palettes for widgets
4316 yourself by passing a custom palette and the name of a widget to
4317 QApplication::setPalette(). Finally, the style always has the option of
4318 polishing the palette as it's assigned (see QStyle::polish()).
4319
4320 QWidget propagates explicit palette roles from parent to child. If you
4321 assign a brush or color to a specific role on a palette and assign that
4322 palette to a widget, that role will propagate to all the widget's
4323 children, overriding any system defaults for that role. Note that palettes
4324 by default don't propagate to windows (see isWindow()) unless the
4325 Qt::WA_WindowPropagation attribute is enabled.
4326
4327 QWidget's palette propagation is similar to its font propagation.
4328
4329 The current style, which is used to render the content of all standard Qt
4330 widgets, is free to choose colors and brushes from the widget palette, or
4331 in some cases, to ignore the palette (partially, or completely). In
4332 particular, certain styles like GTK style, Mac style, and Windows Vista
4333 style, depend on third party APIs to render the content of widgets,
4334 and these styles typically do not follow the palette. Because of this,
4335 assigning roles to a widget's palette is not guaranteed to change the
4336 appearance of the widget. Instead, you may choose to apply a \l {styleSheet}.
4337
4338 \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
4339 When using style sheets, the palette of a widget can be customized using
4340 the "color", "background-color", "selection-color",
4341 "selection-background-color" and "alternate-background-color".
4342
4343 \sa QGuiApplication::palette(), QWidget::font(), {Qt Style Sheets}
4344*/
4345const QPalette &QWidget::palette() const
4346{
4347 if (!isEnabled()) {
4348 data->pal.setCurrentColorGroup(QPalette::Disabled);
4349 } else if ((!isVisible() || isActiveWindow())
4350#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
4351 && !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this))
4352#endif
4353 ) {
4354 data->pal.setCurrentColorGroup(QPalette::Active);
4355 } else {
4356 data->pal.setCurrentColorGroup(QPalette::Inactive);
4357 }
4358 return data->pal;
4359}
4360
4361void QWidget::setPalette(const QPalette &palette)
4362{
4363 Q_D(QWidget);
4364 setAttribute(Qt::WA_SetPalette, on: palette.resolve() != 0);
4365
4366 // Determine which palette is inherited from this widget's ancestors and
4367 // QApplication::palette, resolve this against \a palette (attributes from
4368 // the inherited palette are copied over this widget's palette). Then
4369 // propagate this palette to this widget's children.
4370 QPalette naturalPalette = d->naturalWidgetPalette(inheritedMask: d->inheritedPaletteResolveMask);
4371 QPalette resolvedPalette = palette.resolve(naturalPalette);
4372 d->setPalette_helper(resolvedPalette);
4373}
4374
4375/*!
4376 \internal
4377
4378 Returns the palette that the widget \a w inherits from its ancestors and
4379 QApplication::palette. \a inheritedMask is the combination of the widget's
4380 ancestors palette request masks (i.e., which attributes from the parent
4381 widget's palette are implicitly imposed on this widget by the user). Note
4382 that this font does not take into account the palette set on \a w itself.
4383*/
4384QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
4385{
4386 Q_Q(const QWidget);
4387
4388 const bool useStyleSheetPropagationInWidgetStyles =
4389 QCoreApplication::testAttribute(attribute: Qt::AA_UseStyleSheetPropagationInWidgetStyles);
4390
4391 QPalette naturalPalette = QApplication::palette(q);
4392 if ((!q->testAttribute(attribute: Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
4393 && (!q->isWindow() || q->testAttribute(attribute: Qt::WA_WindowPropagation)
4394#if QT_CONFIG(graphicsview)
4395 || (extra && extra->proxyWidget)
4396#endif // QT_CONFIG(graphicsview)
4397 )) {
4398 if (QWidget *p = q->parentWidget()) {
4399 if (!p->testAttribute(attribute: Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
4400 if (!naturalPalette.isCopyOf(p: QGuiApplication::palette())) {
4401 QPalette inheritedPalette = p->palette();
4402 inheritedPalette.resolve(mask: inheritedMask);
4403 naturalPalette = inheritedPalette.resolve(naturalPalette);
4404 } else {
4405 naturalPalette = p->palette();
4406 }
4407 }
4408 }
4409#if QT_CONFIG(graphicsview)
4410 else if (extra && extra->proxyWidget) {
4411 QPalette inheritedPalette = extra->proxyWidget->palette();
4412 inheritedPalette.resolve(mask: inheritedMask);
4413 naturalPalette = inheritedPalette.resolve(naturalPalette);
4414 }
4415#endif // QT_CONFIG(graphicsview)
4416 }
4417 naturalPalette.resolve(mask: 0);
4418 return naturalPalette;
4419}
4420/*!
4421 \internal
4422
4423 Determine which palette is inherited from this widget's ancestors and
4424 QApplication::palette, resolve this against this widget's palette
4425 (attributes from the inherited palette are copied over this widget's
4426 palette). Then propagate this palette to this widget's children.
4427*/
4428void QWidgetPrivate::resolvePalette()
4429{
4430 QPalette naturalPalette = naturalWidgetPalette(inheritedMask: inheritedPaletteResolveMask);
4431 QPalette resolvedPalette = data.pal.resolve(naturalPalette);
4432 setPalette_helper(resolvedPalette);
4433}
4434
4435void QWidgetPrivate::setPalette_helper(const QPalette &palette)
4436{
4437 Q_Q(QWidget);
4438 if (data.pal == palette && data.pal.resolve() == palette.resolve())
4439 return;
4440 data.pal = palette;
4441 updateSystemBackground();
4442 propagatePaletteChange();
4443 updateIsOpaque();
4444 q->update();
4445 updateIsOpaque();
4446}
4447
4448void QWidgetPrivate::updateSystemBackground()
4449{
4450}
4451
4452/*!
4453 \property QWidget::font
4454 \brief the font currently set for the widget
4455
4456 This property describes the widget's requested font. The font is used by
4457 the widget's style when rendering standard components, and is available as
4458 a means to ensure that custom widgets can maintain consistency with the
4459 native platform's look and feel. It's common that different platforms, or
4460 different styles, define different fonts for an application.
4461
4462 When you assign a new font to a widget, the properties from this font are
4463 combined with the widget's default font to form the widget's final
4464 font. You can call fontInfo() to get a copy of the widget's final
4465 font. The final font is also used to initialize QPainter's font.
4466
4467 The default depends on the system environment. QApplication maintains a
4468 system/theme font which serves as a default for all widgets. There may
4469 also be special font defaults for certain types of widgets. You can also
4470 define default fonts for widgets yourself by passing a custom font and the
4471 name of a widget to QApplication::setFont(). Finally, the font is matched
4472 against Qt's font database to find the best match.
4473
4474 QWidget propagates explicit font properties from parent to child. If you
4475 change a specific property on a font and assign that font to a widget,
4476 that property will propagate to all the widget's children, overriding any
4477 system defaults for that property. Note that fonts by default don't
4478 propagate to windows (see isWindow()) unless the Qt::WA_WindowPropagation
4479 attribute is enabled.
4480
4481 QWidget's font propagation is similar to its palette propagation.
4482
4483 The current style, which is used to render the content of all standard Qt
4484 widgets, is free to choose to use the widget font, or in some cases, to
4485 ignore it (partially, or completely). In particular, certain styles like
4486 GTK style, Mac style, and Windows Vista style, apply special
4487 modifications to the widget font to match the platform's native look and
4488 feel. Because of this, assigning properties to a widget's font is not
4489 guaranteed to change the appearance of the widget. Instead, you may choose
4490 to apply a \l styleSheet.
4491
4492 \note If \l{Qt Style Sheets} are used on the same widget as setFont(),
4493 style sheets will take precedence if the settings conflict.
4494
4495 \sa fontInfo(), fontMetrics()
4496*/
4497
4498void QWidget::setFont(const QFont &font)
4499{
4500 Q_D(QWidget);
4501
4502#ifndef QT_NO_STYLE_STYLESHEET
4503 const QStyleSheetStyle* style;
4504 if (d->extra && (style = qt_styleSheet(style: d->extra->style)))
4505 style->saveWidgetFont(w: this, font);
4506#endif
4507
4508 setAttribute(Qt::WA_SetFont, on: font.resolve() != 0);
4509
4510 // Determine which font is inherited from this widget's ancestors and
4511 // QApplication::font, resolve this against \a font (attributes from the
4512 // inherited font are copied over). Then propagate this font to this
4513 // widget's children.
4514 QFont naturalFont = d->naturalWidgetFont(inheritedMask: d->inheritedFontResolveMask);
4515 QFont resolvedFont = font.resolve(naturalFont);
4516 d->setFont_helper(resolvedFont);
4517}
4518
4519/*
4520 \internal
4521
4522 Returns the font that the widget \a w inherits from its ancestors and
4523 QApplication::font. \a inheritedMask is the combination of the widget's
4524 ancestors font request masks (i.e., which attributes from the parent
4525 widget's font are implicitly imposed on this widget by the user). Note
4526 that this font does not take into account the font set on \a w itself.
4527
4528 ### Stylesheet has a different font propagation mechanism. When a stylesheet
4529 is applied, fonts are not propagated anymore
4530*/
4531QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
4532{
4533 Q_Q(const QWidget);
4534
4535 const bool useStyleSheetPropagationInWidgetStyles =
4536 QCoreApplication::testAttribute(attribute: Qt::AA_UseStyleSheetPropagationInWidgetStyles);
4537
4538 QFont naturalFont = QApplication::font(q);
4539 if ((!q->testAttribute(attribute: Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
4540 && (!q->isWindow() || q->testAttribute(attribute: Qt::WA_WindowPropagation)
4541#if QT_CONFIG(graphicsview)
4542 || (extra && extra->proxyWidget)
4543#endif // QT_CONFIG(graphicsview)
4544 )) {
4545 if (QWidget *p = q->parentWidget()) {
4546 if (!p->testAttribute(attribute: Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
4547 if (!naturalFont.isCopyOf(QApplication::font())) {
4548 if (inheritedMask != 0) {
4549 QFont inheritedFont = p->font();
4550 inheritedFont.resolve(mask: inheritedMask);
4551 naturalFont = inheritedFont.resolve(naturalFont);
4552 } // else nothing to do (naturalFont = naturalFont)
4553 } else {
4554 naturalFont = p->font();
4555 }
4556 }
4557 }
4558#if QT_CONFIG(graphicsview)
4559 else if (extra && extra->proxyWidget) {
4560 if (inheritedMask != 0) {
4561 QFont inheritedFont = extra->proxyWidget->font();
4562 inheritedFont.resolve(mask: inheritedMask);
4563 naturalFont = inheritedFont.resolve(naturalFont);
4564 } // else nothing to do (naturalFont = naturalFont)
4565 }
4566#endif // QT_CONFIG(graphicsview)
4567 }
4568 naturalFont.resolve(mask: 0);
4569 return naturalFont;
4570}
4571
4572/*!
4573 \internal
4574
4575 Returns a font suitable for inheritance, where only locally set attributes are considered resolved.
4576*/
4577QFont QWidgetPrivate::localFont() const
4578{
4579 QFont localfont = data.fnt;
4580 localfont.resolve(mask: directFontResolveMask);
4581 return localfont;
4582}
4583
4584/*!
4585 \internal
4586
4587 Determine which font is implicitly imposed on this widget by its ancestors
4588 and QApplication::font, resolve this against its own font (attributes from
4589 the implicit font are copied over). Then propagate this font to this
4590 widget's children.
4591*/
4592void QWidgetPrivate::resolveFont()
4593{
4594 QFont naturalFont = naturalWidgetFont(inheritedMask: inheritedFontResolveMask);
4595 QFont resolvedFont = localFont().resolve(naturalFont);
4596 setFont_helper(resolvedFont);
4597}
4598
4599/*!
4600 \internal
4601
4602 Assign \a font to this widget, and propagate it to all children, except
4603 style sheet widgets (handled differently) and windows that don't enable
4604 window propagation. \a implicitMask is the union of all ancestor widgets'
4605 font request masks, and determines which attributes from this widget's
4606 font should propagate.
4607*/
4608void QWidgetPrivate::updateFont(const QFont &font)
4609{
4610 Q_Q(QWidget);
4611#ifndef QT_NO_STYLE_STYLESHEET
4612 const QStyleSheetStyle* cssStyle;
4613 cssStyle = extra ? qt_styleSheet(style: extra->style) : nullptr;
4614 const bool useStyleSheetPropagationInWidgetStyles =
4615 QCoreApplication::testAttribute(attribute: Qt::AA_UseStyleSheetPropagationInWidgetStyles);
4616#endif
4617
4618 data.fnt = QFont(font, q);
4619
4620 // Combine new mask with natural mask and propagate to children.
4621#if QT_CONFIG(graphicsview)
4622 if (!q->parentWidget() && extra && extra->proxyWidget) {
4623 QGraphicsProxyWidget *p = extra->proxyWidget;
4624 inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve();
4625 } else
4626#endif // QT_CONFIG(graphicsview)
4627 if (q->isWindow() && !q->testAttribute(attribute: Qt::WA_WindowPropagation)) {
4628 inheritedFontResolveMask = 0;
4629 }
4630 uint newMask = data.fnt.resolve() | inheritedFontResolveMask;
4631 // Set the font as also having resolved inherited traits, so the result of reading QWidget::font()
4632 // isn't all weak information, but save the original mask to be able to let new changes on the
4633 // parent widget font propagate correctly.
4634 directFontResolveMask = data.fnt.resolve();
4635 data.fnt.resolve(mask: newMask);
4636
4637 for (int i = 0; i < children.size(); ++i) {
4638 QWidget *w = qobject_cast<QWidget*>(o: children.at(i));
4639 if (w) {
4640 if (0) {
4641#ifndef QT_NO_STYLE_STYLESHEET
4642 } else if (!useStyleSheetPropagationInWidgetStyles && w->testAttribute(attribute: Qt::WA_StyleSheet)) {
4643 // Style sheets follow a different font propagation scheme.
4644 if (cssStyle)
4645 cssStyle->updateStyleSheetFont(w);
4646#endif
4647 } else if ((!w->isWindow() || w->testAttribute(attribute: Qt::WA_WindowPropagation))) {
4648 // Propagate font changes.
4649 QWidgetPrivate *wd = w->d_func();
4650 wd->inheritedFontResolveMask = newMask;
4651 wd->resolveFont();
4652 }
4653 }
4654 }
4655
4656#ifndef QT_NO_STYLE_STYLESHEET
4657 if (!useStyleSheetPropagationInWidgetStyles && cssStyle) {
4658 cssStyle->updateStyleSheetFont(w: q);
4659 }
4660#endif
4661
4662 QEvent e(QEvent::FontChange);
4663 QCoreApplication::sendEvent(receiver: q, event: &e);
4664}
4665
4666void QWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
4667{
4668 Q_Q(QWidget);
4669
4670 if ( (direction == Qt::RightToLeft) == q->testAttribute(attribute: Qt::WA_RightToLeft))
4671 return;
4672 q->setAttribute(Qt::WA_RightToLeft, on: (direction == Qt::RightToLeft));
4673 if (!children.isEmpty()) {
4674 for (int i = 0; i < children.size(); ++i) {
4675 QWidget *w = qobject_cast<QWidget*>(o: children.at(i));
4676 if (w && !w->isWindow() && !w->testAttribute(attribute: Qt::WA_SetLayoutDirection))
4677 w->d_func()->setLayoutDirection_helper(direction);
4678 }
4679 }
4680 QEvent e(QEvent::LayoutDirectionChange);
4681 QCoreApplication::sendEvent(receiver: q, event: &e);
4682}
4683
4684void QWidgetPrivate::resolveLayoutDirection()
4685{
4686 Q_Q(const QWidget);
4687 if (!q->testAttribute(attribute: Qt::WA_SetLayoutDirection))
4688 setLayoutDirection_helper(q->isWindow() ? QGuiApplication::layoutDirection() : q->parentWidget()->layoutDirection());
4689}
4690
4691/*!
4692 \property QWidget::layoutDirection
4693
4694 \brief the layout direction for this widget.
4695
4696 \note This method no longer affects text layout direction since Qt 4.7.
4697
4698 By default, this property is set to Qt::LeftToRight.
4699
4700 When the layout direction is set on a widget, it will propagate to
4701 the widget's children, but not to a child that is a window and not
4702 to a child for which setLayoutDirection() has been explicitly
4703 called. Also, child widgets added \e after setLayoutDirection()
4704 has been called for the parent do not inherit the parent's layout
4705 direction.
4706
4707
4708 \sa QApplication::layoutDirection
4709*/
4710void QWidget::setLayoutDirection(Qt::LayoutDirection direction)
4711{
4712 Q_D(QWidget);
4713
4714 if (direction == Qt::LayoutDirectionAuto) {
4715 unsetLayoutDirection();
4716 return;
4717 }
4718
4719 setAttribute(Qt::WA_SetLayoutDirection);
4720 d->setLayoutDirection_helper(direction);
4721}
4722
4723Qt::LayoutDirection QWidget::layoutDirection() const
4724{
4725 return testAttribute(attribute: Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
4726}
4727
4728void QWidget::unsetLayoutDirection()
4729{
4730 Q_D(QWidget);
4731 setAttribute(Qt::WA_SetLayoutDirection, on: false);
4732 d->resolveLayoutDirection();
4733}
4734
4735/*!
4736 \fn QFontMetrics QWidget::fontMetrics() const
4737
4738 Returns the font metrics for the widget's current font.
4739 Equivalent to \c QFontMetrics(widget->font()).
4740
4741 \sa font(), fontInfo(), setFont()
4742*/
4743
4744/*!
4745 \fn QFontInfo QWidget::fontInfo() const
4746
4747 Returns the font info for the widget's current font.
4748 Equivalent to \c QFontInfo(widget->font()).
4749
4750 \sa font(), fontMetrics(), setFont()
4751*/
4752
4753
4754/*!
4755 \property QWidget::cursor
4756 \brief the cursor shape for this widget
4757
4758 The mouse cursor will assume this shape when it's over this
4759 widget. See the \l{Qt::CursorShape}{list of predefined cursor objects} for a range of useful shapes.
4760
4761 An editor widget might use an I-beam cursor:
4762 \snippet code/src_gui_kernel_qwidget.cpp 6
4763
4764 If no cursor has been set, or after a call to unsetCursor(), the
4765 parent's cursor is used.
4766
4767 By default, this property contains a cursor with the Qt::ArrowCursor
4768 shape.
4769
4770 Some underlying window implementations will reset the cursor if it
4771 leaves a widget even if the mouse is grabbed. If you want to have
4772 a cursor set for all widgets, even when outside the window, consider
4773 QGuiApplication::setOverrideCursor().
4774
4775 \sa QGuiApplication::setOverrideCursor()
4776*/
4777
4778#ifndef QT_NO_CURSOR
4779QCursor QWidget::cursor() const
4780{
4781 Q_D(const QWidget);
4782 if (testAttribute(attribute: Qt::WA_SetCursor))
4783 return (d->extra && d->extra->curs)
4784 ? *d->extra->curs
4785 : QCursor(Qt::ArrowCursor);
4786 if (isWindow() || !parentWidget())
4787 return QCursor(Qt::ArrowCursor);
4788 return parentWidget()->cursor();
4789}
4790
4791void QWidget::setCursor(const QCursor &cursor)
4792{
4793 Q_D(QWidget);
4794 if (cursor.shape() != Qt::ArrowCursor
4795 || (d->extra && d->extra->curs))
4796 {
4797 d->createExtra();
4798 d->extra->curs = qt_make_unique<QCursor>(args: cursor);
4799 }
4800 setAttribute(Qt::WA_SetCursor);
4801 d->setCursor_sys(cursor);
4802
4803 QEvent event(QEvent::CursorChange);
4804 QCoreApplication::sendEvent(receiver: this, event: &event);
4805}
4806
4807void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
4808{
4809 Q_UNUSED(cursor);
4810 Q_Q(QWidget);
4811 qt_qpa_set_cursor(w: q, force: false);
4812}
4813
4814void QWidget::unsetCursor()
4815{
4816 Q_D(QWidget);
4817 if (d->extra)
4818 d->extra->curs.reset();
4819 if (!isWindow())
4820 setAttribute(Qt::WA_SetCursor, on: false);
4821 d->unsetCursor_sys();
4822
4823 QEvent event(QEvent::CursorChange);
4824 QCoreApplication::sendEvent(receiver: this, event: &event);
4825}
4826
4827void QWidgetPrivate::unsetCursor_sys()
4828{
4829 Q_Q(QWidget);
4830 qt_qpa_set_cursor(w: q, force: false);
4831}
4832
4833static inline void applyCursor(QWidget *w, const QCursor &c)
4834{
4835 if (QWindow *window = w->windowHandle())
4836 window->setCursor(c);
4837}
4838
4839static inline void unsetCursor(QWidget *w)
4840{
4841 if (QWindow *window = w->windowHandle())
4842 window->unsetCursor();
4843}
4844
4845void qt_qpa_set_cursor(QWidget *w, bool force)
4846{
4847 if (!w->testAttribute(attribute: Qt::WA_WState_Created))
4848 return;
4849
4850 static QPointer<QWidget> lastUnderMouse = nullptr;
4851 if (force) {
4852 lastUnderMouse = w;
4853 } else if (lastUnderMouse) {
4854 const WId lastWinId = lastUnderMouse->effectiveWinId();
4855 const WId winId = w->effectiveWinId();
4856 if (lastWinId && lastWinId == winId)
4857 w = lastUnderMouse;
4858 } else if (!w->internalWinId()) {
4859 return; // The mouse is not under this widget, and it's not native, so don't change it.
4860 }
4861
4862 while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
4863 && !w->testAttribute(attribute: Qt::WA_SetCursor))
4864 w = w->parentWidget();
4865
4866 QWidget *nativeParent = w;
4867 if (!w->internalWinId())
4868 nativeParent = w->nativeParentWidget();
4869 if (!nativeParent || !nativeParent->internalWinId())
4870 return;
4871
4872 if (w->isWindow() || w->testAttribute(attribute: Qt::WA_SetCursor)) {
4873 if (w->isEnabled())
4874 applyCursor(w: nativeParent, c: w->cursor());
4875 else
4876 // Enforce the windows behavior of clearing the cursor on
4877 // disabled widgets.
4878 unsetCursor(w: nativeParent);
4879 } else {
4880 unsetCursor(w: nativeParent);
4881 }
4882}
4883#endif
4884
4885/*!
4886 \enum QWidget::RenderFlag
4887
4888 This enum describes how to render the widget when calling QWidget::render().
4889
4890 \value DrawWindowBackground If you enable this option, the widget's background
4891 is rendered into the target even if autoFillBackground is not set. By default,
4892 this option is enabled.
4893
4894 \value DrawChildren If you enable this option, the widget's children
4895 are rendered recursively into the target. By default, this option is enabled.
4896
4897 \value IgnoreMask If you enable this option, the widget's QWidget::mask()
4898 is ignored when rendering into the target. By default, this option is disabled.
4899
4900 \since 4.3
4901*/
4902
4903/*!
4904 \since 4.3
4905
4906 Renders the \a sourceRegion of this widget into the \a target
4907 using \a renderFlags to determine how to render. Rendering
4908 starts at \a targetOffset in the \a target. For example:
4909
4910 \snippet code/src_gui_kernel_qwidget.cpp 7
4911
4912 If \a sourceRegion is a null region, this function will use QWidget::rect() as
4913 the region, i.e. the entire widget.
4914
4915 Ensure that you call QPainter::end() for the \a target device's
4916 active painter (if any) before rendering. For example:
4917
4918 \snippet code/src_gui_kernel_qwidget.cpp 8
4919
4920 \note To obtain the contents of a QOpenGLWidget, use QOpenGLWidget::grabFramebuffer()
4921 instead.
4922
4923 \note To obtain the contents of a QGLWidget (deprecated), use
4924 QGLWidget::grabFrameBuffer() or QGLWidget::renderPixmap() instead.
4925*/
4926void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
4927 const QRegion &sourceRegion, RenderFlags renderFlags)
4928{
4929 QPainter p(target);
4930 render(painter: &p, targetOffset, sourceRegion, renderFlags);
4931}
4932
4933/*!
4934 \overload
4935
4936 Renders the widget into the \a painter's QPainter::device().
4937
4938 Transformations and settings applied to the \a painter will be used
4939 when rendering.
4940
4941 \note The \a painter must be active. On \macos the widget will be
4942 rendered into a QPixmap and then drawn by the \a painter.
4943
4944 \sa QPainter::device()
4945*/
4946void QWidget::render(QPainter *painter, const QPoint &targetOffset,
4947 const QRegion &sourceRegion, RenderFlags renderFlags)
4948{
4949 if (Q_UNLIKELY(!painter)) {
4950 qWarning(msg: "QWidget::render: Null pointer to painter");
4951 return;
4952 }
4953
4954 if (Q_UNLIKELY(!painter->isActive())) {
4955 qWarning(msg: "QWidget::render: Cannot render with an inactive painter");
4956 return;
4957 }
4958
4959 const qreal opacity = painter->opacity();
4960 if (qFuzzyIsNull(d: opacity))
4961 return; // Fully transparent.
4962
4963 Q_D(QWidget);
4964 const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter;
4965 const QRegion toBePainted = !inRenderWithPainter ? d->prepareToRender(region: sourceRegion, renderFlags)
4966 : sourceRegion;
4967 if (toBePainted.isEmpty())
4968 return;
4969
4970 if (!d->extra)
4971 d->createExtra();
4972 d->extra->inRenderWithPainter = true;
4973
4974 QPaintEngine *engine = painter->paintEngine();
4975 Q_ASSERT(engine);
4976 QPaintEnginePrivate *enginePriv = engine->d_func();
4977 Q_ASSERT(enginePriv);
4978 QPaintDevice *target = engine->paintDevice();
4979 Q_ASSERT(target);
4980
4981 // Render via a pixmap when dealing with non-opaque painters or printers.
4982 if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) {
4983 d->render_helper(painter, targetOffset, sourceRegion: toBePainted, renderFlags);
4984 d->extra->inRenderWithPainter = inRenderWithPainter;
4985 return;
4986 }
4987
4988 // Set new shared painter.
4989 QPainter *oldPainter = d->sharedPainter();
4990 d->setSharedPainter(painter);
4991
4992 // Save current system clip, viewport and transform,
4993 const QTransform oldTransform = enginePriv->systemTransform;
4994 const QRegion oldSystemClip = enginePriv->systemClip;
4995 const QRegion oldBaseClip = enginePriv->baseSystemClip;
4996 const QRegion oldSystemViewport = enginePriv->systemViewport;
4997
4998 // This ensures that all painting triggered by render() is clipped to the current engine clip.
4999 if (painter->hasClipping()) {
5000 const QRegion painterClip = painter->deviceTransform().map(r: painter->clipRegion());
5001 enginePriv->setSystemViewport(oldSystemClip.isEmpty() ? painterClip : oldSystemClip & painterClip);
5002 } else {
5003 enginePriv->setSystemViewport(oldSystemClip);
5004 }
5005
5006 d->render(target, targetOffset, sourceRegion: toBePainted, renderFlags);
5007
5008 // Restore system clip, viewport and transform.
5009 enginePriv->baseSystemClip = oldBaseClip;
5010 enginePriv->setSystemTransformAndViewport(xform: oldTransform, region: oldSystemViewport);
5011 enginePriv->systemStateChanged();
5012
5013 // Restore shared painter.
5014 d->setSharedPainter(oldPainter);
5015
5016 d->extra->inRenderWithPainter = inRenderWithPainter;
5017}
5018
5019static void sendResizeEvents(QWidget *target)
5020{
5021 QResizeEvent e(target->size(), QSize());
5022 QCoreApplication::sendEvent(receiver: target, event: &e);
5023
5024 const QObjectList children = target->children();
5025 for (int i = 0; i < children.size(); ++i) {
5026 if (!children.at(i)->isWidgetType())
5027 continue;
5028 QWidget *child = static_cast<QWidget*>(children.at(i));
5029 if (!child->isWindow() && child->testAttribute(attribute: Qt::WA_PendingResizeEvent))
5030 sendResizeEvents(target: child);
5031 }
5032}
5033
5034/*!
5035 \since 5.0
5036
5037 Renders the widget into a pixmap restricted by the
5038 given \a rectangle. If the widget has any children, then
5039 they are also painted in the appropriate positions.
5040
5041 If a rectangle with an invalid size is specified (the default),
5042 the entire widget is painted.
5043
5044 \sa render(), QPixmap
5045*/
5046QPixmap QWidget::grab(const QRect &rectangle)
5047{
5048 Q_D(QWidget);
5049 if (testAttribute(attribute: Qt::WA_PendingResizeEvent) || !testAttribute(attribute: Qt::WA_WState_Created))
5050 sendResizeEvents(target: this);
5051
5052 const QWidget::RenderFlags renderFlags = QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask;
5053
5054 const bool oldDirtyOpaqueChildren = d->dirtyOpaqueChildren;
5055 QRect r(rectangle);
5056 if (r.width() < 0 || r.height() < 0) {
5057 // For grabbing widgets that haven't been shown yet,
5058 // we trigger the layouting mechanism to determine the widget's size.
5059 r = d->prepareToRender(region: QRegion(), renderFlags).boundingRect();
5060 r.setTopLeft(rectangle.topLeft());
5061 }
5062
5063 if (!r.intersects(r: rect()))
5064 return QPixmap();
5065
5066 const qreal dpr = devicePixelRatioF();
5067 QPixmap res((QSizeF(r.size()) * dpr).toSize());
5068 res.setDevicePixelRatio(dpr);
5069 if (!d->isOpaque)
5070 res.fill(fillColor: Qt::transparent);
5071 d->render(target: &res, targetOffset: QPoint(), sourceRegion: QRegion(r), renderFlags);
5072
5073 d->dirtyOpaqueChildren = oldDirtyOpaqueChildren;
5074 return res;
5075}
5076
5077/*!
5078 \brief The graphicsEffect function returns a pointer to the
5079 widget's graphics effect.
5080
5081 If the widget has no graphics effect, \nullptr is returned.
5082
5083 \since 4.6
5084
5085 \sa setGraphicsEffect()
5086*/
5087#if QT_CONFIG(graphicseffect)
5088QGraphicsEffect *QWidget::graphicsEffect() const
5089{
5090 Q_D(const QWidget);
5091 return d->graphicsEffect;
5092}
5093#endif // QT_CONFIG(graphicseffect)
5094
5095/*!
5096
5097 \brief The setGraphicsEffect function is for setting the widget's graphics effect.
5098
5099 Sets \a effect as the widget's effect. If there already is an effect installed
5100 on this widget, QWidget will delete the existing effect before installing
5101 the new \a effect.
5102
5103 If \a effect is the installed effect on a different widget, setGraphicsEffect() will remove
5104 the effect from the widget and install it on this widget.
5105
5106 QWidget takes ownership of \a effect.
5107
5108 \note This function will apply the effect on itself and all its children.
5109
5110 \note Graphics effects are not supported for OpenGL-based widgets, such as QGLWidget,
5111 QOpenGLWidget and QQuickWidget.
5112
5113 \since 4.6
5114
5115 \sa graphicsEffect()
5116*/
5117#if QT_CONFIG(graphicseffect)
5118void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
5119{
5120 Q_D(QWidget);
5121 if (d->graphicsEffect == effect)
5122 return;
5123
5124 if (d->graphicsEffect) {
5125 d->invalidateBackingStore(rect());
5126 delete d->graphicsEffect;
5127 d->graphicsEffect = nullptr;
5128 }
5129
5130 if (effect) {
5131 // Set new effect.
5132 QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
5133 QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
5134 d->graphicsEffect = effect;
5135 effect->d_func()->setGraphicsEffectSource(source);
5136 update();
5137 }
5138
5139 d->updateIsOpaque();
5140}
5141#endif // QT_CONFIG(graphicseffect)
5142
5143bool QWidgetPrivate::isAboutToShow() const
5144{
5145 if (data.in_show)
5146 return true;
5147
5148 Q_Q(const QWidget);
5149 if (q->isHidden())
5150 return false;
5151
5152 // The widget will be shown if any of its ancestors are about to show.
5153 QWidget *parent = q->parentWidget();
5154 return parent ? parent->d_func()->isAboutToShow() : false;
5155}
5156
5157QRegion QWidgetPrivate::prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags)
5158{
5159 Q_Q(QWidget);
5160 const bool isVisible = q->isVisible();
5161
5162 // Make sure the widget is laid out correctly.
5163 if (!isVisible && !isAboutToShow()) {
5164 QWidget *topLevel = q->window();
5165 (void)topLevel->d_func()->topData(); // Make sure we at least have top-data.
5166 topLevel->ensurePolished();
5167
5168 // Invalidate the layout of hidden ancestors (incl. myself) and pretend
5169 // they're not explicitly hidden.
5170 QWidget *widget = q;
5171 QWidgetList hiddenWidgets;
5172 while (widget) {
5173 if (widget->isHidden()) {
5174 widget->setAttribute(Qt::WA_WState_Hidden, on: false);
5175 hiddenWidgets.append(t: widget);
5176 if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
5177 widget->d_func()->updateGeometry_helper(forceUpdate: true);
5178 }
5179 widget = widget->parentWidget();
5180 }
5181
5182 // Activate top-level layout.
5183 if (topLevel->d_func()->layout)
5184 topLevel->d_func()->layout->activate();
5185
5186 // Adjust size if necessary.
5187 QTLWExtra *topLevelExtra = topLevel->d_func()->maybeTopData();
5188 if (topLevelExtra && !topLevelExtra->sizeAdjusted
5189 && !topLevel->testAttribute(attribute: Qt::WA_Resized)) {
5190 topLevel->adjustSize();
5191 topLevel->setAttribute(Qt::WA_Resized, on: false);
5192 }
5193
5194 // Activate child layouts.
5195 topLevel->d_func()->activateChildLayoutsRecursively();
5196
5197 // We're not cheating with WA_WState_Hidden anymore.
5198 for (int i = 0; i < hiddenWidgets.size(); ++i) {
5199 QWidget *widget = hiddenWidgets.at(i);
5200 widget->setAttribute(Qt::WA_WState_Hidden);
5201 if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
5202 widget->parentWidget()->d_func()->layout->invalidate();
5203 }
5204 } else if (isVisible) {
5205 q->window()->d_func()->sendPendingMoveAndResizeEvents(recursive: true, disableUpdates: true);
5206 }
5207
5208 // Calculate the region to be painted.
5209 QRegion toBePainted = !region.isEmpty() ? region : QRegion(q->rect());
5210 if (!(renderFlags & QWidget::IgnoreMask) && extra && extra->hasMask)
5211 toBePainted &= extra->mask;
5212 return toBePainted;
5213}
5214
5215void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &toBePainted,
5216 QWidget::RenderFlags renderFlags)
5217{
5218 Q_ASSERT(painter);
5219 Q_ASSERT(!toBePainted.isEmpty());
5220
5221 Q_Q(QWidget);
5222 const QTransform originalTransform = painter->worldTransform();
5223 const bool useDeviceCoordinates = originalTransform.isScaling();
5224 if (!useDeviceCoordinates) {
5225 // Render via a pixmap.
5226 const QRect rect = toBePainted.boundingRect();
5227 const QSize size = rect.size();
5228 if (size.isNull())
5229 return;
5230
5231 const qreal pixmapDevicePixelRatio = painter->device()->devicePixelRatioF();
5232 QPixmap pixmap(size * pixmapDevicePixelRatio);
5233 pixmap.setDevicePixelRatio(pixmapDevicePixelRatio);
5234
5235 if (!(renderFlags & QWidget::DrawWindowBackground) || !isOpaque)
5236 pixmap.fill(fillColor: Qt::transparent);
5237 q->render(target: &pixmap, targetOffset: QPoint(), sourceRegion: toBePainted, renderFlags);
5238
5239 const bool restore = !(painter->renderHints() & QPainter::SmoothPixmapTransform);
5240 painter->setRenderHints(hints: QPainter::SmoothPixmapTransform, on: true);
5241
5242 painter->drawPixmap(p: targetOffset, pm: pixmap);
5243
5244 if (restore)
5245 painter->setRenderHints(hints: QPainter::SmoothPixmapTransform, on: false);
5246
5247 } else {
5248 // Render via a pixmap in device coordinates (to avoid pixmap scaling).
5249 QTransform transform = originalTransform;
5250 transform.translate(dx: targetOffset.x(), dy: targetOffset.y());
5251
5252 QPaintDevice *device = painter->device();
5253 Q_ASSERT(device);
5254
5255 // Calculate device rect.
5256 const QRectF rect(toBePainted.boundingRect());
5257 QRect deviceRect = transform.mapRect(QRectF(0, 0, rect.width(), rect.height())).toAlignedRect();
5258 deviceRect &= QRect(0, 0, device->width(), device->height());
5259
5260 QPixmap pixmap(deviceRect.size());
5261 pixmap.fill(fillColor: Qt::transparent);
5262
5263 // Create a pixmap device coordinate painter.
5264 QPainter pixmapPainter(&pixmap);
5265 pixmapPainter.setRenderHints(hints: painter->renderHints());
5266 transform *= QTransform::fromTranslate(dx: -deviceRect.x(), dy: -deviceRect.y());
5267 pixmapPainter.setTransform(transform);
5268
5269 q->render(painter: &pixmapPainter, targetOffset: QPoint(), sourceRegion: toBePainted, renderFlags);
5270 pixmapPainter.end();
5271
5272 // And then draw the pixmap.
5273 painter->setTransform(transform: QTransform());
5274 painter->drawPixmap(p: deviceRect.topLeft(), pm: pixmap);
5275 painter->setTransform(transform: originalTransform);
5276 }
5277}
5278
5279void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, DrawWidgetFlags flags,
5280 QPainter *sharedPainter, QWidgetRepaintManager *repaintManager)
5281{
5282 if (rgn.isEmpty())
5283 return;
5284
5285 Q_Q(QWidget);
5286
5287 qCInfo(lcWidgetPainting) << "Drawing" << rgn << "of" << q << "at" << offset
5288 << "into paint device" << pdev << "with" << flags;
5289
5290 const bool asRoot = flags & DrawAsRoot;
5291 bool onScreen = shouldPaintOnScreen();
5292
5293#if QT_CONFIG(graphicseffect)
5294 if (graphicsEffect && graphicsEffect->isEnabled()) {
5295 QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
5296 QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
5297 (source->d_func());
5298 if (!sourced->context) {
5299 const QRegion effectRgn(rgn.boundingRect());
5300 QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
5301 sourced->context = &context;
5302 if (!sharedPainter) {
5303 setSystemClip(paintEngine: pdev->paintEngine(), devicePixelRatio: pdev->devicePixelRatioF(), region: effectRgn.translated(p: offset));
5304 QPainter p(pdev);
5305 p.translate(offset);
5306 context.painter = &p;
5307 graphicsEffect->draw(painter: &p);
5308 setSystemClip(paintEngine: pdev->paintEngine(), devicePixelRatio: 1, region: QRegion());
5309 } else {
5310 context.painter = sharedPainter;
5311 if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
5312 sourced->invalidateCache();
5313 sourced->lastEffectTransform = sharedPainter->worldTransform();
5314 }
5315 sharedPainter->save();
5316 sharedPainter->translate(offset);
5317 setSystemClip(paintEngine: sharedPainter->paintEngine(), devicePixelRatio: sharedPainter->device()->devicePixelRatioF(), region: effectRgn.translated(p: offset));
5318 graphicsEffect->draw(painter: sharedPainter);
5319 setSystemClip(paintEngine: sharedPainter->paintEngine(), devicePixelRatio: 1, region: QRegion());
5320 sharedPainter->restore();
5321 }
5322 sourced->context = nullptr;
5323
5324 if (repaintManager)
5325 repaintManager->markNeedsFlush(widget: q, region: effectRgn, topLevelOffset: offset);
5326
5327 return;
5328 }
5329 }
5330#endif // QT_CONFIG(graphicseffect)
5331
5332 const bool alsoOnScreen = flags & DrawPaintOnScreen;
5333 const bool recursive = flags & DrawRecursive;
5334 const bool alsoInvisible = flags & DrawInvisible;
5335
5336 Q_ASSERT(sharedPainter ? sharedPainter->isActive() : true);
5337
5338 QRegion toBePainted(rgn);
5339 if (asRoot && !alsoInvisible)
5340 toBePainted &= clipRect(); //(rgn & visibleRegion());
5341 if (!(flags & DontSubtractOpaqueChildren))
5342 subtractOpaqueChildren(source&: toBePainted, clipRect: q->rect());
5343
5344 if (!toBePainted.isEmpty()) {
5345 if (!onScreen || alsoOnScreen) {
5346 //update the "in paint event" flag
5347 if (Q_UNLIKELY(q->testAttribute(Qt::WA_WState_InPaintEvent)))
5348 qWarning(msg: "QWidget::repaint: Recursive repaint detected");
5349 q->setAttribute(Qt::WA_WState_InPaintEvent);
5350
5351 //clip away the new area
5352 QPaintEngine *paintEngine = pdev->paintEngine();
5353 if (paintEngine) {
5354 setRedirected(replacement: pdev, offset: -offset);
5355
5356 if (sharedPainter)
5357 setSystemClip(paintEngine: pdev->paintEngine(), devicePixelRatio: pdev->devicePixelRatioF(), region: toBePainted);
5358 else
5359 paintEngine->d_func()->systemRect = q->data->crect;
5360
5361 //paint the background
5362 if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(attribute: Qt::WA_StyledBackground))
5363 && !q->testAttribute(attribute: Qt::WA_OpaquePaintEvent) && !q->testAttribute(attribute: Qt::WA_NoSystemBackground)) {
5364#ifndef QT_NO_OPENGL
5365 beginBackingStorePainting();
5366#endif
5367 QPainter p(q);
5368 paintBackground(painter: &p, rgn: toBePainted, flags: (asRoot || onScreen) ? (flags | DrawAsRoot) : DrawWidgetFlags());
5369#ifndef QT_NO_OPENGL
5370 endBackingStorePainting();
5371#endif
5372 }
5373
5374 if (!sharedPainter)
5375 setSystemClip(paintEngine: pdev->paintEngine(), devicePixelRatio: pdev->devicePixelRatioF(), region: toBePainted.translated(p: offset));
5376
5377 if (!onScreen && !asRoot && !isOpaque && q->testAttribute(attribute: Qt::WA_TintedBackground)) {
5378#ifndef QT_NO_OPENGL
5379 beginBackingStorePainting();
5380#endif
5381 QPainter p(q);
5382 QColor tint = q->palette().window().color();
5383 tint.setAlphaF(qreal(.6));
5384 p.fillRect(toBePainted.boundingRect(), color: tint);
5385#ifndef QT_NO_OPENGL
5386 endBackingStorePainting();
5387#endif
5388 }
5389 }
5390
5391#if 0
5392 qDebug() << "painting" << q << "opaque ==" << isOpaque();
5393 qDebug() << "clipping to" << toBePainted << "location == " << offset
5394 << "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size());
5395#endif
5396
5397 bool skipPaintEvent = false;
5398#ifndef QT_NO_OPENGL
5399 if (renderToTexture) {
5400 // This widget renders into a texture which is composed later. We just need to
5401 // punch a hole in the backingstore, so the texture will be visible.
5402 beginBackingStorePainting();
5403 if (!q->testAttribute(attribute: Qt::WA_AlwaysStackOnTop) && repaintManager) {
5404 QPainter p(q);
5405 p.setCompositionMode(QPainter::CompositionMode_Source);
5406 p.fillRect(r: q->rect(), c: Qt::transparent);
5407 } else if (!repaintManager) {
5408 // We are not drawing to a backingstore: fall back to QImage
5409 QImage img = grabFramebuffer();
5410 // grabFramebuffer() always sets the format to RGB32
5411 // regardless of whether it is transparent or not.
5412 if (img.format() == QImage::Format_RGB32)
5413 img.reinterpretAsFormat(f: QImage::Format_ARGB32_Premultiplied);
5414 QPainter p(q);
5415 p.drawImage(r: q->rect(), image: img);
5416 skipPaintEvent = true;
5417 }
5418 endBackingStorePainting();
5419 if (renderToTextureReallyDirty)
5420 renderToTextureReallyDirty = 0;
5421 else
5422 skipPaintEvent = true;
5423 }
5424#endif // QT_NO_OPENGL
5425
5426 if (!skipPaintEvent) {
5427 //actually send the paint event
5428 sendPaintEvent(toBePainted);
5429 }
5430
5431 if (repaintManager)
5432 repaintManager->markNeedsFlush(widget: q, region: toBePainted, topLevelOffset: offset);
5433
5434 //restore
5435 if (paintEngine) {
5436 restoreRedirected();
5437 if (!sharedPainter)
5438 paintEngine->d_func()->systemRect = QRect();
5439 else
5440 paintEngine->d_func()->currentClipDevice = nullptr;
5441
5442 setSystemClip(paintEngine: pdev->paintEngine(), devicePixelRatio: 1, region: QRegion());
5443 }
5444 q->setAttribute(Qt::WA_WState_InPaintEvent, on: false);
5445 if (Q_UNLIKELY(q->paintingActive()))
5446 qWarning(msg: "QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
5447
5448 if (paintEngine && paintEngine->autoDestruct()) {
5449 delete paintEngine;
5450 }
5451 } else if (q->isWindow()) {
5452 QPaintEngine *engine = pdev->paintEngine();
5453 if (engine) {
5454 QPainter p(pdev);
5455 p.setClipRegion(toBePainted);
5456 const QBrush bg = q->palette().brush(cr: QPalette::Window);
5457 if (bg.style() == Qt::TexturePattern)
5458 p.drawTiledPixmap(rect: q->rect(), pm: bg.texture());
5459 else
5460 p.fillRect(q->rect(), bg);
5461
5462 if (engine->autoDestruct())
5463 delete engine;
5464 }
5465 }
5466 }
5467
5468 if (recursive && !children.isEmpty()) {
5469 paintSiblingsRecursive(pdev, children, index: children.size() - 1, rgn, offset, flags: flags & ~DrawAsRoot,
5470 sharedPainter, repaintManager);
5471 }
5472}
5473
5474void QWidgetPrivate::sendPaintEvent(const QRegion &toBePainted)
5475{
5476 Q_Q(QWidget);
5477 QPaintEvent e(toBePainted);
5478 QCoreApplication::sendSpontaneousEvent(receiver: q, event: &e);
5479
5480#ifndef QT_NO_OPENGL
5481 if (renderToTexture)
5482 resolveSamples();
5483#endif // QT_NO_OPENGL
5484}
5485
5486void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
5487 const QRegion &sourceRegion, QWidget::RenderFlags renderFlags)
5488{
5489 if (Q_UNLIKELY(!target)) {
5490 qWarning(msg: "QWidget::render: null pointer to paint device");
5491 return;
5492 }
5493
5494 const bool inRenderWithPainter = extra && extra->inRenderWithPainter;
5495 QRegion paintRegion = !inRenderWithPainter
5496 ? prepareToRender(region: sourceRegion, renderFlags)
5497 : sourceRegion;
5498 if (paintRegion.isEmpty())
5499 return;
5500
5501 QPainter *oldSharedPainter = inRenderWithPainter ? sharedPainter() : nullptr;
5502
5503 // Use the target's shared painter if set (typically set when doing
5504 // "other->render(widget);" in the widget's paintEvent.
5505 if (target->devType() == QInternal::Widget) {
5506 QWidgetPrivate *targetPrivate = static_cast<QWidget *>(target)->d_func();
5507 if (targetPrivate->extra && targetPrivate->extra->inRenderWithPainter) {
5508 QPainter *targetPainter = targetPrivate->sharedPainter();
5509 if (targetPainter && targetPainter->isActive())
5510 setSharedPainter(targetPainter);
5511 }
5512 }
5513
5514 // Use the target's redirected device if set and adjust offset and paint
5515 // region accordingly. This is typically the case when people call render
5516 // from the paintEvent.
5517 QPoint offset = targetOffset;
5518 offset -= paintRegion.boundingRect().topLeft();
5519 QPoint redirectionOffset;
5520 QPaintDevice *redirected = nullptr;
5521
5522 if (target->devType() == QInternal::Widget)
5523 redirected = static_cast<QWidget *>(target)->d_func()->redirected(offset: &redirectionOffset);
5524
5525 if (redirected) {
5526 target = redirected;
5527 offset -= redirectionOffset;
5528 }
5529
5530 if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp).
5531 if (QPaintEngine *targetEngine = target->paintEngine()) {
5532 const QRegion targetSystemClip = targetEngine->systemClip();
5533 if (!targetSystemClip.isEmpty())
5534 paintRegion &= targetSystemClip.translated(p: -offset);
5535 }
5536 }
5537
5538 // Set backingstore flags.
5539 DrawWidgetFlags flags = DrawPaintOnScreen | DrawInvisible;
5540 if (renderFlags & QWidget::DrawWindowBackground)
5541 flags |= DrawAsRoot;
5542
5543 if (renderFlags & QWidget::DrawChildren)
5544 flags |= DrawRecursive;
5545 else
5546 flags |= DontSubtractOpaqueChildren;
5547
5548 flags |= DontSetCompositionMode;
5549
5550 // Render via backingstore.
5551 drawWidget(pdev: target, rgn: paintRegion, offset, flags, sharedPainter: sharedPainter());
5552
5553 // Restore shared painter.
5554 if (oldSharedPainter)
5555 setSharedPainter(oldSharedPainter);
5556}
5557
5558void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn,
5559 const QPoint &offset, DrawWidgetFlags flags
5560 , QPainter *sharedPainter, QWidgetRepaintManager *repaintManager)
5561{
5562 QWidget *w = nullptr;
5563 QRect boundingRect;
5564 bool dirtyBoundingRect = true;
5565 const bool exludeOpaqueChildren = (flags & DontDrawOpaqueChildren);
5566 const bool excludeNativeChildren = (flags & DontDrawNativeChildren);
5567
5568 do {
5569 QWidget *x = qobject_cast<QWidget*>(o: siblings.at(i: index));
5570 if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()
5571 && !(excludeNativeChildren && x->internalWinId())) {
5572 if (dirtyBoundingRect) {
5573 boundingRect = rgn.boundingRect();
5574 dirtyBoundingRect = false;
5575 }
5576
5577 if (qRectIntersects(r1: boundingRect, r2: x->d_func()->effectiveRectFor(rect: x->data->crect))) {
5578 w = x;
5579 break;
5580 }
5581 }
5582 --index;
5583 } while (index >= 0);
5584
5585 if (!w)
5586 return;
5587
5588 QWidgetPrivate *wd = w->d_func();
5589 const QPoint widgetPos(w->data->crect.topLeft());
5590 const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect;
5591 if (index > 0) {
5592 QRegion wr(rgn);
5593 if (wd->isOpaque)
5594 wr -= hasMask ? wd->extra->mask.translated(p: widgetPos) : w->data->crect;
5595 paintSiblingsRecursive(pdev, siblings, index: --index, rgn: wr, offset, flags,
5596 sharedPainter, repaintManager);
5597 }
5598
5599 if (w->updatesEnabled()
5600#if QT_CONFIG(graphicsview)
5601 && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget)
5602#endif // QT_CONFIG(graphicsview)
5603 ) {
5604 QRegion wRegion(rgn);
5605 wRegion &= wd->effectiveRectFor(rect: w->data->crect);
5606 wRegion.translate(p: -widgetPos);
5607 if (hasMask)
5608 wRegion &= wd->extra->mask;
5609 wd->drawWidget(pdev, rgn: wRegion, offset: offset + widgetPos, flags, sharedPainter, repaintManager);
5610 }
5611}
5612
5613#if QT_CONFIG(graphicseffect)
5614QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
5615{
5616 if (system != Qt::DeviceCoordinates)
5617 return m_widget->rect();
5618
5619 if (Q_UNLIKELY(!context)) {
5620 // Device coordinates without context not yet supported.
5621 qWarning(msg: "QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
5622 return QRectF();
5623 }
5624
5625 return context->painter->worldTransform().mapRect(m_widget->rect());
5626}
5627
5628void QWidgetEffectSourcePrivate::draw(QPainter *painter)
5629{
5630 if (!context || context->painter != painter) {
5631 m_widget->render(painter);
5632 return;
5633 }
5634
5635 // The region saved in the context is neither clipped to the rect
5636 // nor the mask, so we have to clip it here before calling drawWidget.
5637 QRegion toBePainted = context->rgn;
5638 toBePainted &= m_widget->rect();
5639 QWidgetPrivate *wd = qt_widget_private(widget: m_widget);
5640 if (wd->extra && wd->extra->hasMask)
5641 toBePainted &= wd->extra->mask;
5642
5643 wd->drawWidget(pdev: context->pdev, rgn: toBePainted, offset: context->offset, flags: context->flags,
5644 sharedPainter: context->sharedPainter, repaintManager: context->repaintManager);
5645}
5646
5647QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
5648 QGraphicsEffect::PixmapPadMode mode) const
5649{
5650 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
5651 if (Q_UNLIKELY(!context && deviceCoordinates)) {
5652 // Device coordinates without context not yet supported.
5653 qWarning(msg: "QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
5654 return QPixmap();
5655 }
5656
5657 QPoint pixmapOffset;
5658 QRectF sourceRect = m_widget->rect();
5659
5660 if (deviceCoordinates) {
5661 const QTransform &painterTransform = context->painter->worldTransform();
5662 sourceRect = painterTransform.mapRect(sourceRect);
5663 pixmapOffset = painterTransform.map(p: pixmapOffset);
5664 }
5665
5666 QRect effectRect;
5667
5668 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect)
5669 effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
5670 else if (mode == QGraphicsEffect::PadToTransparentBorder)
5671 effectRect = sourceRect.adjusted(xp1: -1, yp1: -1, xp2: 1, yp2: 1).toAlignedRect();
5672 else
5673 effectRect = sourceRect.toAlignedRect();
5674
5675 if (offset)
5676 *offset = effectRect.topLeft();
5677
5678 pixmapOffset -= effectRect.topLeft();
5679
5680 qreal dpr(1.0);
5681 if (const auto *paintDevice = context->painter->device())
5682 dpr = paintDevice->devicePixelRatioF();
5683 else
5684 qWarning(msg: "QWidgetEffectSourcePrivate::pixmap: Painter not active");
5685 QPixmap pixmap(effectRect.size() * dpr);
5686 pixmap.setDevicePixelRatio(dpr);
5687
5688 pixmap.fill(fillColor: Qt::transparent);
5689 m_widget->render(target: &pixmap, targetOffset: pixmapOffset, sourceRegion: QRegion(), renderFlags: QWidget::DrawChildren);
5690 return pixmap;
5691}
5692#endif // QT_CONFIG(graphicseffect)
5693
5694#if QT_CONFIG(graphicsview)
5695/*!
5696 \internal
5697
5698 Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this
5699 widget and its ancestors. The search starts at \a origin (inclusive).
5700 If successful, the function returns the proxy that embeds the widget, or \nullptr if no
5701 embedded widget was found.
5702*/
5703QGraphicsProxyWidget *QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
5704{
5705 if (origin) {
5706 const auto &extra = origin->d_func()->extra;
5707 if (extra && extra->proxyWidget)
5708 return extra->proxyWidget;
5709 return nearestGraphicsProxyWidget(origin: origin->parentWidget());
5710 }
5711 return nullptr;
5712}
5713#endif
5714
5715/*!
5716 \property QWidget::locale
5717 \brief the widget's locale
5718 \since 4.3
5719
5720 As long as no special locale has been set, this is either
5721 the parent's locale or (if this widget is a top level widget),
5722 the default locale.
5723
5724 If the widget displays dates or numbers, these should be formatted
5725 using the widget's locale.
5726
5727 \sa QLocale, QLocale::setDefault()
5728*/
5729
5730void QWidgetPrivate::setLocale_helper(const QLocale &loc, bool forceUpdate)
5731{
5732 Q_Q(QWidget);
5733 if (locale == loc && !forceUpdate)
5734 return;
5735
5736 locale = loc;
5737
5738 if (!children.isEmpty()) {
5739 for (int i = 0; i < children.size(); ++i) {
5740 QWidget *w = qobject_cast<QWidget*>(o: children.at(i));
5741 if (!w)
5742 continue;
5743 if (w->testAttribute(attribute: Qt::WA_SetLocale))
5744 continue;
5745 if (w->isWindow() && !w->testAttribute(attribute: Qt::WA_WindowPropagation))
5746 continue;
5747 w->d_func()->setLocale_helper(loc, forceUpdate);
5748 }
5749 }
5750 QEvent e(QEvent::LocaleChange);
5751 QCoreApplication::sendEvent(receiver: q, event: &e);
5752}
5753
5754void QWidget::setLocale(const QLocale &locale)
5755{
5756 Q_D(QWidget);
5757
5758 setAttribute(Qt::WA_SetLocale);
5759 d->setLocale_helper(loc: locale);
5760}
5761
5762QLocale QWidget::locale() const
5763{
5764 Q_D(const QWidget);
5765
5766 return d->locale;
5767}
5768
5769void QWidgetPrivate::resolveLocale()
5770{
5771 Q_Q(const QWidget);
5772
5773 if (!q->testAttribute(attribute: Qt::WA_SetLocale)) {
5774 QWidget *parent = q->parentWidget();
5775 setLocale_helper(loc: !parent || (q->isWindow() && !q->testAttribute(attribute: Qt::WA_WindowPropagation))
5776 ? QLocale() : parent->locale());
5777 }
5778}
5779
5780void QWidget::unsetLocale()
5781{
5782 Q_D(QWidget);
5783 setAttribute(Qt::WA_SetLocale, on: false);
5784 d->resolveLocale();
5785}
5786
5787/*!
5788 \property QWidget::windowTitle
5789 \brief the window title (caption)
5790
5791 This property only makes sense for top-level widgets, such as
5792 windows and dialogs. If no caption has been set, the title is based of the
5793 \l windowFilePath. If neither of these is set, then the title is
5794 an empty string.
5795
5796 If you use the \l windowModified mechanism, the window title must
5797 contain a "[*]" placeholder, which indicates where the '*' should
5798 appear. Normally, it should appear right after the file name
5799 (e.g., "document1.txt[*] - Text Editor"). If the \l
5800 windowModified property is \c false (the default), the placeholder
5801 is simply removed.
5802
5803 On some desktop platforms (including Windows and Unix), the application name
5804 (from QGuiApplication::applicationDisplayName) is added at the end of the
5805 window title, if set. This is done by the QPA plugin, so it is shown to the
5806 user, but isn't part of the windowTitle string.
5807
5808 \sa windowIcon, windowModified, windowFilePath
5809*/
5810QString QWidget::windowTitle() const
5811{
5812 Q_D(const QWidget);
5813 if (d->extra && d->extra->topextra) {
5814 if (!d->extra->topextra->caption.isEmpty())
5815 return d->extra->topextra->caption;
5816 if (!d->extra->topextra->filePath.isEmpty())
5817 return QFileInfo(d->extra->topextra->filePath).fileName() + QLatin1String("[*]");
5818 }
5819 return QString();
5820}
5821
5822/*!
5823 Returns a modified window title with the [*] place holder
5824 replaced according to the rules described in QWidget::setWindowTitle
5825
5826 This function assumes that "[*]" can be quoted by another
5827 "[*]", so it will replace two place holders by one and
5828 a single last one by either "*" or nothing depending on
5829 the modified flag.
5830
5831 \internal
5832*/
5833QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget)
5834{
5835 Q_ASSERT(widget);
5836
5837 QString cap = title;
5838 if (cap.isEmpty())
5839 return cap;
5840
5841 QLatin1String placeHolder("[*]");
5842 int index = cap.indexOf(s: placeHolder);
5843
5844 // here the magic begins
5845 while (index != -1) {
5846 index += placeHolder.size();
5847 int count = 1;
5848 while (cap.indexOf(s: placeHolder, from: index) == index) {
5849 ++count;
5850 index += placeHolder.size();
5851 }
5852
5853 if (count%2) { // odd number of [*] -> replace last one
5854 int lastIndex = cap.lastIndexOf(s: placeHolder, from: index - 1);
5855 if (widget->isWindowModified()
5856 && widget->style()->styleHint(stylehint: QStyle::SH_TitleBar_ModifyNotification, opt: nullptr, widget))
5857 cap.replace(i: lastIndex, len: 3, after: QWidget::tr(s: "*"));
5858 else
5859 cap.remove(i: lastIndex, len: 3);
5860 }
5861
5862 index = cap.indexOf(s: placeHolder, from: index);
5863 }
5864
5865 cap.replace(before: QLatin1String("[*][*]"), after: placeHolder);
5866
5867 return cap;
5868}
5869
5870void QWidgetPrivate::setWindowTitle_helper(const QString &title)
5871{
5872 Q_Q(QWidget);
5873 if (q->testAttribute(attribute: Qt::WA_WState_Created))
5874 setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, widget: q));
5875}
5876
5877void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
5878{
5879 Q_Q(QWidget);
5880 if (!q->isWindow())
5881 return;
5882
5883 if (QWindow *window = q->windowHandle())
5884 window->setTitle(caption);
5885
5886}
5887
5888void QWidgetPrivate::setWindowIconText_helper(const QString &title)
5889{
5890 Q_Q(QWidget);
5891 if (q->testAttribute(attribute: Qt::WA_WState_Created))
5892 setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, widget: q));
5893}
5894
5895void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
5896{
5897 Q_Q(QWidget);
5898 // ### The QWidget property is deprecated, but the XCB window function is not.
5899 // It should remain available for the rare application that needs it.
5900 if (QWindow *window = q->windowHandle())
5901 QXcbWindowFunctions::setWmWindowIconText(window, text: iconText);
5902}
5903
5904/*!
5905 \fn void QWidget::windowIconTextChanged(const QString &iconText)
5906
5907 This signal is emitted when the window's icon text has changed, with the
5908 new \a iconText as an argument.
5909
5910 \since 5.2
5911 \obsolete
5912
5913 This signal is deprecated.
5914*/
5915
5916void QWidget::setWindowIconText(const QString &iconText)
5917{
5918 if (QWidget::windowIconText() == iconText)
5919 return;
5920
5921 Q_D(QWidget);
5922 d->topData()->iconText = iconText;
5923 d->setWindowIconText_helper(iconText);
5924
5925 QEvent e(QEvent::IconTextChange);
5926 QCoreApplication::sendEvent(receiver: this, event: &e);
5927
5928 emit windowIconTextChanged(iconText);
5929}
5930
5931/*!
5932 \fn void QWidget::windowTitleChanged(const QString &title)
5933
5934 This signal is emitted when the window's title has changed, with the
5935 new \a title as an argument.
5936
5937 \since 5.2
5938*/
5939
5940void QWidget::setWindowTitle(const QString &title)
5941{
5942 if (QWidget::windowTitle() == title && !title.isEmpty() && !title.isNull())
5943 return;
5944
5945 Q_D(QWidget);
5946 d->topData()->caption = title;
5947 d->setWindowTitle_helper(title);
5948
5949 QEvent e(QEvent::WindowTitleChange);
5950 QCoreApplication::sendEvent(receiver: this, event: &e);
5951
5952 emit windowTitleChanged(title);
5953}
5954
5955
5956/*!
5957 \property QWidget::windowIcon
5958 \brief the widget's icon
5959
5960 This property only makes sense for windows. If no icon
5961 has been set, windowIcon() returns the application icon
5962 (QApplication::windowIcon()).
5963
5964 \note On \macos, window icons represent the active document,
5965 and will not be displayed unless a file path has also been
5966 set using setWindowFilePath.
5967
5968 \sa windowTitle, setWindowFilePath
5969*/
5970QIcon QWidget::windowIcon() const
5971{
5972 const QWidget *w = this;
5973 while (w) {
5974 const QWidgetPrivate *d = w->d_func();
5975 if (d->extra && d->extra->topextra && d->extra->topextra->icon)
5976 return *d->extra->topextra->icon;
5977 w = w->parentWidget();
5978 }
5979 return QApplication::windowIcon();
5980}
5981
5982void QWidgetPrivate::setWindowIcon_helper()
5983{
5984 Q_Q(QWidget);
5985 QEvent e(QEvent::WindowIconChange);
5986
5987 // Do not send the event if the widget is a top level.
5988 // In that case, setWindowIcon_sys does it, and event propagation from
5989 // QWidgetWindow to the top level QWidget ensures that the event reaches
5990 // the top level anyhow
5991 if (!q->windowHandle())
5992 QCoreApplication::sendEvent(receiver: q, event: &e);
5993 for (int i = 0; i < children.size(); ++i) {
5994 QWidget *w = qobject_cast<QWidget *>(o: children.at(i));
5995 if (w && !w->isWindow())
5996 QCoreApplication::sendEvent(receiver: w, event: &e);
5997 }
5998}
5999
6000/*!
6001 \fn void QWidget::windowIconChanged(const QIcon &icon)
6002
6003 This signal is emitted when the window's icon has changed, with the
6004 new \a icon as an argument.
6005
6006 \since 5.2
6007*/
6008
6009void QWidget::setWindowIcon(const QIcon &icon)
6010{
6011 Q_D(QWidget);
6012
6013 setAttribute(Qt::WA_SetWindowIcon, on: !icon.isNull());
6014 d->createTLExtra();
6015
6016 if (!d->extra->topextra->icon)
6017 d->extra->topextra->icon = qt_make_unique<QIcon>(args: icon);
6018 else
6019 *d->extra->topextra->icon = icon;
6020
6021 d->setWindowIcon_sys();
6022 d->setWindowIcon_helper();
6023
6024 emit windowIconChanged(icon);
6025}
6026
6027void QWidgetPrivate::setWindowIcon_sys()
6028{
6029 Q_Q(QWidget);
6030 if (QWindow *window = q->windowHandle())
6031 window->setIcon(q->windowIcon());
6032}
6033
6034/*!
6035 \property QWidget::windowIconText
6036 \brief the text to be displayed on the icon of a minimized window
6037
6038 This property only makes sense for windows. If no icon
6039 text has been set, this accessor returns an empty string.
6040 It is only implemented on the X11 platform, and only certain
6041 window managers use this window property.
6042
6043 \obsolete
6044 This property is deprecated.
6045
6046 \sa windowIcon, windowTitle
6047*/
6048
6049QString QWidget::windowIconText() const
6050{
6051 Q_D(const QWidget);
6052 return (d->extra && d->extra->topextra) ? d->extra->topextra->iconText : QString();
6053}
6054
6055/*!
6056 \property QWidget::windowFilePath
6057 \since 4.4
6058 \brief the file path associated with a widget
6059
6060 This property only makes sense for windows. It associates a file path with
6061 a window. If you set the file path, but have not set the window title, Qt
6062 sets the window title to the file name of the specified path, obtained using
6063 QFileInfo::fileName().
6064
6065 If the window title is set at any point, then the window title takes precedence and
6066 will be shown instead of the file path string.
6067
6068 Additionally, on \macos, this has an added benefit that it sets the
6069 \l{http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGWindows/chapter_17_section_3.html}{proxy icon}
6070 for the window, assuming that the file path exists.
6071
6072 If no file path is set, this property contains an empty string.
6073
6074 By default, this property contains an empty string.
6075
6076 \sa windowTitle, windowIcon
6077*/
6078
6079QString QWidget::windowFilePath() const
6080{
6081 Q_D(const QWidget);
6082 return (d->extra && d->extra->topextra) ? d->extra->topextra->filePath : QString();
6083}
6084
6085void QWidget::setWindowFilePath(const QString &filePath)
6086{
6087 if (filePath == windowFilePath())
6088 return;
6089
6090 Q_D(QWidget);
6091
6092 d->createTLExtra();
6093 d->extra->topextra->filePath = filePath;
6094 d->setWindowFilePath_helper(filePath);
6095}
6096
6097void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath)
6098{
6099 if (extra->topextra && extra->topextra->caption.isEmpty()) {
6100#ifdef Q_OS_MAC
6101 setWindowTitle_helper(QFileInfo(filePath).fileName());
6102#else
6103 Q_Q(QWidget);
6104 Q_UNUSED(filePath);
6105 setWindowTitle_helper(q->windowTitle());
6106#endif
6107 }
6108#ifdef Q_OS_MAC
6109 setWindowFilePath_sys(filePath);
6110#endif
6111}
6112
6113void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
6114{
6115 Q_Q(QWidget);
6116 if (!q->isWindow())
6117 return;
6118
6119 if (QWindow *window = q->windowHandle())
6120 window->setFilePath(filePath);
6121}
6122
6123/*!
6124 Returns the window's role, or an empty string.
6125
6126 \sa windowIcon, windowTitle
6127*/
6128
6129QString QWidget::windowRole() const
6130{
6131 Q_D(const QWidget);
6132 return (d->extra && d->extra->topextra) ? d->extra->topextra->role : QString();
6133}
6134
6135/*!
6136 Sets the window's role to \a role. This only makes sense for
6137 windows on X11.
6138*/
6139void QWidget::setWindowRole(const QString &role)
6140{
6141 Q_D(QWidget);
6142 d->createTLExtra();
6143 d->topData()->role = role;
6144 if (windowHandle())
6145 QXcbWindowFunctions::setWmWindowRole(window: windowHandle(), role: role.toLatin1());
6146}
6147
6148/*!
6149 \property QWidget::mouseTracking
6150 \brief whether mouse tracking is enabled for the widget
6151
6152 If mouse tracking is disabled (the default), the widget only
6153 receives mouse move events when at least one mouse button is
6154 pressed while the mouse is being moved.
6155
6156 If mouse tracking is enabled, the widget receives mouse move
6157 events even if no buttons are pressed.
6158
6159 \sa mouseMoveEvent()
6160*/
6161
6162/*!
6163 \property QWidget::tabletTracking
6164 \brief whether tablet tracking is enabled for the widget
6165 \since 5.9
6166
6167 If tablet tracking is disabled (the default), the widget only
6168 receives tablet move events when the stylus is in contact with
6169 the tablet, or at least one stylus button is pressed,
6170 while the stylus is being moved.
6171
6172 If tablet tracking is enabled, the widget receives tablet move
6173 events even while hovering in proximity. This is useful for
6174 monitoring position as well as the auxiliary properties such
6175 as rotation and tilt, and providing feedback in the UI.
6176
6177 \sa tabletEvent()
6178*/
6179
6180
6181/*!
6182 Sets the widget's focus proxy to widget \a w. If \a w is \nullptr, the
6183 function resets this widget to have no focus proxy.
6184
6185 Some widgets can "have focus", but create a child widget, such as
6186 QLineEdit, to actually handle the focus. In this case, the widget
6187 can set the line edit to be its focus proxy.
6188
6189 setFocusProxy() sets the widget which will actually get focus when
6190 "this widget" gets it. If there is a focus proxy, setFocus() and
6191 hasFocus() operate on the focus proxy. If "this widget" is the focus
6192 widget, then setFocusProxy() moves focus to the new focus proxy.
6193
6194 \sa focusProxy()
6195*/
6196
6197void QWidget::setFocusProxy(QWidget * w)
6198{
6199 Q_D(QWidget);
6200 if (!w && !d->extra)
6201 return;
6202
6203 for (QWidget* fp = w; fp; fp = fp->focusProxy()) {
6204 if (Q_UNLIKELY(fp == this)) {
6205 qWarning(msg: "QWidget: %s (%s) already in focus proxy chain", metaObject()->className(), objectName().toLocal8Bit().constData());
6206 return;
6207 }
6208 }
6209
6210 const bool moveFocusToProxy = (QApplicationPrivate::focus_widget == this);
6211
6212 d->createExtra();
6213 d->extra->focus_proxy = w;
6214
6215 if (moveFocusToProxy)
6216 setFocus(Qt::OtherFocusReason);
6217}
6218
6219
6220/*!
6221 Returns the focus proxy, or \nullptr if there is no focus proxy.
6222
6223 \sa setFocusProxy()
6224*/
6225
6226QWidget *QWidget::focusProxy() const
6227{
6228 Q_D(const QWidget);
6229 return d->extra ? d->extra->focus_proxy.data() : nullptr;
6230}
6231
6232
6233/*!
6234 \property QWidget::focus
6235 \brief whether this widget (or its focus proxy) has the keyboard
6236 input focus
6237
6238 By default, this property is \c false.
6239
6240 \note Obtaining the value of this property for a widget is effectively equivalent
6241 to checking whether QApplication::focusWidget() refers to the widget.
6242
6243 \sa setFocus(), clearFocus(), setFocusPolicy(), QApplication::focusWidget()
6244*/
6245bool QWidget::hasFocus() const
6246{
6247 const QWidget* w = this;
6248 while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
6249 w = w->d_func()->extra->focus_proxy;
6250#if QT_CONFIG(graphicsview)
6251 if (QWidget *window = w->window()) {
6252 const auto &e = window->d_func()->extra;
6253 if (e && e->proxyWidget && e->proxyWidget->hasFocus() && window->focusWidget() == w)
6254 return true;
6255 }
6256#endif // QT_CONFIG(graphicsview)
6257 return (QApplication::focusWidget() == w);
6258}
6259
6260/*!
6261 Gives the keyboard input focus to this widget (or its focus
6262 proxy) if this widget or one of its parents is the \l{isActiveWindow()}{active window}. The \a reason argument will
6263 be passed into any focus event sent from this function, it is used
6264 to give an explanation of what caused the widget to get focus.
6265 If the window is not active, the widget will be given the focus when
6266 the window becomes active.
6267
6268 First, a focus about to change event is sent to the focus widget (if any) to
6269 tell it that it is about to lose the focus. Then focus is changed, a
6270 focus out event is sent to the previous focus item and a focus in event is sent
6271 to the new item to tell it that it just received the focus.
6272 (Nothing happens if the focus in and focus out widgets are the
6273 same.)
6274
6275 \note On embedded platforms, setFocus() will not cause an input panel
6276 to be opened by the input method. If you want this to happen, you
6277 have to send a QEvent::RequestSoftwareInputPanel event to the
6278 widget yourself.
6279
6280 setFocus() gives focus to a widget regardless of its focus policy,
6281 but does not clear any keyboard grab (see grabKeyboard()).
6282
6283 Be aware that if the widget is hidden, it will not accept focus
6284 until it is shown.
6285
6286 \warning If you call setFocus() in a function which may itself be
6287 called from focusOutEvent() or focusInEvent(), you may get an
6288 infinite recursion.
6289
6290 \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(),
6291 setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(),
6292 grabMouse(), {Keyboard Focus in Widgets}, QEvent::RequestSoftwareInputPanel
6293*/
6294
6295void QWidget::setFocus(Qt::FocusReason reason)
6296{
6297 if (!isEnabled())
6298 return;
6299
6300 QWidget *f = d_func()->deepestFocusProxy();
6301 if (!f)
6302 f = this;
6303
6304 if (QApplication::focusWidget() == f)
6305 return;
6306
6307#if QT_CONFIG(graphicsview)
6308 QWidget *previousProxyFocus = nullptr;
6309 if (const auto &topData = window()->d_func()->extra) {
6310 if (topData->proxyWidget && topData->proxyWidget->hasFocus()) {
6311 previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
6312 if (previousProxyFocus && previousProxyFocus->focusProxy())
6313 previousProxyFocus = previousProxyFocus->focusProxy();
6314 if (previousProxyFocus == f && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
6315 return;
6316 }
6317 }
6318#endif
6319
6320#if QT_CONFIG(graphicsview)
6321 // Update proxy state
6322 if (const auto &topData = window()->d_func()->extra) {
6323 if (topData->proxyWidget && !topData->proxyWidget->hasFocus()) {
6324 f->d_func()->updateFocusChild();
6325 topData->proxyWidget->d_func()->focusFromWidgetToProxy = 1;
6326 topData->proxyWidget->setFocus(reason);
6327 topData->proxyWidget->d_func()->focusFromWidgetToProxy = 0;
6328 }
6329 }
6330#endif
6331
6332 if (f->isActiveWindow()) {
6333 QWidget *prev = QApplicationPrivate::focus_widget;
6334 if (prev) {
6335 if (reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason
6336 && prev->testAttribute(attribute: Qt::WA_InputMethodEnabled)) {
6337 QGuiApplication::inputMethod()->commit();
6338 }
6339
6340 if (reason != Qt::NoFocusReason) {
6341 QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange, reason);
6342 QCoreApplication::sendEvent(receiver: prev, event: &focusAboutToChange);
6343 }
6344 }
6345
6346 f->d_func()->updateFocusChild();
6347
6348 QApplicationPrivate::setFocusWidget(focus: f, reason);
6349#ifndef QT_NO_ACCESSIBILITY
6350 // menus update the focus manually and this would create bogus events
6351 if (!(f->inherits(classname: "QMenuBar") || f->inherits(classname: "QMenu") || f->inherits(classname: "QMenuItem")))
6352 {
6353 QAccessibleEvent event(f, QAccessible::Focus);
6354 QAccessible::updateAccessibility(event: &event);
6355 }
6356#endif
6357#if QT_CONFIG(graphicsview)
6358 if (const auto &topData = window()->d_func()->extra) {
6359 if (topData->proxyWidget) {
6360 if (previousProxyFocus && previousProxyFocus != f) {
6361 // Send event to self
6362 QFocusEvent event(QEvent::FocusOut, reason);
6363 QPointer<QWidget> that = previousProxyFocus;
6364 QCoreApplication::sendEvent(receiver: previousProxyFocus, event: &event);
6365 if (that)
6366 QCoreApplication::sendEvent(receiver: that->style(), event: &event);
6367 }
6368 if (!isHidden()) {
6369#if QT_CONFIG(graphicsview)
6370 // Update proxy state
6371 if (const auto &topData = window()->d_func()->extra)
6372 if (topData->proxyWidget && topData->proxyWidget->hasFocus())
6373 topData->proxyWidget->d_func()->updateProxyInputMethodAcceptanceFromWidget();
6374#endif
6375 // Send event to self
6376 QFocusEvent event(QEvent::FocusIn, reason);
6377 QPointer<QWidget> that = f;
6378 QCoreApplication::sendEvent(receiver: f, event: &event);
6379 if (that)
6380 QCoreApplication::sendEvent(receiver: that->style(), event: &event);
6381 }
6382 }
6383 }
6384#endif
6385 } else {
6386 f->d_func()->updateFocusChild();
6387 }
6388}
6389
6390
6391/*!\internal
6392 * A focus proxy can have its own focus proxy, which can have its own
6393 * proxy, and so on. This helper function returns the widget that sits
6394 * at the bottom of the proxy chain, and therefore the one that should
6395 * normally get focus if this widget receives a focus request.
6396 */
6397QWidget *QWidgetPrivate::deepestFocusProxy() const
6398{
6399 Q_Q(const QWidget);
6400
6401 QWidget *focusProxy = q->focusProxy();
6402 if (!focusProxy)
6403 return nullptr;
6404
6405 while (QWidget *nextFocusProxy = focusProxy->focusProxy())
6406 focusProxy = nextFocusProxy;
6407
6408 return focusProxy;
6409}
6410
6411static inline bool isEmbedded(const QWindow *w)
6412{
6413 const auto platformWindow = w->handle();
6414 return platformWindow && platformWindow->isEmbedded();
6415}
6416
6417void QWidgetPrivate::setFocus_sys()
6418{
6419 Q_Q(QWidget);
6420 // Embedded native widget may have taken the focus; get it back to toplevel
6421 // if that is the case (QTBUG-25852)
6422 // Do not activate in case the popup menu opens another application (QTBUG-70810)
6423 // unless the application is embedded (QTBUG-71991).
6424 if (QWindow *nativeWindow = q->testAttribute(attribute: Qt::WA_WState_Created) ? q->window()->windowHandle() : nullptr) {
6425 if (nativeWindow->type() != Qt::Popup && nativeWindow != QGuiApplication::focusWindow()
6426 && (QGuiApplication::applicationState() == Qt::ApplicationActive
6427 || QCoreApplication::testAttribute(attribute: Qt::AA_PluginApplication)
6428 || isEmbedded(w: nativeWindow))) {
6429 nativeWindow->requestActivate();
6430 }
6431 }
6432}
6433
6434// updates focus_child on parent widgets to point into this widget
6435void QWidgetPrivate::updateFocusChild()
6436{
6437 Q_Q(QWidget);
6438
6439 QWidget *w = q;
6440 if (q->isHidden()) {
6441 while (w && w->isHidden()) {
6442 w->d_func()->focus_child = q;
6443 w = w->isWindow() ? nullptr : w->parentWidget();
6444 }
6445 } else {
6446 while (w) {
6447 w->d_func()->focus_child = q;
6448 w = w->isWindow() ? nullptr : w->parentWidget();
6449 }
6450 }
6451
6452 if (QTLWExtra *extra = q->window()->d_func()->maybeTopData()) {
6453 if (extra->window)
6454 emit extra->window->focusObjectChanged(object: q);
6455 }
6456}
6457
6458/*!
6459 \fn void QWidget::setFocus()
6460 \overload
6461
6462 Gives the keyboard input focus to this widget (or its focus
6463 proxy) if this widget or one of its parents is the
6464 \l{isActiveWindow()}{active window}.
6465*/
6466
6467/*!
6468 Takes keyboard input focus from the widget.
6469
6470 If the widget has active focus, a \l{focusOutEvent()}{focus out event} is sent to this widget to tell it that it has
6471 lost the focus.
6472
6473 This widget must enable focus setting in order to get the keyboard
6474 input focus, i.e. it must call setFocusPolicy().
6475
6476 \sa hasFocus(), setFocus(), focusInEvent(), focusOutEvent(),
6477 setFocusPolicy(), QApplication::focusWidget()
6478*/
6479
6480void QWidget::clearFocus()
6481{
6482 if (hasFocus()) {
6483 if (testAttribute(attribute: Qt::WA_InputMethodEnabled))
6484 QGuiApplication::inputMethod()->commit();
6485
6486 QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange);
6487 QCoreApplication::sendEvent(receiver: this, event: &focusAboutToChange);
6488 }
6489
6490 QTLWExtra *extra = window()->d_func()->maybeTopData();
6491 QObject *originalFocusObject = (extra && extra->window) ? extra->window->focusObject() : nullptr;
6492
6493 QWidget *w = this;
6494 while (w) {
6495 // Just like setFocus(), we update (clear) the focus_child of our parents
6496 if (w->d_func()->focus_child == this)
6497 w->d_func()->focus_child = nullptr;
6498 w = w->parentWidget();
6499 }
6500
6501 // We've potentially cleared the focus_child of our parents, so we need
6502 // to report this to the rest of Qt. Note that the focus_child is not the same
6503 // thing as the application's focusWidget, which is why this piece of code is
6504 // not inside a hasFocus() block.
6505 if (originalFocusObject && originalFocusObject != extra->window->focusObject())
6506 emit extra->window->focusObjectChanged(object: extra->window->focusObject());
6507
6508#if QT_CONFIG(graphicsview)
6509 const auto &topData = d_func()->extra;
6510 if (topData && topData->proxyWidget)
6511 topData->proxyWidget->clearFocus();
6512#endif
6513
6514 if (hasFocus()) {
6515 // Update proxy state
6516 QApplicationPrivate::setFocusWidget(focus: nullptr, reason: Qt::OtherFocusReason);
6517#ifndef QT_NO_ACCESSIBILITY
6518 QAccessibleEvent event(this, QAccessible::Focus);
6519 QAccessible::updateAccessibility(event: &event);
6520#endif
6521 }
6522}
6523
6524
6525/*!
6526 \fn bool QWidget::focusNextChild()
6527
6528 Finds a new widget to give the keyboard focus to, as appropriate
6529 for \uicontrol Tab, and returns \c true if it can find a new widget, or
6530 false if it can't.
6531
6532 \sa focusPreviousChild()
6533*/
6534
6535/*!
6536 \fn bool QWidget::focusPreviousChild()
6537
6538 Finds a new widget to give the keyboard focus to, as appropriate
6539 for \uicontrol Shift+Tab, and returns \c true if it can find a new widget,
6540 or false if it can't.
6541
6542 \sa focusNextChild()
6543*/
6544
6545/*!
6546 Finds a new widget to give the keyboard focus to, as appropriate
6547 for Tab and Shift+Tab, and returns \c true if it can find a new
6548 widget, or false if it can't.
6549
6550 If \a next is true, this function searches forward, if \a next
6551 is false, it searches backward.
6552
6553 Sometimes, you will want to reimplement this function. For
6554 example, a web browser might reimplement it to move its "current
6555 active link" forward or backward, and call
6556 focusNextPrevChild() only when it reaches the last or
6557 first link on the "page".
6558
6559 Child widgets call focusNextPrevChild() on their parent widgets,
6560 but only the window that contains the child widgets decides where
6561 to redirect focus. By reimplementing this function for an object,
6562 you thus gain control of focus traversal for all child widgets.
6563
6564 \sa focusNextChild(), focusPreviousChild()
6565*/
6566
6567bool QWidget::focusNextPrevChild(bool next)
6568{
6569 QWidget* p = parentWidget();
6570 bool isSubWindow = (windowType() == Qt::SubWindow);
6571 if (!isWindow() && !isSubWindow && p)
6572 return p->focusNextPrevChild(next);
6573#if QT_CONFIG(graphicsview)
6574 Q_D(QWidget);
6575 if (d->extra && d->extra->proxyWidget)
6576 return d->extra->proxyWidget->focusNextPrevChild(next);
6577#endif
6578
6579 bool wrappingOccurred = false;
6580 QWidget *w = QApplicationPrivate::focusNextPrevChild_helper(toplevel: this, next,
6581 wrappingOccurred: &wrappingOccurred);
6582 if (!w) return false;
6583
6584 Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;
6585
6586 /* If we are about to wrap the focus chain, give the platform
6587 * implementation a chance to alter the wrapping behavior. This is
6588 * especially needed when the window is embedded in a window created by
6589 * another process.
6590 */
6591 if (wrappingOccurred) {
6592 QWindow *window = windowHandle();
6593 if (window != nullptr) {
6594 QWindowPrivate *winp = qt_window_private(window);
6595
6596 if (winp->platformWindow != nullptr) {
6597 QFocusEvent event(QEvent::FocusIn, reason);
6598 event.ignore();
6599 winp->platformWindow->windowEvent(event: &event);
6600 if (event.isAccepted()) return true;
6601 }
6602 }
6603 }
6604
6605 w->setFocus(reason);
6606 return true;
6607}
6608
6609/*!
6610 Returns the last child of this widget that setFocus had been
6611 called on. For top level widgets this is the widget that will get
6612 focus in case this window gets activated
6613
6614 This is not the same as QApplication::focusWidget(), which returns
6615 the focus widget in the currently active window.
6616*/
6617
6618QWidget *QWidget::focusWidget() const
6619{
6620 return const_cast<QWidget *>(d_func()->focus_child);
6621}
6622
6623/*!
6624 Returns the next widget in this widget's focus chain.
6625
6626 \sa previousInFocusChain()
6627*/
6628QWidget *QWidget::nextInFocusChain() const
6629{
6630 return const_cast<QWidget *>(d_func()->focus_next);
6631}
6632
6633/*!
6634 \brief The previousInFocusChain function returns the previous
6635 widget in this widget's focus chain.
6636
6637 \sa nextInFocusChain()
6638
6639 \since 4.6
6640*/
6641QWidget *QWidget::previousInFocusChain() const
6642{
6643 return const_cast<QWidget *>(d_func()->focus_prev);
6644}
6645
6646/*!
6647 \property QWidget::isActiveWindow
6648 \brief whether this widget's window is the active window
6649
6650 The active window is the window that contains the widget that has
6651 keyboard focus (The window may still have focus if it has no
6652 widgets or none of its widgets accepts keyboard focus).
6653
6654 When popup windows are visible, this property is \c true for both the
6655 active window \e and for the popup.
6656
6657 By default, this property is \c false.
6658
6659 \sa activateWindow(), QApplication::activeWindow()
6660*/
6661bool QWidget::isActiveWindow() const
6662{
6663 QWidget *tlw = window();
6664 if(tlw == QApplication::activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup)))
6665 return true;
6666
6667#if QT_CONFIG(graphicsview)
6668 if (const auto &tlwExtra = tlw->d_func()->extra) {
6669 if (isVisible() && tlwExtra->proxyWidget)
6670 return tlwExtra->proxyWidget->isActiveWindow();
6671 }
6672#endif
6673
6674 if (style()->styleHint(stylehint: QStyle::SH_Widget_ShareActivation, opt: nullptr, widget: this)) {
6675 if(tlw->windowType() == Qt::Tool &&
6676 !tlw->isModal() &&
6677 (!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
6678 return true;
6679 QWidget *w = QApplication::activeWindow();
6680 while(w && tlw->windowType() == Qt::Tool &&
6681 !w->isModal() && w->parentWidget()) {
6682 w = w->parentWidget()->window();
6683 if(w == tlw)
6684 return true;
6685 }
6686 }
6687
6688 // Check for an active window container
6689 if (QWindow *ww = QGuiApplication::focusWindow()) {
6690 while (ww) {
6691 QWidgetWindow *qww = qobject_cast<QWidgetWindow *>(object: ww);
6692 QWindowContainer *qwc = qww ? qobject_cast<QWindowContainer *>(object: qww->widget()) : 0;
6693 if (qwc && qwc->topLevelWidget() == tlw)
6694 return true;
6695 ww = ww->parent();
6696 }
6697 }
6698
6699 // Check if platform adaptation thinks the window is active. This is necessary for
6700 // example in case of ActiveQt servers that are embedded into another application.
6701 // Those are separate processes that are not part of the parent application Qt window/widget
6702 // hierarchy, so they need to rely on native methods to determine if they are part of the
6703 // active window.
6704 if (const QWindow *w = tlw->windowHandle()) {
6705 if (w->handle())
6706 return w->handle()->isActive();
6707 }
6708
6709 return false;
6710}
6711
6712/*!
6713 Puts the \a second widget after the \a first widget in the focus order.
6714
6715 It effectively removes the \a second widget from its focus chain and
6716 inserts it after the \a first widget.
6717
6718 Note that since the tab order of the \a second widget is changed, you
6719 should order a chain like this:
6720
6721 \snippet code/src_gui_kernel_qwidget.cpp 9
6722
6723 \e not like this:
6724
6725 \snippet code/src_gui_kernel_qwidget.cpp 10
6726
6727 If \a first or \a second has a focus proxy, setTabOrder()
6728 correctly substitutes the proxy.
6729
6730 \note Since Qt 5.10: A widget that has a child as focus proxy is understood as
6731 a compound widget. When setting a tab order between one or two compound widgets, the
6732 local tab order inside each will be preserved. This means that if both widgets are
6733 compound widgets, the resulting tab order will be from the last child inside
6734 \a first, to the first child inside \a second.
6735
6736 \sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus in Widgets}
6737*/
6738void QWidget::setTabOrder(QWidget* first, QWidget *second)
6739{
6740 if (!first || !second || first == second
6741 || first->focusPolicy() == Qt::NoFocus
6742 || second->focusPolicy() == Qt::NoFocus)
6743 return;
6744
6745 if (Q_UNLIKELY(first->window() != second->window())) {
6746 qWarning(msg: "QWidget::setTabOrder: 'first' and 'second' must be in the same window");
6747 return;
6748 }
6749
6750 auto determineLastFocusChild = [](QWidget *target, QWidget *&lastFocusChild)
6751 {
6752 // Since we need to repeat the same logic for both 'first' and 'second', we add a function that
6753 // determines the last focus child for a widget, taking proxies and compound widgets into account.
6754 // If the target is not a compound widget (it doesn't have a focus proxy that points to a child),
6755 // 'lastFocusChild' will be set to the target itself.
6756 lastFocusChild = target;
6757
6758 QWidget *focusProxy = target->d_func()->deepestFocusProxy();
6759 if (!focusProxy || !target->isAncestorOf(child: focusProxy)) {
6760 // QTBUG-81097: Another case is possible here. We can have a child
6761 // widget, that sets its focusProxy() to the parent (target).
6762 // An example of such widget is a QLineEdit, nested into
6763 // a QAbstractSpinBox. In this case such widget should be considered
6764 // the last focus child.
6765 for (auto *object : target->children()) {
6766 QWidget *w = qobject_cast<QWidget*>(o: object);
6767 if (w && w->focusProxy() == target) {
6768 lastFocusChild = w;
6769 break;
6770 }
6771 }
6772 return;
6773 }
6774
6775 lastFocusChild = focusProxy;
6776
6777 for (QWidget *focusNext = lastFocusChild->d_func()->focus_next;
6778 focusNext != focusProxy && target->isAncestorOf(child: focusNext) && focusNext->window() == focusProxy->window();
6779 focusNext = focusNext->d_func()->focus_next) {
6780 if (focusNext->focusPolicy() != Qt::NoFocus)
6781 lastFocusChild = focusNext;
6782 }
6783 };
6784 auto setPrev = [](QWidget *w, QWidget *prev)
6785 {
6786 w->d_func()->focus_prev = prev;
6787 };
6788 auto setNext = [](QWidget *w, QWidget *next)
6789 {
6790 w->d_func()->focus_next = next;
6791 };
6792
6793 // remove the second widget from the chain
6794 QWidget *lastFocusChildOfSecond;
6795 determineLastFocusChild(second, lastFocusChildOfSecond);
6796 {
6797 QWidget *oldPrev = second->d_func()->focus_prev;
6798 QWidget *prevWithFocus = oldPrev;
6799 while (prevWithFocus->focusPolicy() == Qt::NoFocus)
6800 prevWithFocus = prevWithFocus->d_func()->focus_prev;
6801 // only widgets between first and second -> all is fine
6802 if (prevWithFocus == first)
6803 return;
6804 QWidget *oldNext = lastFocusChildOfSecond->d_func()->focus_next;
6805 setPrev(oldNext, oldPrev);
6806 setNext(oldPrev, oldNext);
6807 }
6808
6809 // insert the second widget into the chain
6810 QWidget *lastFocusChildOfFirst;
6811 determineLastFocusChild(first, lastFocusChildOfFirst);
6812 {
6813 QWidget *oldNext = lastFocusChildOfFirst->d_func()->focus_next;
6814 setPrev(second, lastFocusChildOfFirst);
6815 setNext(lastFocusChildOfFirst, second);
6816 setPrev(oldNext, lastFocusChildOfSecond);
6817 setNext(lastFocusChildOfSecond, oldNext);
6818 }
6819}
6820
6821/*!\internal
6822
6823 Moves the relevant subwidgets of this widget from the \a oldtlw's
6824 tab chain to that of the new parent, if there's anything to move and
6825 we're really moving
6826
6827 This function is called from QWidget::reparent() *after* the widget
6828 has been reparented.
6829
6830 \sa reparent()
6831*/
6832
6833void QWidgetPrivate::reparentFocusWidgets(QWidget * oldtlw)
6834{
6835 Q_Q(QWidget);
6836 if (oldtlw == q->window())
6837 return; // nothing to do
6838
6839 if(focus_child)
6840 focus_child->clearFocus();
6841
6842 // separate the focus chain into new (children of myself) and old (the rest)
6843 QWidget *firstOld = nullptr;
6844 //QWidget *firstNew = q; //invariant
6845 QWidget *o = nullptr; // last in the old list
6846 QWidget *n = q; // last in the new list
6847
6848 bool prevWasNew = true;
6849 QWidget *w = focus_next;
6850
6851 //Note: for efficiency, we do not maintain the list invariant inside the loop
6852 //we append items to the relevant list, and we optimize by not changing pointers
6853 //when subsequent items are going into the same list.
6854 while (w != q) {
6855 bool currentIsNew = q->isAncestorOf(child: w);
6856 if (currentIsNew) {
6857 if (!prevWasNew) {
6858 //prev was old -- append to new list
6859 n->d_func()->focus_next = w;
6860 w->d_func()->focus_prev = n;
6861 }
6862 n = w;
6863 } else {
6864 if (prevWasNew) {
6865 //prev was new -- append to old list, if there is one
6866 if (o) {
6867 o->d_func()->focus_next = w;
6868 w->d_func()->focus_prev = o;
6869 } else {
6870 // "create" the old list
6871 firstOld = w;
6872 }
6873 }
6874 o = w;
6875 }
6876 w = w->d_func()->focus_next;
6877 prevWasNew = currentIsNew;
6878 }
6879
6880 //repair the old list:
6881 if (firstOld) {
6882 o->d_func()->focus_next = firstOld;
6883 firstOld->d_func()->focus_prev = o;
6884 }
6885
6886 if (!q->isWindow()) {
6887 QWidget *topLevel = q->window();
6888 //insert new chain into toplevel's chain
6889
6890 QWidget *prev = topLevel->d_func()->focus_prev;
6891
6892 topLevel->d_func()->focus_prev = n;
6893 prev->d_func()->focus_next = q;
6894
6895 focus_prev = prev;
6896 n->d_func()->focus_next = topLevel;
6897 } else {
6898 //repair the new list
6899 n->d_func()->focus_next = q;
6900 focus_prev = n;
6901 }
6902
6903}
6904
6905/*!\internal
6906
6907 Measures the shortest distance from a point to a rect.
6908
6909 This function is called from QDesktopwidget::screen(QPoint) to find the
6910 closest screen for a point.
6911 In directional KeypadNavigation, it is called to find the closest
6912 widget to the current focus widget center.
6913*/
6914int QWidgetPrivate::pointToRect(const QPoint &p, const QRect &r)
6915{
6916 int dx = 0;
6917 int dy = 0;
6918 if (p.x() < r.left())
6919 dx = r.left() - p.x();
6920 else if (p.x() > r.right())
6921 dx = p.x() - r.right();
6922 if (p.y() < r.top())
6923 dy = r.top() - p.y();
6924 else if (p.y() > r.bottom())
6925 dy = p.y() - r.bottom();
6926 return dx + dy;
6927}
6928
6929/*!
6930 \property QWidget::frameSize
6931 \brief the size of the widget including any window frame
6932
6933 By default, this property contains a value that depends on the user's
6934 platform and screen geometry.
6935*/
6936QSize QWidget::frameSize() const
6937{
6938 Q_D(const QWidget);
6939 if (isWindow() && !(windowType() == Qt::Popup)) {
6940 QRect fs = d->frameStrut();
6941 return QSize(data->crect.width() + fs.left() + fs.right(),
6942 data->crect.height() + fs.top() + fs.bottom());
6943 }
6944 return data->crect.size();
6945}
6946
6947/*! \fn void QWidget::move(int x, int y)
6948
6949 \overload
6950
6951 This corresponds to move(QPoint(\a x, \a y)).
6952*/
6953
6954void QWidget::move(const QPoint &p)
6955{
6956 Q_D(QWidget);
6957 setAttribute(Qt::WA_Moved);
6958 if (testAttribute(attribute: Qt::WA_WState_Created)) {
6959 if (isWindow())
6960 d->topData()->posIncludesFrame = false;
6961 d->setGeometry_sys(p.x() + geometry().x() - QWidget::x(),
6962 p.y() + geometry().y() - QWidget::y(),
6963 width(), height(), true);
6964 d->setDirtyOpaqueRegion();
6965 } else {
6966 // no frame yet: see also QWidgetPrivate::fixPosIncludesFrame(), QWindowPrivate::PositionPolicy.
6967 if (isWindow())
6968 d->topData()->posIncludesFrame = true;
6969 data->crect.moveTopLeft(p); // no frame yet
6970 setAttribute(Qt::WA_PendingMoveEvent);
6971 }
6972
6973 if (d->extra && d->extra->hasWindowContainer)
6974 QWindowContainer::parentWasMoved(parent: this);
6975}
6976
6977// move() was invoked with Qt::WA_WState_Created not set (frame geometry
6978// unknown), that is, crect has a position including the frame.
6979// If we can determine the frame strut, fix that and clear the flag.
6980// FIXME: This does not play well with window states other than
6981// Qt::WindowNoState, as we depend on calling setGeometry() on the
6982// platform window after fixing up the position so that the new
6983// geometry is reflected in the platform window, but when the frame
6984// comes in after the window has been shown (e.g. maximized), we're
6985// not in a position to do that kind of fixup.
6986void QWidgetPrivate::fixPosIncludesFrame()
6987{
6988 Q_Q(QWidget);
6989 if (QTLWExtra *te = maybeTopData()) {
6990 if (te->posIncludesFrame) {
6991 // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
6992 // example, in QGraphicsProxyWidget).
6993 if (q->testAttribute(attribute: Qt::WA_DontShowOnScreen)) {
6994 te->posIncludesFrame = 0;
6995 } else {
6996 if (q->windowHandle() && q->windowHandle()->handle()) {
6997 updateFrameStrut();
6998 if (!q->data->fstrut_dirty) {
6999 data.crect.translate(dx: te->frameStrut.x(), dy: te->frameStrut.y());
7000 te->posIncludesFrame = 0;
7001 }
7002 } // windowHandle()
7003 } // !WA_DontShowOnScreen
7004 } // posIncludesFrame
7005 } // QTLWExtra
7006}
7007
7008/*! \fn void QWidget::resize(int w, int h)
7009 \overload
7010
7011 This corresponds to resize(QSize(\a w, \a h)).
7012*/
7013
7014void QWidget::resize(const QSize &s)
7015{
7016 Q_D(QWidget);
7017 setAttribute(Qt::WA_Resized);
7018 if (testAttribute(attribute: Qt::WA_WState_Created)) {
7019 d->fixPosIncludesFrame();
7020 d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
7021 d->setDirtyOpaqueRegion();
7022 } else {
7023 const auto oldRect = data->crect;
7024 data->crect.setSize(s.boundedTo(otherSize: maximumSize()).expandedTo(otherSize: minimumSize()));
7025 if (oldRect != data->crect)
7026 setAttribute(Qt::WA_PendingResizeEvent);
7027 }
7028}
7029
7030void QWidget::setGeometry(const QRect &r)
7031{
7032 Q_D(QWidget);
7033 setAttribute(Qt::WA_Resized);
7034 setAttribute(Qt::WA_Moved);
7035 if (isWindow())
7036 d->topData()->posIncludesFrame = 0;
7037 if (testAttribute(attribute: Qt::WA_WState_Created)) {
7038 d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true);
7039 d->setDirtyOpaqueRegion();
7040 } else {
7041 const auto oldRect = data->crect;
7042 data->crect.setTopLeft(r.topLeft());
7043 data->crect.setSize(r.size().boundedTo(otherSize: maximumSize()).expandedTo(otherSize: minimumSize()));
7044 if (oldRect != data->crect) {
7045 setAttribute(Qt::WA_PendingMoveEvent);
7046 setAttribute(Qt::WA_PendingResizeEvent);
7047 }
7048 }
7049
7050 if (d->extra && d->extra->hasWindowContainer)
7051 QWindowContainer::parentWasMoved(parent: this);
7052}
7053
7054void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
7055{
7056 Q_Q(QWidget);
7057 if (extra) { // any size restrictions?
7058 w = qMin(a: w,b: extra->maxw);
7059 h = qMin(a: h,b: extra->maxh);
7060 w = qMax(a: w,b: extra->minw);
7061 h = qMax(a: h,b: extra->minh);
7062 }
7063
7064 if (q->isWindow() && q->windowHandle()) {
7065 QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
7066 if (!integration->hasCapability(cap: QPlatformIntegration::NonFullScreenWindows)) {
7067 x = 0;
7068 y = 0;
7069 w = q->windowHandle()->width();
7070 h = q->windowHandle()->height();
7071 }
7072 }
7073
7074 QPoint oldp = q->geometry().topLeft();
7075 QSize olds = q->size();
7076 QRect r(x, y, w, h);
7077
7078 bool isResize = olds != r.size();
7079 if (!isMove)
7080 isMove = oldp != r.topLeft();
7081
7082
7083 // We only care about stuff that changes the geometry, or may
7084 // cause the window manager to change its state
7085 if (r.size() == olds && oldp == r.topLeft())
7086 return;
7087
7088 if (!data.in_set_window_state) {
7089 q->data->window_state &= ~Qt::WindowMaximized;
7090 q->data->window_state &= ~Qt::WindowFullScreen;
7091 if (q->isWindow())
7092 topData()->normalGeometry = QRect(0, 0, -1, -1);
7093 }
7094
7095 QPoint oldPos = q->pos();
7096 data.crect = r;
7097
7098 bool needsShow = false;
7099
7100 if (q->isWindow() || q->windowHandle()) {
7101 if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) {
7102 q->setAttribute(Qt::WA_OutsideWSRange, on: true);
7103 if (q->isVisible())
7104 hide_sys();
7105 data.crect = QRect(x, y, w, h);
7106 } else if (q->testAttribute(attribute: Qt::WA_OutsideWSRange)) {
7107 q->setAttribute(Qt::WA_OutsideWSRange, on: false);
7108 needsShow = true;
7109 }
7110 }
7111
7112 if (q->isVisible()) {
7113 if (!q->testAttribute(attribute: Qt::WA_DontShowOnScreen) && !q->testAttribute(attribute: Qt::WA_OutsideWSRange)) {
7114 if (QWindow *win = q->windowHandle()) {
7115 if (q->isWindow()) {
7116 if (isResize && !isMove)
7117 win->resize(w, h);
7118 else if (isMove && !isResize)
7119 win->setPosition(posx: x, posy: y);
7120 else
7121 win->setGeometry(q->geometry());
7122 } else {
7123 QPoint posInNativeParent = q->mapTo(parent: q->nativeParentWidget(),pos: QPoint());
7124 win->setGeometry(QRect(posInNativeParent,r.size()));
7125 }
7126
7127 if (needsShow)
7128 show_sys();
7129 }
7130
7131 if (!q->isWindow()) {
7132 if (renderToTexture) {
7133 QRegion updateRegion(q->geometry());
7134 updateRegion += QRect(oldPos, olds);
7135 q->parentWidget()->d_func()->invalidateBackingStore(updateRegion);
7136 } else if (isMove && !isResize) {
7137 moveRect(QRect(oldPos, olds), dx: x - oldPos.x(), dy: y - oldPos.y());
7138 } else {
7139 invalidateBackingStore_resizeHelper(oldPos, oldSize: olds);
7140 }
7141 }
7142 }
7143
7144 if (isMove) {
7145 QMoveEvent e(q->pos(), oldPos);
7146 QCoreApplication::sendEvent(receiver: q, event: &e);
7147 }
7148 if (isResize) {
7149 QResizeEvent e(r.size(), olds);
7150 QCoreApplication::sendEvent(receiver: q, event: &e);
7151 if (q->windowHandle())
7152 q->update();
7153 }
7154 } else { // not visible
7155 if (isMove && q->pos() != oldPos)
7156 q->setAttribute(Qt::WA_PendingMoveEvent, on: true);
7157 if (isResize)
7158 q->setAttribute(Qt::WA_PendingResizeEvent, on: true);
7159 }
7160
7161}
7162
7163/*!
7164 \since 4.2
7165 Saves the current geometry and state for top-level widgets.
7166
7167 To save the geometry when the window closes, you can
7168 implement a close event like this:
7169
7170 \snippet code/src_gui_kernel_qwidget.cpp 11
7171
7172 See the \l{Window Geometry} documentation for an overview of geometry
7173 issues with windows.
7174
7175 Use QMainWindow::saveState() to save the geometry and the state of
7176 toolbars and dock widgets.
7177
7178 \sa restoreGeometry(), QMainWindow::saveState(), QMainWindow::restoreState()
7179*/
7180QByteArray QWidget::saveGeometry() const
7181{
7182 QByteArray array;
7183 QDataStream stream(&array, QIODevice::WriteOnly);
7184 stream.setVersion(QDataStream::Qt_4_0);
7185 const quint32 magicNumber = 0x1D9D0CB;
7186 // Version history:
7187 // - Qt 4.2 - 4.8.6, 5.0 - 5.3 : Version 1.0
7188 // - Qt 4.8.6 - today, 5.4 - today: Version 2.0, save screen width in addition to check for high DPI scaling.
7189 // - Qt 5.12 - today : Version 3.0, save QWidget::geometry()
7190 quint16 majorVersion = 3;
7191 quint16 minorVersion = 0;
7192 const int screenNumber = QDesktopWidgetPrivate::screenNumber(widget: this);
7193 stream << magicNumber
7194 << majorVersion
7195 << minorVersion
7196 << frameGeometry()
7197 << normalGeometry()
7198 << qint32(screenNumber)
7199 << quint8(windowState() & Qt::WindowMaximized)
7200 << quint8(windowState() & Qt::WindowFullScreen)
7201 << qint32(QDesktopWidgetPrivate::screenGeometry(screen: screenNumber).width()) // added in 2.0
7202 << geometry(); // added in 3.0
7203 return array;
7204}
7205
7206static void checkRestoredGeometry(const QRect &availableGeometry, QRect *restoredGeometry,
7207 int frameHeight)
7208{
7209 if (!restoredGeometry->intersects(r: availableGeometry)) {
7210 restoredGeometry->moveBottom(pos: qMin(a: restoredGeometry->bottom(), b: availableGeometry.bottom()));
7211 restoredGeometry->moveLeft(pos: qMax(a: restoredGeometry->left(), b: availableGeometry.left()));
7212 restoredGeometry->moveRight(pos: qMin(a: restoredGeometry->right(), b: availableGeometry.right()));
7213 }
7214 restoredGeometry->moveTop(pos: qMax(a: restoredGeometry->top(), b: availableGeometry.top() + frameHeight));
7215}
7216
7217/*!
7218 \since 4.2
7219
7220 Restores the geometry and state of top-level widgets stored in the
7221 byte array \a geometry. Returns \c true on success; otherwise
7222 returns \c false.
7223
7224 If the restored geometry is off-screen, it will be modified to be
7225 inside the available screen geometry.
7226
7227 To restore geometry saved using QSettings, you can use code like
7228 this:
7229
7230 \snippet code/src_gui_kernel_qwidget.cpp 12
7231
7232 See the \l{Window Geometry} documentation for an overview of geometry
7233 issues with windows.
7234
7235 Use QMainWindow::restoreState() to restore the geometry and the
7236 state of toolbars and dock widgets.
7237
7238 \sa saveGeometry(), QSettings, QMainWindow::saveState(), QMainWindow::restoreState()
7239*/
7240bool QWidget::restoreGeometry(const QByteArray &geometry)
7241{
7242 if (geometry.size() < 4)
7243 return false;
7244 QDataStream stream(geometry);
7245 stream.setVersion(QDataStream::Qt_4_0);
7246
7247 const quint32 magicNumber = 0x1D9D0CB;
7248 quint32 storedMagicNumber;
7249 stream >> storedMagicNumber;
7250 if (storedMagicNumber != magicNumber)
7251 return false;
7252
7253 const quint16 currentMajorVersion = 3;
7254 quint16 majorVersion = 0;
7255 quint16 minorVersion = 0;
7256
7257 stream >> majorVersion >> minorVersion;
7258
7259 if (majorVersion > currentMajorVersion)
7260 return false;
7261 // (Allow all minor versions.)
7262
7263 QRect restoredFrameGeometry;
7264 QRect restoredGeometry;
7265 QRect restoredNormalGeometry;
7266 qint32 restoredScreenNumber;
7267 quint8 maximized;
7268 quint8 fullScreen;
7269 qint32 restoredScreenWidth = 0;
7270
7271 stream >> restoredFrameGeometry // Only used for sanity checks in version 0
7272 >> restoredNormalGeometry
7273 >> restoredScreenNumber
7274 >> maximized
7275 >> fullScreen;
7276
7277 if (majorVersion > 1)
7278 stream >> restoredScreenWidth;
7279 if (majorVersion > 2)
7280 stream >> restoredGeometry;
7281
7282 // ### Qt 6 - Perhaps it makes sense to dumb down the restoreGeometry() logic, see QTBUG-69104
7283
7284 if (restoredScreenNumber >= QDesktopWidgetPrivate::numScreens())
7285 restoredScreenNumber = QDesktopWidgetPrivate::primaryScreen();
7286 const qreal screenWidthF = qreal(QDesktopWidgetPrivate::screenGeometry(screen: restoredScreenNumber).width());
7287 // Sanity check bailing out when large variations of screen sizes occur due to
7288 // high DPI scaling or different levels of DPI awareness.
7289 if (restoredScreenWidth) {
7290 const qreal factor = qreal(restoredScreenWidth) / screenWidthF;
7291 if (factor < 0.8 || factor > 1.25)
7292 return false;
7293 } else {
7294 // Saved by Qt 5.3 and earlier, try to prevent too large windows
7295 // unless the size will be adapted by maximized or fullscreen.
7296 if (!maximized && !fullScreen && qreal(restoredFrameGeometry.width()) / screenWidthF > 1.5)
7297 return false;
7298 }
7299
7300 const int frameHeight = 20;
7301
7302 if (!restoredNormalGeometry.isValid())
7303 restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint());
7304 if (!restoredNormalGeometry.isValid()) {
7305 // use the widget's adjustedSize if the sizeHint() doesn't help
7306 restoredNormalGeometry.setSize(restoredNormalGeometry
7307 .size()
7308 .expandedTo(otherSize: d_func()->adjustedSize()));
7309 }
7310
7311 const QRect availableGeometry = QDesktopWidgetPrivate::availableGeometry(screen: restoredScreenNumber);
7312
7313 // Modify the restored geometry if we are about to restore to coordinates
7314 // that would make the window "lost". This happens if:
7315 // - The restored geometry is completely oustside the available geometry
7316 // - The title bar is outside the available geometry.
7317
7318 checkRestoredGeometry(availableGeometry, restoredGeometry: &restoredGeometry, frameHeight);
7319 checkRestoredGeometry(availableGeometry, restoredGeometry: &restoredNormalGeometry, frameHeight);
7320
7321 if (maximized || fullScreen) {
7322 // set geometry before setting the window state to make
7323 // sure the window is maximized to the right screen.
7324 Qt::WindowStates ws = windowState();
7325#ifndef Q_OS_WIN
7326 setGeometry(restoredNormalGeometry);
7327#else
7328 if (ws & Qt::WindowFullScreen) {
7329 // Full screen is not a real window state on Windows.
7330 move(availableGeometry.topLeft());
7331 } else if (ws & Qt::WindowMaximized) {
7332 // Setting a geometry on an already maximized window causes this to be
7333 // restored into a broken, half-maximized state, non-resizable state (QTBUG-4397).
7334 // Move the window in normal state if needed.
7335 if (restoredScreenNumber != QDesktopWidgetPrivate::screenNumber(this)) {
7336 setWindowState(Qt::WindowNoState);
7337 setGeometry(restoredNormalGeometry);
7338 }
7339 } else {
7340 setGeometry(restoredNormalGeometry);
7341 }
7342#endif // Q_OS_WIN
7343 if (maximized)
7344 ws |= Qt::WindowMaximized;
7345 if (fullScreen)
7346 ws |= Qt::WindowFullScreen;
7347 setWindowState(ws);
7348 d_func()->topData()->normalGeometry = restoredNormalGeometry;
7349 } else {
7350 setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen));
7351 if (majorVersion > 2)
7352 setGeometry(restoredGeometry);
7353 else
7354 setGeometry(restoredNormalGeometry);
7355 }
7356 return true;
7357}
7358
7359/*!\fn void QWidget::setGeometry(int x, int y, int w, int h)
7360 \overload
7361
7362 This corresponds to setGeometry(QRect(\a x, \a y, \a w, \a h)).
7363*/
7364
7365/*!
7366 Sets the margins around the contents of the widget to have the sizes
7367 \a left, \a top, \a right, and \a bottom. The margins are used by
7368 the layout system, and may be used by subclasses to specify the area
7369 to draw in (e.g. excluding the frame).
7370
7371 Changing the margins will trigger a resizeEvent().
7372
7373 \sa contentsRect(), contentsMargins()
7374*/
7375void QWidget::setContentsMargins(int left, int top, int right, int bottom)
7376{
7377 Q_D(QWidget);
7378 if (left == d->leftmargin && top == d->topmargin
7379 && right == d->rightmargin && bottom == d->bottommargin)
7380 return;
7381 d->leftmargin = left;
7382 d->topmargin = top;
7383 d->rightmargin = right;
7384 d->bottommargin = bottom;
7385
7386 d->updateContentsRect();
7387}
7388
7389/*!
7390 \overload
7391 \since 4.6
7392
7393 \brief The setContentsMargins function sets the margins around the
7394 widget's contents.
7395
7396 Sets the margins around the contents of the widget to have the
7397 sizes determined by \a margins. The margins are
7398 used by the layout system, and may be used by subclasses to
7399 specify the area to draw in (e.g. excluding the frame).
7400
7401 Changing the margins will trigger a resizeEvent().
7402
7403 \sa contentsRect(), contentsMargins()
7404*/
7405void QWidget::setContentsMargins(const QMargins &margins)
7406{
7407 setContentsMargins(left: margins.left(), top: margins.top(),
7408 right: margins.right(), bottom: margins.bottom());
7409}
7410
7411void QWidgetPrivate::updateContentsRect()
7412{
7413 Q_Q(QWidget);
7414
7415 if (layout)
7416 layout->update(); //force activate; will do updateGeometry
7417 else
7418 q->updateGeometry();
7419
7420 if (q->isVisible()) {
7421 q->update();
7422 QResizeEvent e(q->data->crect.size(), q->data->crect.size());
7423 QCoreApplication::sendEvent(receiver: q, event: &e);
7424 } else {
7425 q->setAttribute(Qt::WA_PendingResizeEvent, on: true);
7426 }
7427
7428 QEvent e(QEvent::ContentsRectChange);
7429 QCoreApplication::sendEvent(receiver: q, event: &e);
7430}
7431
7432#if QT_DEPRECATED_SINCE(5, 14)
7433/*!
7434 \obsolete
7435 Use contentsMargins().
7436
7437 Returns the widget's contents margins for \a left, \a top, \a
7438 right, and \a bottom.
7439
7440 \sa setContentsMargins(), contentsRect()
7441 */
7442void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const
7443{
7444 QMargins m = contentsMargins();
7445 if (left)
7446 *left = m.left();
7447 if (top)
7448 *top = m.top();
7449 if (right)
7450 *right = m.right();
7451 if (bottom)
7452 *bottom = m.bottom();
7453}
7454#endif
7455
7456// FIXME: Move to qmargins.h for next minor Qt release
7457QMargins operator|(const QMargins &m1, const QMargins &m2)
7458{
7459 return QMargins(qMax(a: m1.left(), b: m2.left()), qMax(a: m1.top(), b: m2.top()),
7460 qMax(a: m1.right(), b: m2.right()), qMax(a: m1.bottom(), b: m2.bottom()));
7461}
7462
7463/*!
7464 \since 4.6
7465
7466 \brief The contentsMargins function returns the widget's contents margins.
7467
7468 \sa setContentsMargins(), contentsRect()
7469 */
7470QMargins QWidget::contentsMargins() const
7471{
7472 Q_D(const QWidget);
7473 QMargins userMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin);
7474 return testAttribute(attribute: Qt::WA_ContentsMarginsRespectsSafeArea) ?
7475 userMargins | d->safeAreaMargins() : userMargins;
7476}
7477
7478/*!
7479 Returns the area inside the widget's margins.
7480
7481 \sa setContentsMargins(), contentsMargins()
7482*/
7483QRect QWidget::contentsRect() const
7484{
7485 return rect() - contentsMargins();
7486}
7487
7488QMargins QWidgetPrivate::safeAreaMargins() const
7489{
7490 Q_Q(const QWidget);
7491 QWidget *nativeWidget = q->window();
7492 if (!nativeWidget->windowHandle())
7493 return QMargins();
7494
7495 QPlatformWindow *platformWindow = nativeWidget->windowHandle()->handle();
7496 if (!platformWindow)
7497 return QMargins();
7498
7499 QMargins safeAreaMargins = platformWindow->safeAreaMargins();
7500
7501 if (!q->isWindow()) {
7502 // In theory the native parent widget already has a contents rect reflecting
7503 // the safe area of that widget, but we can't be sure that the widget or child
7504 // widgets of that widget have respected the contents rect when setting their
7505 // geometry, so we need to manually compute the safe area.
7506
7507 // Unless the native widget doesn't have any margins, in which case there's
7508 // nothing for us to compute.
7509 if (safeAreaMargins.isNull())
7510 return QMargins();
7511
7512 // Or, if one of our ancestors are in a layout that does not have WA_LayoutOnEntireRect
7513 // set, then we know that the layout has already taken care of placing us inside the
7514 // safe area, by taking the contents rect of its parent widget into account.
7515 const QWidget *assumedSafeWidget = nullptr;
7516 for (const QWidget *w = q; w != nativeWidget; w = w->parentWidget()) {
7517 QWidget *parentWidget = w->parentWidget();
7518 if (parentWidget->testAttribute(attribute: Qt::WA_LayoutOnEntireRect))
7519 continue; // Layout not going to help us
7520
7521 QLayout *layout = parentWidget->layout();
7522 if (!layout)
7523 continue;
7524
7525 if (layout->geometry().isNull())
7526 continue; // Layout hasn't been activated yet
7527
7528 if (layout->indexOf(const_cast<QWidget *>(w)) < 0)
7529 continue; // Widget is not in layout
7530
7531 assumedSafeWidget = w;
7532 break;
7533 }
7534
7535#if !defined(QT_DEBUG)
7536 if (assumedSafeWidget) {
7537 // We found a layout that we assume will take care of keeping us within the safe area
7538 // For debug builds we still map the safe area using the fallback logic, so that we
7539 // can detect any misbehaving layouts.
7540 return QMargins();
7541 }
7542#endif
7543
7544 // In all other cases we need to map the safe area of the native parent to the widget.
7545 // This depends on the widget being positioned and sized already, which means the initial
7546 // layout will be wrong, but the layout will then adjust itself.
7547 QPoint topLeftMargins = q->mapFrom(parent: nativeWidget, pos: QPoint(safeAreaMargins.left(), safeAreaMargins.top()));
7548 QRect widgetRect = q->isVisible() ? q->visibleRegion().boundingRect() : q->rect();
7549 QPoint bottomRightMargins = widgetRect.bottomRight() - q->mapFrom(parent: nativeWidget,
7550 pos: nativeWidget->rect().bottomRight() - QPoint(safeAreaMargins.right(), safeAreaMargins.bottom()));
7551
7552 // Margins should never be negative
7553 safeAreaMargins = QMargins(qMax(a: 0, b: topLeftMargins.x()), qMax(a: 0, b: topLeftMargins.y()),
7554 qMax(a: 0, b: bottomRightMargins.x()), qMax(a: 0, b: bottomRightMargins.y()));
7555
7556 if (!safeAreaMargins.isNull() && assumedSafeWidget) {
7557 QLayout *layout = assumedSafeWidget->parentWidget()->layout();
7558 qWarning() << layout << "is laying out" << assumedSafeWidget
7559 << "outside of the contents rect of" << layout->parentWidget();
7560 return QMargins(); // Return empty margin to visually highlight the error
7561 }
7562 }
7563
7564 return safeAreaMargins;
7565}
7566
7567/*!
7568 \fn void QWidget::customContextMenuRequested(const QPoint &pos)
7569
7570 This signal is emitted when the widget's \l contextMenuPolicy is
7571 Qt::CustomContextMenu, and the user has requested a context menu on
7572 the widget. The position \a pos is the position of the context menu
7573 event that the widget receives. Normally this is in widget
7574 coordinates. The exception to this rule is QAbstractScrollArea and
7575 its subclasses that map the context menu event to coordinates of the
7576 \l{QAbstractScrollArea::viewport()}{viewport()}.
7577
7578
7579 \sa mapToGlobal(), QMenu, contextMenuPolicy
7580*/
7581
7582
7583/*!
7584 \property QWidget::contextMenuPolicy
7585 \brief how the widget shows a context menu
7586
7587 The default value of this property is Qt::DefaultContextMenu,
7588 which means the contextMenuEvent() handler is called. Other values
7589 are Qt::NoContextMenu, Qt::PreventContextMenu,
7590 Qt::ActionsContextMenu, and Qt::CustomContextMenu. With
7591 Qt::CustomContextMenu, the signal customContextMenuRequested() is
7592 emitted.
7593
7594 \sa contextMenuEvent(), customContextMenuRequested(), actions()
7595*/
7596
7597Qt::ContextMenuPolicy QWidget::contextMenuPolicy() const
7598{
7599 return (Qt::ContextMenuPolicy)data->context_menu_policy;
7600}
7601
7602void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
7603{
7604 data->context_menu_policy = (uint) policy;
7605}
7606
7607/*!
7608 \property QWidget::focusPolicy
7609 \brief the way the widget accepts keyboard focus
7610
7611 The policy is Qt::TabFocus if the widget accepts keyboard
7612 focus by tabbing, Qt::ClickFocus if the widget accepts
7613 focus by clicking, Qt::StrongFocus if it accepts both, and
7614 Qt::NoFocus (the default) if it does not accept focus at
7615 all.
7616
7617 You must enable keyboard focus for a widget if it processes
7618 keyboard events. This is normally done from the widget's
7619 constructor. For instance, the QLineEdit constructor calls
7620 setFocusPolicy(Qt::StrongFocus).
7621
7622 If the widget has a focus proxy, then the focus policy will
7623 be propagated to it.
7624
7625 \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
7626*/
7627
7628
7629Qt::FocusPolicy QWidget::focusPolicy() const
7630{
7631 return (Qt::FocusPolicy)data->focus_policy;
7632}
7633
7634void QWidget::setFocusPolicy(Qt::FocusPolicy policy)
7635{
7636 data->focus_policy = (uint) policy;
7637 Q_D(QWidget);
7638 if (d->extra && d->extra->focus_proxy)
7639 d->extra->focus_proxy->setFocusPolicy(policy);
7640}
7641
7642/*!
7643 \property QWidget::updatesEnabled
7644 \brief whether updates are enabled
7645
7646 An updates enabled widget receives paint events and has a system
7647 background; a disabled widget does not. This also implies that
7648 calling update() and repaint() has no effect if updates are
7649 disabled.
7650
7651 By default, this property is \c true.
7652
7653 setUpdatesEnabled() is normally used to disable updates for a
7654 short period of time, for instance to avoid screen flicker during
7655 large changes. In Qt, widgets normally do not generate screen
7656 flicker, but on X11 the server might erase regions on the screen
7657 when widgets get hidden before they can be replaced by other
7658 widgets. Disabling updates solves this.
7659
7660 Example:
7661 \snippet code/src_gui_kernel_qwidget.cpp 13
7662
7663 Disabling a widget implicitly disables all its children. Enabling a widget
7664 enables all child widgets \e except top-level widgets or those that
7665 have been explicitly disabled. Re-enabling updates implicitly calls
7666 update() on the widget.
7667
7668 \sa paintEvent()
7669*/
7670void QWidget::setUpdatesEnabled(bool enable)
7671{
7672 Q_D(QWidget);
7673 setAttribute(Qt::WA_ForceUpdatesDisabled, on: !enable);
7674 d->setUpdatesEnabled_helper(enable);
7675}
7676
7677/*!
7678 Shows the widget and its child widgets.
7679
7680 This is equivalent to calling showFullScreen(), showMaximized(), or setVisible(true),
7681 depending on the platform's default behavior for the window flags.
7682
7683 \sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(),
7684 showNormal(), isVisible(), windowFlags()
7685*/
7686void QWidget::show()
7687{
7688 Qt::WindowState defaultState = QGuiApplicationPrivate::platformIntegration()->defaultWindowState(data->window_flags);
7689 if (defaultState == Qt::WindowFullScreen)
7690 showFullScreen();
7691 else if (defaultState == Qt::WindowMaximized)
7692 showMaximized();
7693 else
7694 setVisible(true); // Don't call showNormal() as not to clobber Qt::Window(Max/Min)imized
7695}
7696
7697/*! \internal
7698
7699 Makes the widget visible in the isVisible() meaning of the word.
7700 It is only called for toplevels or widgets with visible parents.
7701 */
7702void QWidgetPrivate::show_recursive()
7703{
7704 Q_Q(QWidget);
7705 // polish if necessary
7706
7707 if (!q->testAttribute(attribute: Qt::WA_WState_Created))
7708 createRecursively();
7709 q->ensurePolished();
7710
7711 if (!q->isWindow() && q->parentWidget()->d_func()->layout && !q->parentWidget()->data->in_show)
7712 q->parentWidget()->d_func()->layout->activate();
7713 // activate our layout before we and our children become visible
7714 if (layout)
7715 layout->activate();
7716
7717 show_helper();
7718}
7719
7720void QWidgetPrivate::sendPendingMoveAndResizeEvents(bool recursive, bool disableUpdates)
7721{
7722 Q_Q(QWidget);
7723
7724 disableUpdates = disableUpdates && q->updatesEnabled();
7725 if (disableUpdates)
7726 q->setAttribute(Qt::WA_UpdatesDisabled);
7727
7728 if (q->testAttribute(attribute: Qt::WA_PendingMoveEvent)) {
7729 QMoveEvent e(data.crect.topLeft(), data.crect.topLeft());
7730 QCoreApplication::sendEvent(receiver: q, event: &e);
7731 q->setAttribute(Qt::WA_PendingMoveEvent, on: false);
7732 }
7733
7734 if (q->testAttribute(attribute: Qt::WA_PendingResizeEvent)) {
7735 QResizeEvent e(data.crect.size(), QSize());
7736 QCoreApplication::sendEvent(receiver: q, event: &e);
7737 q->setAttribute(Qt::WA_PendingResizeEvent, on: false);
7738 }
7739
7740 if (disableUpdates)
7741 q->setAttribute(Qt::WA_UpdatesDisabled, on: false);
7742
7743 if (!recursive)
7744 return;
7745
7746 for (int i = 0; i < children.size(); ++i) {
7747 if (QWidget *child = qobject_cast<QWidget *>(o: children.at(i)))
7748 child->d_func()->sendPendingMoveAndResizeEvents(recursive, disableUpdates);
7749 }
7750}
7751
7752void QWidgetPrivate::activateChildLayoutsRecursively()
7753{
7754 sendPendingMoveAndResizeEvents(recursive: false, disableUpdates: true);
7755
7756 for (int i = 0; i < children.size(); ++i) {
7757 QWidget *child = qobject_cast<QWidget *>(o: children.at(i));
7758 if (!child || child->isHidden() || child->isWindow())
7759 continue;
7760
7761 child->ensurePolished();
7762
7763 // Activate child's layout
7764 QWidgetPrivate *childPrivate = child->d_func();
7765 if (childPrivate->layout)
7766 childPrivate->layout->activate();
7767
7768 // Pretend we're visible.
7769 const bool wasVisible = child->isVisible();
7770 if (!wasVisible)
7771 child->setAttribute(Qt::WA_WState_Visible);
7772
7773 // Do the same for all my children.
7774 childPrivate->activateChildLayoutsRecursively();
7775
7776 // We're not cheating anymore.
7777 if (!wasVisible)
7778 child->setAttribute(Qt::WA_WState_Visible, on: false);
7779 }
7780}
7781
7782void QWidgetPrivate::show_helper()
7783{
7784 Q_Q(QWidget);
7785 data.in_show = true; // qws optimization
7786 // make sure we receive pending move and resize events
7787 sendPendingMoveAndResizeEvents();
7788
7789 // become visible before showing all children
7790 q->setAttribute(Qt::WA_WState_Visible);
7791
7792 // finally show all children recursively
7793 showChildren(spontaneous: false);
7794
7795
7796
7797 const bool isWindow = q->isWindow();
7798#if QT_CONFIG(graphicsview)
7799 bool isEmbedded = isWindow && q->graphicsProxyWidget() != nullptr;
7800#else
7801 bool isEmbedded = false;
7802#endif
7803
7804 // popup handling: new popups and tools need to be raised, and
7805 // existing popups must be closed. Also propagate the current
7806 // windows's KeyboardFocusChange status.
7807 if (isWindow && !isEmbedded) {
7808 if ((q->windowType() == Qt::Tool) || (q->windowType() == Qt::Popup) || q->windowType() == Qt::ToolTip) {
7809 q->raise();
7810 if (q->parentWidget() && q->parentWidget()->window()->testAttribute(attribute: Qt::WA_KeyboardFocusChange))
7811 q->setAttribute(Qt::WA_KeyboardFocusChange);
7812 } else {
7813 while (QApplication::activePopupWidget()) {
7814 if (!QApplication::activePopupWidget()->close())
7815 break;
7816 }
7817 }
7818 }
7819
7820 // Automatic embedding of child windows of widgets already embedded into
7821 // QGraphicsProxyWidget when they are shown the first time.
7822#if QT_CONFIG(graphicsview)
7823 if (isWindow) {
7824 if (!isEmbedded && !bypassGraphicsProxyWidget(p: q)) {
7825 QGraphicsProxyWidget *ancestorProxy = nearestGraphicsProxyWidget(origin: q->parentWidget());
7826 if (ancestorProxy) {
7827 isEmbedded = true;
7828 ancestorProxy->d_func()->embedSubWindow(q);
7829 }
7830 }
7831 }
7832#else
7833 Q_UNUSED(isEmbedded);
7834#endif
7835
7836 // send the show event before showing the window
7837 QShowEvent showEvent;
7838 QCoreApplication::sendEvent(receiver: q, event: &showEvent);
7839
7840 show_sys();
7841
7842 if (!isEmbedded && q->windowType() == Qt::Popup)
7843 qApp->d_func()->openPopup(popup: q);
7844
7845#ifndef QT_NO_ACCESSIBILITY
7846 if (q->windowType() != Qt::ToolTip) { // Tooltips are read aloud twice in MS narrator.
7847 QAccessibleEvent event(q, QAccessible::ObjectShow);
7848 QAccessible::updateAccessibility(event: &event);
7849 }
7850#endif
7851
7852 if (QApplicationPrivate::hidden_focus_widget == q) {
7853 QApplicationPrivate::hidden_focus_widget = nullptr;
7854 q->setFocus(Qt::OtherFocusReason);
7855 }
7856
7857 // Process events when showing a Qt::SplashScreen widget before the event loop
7858 // is spinnning; otherwise it might not show up on particular platforms.
7859 // This makes QSplashScreen behave the same on all platforms.
7860 if (!qApp->d_func()->in_exec && q->windowType() == Qt::SplashScreen)
7861 QCoreApplication::processEvents();
7862
7863 data.in_show = false; // reset qws optimization
7864}
7865
7866void QWidgetPrivate::show_sys()
7867{
7868 Q_Q(QWidget);
7869
7870 auto window = qobject_cast<QWidgetWindow *>(object: windowHandle());
7871
7872 if (q->testAttribute(attribute: Qt::WA_DontShowOnScreen)) {
7873 invalidateBackingStore(q->rect());
7874 q->setAttribute(Qt::WA_Mapped);
7875 // add our window the modal window list (native dialogs)
7876 if (window && q->isWindow()
7877#if QT_CONFIG(graphicsview)
7878 && (!extra || !extra->proxyWidget)
7879#endif
7880 && q->windowModality() != Qt::NonModal) {
7881 QGuiApplicationPrivate::showModalWindow(window);
7882 }
7883 return;
7884 }
7885
7886 if (renderToTexture && !q->isWindow())
7887 QCoreApplication::postEvent(receiver: q->parentWidget(), event: new QUpdateLaterEvent(q->geometry()));
7888 else
7889 QCoreApplication::postEvent(receiver: q, event: new QUpdateLaterEvent(q->rect()));
7890
7891 if ((!q->isWindow() && !q->testAttribute(attribute: Qt::WA_NativeWindow))
7892 || q->testAttribute(attribute: Qt::WA_OutsideWSRange)) {
7893 return;
7894 }
7895
7896 if (window) {
7897 if (q->isWindow())
7898 fixPosIncludesFrame();
7899 QRect geomRect = q->geometry();
7900 if (!q->isWindow()) {
7901 QPoint topLeftOfWindow = q->mapTo(parent: q->nativeParentWidget(),pos: QPoint());
7902 geomRect.moveTopLeft(p: topLeftOfWindow);
7903 }
7904 const QRect windowRect = window->geometry();
7905 if (windowRect != geomRect) {
7906 if (q->testAttribute(attribute: Qt::WA_Moved)
7907 || !QGuiApplicationPrivate::platformIntegration()->hasCapability(cap: QPlatformIntegration::WindowManagement))
7908 window->setGeometry(geomRect);
7909 else
7910 window->resize(newSize: geomRect.size());
7911 }
7912
7913#ifndef QT_NO_CURSOR
7914 qt_qpa_set_cursor(w: q, force: false); // Needed in case cursor was set before show
7915#endif
7916 invalidateBackingStore(q->rect());
7917 window->setNativeWindowVisibility(true);
7918 // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ?
7919 if (window->isTopLevel()) {
7920 const QPoint crectTopLeft = q->data->crect.topLeft();
7921 const QPoint windowTopLeft = window->geometry().topLeft();
7922 if (crectTopLeft == QPoint(0, 0) && windowTopLeft != crectTopLeft)
7923 q->data->crect.moveTopLeft(p: windowTopLeft);
7924 }
7925 }
7926}
7927
7928/*!
7929 Hides the widget. This function is equivalent to
7930 setVisible(false).
7931
7932
7933 \note If you are working with QDialog or its subclasses and you invoke
7934 the show() function after this function, the dialog will be displayed in
7935 its original position.
7936
7937 \sa hideEvent(), isHidden(), show(), setVisible(), isVisible(), close()
7938*/
7939void QWidget::hide()
7940{
7941 setVisible(false);
7942}
7943
7944/*!\internal
7945 */
7946void QWidgetPrivate::hide_helper()
7947{
7948 Q_Q(QWidget);
7949
7950 bool isEmbedded = false;
7951#if QT_CONFIG(graphicsview)
7952 isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(p: q) && nearestGraphicsProxyWidget(origin: q->parentWidget()) != nullptr;
7953#else
7954 Q_UNUSED(isEmbedded);
7955#endif
7956
7957 if (!isEmbedded && (q->windowType() == Qt::Popup))
7958 qApp->d_func()->closePopup(popup: q);
7959
7960 q->setAttribute(Qt::WA_Mapped, on: false);
7961 hide_sys();
7962
7963 bool wasVisible = q->testAttribute(attribute: Qt::WA_WState_Visible);
7964
7965 if (wasVisible) {
7966 q->setAttribute(Qt::WA_WState_Visible, on: false);
7967
7968 }
7969
7970 QHideEvent hideEvent;
7971 QCoreApplication::sendEvent(receiver: q, event: &hideEvent);
7972 hideChildren(spontaneous: false);
7973
7974 // next bit tries to move the focus if the focus widget is now
7975 // hidden.
7976 if (wasVisible) {
7977 qApp->d_func()->sendSyntheticEnterLeave(widget: q);
7978 QWidget *fw = QApplication::focusWidget();
7979 while (fw && !fw->isWindow()) {
7980 if (fw == q) {
7981 q->focusNextPrevChild(next: true);
7982 break;
7983 }
7984 fw = fw->parentWidget();
7985 }
7986 }
7987
7988 if (QWidgetRepaintManager *repaintManager = maybeRepaintManager())
7989 repaintManager->removeDirtyWidget(w: q);
7990
7991#ifndef QT_NO_ACCESSIBILITY
7992 if (wasVisible) {
7993 QAccessibleEvent event(q, QAccessible::ObjectHide);
7994 QAccessible::updateAccessibility(event: &event);
7995 }
7996#endif
7997}
7998
7999void QWidgetPrivate::hide_sys()
8000{
8001 Q_Q(QWidget);
8002
8003 auto window = qobject_cast<QWidgetWindow *>(object: windowHandle());
8004
8005 if (q->testAttribute(attribute: Qt::WA_DontShowOnScreen)) {
8006 q->setAttribute(Qt::WA_Mapped, on: false);
8007 // remove our window from the modal window list (native dialogs)
8008 if (window && q->isWindow()
8009#if QT_CONFIG(graphicsview)
8010 && (!extra || !extra->proxyWidget)
8011#endif
8012 && q->windowModality() != Qt::NonModal) {
8013 QGuiApplicationPrivate::hideModalWindow(window);
8014 }
8015 // do not return here, if window non-zero, we must hide it
8016 }
8017
8018 deactivateWidgetCleanup();
8019
8020 if (!q->isWindow()) {
8021 QWidget *p = q->parentWidget();
8022 if (p &&p->isVisible()) {
8023 if (renderToTexture)
8024 p->d_func()->invalidateBackingStore(q->geometry());
8025 else
8026 invalidateBackingStore(q->rect());
8027 }
8028 } else {
8029 invalidateBackingStore(q->rect());
8030 }
8031
8032 if (window)
8033 window->setNativeWindowVisibility(false);
8034}
8035
8036/*!
8037 \fn bool QWidget::isHidden() const
8038
8039 Returns \c true if the widget is hidden, otherwise returns \c false.
8040
8041 A hidden widget will only become visible when show() is called on
8042 it. It will not be automatically shown when the parent is shown.
8043
8044 To check visibility, use !isVisible() instead (notice the exclamation mark).
8045
8046 isHidden() implies !isVisible(), but a widget can be not visible
8047 and not hidden at the same time. This is the case for widgets that are children of
8048 widgets that are not visible.
8049
8050
8051 Widgets are hidden if:
8052 \list
8053 \li they were created as independent windows,
8054 \li they were created as children of visible widgets,
8055 \li hide() or setVisible(false) was called.
8056 \endlist
8057*/
8058
8059void QWidget::setVisible(bool visible)
8060{
8061 if (testAttribute(attribute: Qt::WA_WState_ExplicitShowHide) && testAttribute(attribute: Qt::WA_WState_Hidden) == !visible)
8062 return;
8063
8064 // Remember that setVisible was called explicitly
8065 setAttribute(Qt::WA_WState_ExplicitShowHide);
8066
8067 Q_D(QWidget);
8068 d->setVisible(visible);
8069}
8070
8071// This method is called from QWidgetWindow in response to QWindow::setVisible,
8072// and should match the semantics of QWindow::setVisible. QWidget::setVisible on
8073// the other hand keeps track of WA_WState_ExplicitShowHide in addition.
8074void QWidgetPrivate::setVisible(bool visible)
8075{
8076 Q_Q(QWidget);
8077 if (visible) { // show
8078 // Designer uses a trick to make grabWidget work without showing
8079 if (!q->isWindow() && q->parentWidget() && q->parentWidget()->isVisible()
8080 && !q->parentWidget()->testAttribute(attribute: Qt::WA_WState_Created))
8081 q->parentWidget()->window()->d_func()->createRecursively();
8082
8083 //create toplevels but not children of non-visible parents
8084 QWidget *pw = q->parentWidget();
8085 if (!q->testAttribute(attribute: Qt::WA_WState_Created)
8086 && (q->isWindow() || pw->testAttribute(attribute: Qt::WA_WState_Created))) {
8087 q->create();
8088 }
8089
8090 bool wasResized = q->testAttribute(attribute: Qt::WA_Resized);
8091 Qt::WindowStates initialWindowState = q->windowState();
8092
8093 // polish if necessary
8094 q->ensurePolished();
8095
8096 // whether we need to inform the parent widget immediately
8097 bool needUpdateGeometry = !q->isWindow() && q->testAttribute(attribute: Qt::WA_WState_Hidden);
8098 // we are no longer hidden
8099 q->setAttribute(Qt::WA_WState_Hidden, on: false);
8100
8101 if (needUpdateGeometry)
8102 updateGeometry_helper(forceUpdate: true);
8103
8104 // activate our layout before we and our children become visible
8105 if (layout)
8106 layout->activate();
8107
8108 if (!q->isWindow()) {
8109 QWidget *parent = q->parentWidget();
8110 while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) {
8111 parent->d_func()->layout->activate();
8112 if (parent->isWindow())
8113 break;
8114 parent = parent->parentWidget();
8115 }
8116 if (parent)
8117 parent->d_func()->setDirtyOpaqueRegion();
8118 }
8119
8120 // adjust size if necessary
8121 if (!wasResized
8122 && (q->isWindow() || !q->parentWidget()->d_func()->layout)) {
8123 if (q->isWindow()) {
8124 q->adjustSize();
8125 if (q->windowState() != initialWindowState)
8126 q->setWindowState(initialWindowState);
8127 } else {
8128 q->adjustSize();
8129 }
8130 q->setAttribute(Qt::WA_Resized, on: false);
8131 }
8132
8133 q->setAttribute(Qt::WA_KeyboardFocusChange, on: false);
8134
8135 if (q->isWindow() || q->parentWidget()->isVisible()) {
8136 show_helper();
8137
8138 qApp->d_func()->sendSyntheticEnterLeave(widget: q);
8139 }
8140
8141 QEvent showToParentEvent(QEvent::ShowToParent);
8142 QCoreApplication::sendEvent(receiver: q, event: &showToParentEvent);
8143 } else { // hide
8144 if (QApplicationPrivate::hidden_focus_widget == q)
8145 QApplicationPrivate::hidden_focus_widget = nullptr;
8146
8147 // hw: The test on getOpaqueRegion() needs to be more intelligent
8148 // currently it doesn't work if the widget is hidden (the region will
8149 // be clipped). The real check should be testing the cached region
8150 // (and dirty flag) directly.
8151 if (!q->isWindow() && q->parentWidget()) // && !d->getOpaqueRegion().isEmpty())
8152 q->parentWidget()->d_func()->setDirtyOpaqueRegion();
8153
8154 if (!q->testAttribute(attribute: Qt::WA_WState_Hidden)) {
8155 q->setAttribute(Qt::WA_WState_Hidden);
8156 if (q->testAttribute(attribute: Qt::WA_WState_Created))
8157 hide_helper();
8158 }
8159
8160 // invalidate layout similar to updateGeometry()
8161 if (!q->isWindow() && q->parentWidget()) {
8162 if (q->parentWidget()->d_func()->layout)
8163 q->parentWidget()->d_func()->layout->invalidate();
8164 else if (q->parentWidget()->isVisible())
8165 QCoreApplication::postEvent(receiver: q->parentWidget(), event: new QEvent(QEvent::LayoutRequest));
8166 }
8167
8168 QEvent hideToParentEvent(QEvent::HideToParent);
8169 QCoreApplication::sendEvent(receiver: q, event: &hideToParentEvent);
8170 }
8171}
8172
8173/*!
8174 Convenience function, equivalent to setVisible(!\a hidden).
8175*/
8176void QWidget::setHidden(bool hidden)
8177{
8178 setVisible(!hidden);
8179}
8180
8181void QWidgetPrivate::_q_showIfNotHidden()
8182{
8183 Q_Q(QWidget);
8184 if ( !(q->isHidden() && q->testAttribute(attribute: Qt::WA_WState_ExplicitShowHide)) )
8185 q->setVisible(true);
8186}
8187
8188void QWidgetPrivate::showChildren(bool spontaneous)
8189{
8190 QList<QObject*> childList = children;
8191 for (int i = 0; i < childList.size(); ++i) {
8192 QWidget *widget = qobject_cast<QWidget*>(o: childList.at(i));
8193 if (widget && widget->windowHandle() && !widget->testAttribute(attribute: Qt::WA_WState_ExplicitShowHide))
8194 widget->setAttribute(Qt::WA_WState_Hidden, on: false);
8195 if (!widget
8196 || widget->isWindow()
8197 || widget->testAttribute(attribute: Qt::WA_WState_Hidden))
8198 continue;
8199 if (spontaneous) {
8200 widget->setAttribute(Qt::WA_Mapped);
8201 widget->d_func()->showChildren(spontaneous: true);
8202 QShowEvent e;
8203 QApplication::sendSpontaneousEvent(receiver: widget, event: &e);
8204 } else {
8205 if (widget->testAttribute(attribute: Qt::WA_WState_ExplicitShowHide))
8206 widget->d_func()->show_recursive();
8207 else
8208 widget->show();
8209 }
8210 }
8211}
8212
8213void QWidgetPrivate::hideChildren(bool spontaneous)
8214{
8215 QList<QObject*> childList = children;
8216 for (int i = 0; i < childList.size(); ++i) {
8217 QWidget *widget = qobject_cast<QWidget*>(o: childList.at(i));
8218 if (!widget || widget->isWindow() || widget->testAttribute(attribute: Qt::WA_WState_Hidden))
8219 continue;
8220
8221 if (spontaneous)
8222 widget->setAttribute(Qt::WA_Mapped, on: false);
8223 else
8224 widget->setAttribute(Qt::WA_WState_Visible, on: false);
8225 widget->d_func()->hideChildren(spontaneous);
8226 QHideEvent e;
8227 if (spontaneous) {
8228 QApplication::sendSpontaneousEvent(receiver: widget, event: &e);
8229 } else {
8230 QCoreApplication::sendEvent(receiver: widget, event: &e);
8231 if (widget->internalWinId()
8232 && widget->testAttribute(attribute: Qt::WA_DontCreateNativeAncestors)) {
8233 // hide_sys() on an ancestor won't have any affect on this
8234 // widget, so it needs an explicit hide_sys() of its own
8235 widget->d_func()->hide_sys();
8236 }
8237 }
8238 qApp->d_func()->sendSyntheticEnterLeave(widget);
8239#ifndef QT_NO_ACCESSIBILITY
8240 if (!spontaneous) {
8241 QAccessibleEvent event(widget, QAccessible::ObjectHide);
8242 QAccessible::updateAccessibility(event: &event);
8243 }
8244#endif
8245 }
8246}
8247
8248bool QWidgetPrivate::close_helper(CloseMode mode)
8249{
8250 if (data.is_closing)
8251 return true;
8252
8253 Q_Q(QWidget);
8254 data.is_closing = 1;
8255
8256 QPointer<QWidget> that = q;
8257 QPointer<QWidget> parentWidget = (q->parentWidget() && !QObjectPrivate::get(o: q->parentWidget())->wasDeleted) ? q->parentWidget() : nullptr;
8258
8259 bool quitOnClose = q->testAttribute(attribute: Qt::WA_QuitOnClose);
8260 if (mode != CloseNoEvent) {
8261 QCloseEvent e;
8262 if (mode == CloseWithSpontaneousEvent)
8263 QApplication::sendSpontaneousEvent(receiver: q, event: &e);
8264 else
8265 QCoreApplication::sendEvent(receiver: q, event: &e);
8266 if (!that.isNull() && !e.isAccepted()) {
8267 data.is_closing = 0;
8268 return false;
8269 }
8270 }
8271
8272 if (!that.isNull() && !q->isHidden())
8273 q->hide();
8274
8275 // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent
8276 quitOnClose = quitOnClose && (parentWidget.isNull() || !parentWidget->isVisible());
8277
8278 if (quitOnClose) {
8279 /* if there is no non-withdrawn primary window left (except
8280 the ones without QuitOnClose), we emit the lastWindowClosed
8281 signal */
8282 QWidgetList list = QApplication::topLevelWidgets();
8283 bool lastWindowClosed = true;
8284 for (int i = 0; i < list.size(); ++i) {
8285 QWidget *w = list.at(i);
8286 if (!w->isVisible() || w->parentWidget() || !w->testAttribute(attribute: Qt::WA_QuitOnClose))
8287 continue;
8288 lastWindowClosed = false;
8289 break;
8290 }
8291 if (lastWindowClosed) {
8292 QGuiApplicationPrivate::emitLastWindowClosed();
8293 QCoreApplicationPrivate *applicationPrivate = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(o: QCoreApplication::instance()));
8294 applicationPrivate->maybeQuit();
8295 }
8296 }
8297
8298
8299 if (!that.isNull()) {
8300 data.is_closing = 0;
8301 if (q->testAttribute(attribute: Qt::WA_DeleteOnClose)) {
8302 q->setAttribute(Qt::WA_DeleteOnClose, on: false);
8303 q->deleteLater();
8304 }
8305 }
8306 return true;
8307}
8308
8309
8310/*!
8311 Closes this widget. Returns \c true if the widget was closed;
8312 otherwise returns \c false.
8313
8314 First it sends the widget a QCloseEvent. The widget is
8315 \l{hide()}{hidden} if it \l{QEvent::accept()}{accepts}
8316 the close event. If it \l{QEvent::ignore()}{ignores}
8317 the event, nothing happens. The default
8318 implementation of QWidget::closeEvent() accepts the close event.
8319
8320 If the widget has the Qt::WA_DeleteOnClose flag, the widget
8321 is also deleted. A close events is delivered to the widget no
8322 matter if the widget is visible or not.
8323
8324 The \l QApplication::lastWindowClosed() signal is emitted when the
8325 last visible primary window (i.e. window with no parent) with the
8326 Qt::WA_QuitOnClose attribute set is closed. By default this
8327 attribute is set for all widgets except transient windows such as
8328 splash screens, tool windows, and popup menus.
8329
8330*/
8331
8332bool QWidget::close()
8333{
8334 return d_func()->close_helper(mode: QWidgetPrivate::CloseWithEvent);
8335}
8336
8337/*!
8338 \property QWidget::visible
8339 \brief whether the widget is visible
8340
8341 Calling setVisible(true) or show() sets the widget to visible
8342 status if all its parent widgets up to the window are visible. If
8343 an ancestor is not visible, the widget won't become visible until
8344 all its ancestors are shown. If its size or position has changed,
8345 Qt guarantees that a widget gets move and resize events just
8346 before it is shown. If the widget has not been resized yet, Qt
8347 will adjust the widget's size to a useful default using
8348 adjustSize().
8349
8350 Calling setVisible(false) or hide() hides a widget explicitly. An
8351 explicitly hidden widget will never become visible, even if all
8352 its ancestors become visible, unless you show it.
8353
8354 A widget receives show and hide events when its visibility status
8355 changes. Between a hide and a show event, there is no need to
8356 waste CPU cycles preparing or displaying information to the user.
8357 A video application, for example, might simply stop generating new
8358 frames.
8359
8360 A widget that happens to be obscured by other windows on the
8361 screen is considered to be visible. The same applies to iconified
8362 windows and windows that exist on another virtual
8363 desktop (on platforms that support this concept). A widget
8364 receives spontaneous show and hide events when its mapping status
8365 is changed by the window system, e.g. a spontaneous hide event
8366 when the user minimizes the window, and a spontaneous show event
8367 when the window is restored again.
8368
8369 You almost never have to reimplement the setVisible() function. If
8370 you need to change some settings before a widget is shown, use
8371 showEvent() instead. If you need to do some delayed initialization
8372 use the Polish event delivered to the event() function.
8373
8374 \sa show(), hide(), isHidden(), isVisibleTo(), isMinimized(),
8375 showEvent(), hideEvent()
8376*/
8377
8378
8379/*!
8380 Returns \c true if this widget would become visible if \a ancestor is
8381 shown; otherwise returns \c false.
8382
8383 The true case occurs if neither the widget itself nor any parent
8384 up to but excluding \a ancestor has been explicitly hidden.
8385
8386 This function will still return true if the widget is obscured by
8387 other windows on the screen, but could be physically visible if it
8388 or they were to be moved.
8389
8390 isVisibleTo(0) is identical to isVisible().
8391
8392 \sa show(), hide(), isVisible()
8393*/
8394
8395bool QWidget::isVisibleTo(const QWidget *ancestor) const
8396{
8397 if (!ancestor)
8398 return isVisible();
8399 const QWidget * w = this;
8400 while (!w->isHidden()
8401 && !w->isWindow()
8402 && w->parentWidget()
8403 && w->parentWidget() != ancestor)
8404 w = w->parentWidget();
8405 return !w->isHidden();
8406}
8407
8408
8409/*!
8410 Returns the unobscured region where paint events can occur.
8411
8412 For visible widgets, this is an approximation of the area not
8413 covered by other widgets; otherwise, this is an empty region.
8414
8415 The repaint() function calls this function if necessary, so in
8416 general you do not need to call it.
8417
8418*/
8419QRegion QWidget::visibleRegion() const
8420{
8421 Q_D(const QWidget);
8422
8423 QRect clipRect = d->clipRect();
8424 if (clipRect.isEmpty())
8425 return QRegion();
8426 QRegion r(clipRect);
8427 d->subtractOpaqueChildren(source&: r, clipRect);
8428 d->subtractOpaqueSiblings(sourceRegion&: r);
8429 return r;
8430}
8431
8432
8433QSize QWidgetPrivate::adjustedSize() const
8434{
8435 Q_Q(const QWidget);
8436
8437 QSize s = q->sizeHint();
8438
8439 if (q->isWindow()) {
8440 Qt::Orientations exp;
8441 if (layout) {
8442 if (layout->hasHeightForWidth())
8443 s.setHeight(layout->totalHeightForWidth(w: s.width()));
8444 exp = layout->expandingDirections();
8445 } else
8446 {
8447 if (q->sizePolicy().hasHeightForWidth())
8448 s.setHeight(q->heightForWidth(s.width()));
8449 exp = q->sizePolicy().expandingDirections();
8450 }
8451 if (exp & Qt::Horizontal)
8452 s.setWidth(qMax(a: s.width(), b: 200));
8453 if (exp & Qt::Vertical)
8454 s.setHeight(qMax(a: s.height(), b: 100));
8455
8456 QRect screen = QDesktopWidgetPrivate::screenGeometry(point: q->pos());
8457
8458 s.setWidth(qMin(a: s.width(), b: screen.width()*2/3));
8459 s.setHeight(qMin(a: s.height(), b: screen.height()*2/3));
8460
8461 if (QTLWExtra *extra = maybeTopData())
8462 extra->sizeAdjusted = true;
8463 }
8464
8465 if (!s.isValid()) {
8466 QRect r = q->childrenRect(); // get children rectangle
8467 if (r.isNull())
8468 return s;
8469 s = r.size() + QSize(2 * r.x(), 2 * r.y());
8470 }
8471
8472 return s;
8473}
8474
8475/*!
8476 Adjusts the size of the widget to fit its contents.
8477
8478 This function uses sizeHint() if it is valid, i.e., the size hint's width
8479 and height are \>= 0. Otherwise, it sets the size to the children
8480 rectangle that covers all child widgets (the union of all child widget
8481 rectangles).
8482
8483 For windows, the screen size is also taken into account. If the sizeHint()
8484 is less than (200, 100) and the size policy is \l{QSizePolicy::Expanding}
8485 {expanding}, the window will be at least (200, 100). The maximum size of
8486 a window is 2/3 of the screen's width and height.
8487
8488 \sa sizeHint(), childrenRect()
8489*/
8490
8491void QWidget::adjustSize()
8492{
8493 Q_D(QWidget);
8494 ensurePolished();
8495 QSize s = d->adjustedSize();
8496
8497 if (d->layout)
8498 d->layout->activate();
8499
8500 if (s.isValid())
8501 resize(s);
8502}
8503
8504
8505/*!
8506 \property QWidget::sizeHint
8507 \brief the recommended size for the widget
8508
8509 If the value of this property is an invalid size, no size is
8510 recommended.
8511
8512 The default implementation of sizeHint() returns an invalid size
8513 if there is no layout for this widget, and returns the layout's
8514 preferred size otherwise.
8515
8516 \sa QSize::isValid(), minimumSizeHint(), sizePolicy(),
8517 setMinimumSize(), updateGeometry()
8518*/
8519
8520QSize QWidget::sizeHint() const
8521{
8522 Q_D(const QWidget);
8523 if (d->layout)
8524 return d->layout->totalSizeHint();
8525 return QSize(-1, -1);
8526}
8527
8528/*!
8529 \property QWidget::minimumSizeHint
8530 \brief the recommended minimum size for the widget
8531
8532 If the value of this property is an invalid size, no minimum size
8533 is recommended.
8534
8535 The default implementation of minimumSizeHint() returns an invalid
8536 size if there is no layout for this widget, and returns the
8537 layout's minimum size otherwise. Most built-in widgets reimplement
8538 minimumSizeHint().
8539
8540 \l QLayout will never resize a widget to a size smaller than the
8541 minimum size hint unless minimumSize() is set or the size policy is
8542 set to QSizePolicy::Ignore. If minimumSize() is set, the minimum
8543 size hint will be ignored.
8544
8545 \sa QSize::isValid(), resize(), setMinimumSize(), sizePolicy()
8546*/
8547QSize QWidget::minimumSizeHint() const
8548{
8549 Q_D(const QWidget);
8550 if (d->layout)
8551 return d->layout->totalMinimumSize();
8552 return QSize(-1, -1);
8553}
8554
8555
8556/*!
8557 \fn QWidget *QWidget::parentWidget() const
8558
8559 Returns the parent of this widget, or \nullptr if it does not have any
8560 parent widget.
8561*/
8562
8563
8564/*!
8565 Returns \c true if this widget is a parent, (or grandparent and so on
8566 to any level), of the given \a child, and both widgets are within
8567 the same window; otherwise returns \c false.
8568*/
8569
8570bool QWidget::isAncestorOf(const QWidget *child) const
8571{
8572 while (child) {
8573 if (child == this)
8574 return true;
8575 if (child->isWindow())
8576 return false;
8577 child = child->parentWidget();
8578 }
8579 return false;
8580}
8581
8582/*****************************************************************************
8583 QWidget event handling
8584 *****************************************************************************/
8585
8586/*!
8587 This is the main event handler; it handles event \a event. You can
8588 reimplement this function in a subclass, but we recommend using
8589 one of the specialized event handlers instead.
8590
8591 Key press and release events are treated differently from other
8592 events. event() checks for Tab and Shift+Tab and tries to move the
8593 focus appropriately. If there is no widget to move the focus to
8594 (or the key press is not Tab or Shift+Tab), event() calls
8595 keyPressEvent().
8596
8597 Mouse and tablet event handling is also slightly special: only
8598 when the widget is \l enabled, event() will call the specialized
8599 handlers such as mousePressEvent(); otherwise it will discard the
8600 event.
8601
8602 This function returns \c true if the event was recognized, otherwise
8603 it returns \c false. If the recognized event was accepted (see \l
8604 QEvent::accepted), any further processing such as event
8605 propagation to the parent widget stops.
8606
8607 \sa closeEvent(), focusInEvent(), focusOutEvent(), enterEvent(),
8608 keyPressEvent(), keyReleaseEvent(), leaveEvent(),
8609 mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(),
8610 mouseReleaseEvent(), moveEvent(), paintEvent(), resizeEvent(),
8611 QObject::event(), QObject::timerEvent()
8612*/
8613
8614bool QWidget::event(QEvent *event)
8615{
8616 Q_D(QWidget);
8617
8618 // ignore mouse and key events when disabled
8619 if (!isEnabled()) {
8620 switch(event->type()) {
8621 case QEvent::TabletPress:
8622 case QEvent::TabletRelease:
8623 case QEvent::TabletMove:
8624 case QEvent::MouseButtonPress:
8625 case QEvent::MouseButtonRelease:
8626 case QEvent::MouseButtonDblClick:
8627 case QEvent::MouseMove:
8628 case QEvent::TouchBegin:
8629 case QEvent::TouchUpdate:
8630 case QEvent::TouchEnd:
8631 case QEvent::TouchCancel:
8632 case QEvent::ContextMenu:
8633 case QEvent::KeyPress:
8634 case QEvent::KeyRelease:
8635#if QT_CONFIG(wheelevent)
8636 case QEvent::Wheel:
8637#endif
8638 return false;
8639 default:
8640 break;
8641 }
8642 }
8643 switch (event->type()) {
8644 case QEvent::PlatformSurface: {
8645 // Sync up QWidget's view of whether or not the widget has been created
8646 switch (static_cast<QPlatformSurfaceEvent*>(event)->surfaceEventType()) {
8647 case QPlatformSurfaceEvent::SurfaceCreated:
8648 if (!testAttribute(attribute: Qt::WA_WState_Created))
8649 create();
8650 break;
8651 case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
8652 if (testAttribute(attribute: Qt::WA_WState_Created)) {
8653 // Child windows have already been destroyed by QWindow,
8654 // so we skip them here.
8655 destroy(destroyWindow: false, destroySubWindows: false);
8656 }
8657 break;
8658 }
8659 break;
8660 }
8661 case QEvent::MouseMove:
8662 mouseMoveEvent(event: (QMouseEvent*)event);
8663 break;
8664
8665 case QEvent::MouseButtonPress:
8666 mousePressEvent(event: (QMouseEvent*)event);
8667 break;
8668
8669 case QEvent::MouseButtonRelease:
8670 mouseReleaseEvent(event: (QMouseEvent*)event);
8671 break;
8672
8673 case QEvent::MouseButtonDblClick:
8674 mouseDoubleClickEvent(event: (QMouseEvent*)event);
8675 break;
8676#if QT_CONFIG(wheelevent)
8677 case QEvent::Wheel:
8678 wheelEvent(event: (QWheelEvent*)event);
8679 break;
8680#endif
8681#if QT_CONFIG(tabletevent)
8682 case QEvent::TabletMove:
8683 if (static_cast<QTabletEvent *>(event)->buttons() == Qt::NoButton && !testAttribute(attribute: Qt::WA_TabletTracking))
8684 break;
8685 Q_FALLTHROUGH();
8686 case QEvent::TabletPress:
8687 case QEvent::TabletRelease:
8688 tabletEvent(event: (QTabletEvent*)event);
8689 break;
8690#endif
8691 case QEvent::KeyPress: {
8692 QKeyEvent *k = (QKeyEvent *)event;
8693 bool res = false;
8694 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
8695 if (k->key() == Qt::Key_Backtab
8696 || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
8697 res = focusNextPrevChild(next: false);
8698 else if (k->key() == Qt::Key_Tab)
8699 res = focusNextPrevChild(next: true);
8700 if (res)
8701 break;
8702 }
8703 keyPressEvent(event: k);
8704#ifdef QT_KEYPAD_NAVIGATION
8705 if (!k->isAccepted() && QApplication::keypadNavigationEnabled()
8706 && !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier))) {
8707 if (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder) {
8708 if (k->key() == Qt::Key_Up)
8709 res = focusNextPrevChild(false);
8710 else if (k->key() == Qt::Key_Down)
8711 res = focusNextPrevChild(true);
8712 } else if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
8713 if (k->key() == Qt::Key_Up)
8714 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionNorth);
8715 else if (k->key() == Qt::Key_Right)
8716 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionEast);
8717 else if (k->key() == Qt::Key_Down)
8718 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionSouth);
8719 else if (k->key() == Qt::Key_Left)
8720 res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionWest);
8721 }
8722 if (res) {
8723 k->accept();
8724 break;
8725 }
8726 }
8727#endif
8728#if QT_CONFIG(whatsthis)
8729 if (!k->isAccepted()
8730 && k->modifiers() & Qt::ShiftModifier && k->key() == Qt::Key_F1
8731 && d->whatsThis.size()) {
8732 QWhatsThis::showText(pos: mapToGlobal(inputMethodQuery(Qt::ImCursorRectangle).toRect().center()), text: d->whatsThis, w: this);
8733 k->accept();
8734 }
8735#endif
8736 }
8737 break;
8738
8739 case QEvent::KeyRelease:
8740 keyReleaseEvent(event: (QKeyEvent*)event);
8741 Q_FALLTHROUGH();
8742 case QEvent::ShortcutOverride:
8743 break;
8744
8745 case QEvent::InputMethod:
8746 inputMethodEvent((QInputMethodEvent *) event);
8747 break;
8748
8749 case QEvent::InputMethodQuery:
8750 if (testAttribute(attribute: Qt::WA_InputMethodEnabled)) {
8751 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(event);
8752 Qt::InputMethodQueries queries = query->queries();
8753 for (uint i = 0; i < 32; ++i) {
8754 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
8755 if (q) {
8756 QVariant v = inputMethodQuery(q);
8757 if (q == Qt::ImEnabled && !v.isValid() && isEnabled())
8758 v = QVariant(true); // special case for Qt4 compatibility
8759 query->setValue(query: q, value: v);
8760 }
8761 }
8762 query->accept();
8763 }
8764 break;
8765
8766 case QEvent::PolishRequest:
8767 ensurePolished();
8768 break;
8769
8770 case QEvent::Polish: {
8771 style()->polish(widget: this);
8772 setAttribute(Qt::WA_WState_Polished);
8773 if (!QApplication::font(this).isCopyOf(QApplication::font()))
8774 d->resolveFont();
8775 if (!QApplication::palette(this).isCopyOf(p: QGuiApplication::palette()))
8776 d->resolvePalette();
8777 }
8778 break;
8779
8780 case QEvent::ApplicationWindowIconChange:
8781 if (isWindow() && !testAttribute(attribute: Qt::WA_SetWindowIcon)) {
8782 d->setWindowIcon_sys();
8783 d->setWindowIcon_helper();
8784 }
8785 break;
8786 case QEvent::FocusIn:
8787 focusInEvent(event: (QFocusEvent*)event);
8788 d->updateWidgetTransform(event);
8789 break;
8790
8791 case QEvent::FocusOut:
8792 focusOutEvent(event: (QFocusEvent*)event);
8793 break;
8794
8795 case QEvent::Enter:
8796#if QT_CONFIG(statustip)
8797 if (d->statusTip.size()) {
8798 QStatusTipEvent tip(d->statusTip);
8799 QCoreApplication::sendEvent(receiver: const_cast<QWidget *>(this), event: &tip);
8800 }
8801#endif
8802 enterEvent(event);
8803 break;
8804
8805 case QEvent::Leave:
8806#if QT_CONFIG(statustip)
8807 if (d->statusTip.size()) {
8808 QString empty;
8809 QStatusTipEvent tip(empty);
8810 QCoreApplication::sendEvent(receiver: const_cast<QWidget *>(this), event: &tip);
8811 }
8812#endif
8813 leaveEvent(event);
8814 break;
8815
8816 case QEvent::HoverEnter:
8817 case QEvent::HoverLeave:
8818 update();
8819 break;
8820
8821 case QEvent::Paint:
8822 // At this point the event has to be delivered, regardless
8823 // whether the widget isVisible() or not because it
8824 // already went through the filters
8825 paintEvent(event: (QPaintEvent*)event);
8826 break;
8827
8828 case QEvent::Move:
8829 moveEvent(event: (QMoveEvent*)event);
8830 d->updateWidgetTransform(event);
8831 break;
8832
8833 case QEvent::Resize:
8834 resizeEvent(event: (QResizeEvent*)event);
8835 d->updateWidgetTransform(event);
8836 break;
8837
8838 case QEvent::Close:
8839 closeEvent(event: (QCloseEvent *)event);
8840 break;
8841
8842#ifndef QT_NO_CONTEXTMENU
8843 case QEvent::ContextMenu:
8844 switch (data->context_menu_policy) {
8845 case Qt::PreventContextMenu:
8846 break;
8847 case Qt::DefaultContextMenu:
8848 contextMenuEvent(event: static_cast<QContextMenuEvent *>(event));
8849 break;
8850 case Qt::CustomContextMenu:
8851 emit customContextMenuRequested(pos: static_cast<QContextMenuEvent *>(event)->pos());
8852 break;
8853#if QT_CONFIG(menu)
8854 case Qt::ActionsContextMenu:
8855 if (d->actions.count()) {
8856 QMenu::exec(actions: d->actions, pos: static_cast<QContextMenuEvent *>(event)->globalPos(),
8857 at: nullptr, parent: this);
8858 break;
8859 }
8860 Q_FALLTHROUGH();
8861#endif
8862 default:
8863 event->ignore();
8864 break;
8865 }
8866 break;
8867#endif // QT_NO_CONTEXTMENU
8868
8869#if QT_CONFIG(draganddrop)
8870 case QEvent::Drop:
8871 dropEvent(event: (QDropEvent*) event);
8872 break;
8873
8874 case QEvent::DragEnter:
8875 dragEnterEvent(event: (QDragEnterEvent*) event);
8876 break;
8877
8878 case QEvent::DragMove:
8879 dragMoveEvent(event: (QDragMoveEvent*) event);
8880 break;
8881
8882 case QEvent::DragLeave:
8883 dragLeaveEvent(event: (QDragLeaveEvent*) event);
8884 break;
8885#endif
8886
8887 case QEvent::Show:
8888 showEvent(event: (QShowEvent*) event);
8889 break;
8890
8891 case QEvent::Hide:
8892 hideEvent(event: (QHideEvent*) event);
8893 break;
8894
8895 case QEvent::ShowWindowRequest:
8896 if (!isHidden())
8897 d->show_sys();
8898 break;
8899
8900 case QEvent::ApplicationFontChange:
8901 d->resolveFont();
8902 break;
8903 case QEvent::ApplicationPaletteChange:
8904 if (!(windowType() == Qt::Desktop))
8905 d->resolvePalette();
8906 break;
8907
8908 case QEvent::ToolBarChange:
8909 case QEvent::ActivationChange:
8910 case QEvent::EnabledChange:
8911 case QEvent::FontChange:
8912 case QEvent::StyleChange:
8913 case QEvent::PaletteChange:
8914 case QEvent::WindowTitleChange:
8915 case QEvent::IconTextChange:
8916 case QEvent::ModifiedChange:
8917 case QEvent::MouseTrackingChange:
8918 case QEvent::TabletTrackingChange:
8919 case QEvent::ParentChange:
8920 case QEvent::LocaleChange:
8921 case QEvent::MacSizeChange:
8922 case QEvent::ContentsRectChange:
8923 case QEvent::ThemeChange:
8924 case QEvent::ReadOnlyChange:
8925 changeEvent(event);
8926 break;
8927
8928 case QEvent::WindowStateChange: {
8929 const bool wasMinimized = static_cast<const QWindowStateChangeEvent *>(event)->oldState() & Qt::WindowMinimized;
8930 if (wasMinimized != isMinimized()) {
8931 QWidget *widget = const_cast<QWidget *>(this);
8932 if (wasMinimized) {
8933 // Always send the spontaneous events here, otherwise it can break the application!
8934 if (!d->childrenShownByExpose) {
8935 // Show widgets only when they are not yet shown by the expose event
8936 d->showChildren(spontaneous: true);
8937 QShowEvent showEvent;
8938 QCoreApplication::sendSpontaneousEvent(receiver: widget, event: &showEvent);
8939 }
8940 d->childrenHiddenByWState = false; // Set it always to "false" when window is restored
8941 } else {
8942 QHideEvent hideEvent;
8943 QCoreApplication::sendSpontaneousEvent(receiver: widget, event: &hideEvent);
8944 d->hideChildren(spontaneous: true);
8945 d->childrenHiddenByWState = true;
8946 }
8947 d->childrenShownByExpose = false; // Set it always to "false" when window state changes
8948 }
8949 changeEvent(event);
8950 }
8951 break;
8952
8953 case QEvent::WindowActivate:
8954 case QEvent::WindowDeactivate: {
8955 if (isVisible() && !palette().isEqual(cr1: QPalette::Active, cr2: QPalette::Inactive))
8956 update();
8957 QList<QObject*> childList = d->children;
8958 for (int i = 0; i < childList.size(); ++i) {
8959 QWidget *w = qobject_cast<QWidget *>(o: childList.at(i));
8960 if (w && w->isVisible() && !w->isWindow())
8961 QCoreApplication::sendEvent(receiver: w, event);
8962 }
8963 break; }
8964
8965 case QEvent::LanguageChange:
8966 changeEvent(event);
8967 {
8968 QList<QObject*> childList = d->children;
8969 for (int i = 0; i < childList.size(); ++i) {
8970 QObject *o = childList.at(i);
8971 if (o)
8972 QCoreApplication::sendEvent(receiver: o, event);
8973 }
8974 }
8975 update();
8976 break;
8977
8978 case QEvent::ApplicationLayoutDirectionChange:
8979 d->resolveLayoutDirection();
8980 break;
8981
8982 case QEvent::LayoutDirectionChange:
8983 if (d->layout)
8984 d->layout->invalidate();
8985 update();
8986 changeEvent(event);
8987 break;
8988 case QEvent::UpdateRequest:
8989 d->syncBackingStore();
8990 break;
8991 case QEvent::UpdateLater:
8992 update(static_cast<QUpdateLaterEvent*>(event)->region());
8993 break;
8994 case QEvent::StyleAnimationUpdate:
8995 if (isVisible() && !window()->isMinimized()) {
8996 event->accept();
8997 update();
8998 }
8999 break;
9000
9001 case QEvent::WindowBlocked:
9002 case QEvent::WindowUnblocked:
9003 if (!d->children.isEmpty()) {
9004 QWidget *modalWidget = QApplication::activeModalWidget();
9005 for (int i = 0; i < d->children.size(); ++i) {
9006 QObject *o = d->children.at(i);
9007 if (o && o != modalWidget && o->isWidgetType()) {
9008 QWidget *w = static_cast<QWidget *>(o);
9009 // do not forward the event to child windows; QApplication does this for us
9010 if (!w->isWindow())
9011 QCoreApplication::sendEvent(receiver: w, event);
9012 }
9013 }
9014 }
9015 break;
9016#ifndef QT_NO_TOOLTIP
9017 case QEvent::ToolTip:
9018 if (!d->toolTip.isEmpty())
9019 QToolTip::showText(pos: static_cast<QHelpEvent*>(event)->globalPos(), text: d->toolTip, w: this, rect: QRect(), msecShowTime: d->toolTipDuration);
9020 else
9021 event->ignore();
9022 break;
9023#endif
9024#if QT_CONFIG(whatsthis)
9025 case QEvent::WhatsThis:
9026 if (d->whatsThis.size())
9027 QWhatsThis::showText(pos: static_cast<QHelpEvent *>(event)->globalPos(), text: d->whatsThis, w: this);
9028 else
9029 event->ignore();
9030 break;
9031 case QEvent::QueryWhatsThis:
9032 if (d->whatsThis.isEmpty())
9033 event->ignore();
9034 break;
9035#endif
9036 case QEvent::EmbeddingControl:
9037 d->topData()->frameStrut.setCoords(xp1: 0 ,yp1: 0, xp2: 0, yp2: 0);
9038 data->fstrut_dirty = false;
9039 break;
9040#ifndef QT_NO_ACTION
9041 case QEvent::ActionAdded:
9042 case QEvent::ActionRemoved:
9043 case QEvent::ActionChanged:
9044 actionEvent(event: (QActionEvent*)event);
9045 break;
9046#endif
9047
9048 case QEvent::KeyboardLayoutChange:
9049 {
9050 changeEvent(event);
9051
9052 // inform children of the change
9053 QList<QObject*> childList = d->children;
9054 for (int i = 0; i < childList.size(); ++i) {
9055 QWidget *w = qobject_cast<QWidget *>(o: childList.at(i));
9056 if (w && w->isVisible() && !w->isWindow())
9057 QCoreApplication::sendEvent(receiver: w, event);
9058 }
9059 break;
9060 }
9061 case QEvent::TouchBegin:
9062 case QEvent::TouchUpdate:
9063 case QEvent::TouchEnd:
9064 case QEvent::TouchCancel:
9065 {
9066 event->ignore();
9067 break;
9068 }
9069#ifndef QT_NO_GESTURES
9070 case QEvent::Gesture:
9071 event->ignore();
9072 break;
9073#endif
9074 case QEvent::ScreenChangeInternal:
9075 if (const QTLWExtra *te = d->maybeTopData()) {
9076 const QWindow *win = te->window;
9077 d->setWinId((win && win->handle()) ? win->handle()->winId() : 0);
9078 }
9079 if (d->data.fnt.d->dpi != logicalDpiY())
9080 d->updateFont(font: d->data.fnt);
9081#ifndef QT_NO_OPENGL
9082 d->renderToTextureReallyDirty = 1;
9083#endif
9084 break;
9085#ifndef QT_NO_PROPERTIES
9086 case QEvent::DynamicPropertyChange: {
9087 const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
9088 if (propName.length() == 13 && !qstrncmp(str1: propName, str2: "_q_customDpi", len: 12)) {
9089 uint value = property(name: propName.constData()).toUInt();
9090 if (!d->extra)
9091 d->createExtra();
9092 const char axis = propName.at(i: 12);
9093 if (axis == 'X')
9094 d->extra->customDpiX = value;
9095 else if (axis == 'Y')
9096 d->extra->customDpiY = value;
9097 d->updateFont(font: d->data.fnt);
9098 }
9099 if (windowHandle() && !qstrncmp(str1: propName, str2: "_q_platform_", len: 12))
9100 windowHandle()->setProperty(name: propName, value: property(name: propName));
9101 Q_FALLTHROUGH();
9102 }
9103#endif
9104 default:
9105 return QObject::event(event);
9106 }
9107 return true;
9108}
9109
9110/*!
9111 This event handler can be reimplemented to handle state changes.
9112
9113 The state being changed in this event can be retrieved through the \a event
9114 supplied.
9115
9116 Change events include: QEvent::ToolBarChange,
9117 QEvent::ActivationChange, QEvent::EnabledChange, QEvent::FontChange,
9118 QEvent::StyleChange, QEvent::PaletteChange,
9119 QEvent::WindowTitleChange, QEvent::IconTextChange,
9120 QEvent::ModifiedChange, QEvent::MouseTrackingChange,
9121 QEvent::ParentChange, QEvent::WindowStateChange,
9122 QEvent::LanguageChange, QEvent::LocaleChange,
9123 QEvent::LayoutDirectionChange, QEvent::ReadOnlyChange.
9124
9125*/
9126void QWidget::changeEvent(QEvent * event)
9127{
9128 switch(event->type()) {
9129 case QEvent::EnabledChange: {
9130 update();
9131#ifndef QT_NO_ACCESSIBILITY
9132 QAccessible::State s;
9133 s.disabled = true;
9134 QAccessibleStateChangeEvent event(this, s);
9135 QAccessible::updateAccessibility(event: &event);
9136#endif
9137 break;
9138 }
9139
9140 case QEvent::FontChange:
9141 case QEvent::StyleChange: {
9142 Q_D(QWidget);
9143 update();
9144 updateGeometry();
9145 if (d->layout)
9146 d->layout->invalidate();
9147 break;
9148 }
9149
9150 case QEvent::PaletteChange:
9151 update();
9152 break;
9153
9154 case QEvent::ThemeChange:
9155 if (QGuiApplication::desktopSettingsAware() && windowType() != Qt::Desktop
9156 && qApp && !QCoreApplication::closingDown()) {
9157 if (testAttribute(attribute: Qt::WA_WState_Polished))
9158 QApplication::style()->unpolish(widget: this);
9159 if (testAttribute(attribute: Qt::WA_WState_Polished))
9160 QApplication::style()->polish(widget: this);
9161 QEvent styleChangedEvent(QEvent::StyleChange);
9162 QCoreApplication::sendEvent(receiver: this, event: &styleChangedEvent);
9163 if (isVisible())
9164 update();
9165 }
9166 break;
9167
9168#ifdef Q_OS_MAC
9169 case QEvent::MacSizeChange:
9170 updateGeometry();
9171 break;
9172#endif
9173
9174 default:
9175 break;
9176 }
9177}
9178
9179/*!
9180 This event handler, for event \a event, can be reimplemented in a
9181 subclass to receive mouse move events for the widget.
9182
9183 If mouse tracking is switched off, mouse move events only occur if
9184 a mouse button is pressed while the mouse is being moved. If mouse
9185 tracking is switched on, mouse move events occur even if no mouse
9186 button is pressed.
9187
9188 QMouseEvent::pos() reports the position of the mouse cursor,
9189 relative to this widget. For press and release events, the
9190 position is usually the same as the position of the last mouse
9191 move event, but it might be different if the user's hand shakes.
9192 This is a feature of the underlying window system, not Qt.
9193
9194 If you want to show a tooltip immediately, while the mouse is
9195 moving (e.g., to get the mouse coordinates with QMouseEvent::pos()
9196 and show them as a tooltip), you must first enable mouse tracking
9197 as described above. Then, to ensure that the tooltip is updated
9198 immediately, you must call QToolTip::showText() instead of
9199 setToolTip() in your implementation of mouseMoveEvent().
9200
9201 \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
9202 mouseDoubleClickEvent(), event(), QMouseEvent, {Scribble Example}
9203*/
9204
9205void QWidget::mouseMoveEvent(QMouseEvent *event)
9206{
9207 event->ignore();
9208}
9209
9210/*!
9211 This event handler, for event \a event, can be reimplemented in a
9212 subclass to receive mouse press events for the widget.
9213
9214 If you create new widgets in the mousePressEvent() the
9215 mouseReleaseEvent() may not end up where you expect, depending on
9216 the underlying window system (or X11 window manager), the widgets'
9217 location and maybe more.
9218
9219 The default implementation implements the closing of popup widgets
9220 when you click outside the window. For other widget types it does
9221 nothing.
9222
9223 \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
9224 mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
9225*/
9226
9227void QWidget::mousePressEvent(QMouseEvent *event)
9228{
9229 event->ignore();
9230 if ((windowType() == Qt::Popup)) {
9231 event->accept();
9232 QWidget* w;
9233 while ((w = QApplication::activePopupWidget()) && w != this){
9234 w->close();
9235 if (QApplication::activePopupWidget() == w) // widget does not want to disappear
9236 w->hide(); // hide at least
9237 }
9238 if (!rect().contains(p: event->pos())){
9239 close();
9240 }
9241 }
9242}
9243
9244/*!
9245 This event handler, for event \a event, can be reimplemented in a
9246 subclass to receive mouse release events for the widget.
9247
9248 \sa mousePressEvent(), mouseDoubleClickEvent(),
9249 mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
9250*/
9251
9252void QWidget::mouseReleaseEvent(QMouseEvent *event)
9253{
9254 event->ignore();
9255}
9256
9257/*!
9258 This event handler, for event \a event, can be reimplemented in a
9259 subclass to receive mouse double click events for the widget.
9260
9261 The default implementation calls mousePressEvent().
9262
9263 \note The widget will also receive mouse press and mouse release
9264 events in addition to the double click event. And if another widget
9265 that overlaps this widget disappears in response to press or
9266 release events, then this widget will only receive the double click
9267 event. It is up to the developer to ensure that the application
9268 interprets these events correctly.
9269
9270 \sa mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(),
9271 event(), QMouseEvent
9272*/
9273
9274void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
9275{
9276 mousePressEvent(event);
9277}
9278
9279#if QT_CONFIG(wheelevent)
9280/*!
9281 This event handler, for event \a event, can be reimplemented in a
9282 subclass to receive wheel events for the widget.
9283
9284 If you reimplement this handler, it is very important that you
9285 \l{QEvent}{ignore()} the event if you do not handle
9286 it, so that the widget's parent can interpret it.
9287
9288 The default implementation ignores the event.
9289
9290 \sa QEvent::ignore(), QEvent::accept(), event(),
9291 QWheelEvent
9292*/
9293
9294void QWidget::wheelEvent(QWheelEvent *event)
9295{
9296 event->ignore();
9297}
9298#endif // QT_CONFIG(wheelevent)
9299
9300#if QT_CONFIG(tabletevent)
9301/*!
9302 This event handler, for event \a event, can be reimplemented in a
9303 subclass to receive tablet events for the widget.
9304
9305 If you reimplement this handler, it is very important that you
9306 \l{QEvent}{ignore()} the event if you do not handle
9307 it, so that the widget's parent can interpret it.
9308
9309 The default implementation ignores the event.
9310
9311 If tablet tracking is switched off, tablet move events only occur if the
9312 stylus is in contact with the tablet, or at least one stylus button is
9313 pressed, while the stylus is being moved. If tablet tracking is switched on,
9314 tablet move events occur even while the stylus is hovering in proximity of
9315 the tablet, with no buttons pressed.
9316
9317 \sa QEvent::ignore(), QEvent::accept(), event(), setTabletTracking(),
9318 QTabletEvent
9319*/
9320
9321void QWidget::tabletEvent(QTabletEvent *event)
9322{
9323 event->ignore();
9324}
9325#endif // QT_CONFIG(tabletevent)
9326
9327/*!
9328 This event handler, for event \a event, can be reimplemented in a
9329 subclass to receive key press events for the widget.
9330
9331 A widget must call setFocusPolicy() to accept focus initially and
9332 have focus in order to receive a key press event.
9333
9334 If you reimplement this handler, it is very important that you
9335 call the base class implementation if you do not act upon the key.
9336
9337 The default implementation closes popup widgets if the user
9338 presses the key sequence for QKeySequence::Cancel (typically the
9339 Escape key). Otherwise the event is ignored, so that the widget's
9340 parent can interpret it.
9341
9342 Note that QKeyEvent starts with isAccepted() == true, so you do not
9343 need to call QKeyEvent::accept() - just do not call the base class
9344 implementation if you act upon the key.
9345
9346 \sa keyReleaseEvent(), setFocusPolicy(),
9347 focusInEvent(), focusOutEvent(), event(), QKeyEvent, {Tetrix Example}
9348*/
9349
9350void QWidget::keyPressEvent(QKeyEvent *event)
9351{
9352#ifndef QT_NO_SHORTCUT
9353 if ((windowType() == Qt::Popup) && event->matches(key: QKeySequence::Cancel)) {
9354 event->accept();
9355 close();
9356 } else
9357#endif
9358 {
9359 event->ignore();
9360 }
9361}
9362
9363/*!
9364 This event handler, for event \a event, can be reimplemented in a
9365 subclass to receive key release events for the widget.
9366
9367 A widget must \l{setFocusPolicy()}{accept focus}
9368 initially and \l{hasFocus()}{have focus} in order to
9369 receive a key release event.
9370
9371 If you reimplement this handler, it is very important that you
9372 call the base class implementation if you do not act upon the key.
9373
9374 The default implementation ignores the event, so that the widget's
9375 parent can interpret it.
9376
9377 Note that QKeyEvent starts with isAccepted() == true, so you do not
9378 need to call QKeyEvent::accept() - just do not call the base class
9379 implementation if you act upon the key.
9380
9381 \sa keyPressEvent(), QEvent::ignore(), setFocusPolicy(),
9382 focusInEvent(), focusOutEvent(), event(), QKeyEvent
9383*/
9384
9385void QWidget::keyReleaseEvent(QKeyEvent *event)
9386{
9387 event->ignore();
9388}
9389
9390/*!
9391 \fn void QWidget::focusInEvent(QFocusEvent *event)
9392
9393 This event handler can be reimplemented in a subclass to receive
9394 keyboard focus events (focus received) for the widget. The event
9395 is passed in the \a event parameter
9396
9397 A widget normally must setFocusPolicy() to something other than
9398 Qt::NoFocus in order to receive focus events. (Note that the
9399 application programmer can call setFocus() on any widget, even
9400 those that do not normally accept focus.)
9401
9402 The default implementation updates the widget (except for windows
9403 that do not specify a focusPolicy()).
9404
9405 \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
9406 keyReleaseEvent(), event(), QFocusEvent
9407*/
9408
9409void QWidget::focusInEvent(QFocusEvent *)
9410{
9411 if (focusPolicy() != Qt::NoFocus || !isWindow()) {
9412 update();
9413 }
9414}
9415
9416/*!
9417 \fn void QWidget::focusOutEvent(QFocusEvent *event)
9418
9419 This event handler can be reimplemented in a subclass to receive
9420 keyboard focus events (focus lost) for the widget. The events is
9421 passed in the \a event parameter.
9422
9423 A widget normally must setFocusPolicy() to something other than
9424 Qt::NoFocus in order to receive focus events. (Note that the
9425 application programmer can call setFocus() on any widget, even
9426 those that do not normally accept focus.)
9427
9428 The default implementation updates the widget (except for windows
9429 that do not specify a focusPolicy()).
9430
9431 \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
9432 keyReleaseEvent(), event(), QFocusEvent
9433*/
9434
9435void QWidget::focusOutEvent(QFocusEvent *)
9436{
9437 if (focusPolicy() != Qt::NoFocus || !isWindow())
9438 update();
9439
9440#if !defined(QT_PLATFORM_UIKIT)
9441 // FIXME: revisit autoSIP logic, QTBUG-42906
9442 if (qApp->autoSipEnabled() && testAttribute(attribute: Qt::WA_InputMethodEnabled))
9443 QGuiApplication::inputMethod()->hide();
9444#endif
9445}
9446
9447/*!
9448 \fn void QWidget::enterEvent(QEvent *event)
9449
9450 This event handler can be reimplemented in a subclass to receive
9451 widget enter events which are passed in the \a event parameter.
9452
9453 An event is sent to the widget when the mouse cursor enters the
9454 widget.
9455
9456 \sa leaveEvent(), mouseMoveEvent(), event()
9457*/
9458
9459void QWidget::enterEvent(QEvent *)
9460{
9461}
9462
9463// ### Qt 6: void QWidget::enterEvent(QEnterEvent *).
9464
9465/*!
9466 \fn void QWidget::leaveEvent(QEvent *event)
9467
9468 This event handler can be reimplemented in a subclass to receive
9469 widget leave events which are passed in the \a event parameter.
9470
9471 A leave event is sent to the widget when the mouse cursor leaves
9472 the widget.
9473
9474 \sa enterEvent(), mouseMoveEvent(), event()
9475*/
9476
9477void QWidget::leaveEvent(QEvent *)
9478{
9479}
9480
9481/*!
9482 \fn void QWidget::paintEvent(QPaintEvent *event)
9483
9484 This event handler can be reimplemented in a subclass to receive paint
9485 events passed in \a event.
9486
9487 A paint event is a request to repaint all or part of a widget. It can
9488 happen for one of the following reasons:
9489
9490 \list
9491 \li repaint() or update() was invoked,
9492 \li the widget was obscured and has now been uncovered, or
9493 \li many other reasons.
9494 \endlist
9495
9496 Many widgets can simply repaint their entire surface when asked to, but
9497 some slow widgets need to optimize by painting only the requested region:
9498 QPaintEvent::region(). This speed optimization does not change the result,
9499 as painting is clipped to that region during event processing. QListView
9500 and QTableView do this, for example.
9501
9502 Qt also tries to speed up painting by merging multiple paint events into
9503 one. When update() is called several times or the window system sends
9504 several paint events, Qt merges these events into one event with a larger
9505 region (see QRegion::united()). The repaint() function does not permit this
9506 optimization, so we suggest using update() whenever possible.
9507
9508 When the paint event occurs, the update region has normally been erased, so
9509 you are painting on the widget's background.
9510
9511 The background can be set using setBackgroundRole() and setPalette().
9512
9513 Since Qt 4.0, QWidget automatically double-buffers its painting, so there
9514 is no need to write double-buffering code in paintEvent() to avoid flicker.
9515
9516 \note Generally, you should refrain from calling update() or repaint()
9517 \b{inside} a paintEvent(). For example, calling update() or repaint() on
9518 children inside a paintEvent() results in undefined behavior; the child may
9519 or may not get a paint event.
9520
9521 \warning If you are using a custom paint engine without Qt's backingstore,
9522 Qt::WA_PaintOnScreen must be set. Otherwise, QWidget::paintEngine() will
9523 never be called; the backingstore will be used instead.
9524
9525 \sa event(), repaint(), update(), QPainter, QPixmap, QPaintEvent,
9526 {Analog Clock Example}
9527*/
9528
9529void QWidget::paintEvent(QPaintEvent *)
9530{
9531}
9532
9533
9534/*!
9535 \fn void QWidget::moveEvent(QMoveEvent *event)
9536
9537 This event handler can be reimplemented in a subclass to receive
9538 widget move events which are passed in the \a event parameter.
9539 When the widget receives this event, it is already at the new
9540 position.
9541
9542 The old position is accessible through QMoveEvent::oldPos().
9543
9544 \sa resizeEvent(), event(), move(), QMoveEvent
9545*/
9546
9547void QWidget::moveEvent(QMoveEvent *)
9548{
9549}
9550
9551
9552/*!
9553 This event handler can be reimplemented in a subclass to receive
9554 widget resize events which are passed in the \a event parameter.
9555 When resizeEvent() is called, the widget already has its new
9556 geometry. The old size is accessible through
9557 QResizeEvent::oldSize().
9558
9559 The widget will be erased and receive a paint event immediately
9560 after processing the resize event. No drawing need be (or should
9561 be) done inside this handler.
9562
9563
9564 \sa moveEvent(), event(), resize(), QResizeEvent, paintEvent(),
9565 {Scribble Example}
9566*/
9567
9568void QWidget::resizeEvent(QResizeEvent * /* event */)
9569{
9570}
9571
9572#ifndef QT_NO_ACTION
9573/*!
9574 \fn void QWidget::actionEvent(QActionEvent *event)
9575
9576 This event handler is called with the given \a event whenever the
9577 widget's actions are changed.
9578
9579 \sa addAction(), insertAction(), removeAction(), actions(), QActionEvent
9580*/
9581void QWidget::actionEvent(QActionEvent *)
9582{
9583
9584}
9585#endif
9586
9587/*!
9588 This event handler is called with the given \a event when Qt receives a window
9589 close request for a top-level widget from the window system.
9590
9591 By default, the event is accepted and the widget is closed. You can reimplement
9592 this function to change the way the widget responds to window close requests.
9593 For example, you can prevent the window from closing by calling \l{QEvent::}{ignore()}
9594 on all events.
9595
9596 Main window applications typically use reimplementations of this function to check
9597 whether the user's work has been saved and ask for permission before closing.
9598 For example, the \l{Application Example} uses a helper function to determine whether
9599 or not to close the window:
9600
9601 \snippet mainwindows/application/mainwindow.cpp 3
9602 \snippet mainwindows/application/mainwindow.cpp 4
9603
9604 \sa event(), hide(), close(), QCloseEvent, {Application Example}
9605*/
9606
9607void QWidget::closeEvent(QCloseEvent *event)
9608{
9609 event->accept();
9610}
9611
9612#ifndef QT_NO_CONTEXTMENU
9613/*!
9614 This event handler, for event \a event, can be reimplemented in a
9615 subclass to receive widget context menu events.
9616
9617 The handler is called when the widget's \l contextMenuPolicy is
9618 Qt::DefaultContextMenu.
9619
9620 The default implementation ignores the context event.
9621 See the \l QContextMenuEvent documentation for more details.
9622
9623 \sa event(), QContextMenuEvent, customContextMenuRequested()
9624*/
9625
9626void QWidget::contextMenuEvent(QContextMenuEvent *event)
9627{
9628 event->ignore();
9629}
9630#endif // QT_NO_CONTEXTMENU
9631
9632
9633/*!
9634 This event handler, for event \a event, can be reimplemented in a
9635 subclass to receive Input Method composition events. This handler
9636 is called when the state of the input method changes.
9637
9638 Note that when creating custom text editing widgets, the
9639 Qt::WA_InputMethodEnabled window attribute must be set explicitly
9640 (using the setAttribute() function) in order to receive input
9641 method events.
9642
9643 The default implementation calls event->ignore(), which rejects the
9644 Input Method event. See the \l QInputMethodEvent documentation for more
9645 details.
9646
9647 \sa event(), QInputMethodEvent
9648*/
9649void QWidget::inputMethodEvent(QInputMethodEvent *event)
9650{
9651 event->ignore();
9652}
9653
9654/*!
9655 This method is only relevant for input widgets. It is used by the
9656 input method to query a set of properties of the widget to be
9657 able to support complex input method operations as support for
9658 surrounding text and reconversions.
9659
9660 \a query specifies which property is queried.
9661
9662 \sa inputMethodEvent(), QInputMethodEvent, QInputMethodQueryEvent, inputMethodHints
9663*/
9664QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const
9665{
9666 switch(query) {
9667 case Qt::ImCursorRectangle:
9668 return QRect(width()/2, 0, 1, height());
9669 case Qt::ImFont:
9670 return font();
9671 case Qt::ImAnchorPosition:
9672 // Fallback.
9673 return inputMethodQuery(query: Qt::ImCursorPosition);
9674 case Qt::ImHints:
9675 return (int)inputMethodHints();
9676 case Qt::ImInputItemClipRectangle:
9677 return d_func()->clipRect();
9678 default:
9679 return QVariant();
9680 }
9681}
9682
9683/*!
9684 \property QWidget::inputMethodHints
9685 \brief What input method specific hints the widget has.
9686
9687 This is only relevant for input widgets. It is used by
9688 the input method to retrieve hints as to how the input method
9689 should operate. For example, if the Qt::ImhFormattedNumbersOnly flag
9690 is set, the input method may change its visual components to reflect
9691 that only numbers can be entered.
9692
9693 \warning Some widgets require certain flags in order to work as
9694 intended. To set a flag, do \c{w->setInputMethodHints(w->inputMethodHints()|f)}
9695 instead of \c{w->setInputMethodHints(f)}.
9696
9697 \note The flags are only hints, so the particular input method
9698 implementation is free to ignore them. If you want to be
9699 sure that a certain type of characters are entered,
9700 you should also set a QValidator on the widget.
9701
9702 The default value is Qt::ImhNone.
9703
9704 \since 4.6
9705
9706 \sa inputMethodQuery()
9707*/
9708Qt::InputMethodHints QWidget::inputMethodHints() const
9709{
9710#ifndef QT_NO_IM
9711 const QWidgetPrivate *priv = d_func();
9712 while (priv->inheritsInputMethodHints) {
9713 priv = priv->q_func()->parentWidget()->d_func();
9714 Q_ASSERT(priv);
9715 }
9716 return priv->imHints;
9717#else //QT_NO_IM
9718 return 0;
9719#endif //QT_NO_IM
9720}
9721
9722void QWidget::setInputMethodHints(Qt::InputMethodHints hints)
9723{
9724#ifndef QT_NO_IM
9725 Q_D(QWidget);
9726 if (d->imHints == hints)
9727 return;
9728 d->imHints = hints;
9729 if (this == QGuiApplication::focusObject())
9730 QGuiApplication::inputMethod()->update(queries: Qt::ImHints);
9731#else
9732 Q_UNUSED(hints);
9733#endif //QT_NO_IM
9734}
9735
9736
9737#if QT_CONFIG(draganddrop)
9738
9739/*!
9740 \fn void QWidget::dragEnterEvent(QDragEnterEvent *event)
9741
9742 This event handler is called when a drag is in progress and the
9743 mouse enters this widget. The event is passed in the \a event parameter.
9744
9745 If the event is ignored, the widget won't receive any \l{dragMoveEvent()}{drag
9746 move events}.
9747
9748 See the \l{dnd.html}{Drag-and-drop documentation} for an
9749 overview of how to provide drag-and-drop in your application.
9750
9751 \sa QDrag, QDragEnterEvent
9752*/
9753void QWidget::dragEnterEvent(QDragEnterEvent *)
9754{
9755}
9756
9757/*!
9758 \fn void QWidget::dragMoveEvent(QDragMoveEvent *event)
9759
9760 This event handler is called if a drag is in progress, and when
9761 any of the following conditions occur: the cursor enters this widget,
9762 the cursor moves within this widget, or a modifier key is pressed on
9763 the keyboard while this widget has the focus. The event is passed
9764 in the \a event parameter.
9765
9766 See the \l{dnd.html}{Drag-and-drop documentation} for an
9767 overview of how to provide drag-and-drop in your application.
9768
9769 \sa QDrag, QDragMoveEvent
9770*/
9771void QWidget::dragMoveEvent(QDragMoveEvent *)
9772{
9773}
9774
9775/*!
9776 \fn void QWidget::dragLeaveEvent(QDragLeaveEvent *event)
9777
9778 This event handler is called when a drag is in progress and the
9779 mouse leaves this widget. The event is passed in the \a event
9780 parameter.
9781
9782 See the \l{dnd.html}{Drag-and-drop documentation} for an
9783 overview of how to provide drag-and-drop in your application.
9784
9785 \sa QDrag, QDragLeaveEvent
9786*/
9787void QWidget::dragLeaveEvent(QDragLeaveEvent *)
9788{
9789}
9790
9791/*!
9792 \fn void QWidget::dropEvent(QDropEvent *event)
9793
9794 This event handler is called when the drag is dropped on this
9795 widget. The event is passed in the \a event parameter.
9796
9797 See the \l{dnd.html}{Drag-and-drop documentation} for an
9798 overview of how to provide drag-and-drop in your application.
9799
9800 \sa QDrag, QDropEvent
9801*/
9802void QWidget::dropEvent(QDropEvent *)
9803{
9804}
9805
9806#endif // QT_CONFIG(draganddrop)
9807
9808/*!
9809 \fn void QWidget::showEvent(QShowEvent *event)
9810
9811 This event handler can be reimplemented in a subclass to receive
9812 widget show events which are passed in the \a event parameter.
9813
9814 Non-spontaneous show events are sent to widgets immediately
9815 before they are shown. The spontaneous show events of windows are
9816 delivered afterwards.
9817
9818 Note: A widget receives spontaneous show and hide events when its
9819 mapping status is changed by the window system, e.g. a spontaneous
9820 hide event when the user minimizes the window, and a spontaneous
9821 show event when the window is restored again. After receiving a
9822 spontaneous hide event, a widget is still considered visible in
9823 the sense of isVisible().
9824
9825 \sa visible, event(), QShowEvent
9826*/
9827void QWidget::showEvent(QShowEvent *)
9828{
9829}
9830
9831/*!
9832 \fn void QWidget::hideEvent(QHideEvent *event)
9833
9834 This event handler can be reimplemented in a subclass to receive
9835 widget hide events. The event is passed in the \a event parameter.
9836
9837 Hide events are sent to widgets immediately after they have been
9838 hidden.
9839
9840 Note: A widget receives spontaneous show and hide events when its
9841 mapping status is changed by the window system, e.g. a spontaneous
9842 hide event when the user minimizes the window, and a spontaneous
9843 show event when the window is restored again. After receiving a
9844 spontaneous hide event, a widget is still considered visible in
9845 the sense of isVisible().
9846
9847 \sa visible, event(), QHideEvent
9848*/
9849void QWidget::hideEvent(QHideEvent *)
9850{
9851}
9852
9853/*!
9854 This special event handler can be reimplemented in a subclass to
9855 receive native platform events identified by \a eventType
9856 which are passed in the \a message parameter.
9857
9858 In your reimplementation of this function, if you want to stop the
9859 event being handled by Qt, return true and set \a result. The \a result
9860 parameter has meaning only on Windows. If you return false, this native
9861 event is passed back to Qt, which translates the event into a Qt event
9862 and sends it to the widget.
9863
9864 \note Events are only delivered to this event handler if the widget
9865 has a native window handle.
9866
9867 \note This function superseedes the event filter functions
9868 x11Event(), winEvent() and macEvent() of Qt 4.
9869
9870 \sa QAbstractNativeEventFilter
9871
9872 \table
9873 \header \li Platform \li Event Type Identifier \li Message Type \li Result Type
9874 \row \li Windows \li "windows_generic_MSG" \li MSG * \li LRESULT
9875 \row \li macOS \li "NSEvent" \li NSEvent * \li
9876 \row \li XCB \li "xcb_generic_event_t" \li xcb_generic_event_t * \li
9877 \endtable
9878*/
9879
9880#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
9881bool QWidget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
9882#else
9883bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
9884#endif
9885{
9886 Q_UNUSED(eventType);
9887 Q_UNUSED(message);
9888 Q_UNUSED(result);
9889 return false;
9890}
9891
9892/*!
9893 Ensures that the widget and its children have been polished by
9894 QStyle (i.e., have a proper font and palette).
9895
9896 QWidget calls this function after it has been fully constructed
9897 but before it is shown the very first time. You can call this
9898 function if you want to ensure that the widget is polished before
9899 doing an operation, e.g., the correct font size might be needed in
9900 the widget's sizeHint() reimplementation. Note that this function
9901 \e is called from the default implementation of sizeHint().
9902
9903 Polishing is useful for final initialization that must happen after
9904 all constructors (from base classes as well as from subclasses)
9905 have been called.
9906
9907 If you need to change some settings when a widget is polished,
9908 reimplement event() and handle the QEvent::Polish event type.
9909
9910 \b{Note:} The function is declared const so that it can be called from
9911 other const functions (e.g., sizeHint()).
9912
9913 \sa event()
9914*/
9915void QWidget::ensurePolished() const
9916{
9917 Q_D(const QWidget);
9918
9919 const QMetaObject *m = metaObject();
9920 if (m == d->polished)
9921 return;
9922 d->polished = m;
9923
9924 QEvent e(QEvent::Polish);
9925 QCoreApplication::sendEvent(receiver: const_cast<QWidget *>(this), event: &e);
9926
9927 // polish children after 'this'
9928 QList<QObject*> children = d->children;
9929 for (int i = 0; i < children.size(); ++i) {
9930 QObject *o = children.at(i);
9931 if(!o->isWidgetType())
9932 continue;
9933 if (QWidget *w = qobject_cast<QWidget *>(o))
9934 w->ensurePolished();
9935 }
9936
9937 if (d->parent && d->sendChildEvents) {
9938 QChildEvent e(QEvent::ChildPolished, const_cast<QWidget *>(this));
9939 QCoreApplication::sendEvent(receiver: d->parent, event: &e);
9940 }
9941}
9942
9943/*!
9944 Returns the mask currently set on a widget. If no mask is set the
9945 return value will be an empty region.
9946
9947 \sa setMask(), clearMask(), QRegion::isEmpty(), {Shaped Clock Example}
9948*/
9949QRegion QWidget::mask() const
9950{
9951 Q_D(const QWidget);
9952 return d->extra ? d->extra->mask : QRegion();
9953}
9954
9955/*!
9956 Returns the layout manager that is installed on this widget, or \nullptr
9957 if no layout manager is installed.
9958
9959 The layout manager sets the geometry of the widget's children
9960 that have been added to the layout.
9961
9962 \sa setLayout(), sizePolicy(), {Layout Management}
9963*/
9964QLayout *QWidget::layout() const
9965{
9966 return d_func()->layout;
9967}
9968
9969
9970/*!
9971 \fn void QWidget::setLayout(QLayout *layout)
9972
9973 Sets the layout manager for this widget to \a layout.
9974
9975 If there already is a layout manager installed on this widget,
9976 QWidget won't let you install another. You must first delete the
9977 existing layout manager (returned by layout()) before you can
9978 call setLayout() with the new layout.
9979
9980 If \a layout is the layout manager on a different widget, setLayout()
9981 will reparent the layout and make it the layout manager for this widget.
9982
9983 Example:
9984
9985 \snippet layouts/layouts.cpp 24
9986
9987 An alternative to calling this function is to pass this widget to
9988 the layout's constructor.
9989
9990 The QWidget will take ownership of \a layout.
9991
9992 \sa layout(), {Layout Management}
9993*/
9994
9995void QWidget::setLayout(QLayout *l)
9996{
9997 if (Q_UNLIKELY(!l)) {
9998 qWarning(msg: "QWidget::setLayout: Cannot set layout to 0");
9999 return;
10000 }
10001 if (layout()) {
10002 if (Q_UNLIKELY(layout() != l))
10003 qWarning(msg: "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", which already has a"
10004 " layout", l->objectName().toLocal8Bit().data(), metaObject()->className(),
10005 objectName().toLocal8Bit().data());
10006 return;
10007 }
10008
10009 QObject *oldParent = l->parent();
10010 if (oldParent && oldParent != this) {
10011 if (oldParent->isWidgetType()) {
10012 // Steal the layout off a widget parent. Takes effect when
10013 // morphing laid-out container widgets in Designer.
10014 QWidget *oldParentWidget = static_cast<QWidget *>(oldParent);
10015 oldParentWidget->takeLayout();
10016 } else {
10017 qWarning(msg: "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
10018 l->objectName().toLocal8Bit().data(), metaObject()->className(),
10019 objectName().toLocal8Bit().data());
10020 return;
10021 }
10022 }
10023
10024 Q_D(QWidget);
10025 l->d_func()->topLevel = true;
10026 d->layout = l;
10027 if (oldParent != this) {
10028 l->setParent(this);
10029 l->d_func()->reparentChildWidgets(mw: this);
10030 l->invalidate();
10031 }
10032
10033 if (isWindow() && d->maybeTopData())
10034 d->topData()->sizeAdjusted = false;
10035}
10036
10037/*!
10038 \fn QLayout *QWidget::takeLayout()
10039
10040 Remove the layout from the widget.
10041 \since 4.5
10042*/
10043
10044QLayout *QWidget::takeLayout()
10045{
10046 Q_D(QWidget);
10047 QLayout *l = layout();
10048 if (!l)
10049 return nullptr;
10050 d->layout = nullptr;
10051 l->setParent(nullptr);
10052 return l;
10053}
10054
10055/*!
10056 \property QWidget::sizePolicy
10057 \brief the default layout behavior of the widget
10058
10059 If there is a QLayout that manages this widget's children, the
10060 size policy specified by that layout is used. If there is no such
10061 QLayout, the result of this function is used.
10062
10063 The default policy is Preferred/Preferred, which means that the
10064 widget can be freely resized, but prefers to be the size
10065 sizeHint() returns. Button-like widgets set the size policy to
10066 specify that they may stretch horizontally, but are fixed
10067 vertically. The same applies to lineedit controls (such as
10068 QLineEdit, QSpinBox or an editable QComboBox) and other
10069 horizontally orientated widgets (such as QProgressBar).
10070 QToolButton's are normally square, so they allow growth in both
10071 directions. Widgets that support different directions (such as
10072 QSlider, QScrollBar or QHeader) specify stretching in the
10073 respective direction only. Widgets that can provide scroll bars
10074 (usually subclasses of QScrollArea) tend to specify that they can
10075 use additional space, and that they can make do with less than
10076 sizeHint().
10077
10078 \sa sizeHint(), QLayout, QSizePolicy, updateGeometry()
10079*/
10080QSizePolicy QWidget::sizePolicy() const
10081{
10082 Q_D(const QWidget);
10083 return d->size_policy;
10084}
10085
10086void QWidget::setSizePolicy(QSizePolicy policy)
10087{
10088 Q_D(QWidget);
10089 setAttribute(Qt::WA_WState_OwnSizePolicy);
10090 if (policy == d->size_policy)
10091 return;
10092
10093 if (d->size_policy.retainSizeWhenHidden() != policy.retainSizeWhenHidden())
10094 d->retainSizeWhenHiddenChanged = 1;
10095
10096 d->size_policy = policy;
10097
10098#if QT_CONFIG(graphicsview)
10099 if (const auto &extra = d->extra) {
10100 if (extra->proxyWidget)
10101 extra->proxyWidget->setSizePolicy(policy);
10102 }
10103#endif
10104
10105 updateGeometry();
10106 d->retainSizeWhenHiddenChanged = 0;
10107
10108 if (isWindow() && d->maybeTopData())
10109 d->topData()->sizeAdjusted = false;
10110}
10111
10112/*!
10113 \fn void QWidget::setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
10114 \overload
10115
10116 Sets the size policy of the widget to \a horizontal and \a
10117 vertical, with standard stretch and no height-for-width.
10118
10119 \sa QSizePolicy::QSizePolicy()
10120*/
10121
10122/*!
10123 Returns the preferred height for this widget, given the width \a w.
10124
10125 If this widget has a layout, the default implementation returns
10126 the layout's preferred height. if there is no layout, the default
10127 implementation returns -1 indicating that the preferred height
10128 does not depend on the width.
10129*/
10130
10131int QWidget::heightForWidth(int w) const
10132{
10133 if (layout() && layout()->hasHeightForWidth())
10134 return layout()->totalHeightForWidth(w);
10135 return -1;
10136}
10137
10138
10139/*!
10140 \since 5.0
10141
10142 Returns \c true if the widget's preferred height depends on its width; otherwise returns \c false.
10143*/
10144bool QWidget::hasHeightForWidth() const
10145{
10146 Q_D(const QWidget);
10147 return d->layout ? d->layout->hasHeightForWidth() : d->size_policy.hasHeightForWidth();
10148}
10149
10150/*!
10151 \fn QWidget *QWidget::childAt(int x, int y) const
10152
10153 Returns the visible child widget at the position (\a{x}, \a{y})
10154 in the widget's coordinate system. If there is no visible child
10155 widget at the specified position, the function returns \nullptr.
10156*/
10157
10158/*!
10159 \overload
10160
10161 Returns the visible child widget at point \a p in the widget's own
10162 coordinate system.
10163*/
10164
10165QWidget *QWidget::childAt(const QPoint &p) const
10166{
10167 return d_func()->childAt_helper(p, false);
10168}
10169
10170QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const
10171{
10172 if (children.isEmpty())
10173 return nullptr;
10174
10175 if (!pointInsideRectAndMask(p))
10176 return nullptr;
10177 return childAtRecursiveHelper(p, ignoreChildrenInDestructor);
10178}
10179
10180QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor) const
10181{
10182 for (int i = children.size() - 1; i >= 0; --i) {
10183 QWidget *child = qobject_cast<QWidget *>(o: children.at(i));
10184 if (!child || child->isWindow() || child->isHidden() || child->testAttribute(attribute: Qt::WA_TransparentForMouseEvents)
10185 || (ignoreChildrenInDestructor && child->data->in_destructor)) {
10186 continue;
10187 }
10188
10189 // Map the point 'p' from parent coordinates to child coordinates.
10190 QPoint childPoint = p;
10191 childPoint -= child->data->crect.topLeft();
10192
10193 // Check if the point hits the child.
10194 if (!child->d_func()->pointInsideRectAndMask(p: childPoint))
10195 continue;
10196
10197 // Do the same for the child's descendants.
10198 if (QWidget *w = child->d_func()->childAtRecursiveHelper(p: childPoint, ignoreChildrenInDestructor))
10199 return w;
10200
10201 // We have found our target; namely the child at position 'p'.
10202 return child;
10203 }
10204 return nullptr;
10205}
10206
10207void QWidgetPrivate::updateGeometry_helper(bool forceUpdate)
10208{
10209 Q_Q(QWidget);
10210 if (widgetItem)
10211 widgetItem->invalidateSizeCache();
10212 QWidget *parent;
10213 if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) {
10214 const int isHidden = q->isHidden() && !size_policy.retainSizeWhenHidden() && !retainSizeWhenHiddenChanged;
10215
10216 if (!q->isWindow() && !isHidden && (parent = q->parentWidget())) {
10217 if (parent->d_func()->layout)
10218 parent->d_func()->layout->invalidate();
10219 else if (parent->isVisible())
10220 QCoreApplication::postEvent(receiver: parent, event: new QEvent(QEvent::LayoutRequest));
10221 }
10222 }
10223}
10224
10225/*!
10226 Notifies the layout system that this widget has changed and may
10227 need to change geometry.
10228
10229 Call this function if the sizeHint() or sizePolicy() have changed.
10230
10231 For explicitly hidden widgets, updateGeometry() is a no-op. The
10232 layout system will be notified as soon as the widget is shown.
10233*/
10234
10235void QWidget::updateGeometry()
10236{
10237 Q_D(QWidget);
10238 d->updateGeometry_helper(forceUpdate: false);
10239}
10240
10241/*! \property QWidget::windowFlags
10242
10243 Window flags are a combination of a type (e.g. Qt::Dialog) and
10244 zero or more hints to the window system (e.g.
10245 Qt::FramelessWindowHint).
10246
10247 If the widget had type Qt::Widget or Qt::SubWindow and becomes a
10248 window (Qt::Window, Qt::Dialog, etc.), it is put at position (0,
10249 0) on the desktop. If the widget is a window and becomes a
10250 Qt::Widget or Qt::SubWindow, it is put at position (0, 0)
10251 relative to its parent widget.
10252
10253 \note This function calls setParent() when changing the flags for
10254 a window, causing the widget to be hidden. You must call show() to make
10255 the widget visible again..
10256
10257 \sa windowType(), setWindowFlag(), {Window Flags Example}
10258*/
10259void QWidget::setWindowFlags(Qt::WindowFlags flags)
10260{
10261 Q_D(QWidget);
10262 d->setWindowFlags(flags);
10263}
10264
10265/*!
10266 \since 5.9
10267
10268 Sets the window flag \a flag on this widget if \a on is true;
10269 otherwise clears the flag.
10270
10271 \sa setWindowFlags(), windowFlags(), windowType()
10272*/
10273void QWidget::setWindowFlag(Qt::WindowType flag, bool on)
10274{
10275 Q_D(QWidget);
10276 if (on)
10277 d->setWindowFlags(data->window_flags | flag);
10278 else
10279 d->setWindowFlags(data->window_flags & ~flag);
10280}
10281
10282/*! \internal
10283
10284 Implemented in QWidgetPrivate so that QMdiSubWindowPrivate can reimplement it.
10285*/
10286void QWidgetPrivate::setWindowFlags(Qt::WindowFlags flags)
10287{
10288 Q_Q(QWidget);
10289 if (q->data->window_flags == flags)
10290 return;
10291
10292 if ((q->data->window_flags | flags) & Qt::Window) {
10293 // the old type was a window and/or the new type is a window
10294 QPoint oldPos = q->pos();
10295 bool visible = q->isVisible();
10296 const bool windowFlagChanged = (q->data->window_flags ^ flags) & Qt::Window;
10297 q->setParent(parent: q->parentWidget(), f: flags);
10298
10299 // if both types are windows or neither of them are, we restore
10300 // the old position
10301 if (!windowFlagChanged && (visible || q->testAttribute(attribute: Qt::WA_Moved)))
10302 q->move(p: oldPos);
10303 // for backward-compatibility we change Qt::WA_QuitOnClose attribute value only when the window was recreated.
10304 adjustQuitOnCloseAttribute();
10305 } else {
10306 q->data->window_flags = flags;
10307 }
10308}
10309
10310/*!
10311 Sets the window flags for the widget to \a flags,
10312 \e without telling the window system.
10313
10314 \warning Do not call this function unless you really know what
10315 you're doing.
10316
10317 \sa setWindowFlags()
10318*/
10319void QWidget::overrideWindowFlags(Qt::WindowFlags flags)
10320{
10321 data->window_flags = flags;
10322}
10323
10324/*!
10325 \fn Qt::WindowType QWidget::windowType() const
10326
10327 Returns the window type of this widget. This is identical to
10328 windowFlags() & Qt::WindowType_Mask.
10329
10330 \sa windowFlags
10331*/
10332
10333/*!
10334 Sets the parent of the widget to \a parent, and resets the window
10335 flags. The widget is moved to position (0, 0) in its new parent.
10336
10337 If the new parent widget is in a different window, the
10338 reparented widget and its children are appended to the end of the
10339 \l{setFocusPolicy()}{tab chain} of the new parent
10340 widget, in the same internal order as before. If one of the moved
10341 widgets had keyboard focus, setParent() calls clearFocus() for that
10342 widget.
10343
10344 If the new parent widget is in the same window as the
10345 old parent, setting the parent doesn't change the tab order or
10346 keyboard focus.
10347
10348 If the "new" parent widget is the old parent widget, this function
10349 does nothing.
10350
10351 \note The widget becomes invisible as part of changing its parent,
10352 even if it was previously visible. You must call show() to make the
10353 widget visible again.
10354
10355 \warning It is very unlikely that you will ever need this
10356 function. If you have a widget that changes its content
10357 dynamically, it is far easier to use \l QStackedWidget.
10358
10359 \sa setWindowFlags()
10360*/
10361void QWidget::setParent(QWidget *parent)
10362{
10363 if (parent == parentWidget())
10364 return;
10365 setParent(parent: (QWidget*)parent, f: windowFlags() & ~Qt::WindowType_Mask);
10366}
10367
10368#ifndef QT_NO_OPENGL
10369static void sendWindowChangeToTextureChildrenRecursively(QWidget *widget)
10370{
10371 QWidgetPrivate *d = QWidgetPrivate::get(w: widget);
10372 if (d->renderToTexture) {
10373 QEvent e(QEvent::WindowChangeInternal);
10374 QCoreApplication::sendEvent(receiver: widget, event: &e);
10375 }
10376
10377 for (int i = 0; i < d->children.size(); ++i) {
10378 QWidget *w = qobject_cast<QWidget *>(o: d->children.at(i));
10379 if (w && !w->isWindow() && QWidgetPrivate::get(w)->textureChildSeen)
10380 sendWindowChangeToTextureChildrenRecursively(widget: w);
10381 }
10382}
10383#endif
10384
10385/*!
10386 \overload
10387
10388 This function also takes widget flags, \a f as an argument.
10389*/
10390
10391void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
10392{
10393 Q_D(QWidget);
10394 Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QWidget to itself");
10395#ifdef QT_DEBUG
10396 const auto checkForParentChildLoops = qScopeGuard(f: [&](){
10397 int depth = 0;
10398 auto p = parentWidget();
10399 while (p) {
10400 if (++depth == QObjectPrivate::CheckForParentChildLoopsWarnDepth) {
10401 qWarning(msg: "QWidget %p (class: '%s', object name: '%s') may have a loop in its parent-child chain; "
10402 "this is undefined behavior",
10403 this, metaObject()->className(), qPrintable(objectName()));
10404 }
10405 p = p->parentWidget();
10406 }
10407 });
10408#endif
10409
10410 bool resized = testAttribute(attribute: Qt::WA_Resized);
10411 bool wasCreated = testAttribute(attribute: Qt::WA_WState_Created);
10412 QWidget *oldtlw = window();
10413
10414 if (f & Qt::Window) // Frame geometry likely changes, refresh.
10415 d->data.fstrut_dirty = true;
10416
10417 QWidget *desktopWidget = nullptr;
10418 if (parent && parent->windowType() == Qt::Desktop)
10419 desktopWidget = parent;
10420 bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget;
10421
10422 if (newParent && parent && !desktopWidget) {
10423 if (testAttribute(attribute: Qt::WA_NativeWindow) && !QCoreApplication::testAttribute(attribute: Qt::AA_DontCreateNativeWidgetSiblings))
10424 parent->d_func()->enforceNativeChildren();
10425 else if (parent->d_func()->nativeChildrenForced() || parent->testAttribute(attribute: Qt::WA_PaintOnScreen))
10426 setAttribute(Qt::WA_NativeWindow);
10427 }
10428
10429 if (wasCreated) {
10430 if (!testAttribute(attribute: Qt::WA_WState_Hidden)) {
10431 hide();
10432 setAttribute(Qt::WA_WState_ExplicitShowHide, on: false);
10433 }
10434 if (newParent) {
10435 QEvent e(QEvent::ParentAboutToChange);
10436 QCoreApplication::sendEvent(receiver: this, event: &e);
10437 }
10438 }
10439 if (newParent && isAncestorOf(child: focusWidget()))
10440 focusWidget()->clearFocus();
10441
10442 d->setParent_sys(parent, f);
10443
10444 if (desktopWidget)
10445 parent = nullptr;
10446
10447#ifndef QT_NO_OPENGL
10448 if (d->textureChildSeen && parent) {
10449 // set the textureChildSeen flag up the whole parent chain
10450 QWidgetPrivate::get(w: parent)->setTextureChildSeen();
10451 }
10452#endif
10453
10454 if (QWidgetRepaintManager *oldPaintManager = oldtlw->d_func()->maybeRepaintManager()) {
10455 if (newParent)
10456 oldPaintManager->removeDirtyWidget(w: this);
10457 // Move the widget and all its static children from
10458 // the old backing store to the new one.
10459 oldPaintManager->moveStaticWidgets(reparented: this);
10460 }
10461
10462 // ### fixme: Qt 6: Remove AA_ImmediateWidgetCreation.
10463 if (QApplicationPrivate::testAttribute(flag: Qt::AA_ImmediateWidgetCreation) && !testAttribute(attribute: Qt::WA_WState_Created))
10464 create();
10465
10466 d->reparentFocusWidgets(oldtlw);
10467 setAttribute(Qt::WA_Resized, on: resized);
10468
10469 const bool useStyleSheetPropagationInWidgetStyles =
10470 QCoreApplication::testAttribute(attribute: Qt::AA_UseStyleSheetPropagationInWidgetStyles);
10471
10472 if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(attribute: Qt::WA_StyleSheet)
10473 && (!parent || !parent->testAttribute(attribute: Qt::WA_StyleSheet))) {
10474 // if the parent has a font set or inherited, then propagate the mask to the new child
10475 if (parent) {
10476 const auto pd = parent->d_func();
10477 d->inheritedFontResolveMask = pd->directFontResolveMask | pd->inheritedFontResolveMask;
10478 d->inheritedPaletteResolveMask = pd->directPaletteResolveMask | pd->inheritedPaletteResolveMask;
10479 }
10480 d->resolveFont();
10481 d->resolvePalette();
10482 }
10483 d->resolveLayoutDirection();
10484 d->resolveLocale();
10485
10486 // Note: GL widgets under WGL or EGL will always need a ParentChange
10487 // event to handle recreation/rebinding of the GL context, hence the
10488 // (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all
10489 // platforms).
10490 if (newParent
10491#if defined(QT_OPENGL_ES)
10492 || (f & Qt::MSWindowsOwnDC)
10493#endif
10494 ) {
10495 // propagate enabled updates enabled state to non-windows
10496 if (!isWindow()) {
10497 if (!testAttribute(attribute: Qt::WA_ForceDisabled))
10498 d->setEnabled_helper(parent ? parent->isEnabled() : true);
10499 if (!testAttribute(attribute: Qt::WA_ForceUpdatesDisabled))
10500 d->setUpdatesEnabled_helper(parent ? parent->updatesEnabled() : true);
10501 }
10502 d->inheritStyle();
10503
10504 // send and post remaining QObject events
10505 if (parent && d->sendChildEvents) {
10506 QChildEvent e(QEvent::ChildAdded, this);
10507 QCoreApplication::sendEvent(receiver: parent, event: &e);
10508 }
10509
10510 if (parent && d->sendChildEvents && d->polished) {
10511 QChildEvent e(QEvent::ChildPolished, this);
10512 QCoreApplication::sendEvent(receiver: parent, event: &e);
10513 }
10514
10515 QEvent e(QEvent::ParentChange);
10516 QCoreApplication::sendEvent(receiver: this, event: &e);
10517 }
10518#ifndef QT_NO_OPENGL
10519 //renderToTexture widgets also need to know when their top-level window changes
10520 if (d->textureChildSeen && oldtlw != window()) {
10521 sendWindowChangeToTextureChildrenRecursively(widget: this);
10522 }
10523#endif
10524
10525 if (!wasCreated) {
10526 if (isWindow() || parentWidget()->isVisible())
10527 setAttribute(Qt::WA_WState_Hidden, on: true);
10528 else if (!testAttribute(attribute: Qt::WA_WState_ExplicitShowHide))
10529 setAttribute(Qt::WA_WState_Hidden, on: false);
10530 }
10531
10532 d->updateIsOpaque();
10533
10534#if QT_CONFIG(graphicsview)
10535 // Embed the widget into a proxy if the parent is embedded.
10536 // ### Doesn't handle reparenting out of an embedded widget.
10537 if (oldtlw->graphicsProxyWidget()) {
10538 if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(origin: oldtlw))
10539 ancestorProxy->d_func()->unembedSubWindow(this);
10540 }
10541 if (isWindow() && parent && !graphicsProxyWidget() && !bypassGraphicsProxyWidget(p: this)) {
10542 if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(origin: parent))
10543 ancestorProxy->d_func()->embedSubWindow(this);
10544 }
10545#endif
10546
10547 if (d->extra && d->extra->hasWindowContainer)
10548 QWindowContainer::parentWasChanged(parent: this);
10549}
10550
10551void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
10552{
10553 Q_Q(QWidget);
10554
10555 Qt::WindowFlags oldFlags = data.window_flags;
10556 bool wasCreated = q->testAttribute(attribute: Qt::WA_WState_Created);
10557
10558 int targetScreen = -1;
10559 // Handle a request to move the widget to a particular screen
10560 if (newparent && newparent->windowType() == Qt::Desktop) {
10561 // make sure the widget is created on the same screen as the
10562 // programmer specified desktop widget
10563 const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(object: newparent);
10564 targetScreen = sw ? sw->screenNumber() : 0;
10565 newparent = nullptr;
10566 }
10567
10568 setWinId(0);
10569
10570 if (parent != newparent) {
10571 QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
10572 if (q->windowHandle()) {
10573 q->windowHandle()->setFlags(f);
10574 QWidget *parentWithWindow =
10575 newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : nullptr;
10576 if (parentWithWindow) {
10577 QWidget *topLevel = parentWithWindow->window();
10578 if ((f & Qt::Window) && topLevel && topLevel->windowHandle()) {
10579 q->windowHandle()->setTransientParent(topLevel->windowHandle());
10580 q->windowHandle()->setParent(nullptr);
10581 } else {
10582 q->windowHandle()->setTransientParent(nullptr);
10583 q->windowHandle()->setParent(parentWithWindow->windowHandle());
10584 }
10585 } else {
10586 q->windowHandle()->setTransientParent(nullptr);
10587 q->windowHandle()->setParent(nullptr);
10588 }
10589 }
10590 }
10591
10592 if (!newparent) {
10593 f |= Qt::Window;
10594 if (targetScreen == -1) {
10595 if (parent)
10596 targetScreen = QDesktopWidgetPrivate::screenNumber(widget: q->parentWidget()->window());
10597 }
10598 }
10599
10600 bool explicitlyHidden = q->testAttribute(attribute: Qt::WA_WState_Hidden) && q->testAttribute(attribute: Qt::WA_WState_ExplicitShowHide);
10601
10602 // Reparenting toplevel to child
10603 if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(attribute: Qt::WA_NativeWindow)) {
10604 if (extra && extra->hasWindowContainer)
10605 QWindowContainer::toplevelAboutToBeDestroyed(parent: q);
10606
10607 QWindow *newParentWindow = newparent->windowHandle();
10608 if (!newParentWindow)
10609 if (QWidget *npw = newparent->nativeParentWidget())
10610 newParentWindow = npw->windowHandle();
10611
10612 Q_FOREACH (QObject *child, q->windowHandle()->children()) {
10613 QWindow *childWindow = qobject_cast<QWindow *>(o: child);
10614 if (!childWindow)
10615 continue;
10616
10617 QWidgetWindow *childWW = qobject_cast<QWidgetWindow *>(object: childWindow);
10618 QWidget *childWidget = childWW ? childWW->widget() : nullptr;
10619 if (!childWW || (childWidget && childWidget->testAttribute(attribute: Qt::WA_NativeWindow)))
10620 childWindow->setParent(newParentWindow);
10621 }
10622 q->destroy();
10623 }
10624
10625 adjustFlags(flags&: f, w: q);
10626 data.window_flags = f;
10627 q->setAttribute(Qt::WA_WState_Created, on: false);
10628 q->setAttribute(Qt::WA_WState_Visible, on: false);
10629 q->setAttribute(Qt::WA_WState_Hidden, on: false);
10630
10631 if (newparent && wasCreated && (q->testAttribute(attribute: Qt::WA_NativeWindow) || (f & Qt::Window)))
10632 q->createWinId();
10633
10634 if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
10635 q->setAttribute(Qt::WA_WState_Hidden);
10636 q->setAttribute(Qt::WA_WState_ExplicitShowHide, on: explicitlyHidden);
10637
10638 // move the window to the selected screen
10639 if (!newparent && targetScreen != -1) {
10640 // only if it is already created
10641 if (q->testAttribute(attribute: Qt::WA_WState_Created))
10642 q->windowHandle()->setScreen(QGuiApplication::screens().value(i: targetScreen, defaultValue: 0));
10643 else
10644 topData()->initialScreenIndex = targetScreen;
10645 }
10646}
10647
10648/*!
10649 Scrolls the widget including its children \a dx pixels to the
10650 right and \a dy downward. Both \a dx and \a dy may be negative.
10651
10652 After scrolling, the widgets will receive paint events for
10653 the areas that need to be repainted. For widgets that Qt knows to
10654 be opaque, this is only the newly exposed parts.
10655 For example, if an opaque widget is scrolled 8 pixels to the left,
10656 only an 8-pixel wide stripe at the right edge needs updating.
10657
10658 Since widgets propagate the contents of their parents by default,
10659 you need to set the \l autoFillBackground property, or use
10660 setAttribute() to set the Qt::WA_OpaquePaintEvent attribute, to make
10661 a widget opaque.
10662
10663 For widgets that use contents propagation, a scroll will cause an
10664 update of the entire scroll area.
10665
10666 \sa {Transparency and Double Buffering}
10667*/
10668
10669void QWidget::scroll(int dx, int dy)
10670{
10671 if ((!updatesEnabled() && children().size() == 0) || !isVisible())
10672 return;
10673 if (dx == 0 && dy == 0)
10674 return;
10675 Q_D(QWidget);
10676#if QT_CONFIG(graphicsview)
10677 if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(origin: this)) {
10678 // Graphics View maintains its own dirty region as a list of rects;
10679 // until we can connect item updates directly to the view, we must
10680 // separately add a translated dirty region.
10681 for (const QRect &rect : d->dirty)
10682 proxy->update(rect: rect.translated(dx, dy));
10683 proxy->scroll(dx, dy, rect: proxy->subWidgetRect(widget: this));
10684 return;
10685 }
10686#endif
10687 d->setDirtyOpaqueRegion();
10688 d->scroll_sys(dx, dy);
10689}
10690
10691void QWidgetPrivate::scroll_sys(int dx, int dy)
10692{
10693 Q_Q(QWidget);
10694 scrollChildren(dx, dy);
10695 scrollRect(q->rect(), dx, dy);
10696}
10697
10698/*!
10699 \overload
10700
10701 This version only scrolls \a r and does not move the children of
10702 the widget.
10703
10704 If \a r is empty or invalid, the result is undefined.
10705
10706 \sa QScrollArea
10707*/
10708void QWidget::scroll(int dx, int dy, const QRect &r)
10709{
10710
10711 if ((!updatesEnabled() && children().size() == 0) || !isVisible())
10712 return;
10713 if (dx == 0 && dy == 0)
10714 return;
10715 Q_D(QWidget);
10716#if QT_CONFIG(graphicsview)
10717 if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(origin: this)) {
10718 // Graphics View maintains its own dirty region as a list of rects;
10719 // until we can connect item updates directly to the view, we must
10720 // separately add a translated dirty region.
10721 if (!d->dirty.isEmpty()) {
10722 for (const QRect &rect : d->dirty.translated(dx, dy) & r)
10723 proxy->update(rect);
10724 }
10725 proxy->scroll(dx, dy, rect: r.translated(p: proxy->subWidgetRect(widget: this).topLeft().toPoint()));
10726 return;
10727 }
10728#endif
10729 d->scroll_sys(dx, dy, r);
10730}
10731
10732void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
10733{
10734 scrollRect(r, dx, dy);
10735}
10736
10737/*!
10738 Repaints the widget directly by calling paintEvent() immediately,
10739 unless updates are disabled or the widget is hidden.
10740
10741 We suggest only using repaint() if you need an immediate repaint,
10742 for example during animation. In almost all circumstances update()
10743 is better, as it permits Qt to optimize for speed and minimize
10744 flicker.
10745
10746 \warning If you call repaint() in a function which may itself be
10747 called from paintEvent(), you may get infinite recursion. The
10748 update() function never causes recursion.
10749
10750 \sa update(), paintEvent(), setUpdatesEnabled()
10751*/
10752
10753void QWidget::repaint()
10754{
10755 repaint(rect());
10756}
10757
10758/*! \overload
10759
10760 This version repaints a rectangle (\a x, \a y, \a w, \a h) inside
10761 the widget.
10762
10763 If \a w is negative, it is replaced with \c{width() - x}, and if
10764 \a h is negative, it is replaced width \c{height() - y}.
10765*/
10766void QWidget::repaint(int x, int y, int w, int h)
10767{
10768 if (x > data->crect.width() || y > data->crect.height())
10769 return;
10770
10771 if (w < 0)
10772 w = data->crect.width() - x;
10773 if (h < 0)
10774 h = data->crect.height() - y;
10775
10776 repaint(QRect(x, y, w, h));
10777}
10778
10779/*! \overload
10780
10781 This version repaints a rectangle \a rect inside the widget.
10782*/
10783void QWidget::repaint(const QRect &rect)
10784{
10785 Q_D(QWidget);
10786 d->repaint(t: rect);
10787}
10788
10789/*!
10790 \overload
10791
10792 This version repaints a region \a rgn inside the widget.
10793*/
10794void QWidget::repaint(const QRegion &rgn)
10795{
10796 Q_D(QWidget);
10797 d->repaint(t: rgn);
10798}
10799
10800template <typename T>
10801void QWidgetPrivate::repaint(T r)
10802{
10803 Q_Q(QWidget);
10804
10805 if (!q->isVisible() || !q->updatesEnabled() || r.isEmpty())
10806 return;
10807
10808 QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
10809 if (tlwExtra && tlwExtra->backingStore)
10810 tlwExtra->repaintManager->markDirty(r, q, QWidgetRepaintManager::UpdateNow);
10811}
10812
10813/*!
10814 Updates the widget unless updates are disabled or the widget is
10815 hidden.
10816
10817 This function does not cause an immediate repaint; instead it
10818 schedules a paint event for processing when Qt returns to the main
10819 event loop. This permits Qt to optimize for more speed and less
10820 flicker than a call to repaint() does.
10821
10822 Calling update() several times normally results in just one
10823 paintEvent() call.
10824
10825 Qt normally erases the widget's area before the paintEvent() call.
10826 If the Qt::WA_OpaquePaintEvent widget attribute is set, the widget is
10827 responsible for painting all its pixels with an opaque color.
10828
10829 \sa repaint(), paintEvent(), setUpdatesEnabled(), {Analog Clock Example}
10830*/
10831void QWidget::update()
10832{
10833 update(rect());
10834}
10835
10836/*! \fn void QWidget::update(int x, int y, int w, int h)
10837 \overload
10838
10839 This version updates a rectangle (\a x, \a y, \a w, \a h) inside
10840 the widget.
10841*/
10842
10843/*!
10844 \overload
10845
10846 This version updates a rectangle \a rect inside the widget.
10847*/
10848void QWidget::update(const QRect &rect)
10849{
10850 Q_D(QWidget);
10851 d->update(t: rect);
10852}
10853
10854/*!
10855 \overload
10856
10857 This version repaints a region \a rgn inside the widget.
10858*/
10859void QWidget::update(const QRegion &rgn)
10860{
10861 Q_D(QWidget);
10862 d->update(t: rgn);
10863}
10864
10865template <typename T>
10866void QWidgetPrivate::update(T r)
10867{
10868 Q_Q(QWidget);
10869
10870 if (!q->isVisible() || !q->updatesEnabled())
10871 return;
10872
10873 T clipped = r & q->rect();
10874
10875 if (clipped.isEmpty())
10876 return;
10877
10878 if (q->testAttribute(attribute: Qt::WA_WState_InPaintEvent)) {
10879 QCoreApplication::postEvent(receiver: q, event: new QUpdateLaterEvent(clipped));
10880 return;
10881 }
10882
10883 QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
10884 if (tlwExtra && tlwExtra->backingStore)
10885 tlwExtra->repaintManager->markDirty(clipped, q);
10886}
10887
10888 /*!
10889 \internal
10890
10891 This just sets the corresponding attribute bit to 1 or 0
10892 */
10893static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data,
10894 QWidgetPrivate *d)
10895{
10896 if (attribute < int(8*sizeof(uint))) {
10897 if (on)
10898 data->widget_attributes |= (1<<attribute);
10899 else
10900 data->widget_attributes &= ~(1<<attribute);
10901 } else {
10902 const int x = attribute - 8*sizeof(uint);
10903 const int int_off = x / (8*sizeof(uint));
10904 if (on)
10905 d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint))));
10906 else
10907 d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint))));
10908 }
10909}
10910
10911#ifdef Q_OS_MAC
10912void QWidgetPrivate::macUpdateSizeAttribute()
10913{
10914 Q_Q(QWidget);
10915 QEvent event(QEvent::MacSizeChange);
10916 QCoreApplication::sendEvent(q, &event);
10917 for (int i = 0; i < children.size(); ++i) {
10918 QWidget *w = qobject_cast<QWidget *>(children.at(i));
10919 if (w && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
10920 && !w->testAttribute(Qt::WA_MacMiniSize) // no attribute set? inherit from parent
10921 && !w->testAttribute(Qt::WA_MacSmallSize)
10922 && !w->testAttribute(Qt::WA_MacNormalSize))
10923 w->d_func()->macUpdateSizeAttribute();
10924 }
10925 resolveFont();
10926}
10927#endif
10928
10929/*!
10930 Sets the attribute \a attribute on this widget if \a on is true;
10931 otherwise clears the attribute.
10932
10933 \sa testAttribute()
10934*/
10935void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
10936{
10937 if (testAttribute(attribute) == on)
10938 return;
10939
10940 Q_D(QWidget);
10941 Q_STATIC_ASSERT_X(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8),
10942 "QWidget::setAttribute(WidgetAttribute, bool): "
10943 "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
10944#ifdef Q_OS_WIN
10945 // ### Don't use PaintOnScreen+paintEngine() to do native painting in some future release
10946 if (attribute == Qt::WA_PaintOnScreen && on && windowType() != Qt::Desktop && !inherits("QGLWidget")) {
10947 // see ::paintEngine for details
10948 paintEngine();
10949 if (d->noPaintOnScreen)
10950 return;
10951 }
10952#endif
10953
10954 // Don't set WA_NativeWindow on platforms that don't support it -- except for QGLWidget, which depends on it
10955 if (attribute == Qt::WA_NativeWindow && !d->mustHaveWindowHandle) {
10956 QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
10957 if (!platformIntegration->hasCapability(cap: QPlatformIntegration::NativeWidgets))
10958 return;
10959 }
10960
10961 setAttribute_internal(attribute, on, data, d);
10962
10963 switch (attribute) {
10964
10965#if QT_CONFIG(draganddrop)
10966 case Qt::WA_AcceptDrops: {
10967 if (on && !testAttribute(attribute: Qt::WA_DropSiteRegistered))
10968 setAttribute(attribute: Qt::WA_DropSiteRegistered, on: true);
10969 else if (!on && (isWindow() || !parentWidget() || !parentWidget()->testAttribute(attribute: Qt::WA_DropSiteRegistered)))
10970 setAttribute(attribute: Qt::WA_DropSiteRegistered, on: false);
10971 QEvent e(QEvent::AcceptDropsChange);
10972 QCoreApplication::sendEvent(receiver: this, event: &e);
10973 break;
10974 }
10975 case Qt::WA_DropSiteRegistered: {
10976 for (int i = 0; i < d->children.size(); ++i) {
10977 QWidget *w = qobject_cast<QWidget *>(o: d->children.at(i));
10978 if (w && !w->isWindow() && !w->testAttribute(attribute: Qt::WA_AcceptDrops) && w->testAttribute(attribute: Qt::WA_DropSiteRegistered) != on)
10979 w->setAttribute(attribute: Qt::WA_DropSiteRegistered, on);
10980 }
10981 break;
10982 }
10983#endif
10984
10985 case Qt::WA_NoChildEventsForParent:
10986 d->sendChildEvents = !on;
10987 break;
10988 case Qt::WA_NoChildEventsFromChildren:
10989 d->receiveChildEvents = !on;
10990 break;
10991 case Qt::WA_MacNormalSize:
10992 case Qt::WA_MacSmallSize:
10993 case Qt::WA_MacMiniSize:
10994#ifdef Q_OS_MAC
10995 {
10996 // We can only have one of these set at a time
10997 const Qt::WidgetAttribute MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize,
10998 Qt::WA_MacMiniSize };
10999 for (int i = 0; i < 3; ++i) {
11000 if (MacSizes[i] != attribute)
11001 setAttribute_internal(MacSizes[i], false, data, d);
11002 }
11003 d->macUpdateSizeAttribute();
11004 }
11005#endif
11006 break;
11007 case Qt::WA_ShowModal:
11008 if (!on) {
11009 // reset modality type to NonModal when clearing WA_ShowModal
11010 data->window_modality = Qt::NonModal;
11011 } else if (data->window_modality == Qt::NonModal) {
11012 // determine the modality type if it hasn't been set prior
11013 // to setting WA_ShowModal. set the default to WindowModal
11014 // if we are the child of a group leader; otherwise use
11015 // ApplicationModal.
11016 QWidget *w = parentWidget();
11017 if (w)
11018 w = w->window();
11019 while (w && !w->testAttribute(attribute: Qt::WA_GroupLeader)) {
11020 w = w->parentWidget();
11021 if (w)
11022 w = w->window();
11023 }
11024 data->window_modality = (w && w->testAttribute(attribute: Qt::WA_GroupLeader))
11025 ? Qt::WindowModal
11026 : Qt::ApplicationModal;
11027 // Some window managers do not allow us to enter modality after the
11028 // window is visible.The window must be hidden before changing the
11029 // windowModality property and then reshown.
11030 }
11031 if (testAttribute(attribute: Qt::WA_WState_Created)) {
11032 // don't call setModal_sys() before create()
11033 d->setModal_sys();
11034 }
11035 break;
11036 case Qt::WA_MouseTracking: {
11037 QEvent e(QEvent::MouseTrackingChange);
11038 QCoreApplication::sendEvent(receiver: this, event: &e);
11039 break; }
11040 case Qt::WA_TabletTracking: {
11041 QEvent e(QEvent::TabletTrackingChange);
11042 QCoreApplication::sendEvent(receiver: this, event: &e);
11043 break; }
11044 case Qt::WA_NativeWindow: {
11045 d->createTLExtra();
11046 if (on)
11047 d->createTLSysExtra();
11048#ifndef QT_NO_IM
11049 QWidget *focusWidget = d->effectiveFocusWidget();
11050 if (on && !internalWinId() && this == QGuiApplication::focusObject()
11051 && focusWidget->testAttribute(attribute: Qt::WA_InputMethodEnabled)) {
11052 QGuiApplication::inputMethod()->commit();
11053 QGuiApplication::inputMethod()->update(queries: Qt::ImEnabled);
11054 }
11055 if (!QCoreApplication::testAttribute(attribute: Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget())
11056 parentWidget()->d_func()->enforceNativeChildren();
11057 if (on && !internalWinId() && testAttribute(attribute: Qt::WA_WState_Created))
11058 d->createWinId();
11059 if (isEnabled() && focusWidget->isEnabled() && this == QGuiApplication::focusObject()
11060 && focusWidget->testAttribute(attribute: Qt::WA_InputMethodEnabled)) {
11061 QGuiApplication::inputMethod()->update(queries: Qt::ImEnabled);
11062 }
11063#endif //QT_NO_IM
11064 break;
11065 }
11066 case Qt::WA_PaintOnScreen:
11067 d->updateIsOpaque();
11068 Q_FALLTHROUGH();
11069 case Qt::WA_OpaquePaintEvent:
11070 d->updateIsOpaque();
11071 break;
11072 case Qt::WA_NoSystemBackground:
11073 d->updateIsOpaque();
11074 Q_FALLTHROUGH();
11075 case Qt::WA_UpdatesDisabled:
11076 d->updateSystemBackground();
11077 break;
11078 case Qt::WA_TransparentForMouseEvents:
11079 break;
11080 case Qt::WA_InputMethodEnabled: {
11081#ifndef QT_NO_IM
11082 if (QGuiApplication::focusObject() == this) {
11083 if (!on)
11084 QGuiApplication::inputMethod()->commit();
11085 QGuiApplication::inputMethod()->update(queries: Qt::ImEnabled);
11086 }
11087#endif //QT_NO_IM
11088 break;
11089 }
11090 case Qt::WA_WindowPropagation:
11091 d->resolvePalette();
11092 d->resolveFont();
11093 d->resolveLocale();
11094 break;
11095 case Qt::WA_DontShowOnScreen: {
11096 if (on && isVisible()) {
11097 // Make sure we keep the current state and only hide the widget
11098 // from the desktop. show_sys will only update platform specific
11099 // attributes at this point.
11100 d->hide_sys();
11101 d->show_sys();
11102 }
11103 break;
11104 }
11105
11106 case Qt::WA_X11NetWmWindowTypeDesktop:
11107 case Qt::WA_X11NetWmWindowTypeDock:
11108 case Qt::WA_X11NetWmWindowTypeToolBar:
11109 case Qt::WA_X11NetWmWindowTypeMenu:
11110 case Qt::WA_X11NetWmWindowTypeUtility:
11111 case Qt::WA_X11NetWmWindowTypeSplash:
11112 case Qt::WA_X11NetWmWindowTypeDialog:
11113 case Qt::WA_X11NetWmWindowTypeDropDownMenu:
11114 case Qt::WA_X11NetWmWindowTypePopupMenu:
11115 case Qt::WA_X11NetWmWindowTypeToolTip:
11116 case Qt::WA_X11NetWmWindowTypeNotification:
11117 case Qt::WA_X11NetWmWindowTypeCombo:
11118 case Qt::WA_X11NetWmWindowTypeDND:
11119 d->setNetWmWindowTypes();
11120 break;
11121
11122 case Qt::WA_StaticContents:
11123 if (QWidgetRepaintManager *repaintManager = d->maybeRepaintManager()) {
11124 if (on)
11125 repaintManager->addStaticWidget(widget: this);
11126 else
11127 repaintManager->removeStaticWidget(widget: this);
11128 }
11129 break;
11130 case Qt::WA_TranslucentBackground:
11131 if (on)
11132 setAttribute(attribute: Qt::WA_NoSystemBackground);
11133 d->updateIsTranslucent();
11134
11135 break;
11136 case Qt::WA_AcceptTouchEvents:
11137 break;
11138 default:
11139 break;
11140 }
11141}
11142
11143/*! \fn bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const
11144
11145 Returns \c true if attribute \a attribute is set on this widget;
11146 otherwise returns \c false.
11147
11148 \sa setAttribute()
11149 */
11150bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const
11151{
11152 Q_D(const QWidget);
11153 const int x = attribute - 8*sizeof(uint);
11154 const int int_off = x / (8*sizeof(uint));
11155 return (d->high_attributes[int_off] & (1<<(x-(int_off*8*sizeof(uint)))));
11156}
11157
11158/*!
11159 \property QWidget::windowOpacity
11160
11161 \brief The level of opacity for the window.
11162
11163 The valid range of opacity is from 1.0 (completely opaque) to
11164 0.0 (completely transparent).
11165
11166 By default the value of this property is 1.0.
11167
11168 This feature is available on Embedded Linux, \macos, Windows,
11169 and X11 platforms that support the Composite extension.
11170
11171 \note On X11 you need to have a composite manager running,
11172 and the X11 specific _NET_WM_WINDOW_OPACITY atom needs to be
11173 supported by the window manager you are using.
11174
11175 \warning Changing this property from opaque to transparent might issue a
11176 paint event that needs to be processed before the window is displayed
11177 correctly. This affects mainly the use of QScreen::grabWindow(). Also note
11178 that semi-transparent windows update and resize significantly slower than
11179 opaque windows.
11180
11181 \sa setMask()
11182*/
11183qreal QWidget::windowOpacity() const
11184{
11185 Q_D(const QWidget);
11186 return (isWindow() && d->maybeTopData()) ? d->maybeTopData()->opacity / 255. : 1.0;
11187}
11188
11189void QWidget::setWindowOpacity(qreal opacity)
11190{
11191 Q_D(QWidget);
11192 if (!isWindow())
11193 return;
11194
11195 opacity = qBound(min: qreal(0.0), val: opacity, max: qreal(1.0));
11196 QTLWExtra *extra = d->topData();
11197 extra->opacity = uint(opacity * 255);
11198 setAttribute(attribute: Qt::WA_WState_WindowOpacitySet);
11199 d->setWindowOpacity_sys(opacity);
11200
11201 if (!testAttribute(attribute: Qt::WA_WState_Created))
11202 return;
11203
11204#if QT_CONFIG(graphicsview)
11205 if (QGraphicsProxyWidget *proxy = graphicsProxyWidget()) {
11206 // Avoid invalidating the cache if set.
11207 if (proxy->cacheMode() == QGraphicsItem::NoCache)
11208 proxy->update();
11209 else if (QGraphicsScene *scene = proxy->scene())
11210 scene->update(rect: proxy->sceneBoundingRect());
11211 return;
11212 }
11213#endif
11214}
11215
11216void QWidgetPrivate::setWindowOpacity_sys(qreal level)
11217{
11218 Q_Q(QWidget);
11219 if (q->windowHandle())
11220 q->windowHandle()->setOpacity(level);
11221}
11222
11223/*!
11224 \property QWidget::windowModified
11225 \brief whether the document shown in the window has unsaved changes
11226
11227 A modified window is a window whose content has changed but has
11228 not been saved to disk. This flag will have different effects
11229 varied by the platform. On \macos the close button will have a
11230 modified look; on other platforms, the window title will have an
11231 '*' (asterisk).
11232
11233 The window title must contain a "[*]" placeholder, which
11234 indicates where the '*' should appear. Normally, it should appear
11235 right after the file name (e.g., "document1.txt[*] - Text
11236 Editor"). If the window isn't modified, the placeholder is simply
11237 removed.
11238
11239 Note that if a widget is set as modified, all its ancestors will
11240 also be set as modified. However, if you call \c
11241 {setWindowModified(false)} on a widget, this will not propagate to
11242 its parent because other children of the parent might have been
11243 modified.
11244
11245 \sa windowTitle, {Application Example}, {SDI Example}, {MDI Example}
11246*/
11247bool QWidget::isWindowModified() const
11248{
11249 return testAttribute(attribute: Qt::WA_WindowModified);
11250}
11251
11252void QWidget::setWindowModified(bool mod)
11253{
11254 Q_D(QWidget);
11255 setAttribute(attribute: Qt::WA_WindowModified, on: mod);
11256
11257 d->setWindowModified_helper();
11258
11259 QEvent e(QEvent::ModifiedChange);
11260 QCoreApplication::sendEvent(receiver: this, event: &e);
11261}
11262
11263void QWidgetPrivate::setWindowModified_helper()
11264{
11265 Q_Q(QWidget);
11266 QWindow *window = q->windowHandle();
11267 if (!window)
11268 return;
11269 QPlatformWindow *platformWindow = window->handle();
11270 if (!platformWindow)
11271 return;
11272 bool on = q->testAttribute(attribute: Qt::WA_WindowModified);
11273 if (!platformWindow->setWindowModified(on)) {
11274 if (Q_UNLIKELY(on && !q->windowTitle().contains(QLatin1String("[*]"))))
11275 qWarning(msg: "QWidget::setWindowModified: The window title does not contain a '[*]' placeholder");
11276 setWindowTitle_helper(q->windowTitle());
11277 setWindowIconText_helper(q->windowIconText());
11278 }
11279}
11280
11281#ifndef QT_NO_TOOLTIP
11282/*!
11283 \property QWidget::toolTip
11284
11285 \brief the widget's tooltip
11286
11287 Note that by default tooltips are only shown for widgets that are
11288 children of the active window. You can change this behavior by
11289 setting the attribute Qt::WA_AlwaysShowToolTips on the \e window,
11290 not on the widget with the tooltip.
11291
11292 If you want to control a tooltip's behavior, you can intercept the
11293 event() function and catch the QEvent::ToolTip event (e.g., if you
11294 want to customize the area for which the tooltip should be shown).
11295
11296 By default, this property contains an empty string.
11297
11298 \sa QToolTip, statusTip, whatsThis
11299*/
11300void QWidget::setToolTip(const QString &s)
11301{
11302 Q_D(QWidget);
11303 d->toolTip = s;
11304
11305 QEvent event(QEvent::ToolTipChange);
11306 QCoreApplication::sendEvent(receiver: this, event: &event);
11307}
11308
11309QString QWidget::toolTip() const
11310{
11311 Q_D(const QWidget);
11312 return d->toolTip;
11313}
11314
11315/*!
11316 \property QWidget::toolTipDuration
11317 \brief the widget's tooltip duration
11318 \since 5.2
11319
11320 Specifies how long time the tooltip will be displayed, in milliseconds.
11321 If the value is -1 (default) the duration is calculated depending on the length of the tooltip.
11322
11323 \sa toolTip
11324*/
11325
11326void QWidget::setToolTipDuration(int msec)
11327{
11328 Q_D(QWidget);
11329 d->toolTipDuration = msec;
11330}
11331
11332int QWidget::toolTipDuration() const
11333{
11334 Q_D(const QWidget);
11335 return d->toolTipDuration;
11336}
11337
11338#endif // QT_NO_TOOLTIP
11339
11340
11341#if QT_CONFIG(statustip)
11342/*!
11343 \property QWidget::statusTip
11344 \brief the widget's status tip
11345
11346 By default, this property contains an empty string.
11347
11348 \sa toolTip, whatsThis
11349*/
11350void QWidget::setStatusTip(const QString &s)
11351{
11352 Q_D(QWidget);
11353 d->statusTip = s;
11354}
11355
11356QString QWidget::statusTip() const
11357{
11358 Q_D(const QWidget);
11359 return d->statusTip;
11360}
11361#endif // QT_CONFIG(statustip)
11362
11363#if QT_CONFIG(whatsthis)
11364/*!
11365 \property QWidget::whatsThis
11366
11367 \brief the widget's What's This help text.
11368
11369 By default, this property contains an empty string.
11370
11371 \sa QWhatsThis, QWidget::toolTip, QWidget::statusTip
11372*/
11373void QWidget::setWhatsThis(const QString &s)
11374{
11375 Q_D(QWidget);
11376 d->whatsThis = s;
11377}
11378
11379QString QWidget::whatsThis() const
11380{
11381 Q_D(const QWidget);
11382 return d->whatsThis;
11383}
11384#endif // QT_CONFIG(whatsthis)
11385
11386#ifndef QT_NO_ACCESSIBILITY
11387/*!
11388 \property QWidget::accessibleName
11389
11390 \brief the widget's name as seen by assistive technologies
11391
11392 This is the primary name by which assistive technology such as screen readers
11393 announce this widget. For most widgets setting this property is not required.
11394 For example for QPushButton the button's text will be used.
11395
11396 It is important to set this property when the widget does not provide any
11397 text. For example a button that only contains an icon needs to set this
11398 property to work with screen readers.
11399 The name should be short and equivalent to the visual information conveyed
11400 by the widget.
11401
11402 This property has to be \l{Internationalization with Qt}{localized}.
11403
11404 By default, this property contains an empty string.
11405
11406 \sa QWidget::accessibleDescription, QAccessibleInterface::text()
11407*/
11408void QWidget::setAccessibleName(const QString &name)
11409{
11410 Q_D(QWidget);
11411 d->accessibleName = name;
11412 QAccessibleEvent event(this, QAccessible::NameChanged);
11413 QAccessible::updateAccessibility(event: &event);
11414}
11415
11416QString QWidget::accessibleName() const
11417{
11418 Q_D(const QWidget);
11419 return d->accessibleName;
11420}
11421
11422/*!
11423 \property QWidget::accessibleDescription
11424
11425 \brief the widget's description as seen by assistive technologies
11426
11427 The accessible description of a widget should convey what a widget does.
11428 While the \l accessibleName should be a short and concise string (e.g. \gui{Save}),
11429 the description should give more context, such as \gui{Saves the current document}.
11430
11431 This property has to be \l{Internationalization with Qt}{localized}.
11432
11433 By default, this property contains an empty string and Qt falls back
11434 to using the tool tip to provide this information.
11435
11436 \sa QWidget::accessibleName, QAccessibleInterface::text()
11437*/
11438void QWidget::setAccessibleDescription(const QString &description)
11439{
11440 Q_D(QWidget);
11441 d->accessibleDescription = description;
11442 QAccessibleEvent event(this, QAccessible::DescriptionChanged);
11443 QAccessible::updateAccessibility(event: &event);
11444}
11445
11446QString QWidget::accessibleDescription() const
11447{
11448 Q_D(const QWidget);
11449 return d->accessibleDescription;
11450}
11451#endif // QT_NO_ACCESSIBILITY
11452
11453#ifndef QT_NO_SHORTCUT
11454/*!
11455 Adds a shortcut to Qt's shortcut system that watches for the given
11456 \a key sequence in the given \a context. If the \a context is
11457 Qt::ApplicationShortcut, the shortcut applies to the application as a
11458 whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
11459 or to the window itself, Qt::WindowShortcut.
11460
11461 If the same \a key sequence has been grabbed by several widgets,
11462 when the \a key sequence occurs a QEvent::Shortcut event is sent
11463 to all the widgets to which it applies in a non-deterministic
11464 order, but with the ``ambiguous'' flag set to true.
11465
11466 \warning You should not normally need to use this function;
11467 instead create \l{QAction}s with the shortcut key sequences you
11468 require (if you also want equivalent menu options and toolbar
11469 buttons), or create \l{QShortcut}s if you just need key sequences.
11470 Both QAction and QShortcut handle all the event filtering for you,
11471 and provide signals which are triggered when the user triggers the
11472 key sequence, so are much easier to use than this low-level
11473 function.
11474
11475 \sa releaseShortcut(), setShortcutEnabled()
11476*/
11477int QWidget::grabShortcut(const QKeySequence &key, Qt::ShortcutContext context)
11478{
11479 Q_ASSERT(qApp);
11480 if (key.isEmpty())
11481 return 0;
11482 setAttribute(attribute: Qt::WA_GrabbedShortcut);
11483 return QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(owner: this, key, context, matcher: qWidgetShortcutContextMatcher);
11484}
11485
11486/*!
11487 Removes the shortcut with the given \a id from Qt's shortcut
11488 system. The widget will no longer receive QEvent::Shortcut events
11489 for the shortcut's key sequence (unless it has other shortcuts
11490 with the same key sequence).
11491
11492 \warning You should not normally need to use this function since
11493 Qt's shortcut system removes shortcuts automatically when their
11494 parent widget is destroyed. It is best to use QAction or
11495 QShortcut to handle shortcuts, since they are easier to use than
11496 this low-level function. Note also that this is an expensive
11497 operation.
11498
11499 \sa grabShortcut(), setShortcutEnabled()
11500*/
11501void QWidget::releaseShortcut(int id)
11502{
11503 Q_ASSERT(qApp);
11504 if (id)
11505 QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id, owner: this, key: 0);
11506}
11507
11508/*!
11509 If \a enable is true, the shortcut with the given \a id is
11510 enabled; otherwise the shortcut is disabled.
11511
11512 \warning You should not normally need to use this function since
11513 Qt's shortcut system enables/disables shortcuts automatically as
11514 widgets become hidden/visible and gain or lose focus. It is best
11515 to use QAction or QShortcut to handle shortcuts, since they are
11516 easier to use than this low-level function.
11517
11518 \sa grabShortcut(), releaseShortcut()
11519*/
11520void QWidget::setShortcutEnabled(int id, bool enable)
11521{
11522 Q_ASSERT(qApp);
11523 if (id)
11524 QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, id, owner: this, key: 0);
11525}
11526
11527/*!
11528 \since 4.2
11529
11530 If \a enable is true, auto repeat of the shortcut with the
11531 given \a id is enabled; otherwise it is disabled.
11532
11533 \sa grabShortcut(), releaseShortcut()
11534*/
11535void QWidget::setShortcutAutoRepeat(int id, bool enable)
11536{
11537 Q_ASSERT(qApp);
11538 if (id)
11539 QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(on: enable, id, owner: this, key: 0);
11540}
11541#endif // QT_NO_SHORTCUT
11542
11543/*!
11544 Updates the widget's micro focus.
11545*/
11546void QWidget::updateMicroFocus()
11547{
11548 // updating everything since this is currently called for any kind of state change
11549 if (this == QGuiApplication::focusObject())
11550 QGuiApplication::inputMethod()->update(queries: Qt::ImQueryAll);
11551}
11552
11553/*!
11554 Raises this widget to the top of the parent widget's stack.
11555
11556 After this call the widget will be visually in front of any
11557 overlapping sibling widgets.
11558
11559 \note When using activateWindow(), you can call this function to
11560 ensure that the window is stacked on top.
11561
11562 \sa lower(), stackUnder()
11563*/
11564
11565void QWidget::raise()
11566{
11567 Q_D(QWidget);
11568 if (!isWindow()) {
11569 QWidget *p = parentWidget();
11570 const int parentChildCount = p->d_func()->children.size();
11571 if (parentChildCount < 2)
11572 return;
11573 const int from = p->d_func()->children.indexOf(t: this);
11574 Q_ASSERT(from >= 0);
11575 // Do nothing if the widget is already in correct stacking order _and_ created.
11576 if (from != parentChildCount -1)
11577 p->d_func()->children.move(from, to: parentChildCount - 1);
11578 if (!testAttribute(attribute: Qt::WA_WState_Created) && p->testAttribute(attribute: Qt::WA_WState_Created))
11579 create();
11580 else if (from == parentChildCount - 1)
11581 return;
11582
11583 QRegion region(rect());
11584 d->subtractOpaqueSiblings(sourceRegion&: region);
11585 d->invalidateBackingStore(region);
11586 }
11587 if (testAttribute(attribute: Qt::WA_WState_Created))
11588 d->raise_sys();
11589
11590 if (d->extra && d->extra->hasWindowContainer)
11591 QWindowContainer::parentWasRaised(parent: this);
11592
11593 QEvent e(QEvent::ZOrderChange);
11594 QCoreApplication::sendEvent(receiver: this, event: &e);
11595}
11596
11597void QWidgetPrivate::raise_sys()
11598{
11599 Q_Q(QWidget);
11600 if (q->isWindow() || q->testAttribute(attribute: Qt::WA_NativeWindow)) {
11601 q->windowHandle()->raise();
11602 } else if (renderToTexture) {
11603 if (QWidget *p = q->parentWidget()) {
11604 setDirtyOpaqueRegion();
11605 p->d_func()->invalidateBackingStore(effectiveRectFor(rect: q->geometry()));
11606 }
11607 }
11608}
11609
11610/*!
11611 Lowers the widget to the bottom of the parent widget's stack.
11612
11613 After this call the widget will be visually behind (and therefore
11614 obscured by) any overlapping sibling widgets.
11615
11616 \sa raise(), stackUnder()
11617*/
11618
11619void QWidget::lower()
11620{
11621 Q_D(QWidget);
11622 if (!isWindow()) {
11623 QWidget *p = parentWidget();
11624 const int parentChildCount = p->d_func()->children.size();
11625 if (parentChildCount < 2)
11626 return;
11627 const int from = p->d_func()->children.indexOf(t: this);
11628 Q_ASSERT(from >= 0);
11629 // Do nothing if the widget is already in correct stacking order _and_ created.
11630 if (from != 0)
11631 p->d_func()->children.move(from, to: 0);
11632 if (!testAttribute(attribute: Qt::WA_WState_Created) && p->testAttribute(attribute: Qt::WA_WState_Created))
11633 create();
11634 else if (from == 0)
11635 return;
11636 }
11637 if (testAttribute(attribute: Qt::WA_WState_Created))
11638 d->lower_sys();
11639
11640 if (d->extra && d->extra->hasWindowContainer)
11641 QWindowContainer::parentWasLowered(parent: this);
11642
11643 QEvent e(QEvent::ZOrderChange);
11644 QCoreApplication::sendEvent(receiver: this, event: &e);
11645}
11646
11647void QWidgetPrivate::lower_sys()
11648{
11649 Q_Q(QWidget);
11650 if (q->isWindow() || q->testAttribute(attribute: Qt::WA_NativeWindow)) {
11651 Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
11652 q->windowHandle()->lower();
11653 } else if (QWidget *p = q->parentWidget()) {
11654 setDirtyOpaqueRegion();
11655 p->d_func()->invalidateBackingStore(effectiveRectFor(rect: q->geometry()));
11656 }
11657}
11658
11659/*!
11660 Places the widget under \a w in the parent widget's stack.
11661
11662 To make this work, the widget itself and \a w must be siblings.
11663
11664 \sa raise(), lower()
11665*/
11666void QWidget::stackUnder(QWidget* w)
11667{
11668 Q_D(QWidget);
11669 QWidget *p = parentWidget();
11670 if (!w || isWindow() || p != w->parentWidget() || this == w)
11671 return;
11672 if (p) {
11673 int from = p->d_func()->children.indexOf(t: this);
11674 int to = p->d_func()->children.indexOf(t: w);
11675 Q_ASSERT(from >= 0);
11676 Q_ASSERT(to >= 0);
11677 if (from < to)
11678 --to;
11679 // Do nothing if the widget is already in correct stacking order _and_ created.
11680 if (from != to)
11681 p->d_func()->children.move(from, to);
11682 if (!testAttribute(attribute: Qt::WA_WState_Created) && p->testAttribute(attribute: Qt::WA_WState_Created))
11683 create();
11684 else if (from == to)
11685 return;
11686 }
11687 if (testAttribute(attribute: Qt::WA_WState_Created))
11688 d->stackUnder_sys(w);
11689
11690 QEvent e(QEvent::ZOrderChange);
11691 QCoreApplication::sendEvent(receiver: this, event: &e);
11692}
11693
11694void QWidgetPrivate::stackUnder_sys(QWidget*)
11695{
11696 Q_Q(QWidget);
11697 if (QWidget *p = q->parentWidget()) {
11698 setDirtyOpaqueRegion();
11699 p->d_func()->invalidateBackingStore(effectiveRectFor(rect: q->geometry()));
11700 }
11701}
11702
11703/*!
11704 \fn bool QWidget::isTopLevel() const
11705 \obsolete
11706
11707 Use isWindow() instead.
11708*/
11709
11710/*!
11711 \fn bool QWidget::isRightToLeft() const
11712 \internal
11713*/
11714
11715/*!
11716 \fn bool QWidget::isLeftToRight() const
11717 \internal
11718*/
11719
11720/*!
11721 \macro QWIDGETSIZE_MAX
11722 \relates QWidget
11723
11724 Defines the maximum size for a QWidget object.
11725
11726 The largest allowed size for a widget is QSize(QWIDGETSIZE_MAX,
11727 QWIDGETSIZE_MAX), i.e. QSize (16777215,16777215).
11728
11729 \sa QWidget::setMaximumSize()
11730*/
11731
11732/*!
11733 \fn QWidget::setupUi(QWidget *widget)
11734
11735 Sets up the user interface for the specified \a widget.
11736
11737 \note This function is available with widgets that derive from user
11738 interface descriptions created using \l{uic}.
11739
11740 \sa {Using a Designer UI File in Your C++ Application}
11741*/
11742
11743QRect QWidgetPrivate::frameStrut() const
11744{
11745 Q_Q(const QWidget);
11746 if (!q->isWindow() || (q->windowType() == Qt::Desktop) || q->testAttribute(attribute: Qt::WA_DontShowOnScreen)) {
11747 // x2 = x1 + w - 1, so w/h = 1
11748 return QRect(0, 0, 1, 1);
11749 }
11750
11751 if (data.fstrut_dirty
11752 // ### Fix properly for 4.3
11753 && q->isVisible()
11754 && q->testAttribute(attribute: Qt::WA_WState_Created))
11755 const_cast<QWidgetPrivate *>(this)->updateFrameStrut();
11756
11757 return maybeTopData() ? maybeTopData()->frameStrut : QRect();
11758}
11759
11760void QWidgetPrivate::updateFrameStrut()
11761{
11762 Q_Q(QWidget);
11763 if (q->data->fstrut_dirty) {
11764 if (QTLWExtra *te = maybeTopData()) {
11765 if (te->window && te->window->handle()) {
11766 const QMargins margins = te->window->frameMargins();
11767 if (!margins.isNull()) {
11768 te->frameStrut.setCoords(xp1: margins.left(), yp1: margins.top(), xp2: margins.right(), yp2: margins.bottom());
11769 q->data->fstrut_dirty = false;
11770 }
11771 }
11772 }
11773 }
11774}
11775
11776#ifdef QT_KEYPAD_NAVIGATION
11777/*!
11778 \internal
11779
11780 Changes the focus from the current focusWidget to a widget in
11781 the \a direction.
11782
11783 Returns \c true, if there was a widget in that direction
11784*/
11785bool QWidgetPrivate::navigateToDirection(Direction direction)
11786{
11787 QWidget *targetWidget = widgetInNavigationDirection(direction);
11788 if (targetWidget)
11789 targetWidget->setFocus();
11790 return (targetWidget != 0);
11791}
11792
11793/*!
11794 \internal
11795
11796 Searches for a widget that is positioned in the \a direction, starting
11797 from the current focusWidget.
11798
11799 Returns the pointer to a found widget or \nullptr, if there was no widget
11800 in that direction.
11801*/
11802QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
11803{
11804 const QWidget *sourceWidget = QApplication::focusWidget();
11805 if (!sourceWidget)
11806 return nullptr;
11807 const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint()));
11808 const int sourceX =
11809 (direction == DirectionNorth || direction == DirectionSouth) ?
11810 (sourceRect.left() + (sourceRect.right() - sourceRect.left()) / 2)
11811 :(direction == DirectionEast ? sourceRect.right() : sourceRect.left());
11812 const int sourceY =
11813 (direction == DirectionEast || direction == DirectionWest) ?
11814 (sourceRect.top() + (sourceRect.bottom() - sourceRect.top()) / 2)
11815 :(direction == DirectionSouth ? sourceRect.bottom() : sourceRect.top());
11816 const QPoint sourcePoint(sourceX, sourceY);
11817 const QPoint sourceCenter = sourceRect.center();
11818 const QWidget *sourceWindow = sourceWidget->window();
11819
11820 QWidget *targetWidget = nullptr;
11821 int shortestDistance = INT_MAX;
11822
11823 const auto targetCandidates = QApplication::allWidgets();
11824 for (QWidget *targetCandidate : targetCandidates) {
11825
11826 const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint()));
11827
11828 // For focus proxies, the child widget handling the focus can have keypad navigation focus,
11829 // but the owner of the proxy cannot.
11830 // Additionally, empty widgets should be ignored.
11831 if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty())
11832 continue;
11833
11834 // Only navigate to a target widget that...
11835 if ( targetCandidate != sourceWidget
11836 // ...takes the focus,
11837 && targetCandidate->focusPolicy() & Qt::TabFocus
11838 // ...is above if DirectionNorth,
11839 && !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top())
11840 // ...is on the right if DirectionEast,
11841 && !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right())
11842 // ...is below if DirectionSouth,
11843 && !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom())
11844 // ...is on the left if DirectionWest,
11845 && !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left())
11846 // ...is enabled,
11847 && targetCandidate->isEnabled()
11848 // ...is visible,
11849 && targetCandidate->isVisible()
11850 // ...is in the same window,
11851 && targetCandidate->window() == sourceWindow) {
11852 const int targetCandidateDistance = pointToRect(sourcePoint, targetCandidateRect);
11853 if (targetCandidateDistance < shortestDistance) {
11854 shortestDistance = targetCandidateDistance;
11855 targetWidget = targetCandidate;
11856 }
11857 }
11858 }
11859 return targetWidget;
11860}
11861
11862/*!
11863 \internal
11864
11865 Tells us if it there is currently a reachable widget by keypad navigation in
11866 a certain \a orientation.
11867 If no navigation is possible, occurring key events in that \a orientation may
11868 be used to interact with the value in the focused widget, even though it
11869 currently has not the editFocus.
11870
11871 \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
11872*/
11873bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation)
11874{
11875 return orientation == Qt::Horizontal?
11876 (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
11877 || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
11878 :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
11879 || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
11880}
11881/*!
11882 \internal
11883
11884 Checks, if the \a widget is inside a QTabWidget. If is is inside
11885 one, left/right key events will be used to switch between tabs in keypad
11886 navigation. If there is no QTabWidget, the horizontal key events can be used
11887to
11888 interact with the value in the focused widget, even though it currently has
11889 not the editFocus.
11890
11891 \sa QWidget::hasEditFocus()
11892*/
11893bool QWidgetPrivate::inTabWidget(QWidget *widget)
11894{
11895 for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
11896 if (qobject_cast<const QTabWidget*>(tabWidget))
11897 return true;
11898 return false;
11899}
11900#endif
11901
11902/*!
11903 \since 5.0
11904 \internal
11905
11906 Sets the backing store to be the \a store specified.
11907 The QWidget will take ownership of the \a store.
11908*/
11909void QWidget::setBackingStore(QBackingStore *store)
11910{
11911 // ### createWinId() ??
11912
11913 if (!isTopLevel())
11914 return;
11915
11916 Q_D(QWidget);
11917
11918 QTLWExtra *topData = d->topData();
11919 if (topData->backingStore == store)
11920 return;
11921
11922 QBackingStore *oldStore = topData->backingStore;
11923 deleteBackingStore(d);
11924 topData->backingStore = store;
11925
11926 QWidgetRepaintManager *repaintManager = d->maybeRepaintManager();
11927 if (!repaintManager)
11928 return;
11929
11930 if (isTopLevel()) {
11931 if (repaintManager->backingStore() != oldStore && repaintManager->backingStore() != store)
11932 delete repaintManager->backingStore();
11933 repaintManager->setBackingStore(store);
11934 }
11935}
11936
11937/*!
11938 \since 5.0
11939
11940 Returns the QBackingStore this widget will be drawn into.
11941*/
11942QBackingStore *QWidget::backingStore() const
11943{
11944 Q_D(const QWidget);
11945 QTLWExtra *extra = d->maybeTopData();
11946 if (extra && extra->backingStore)
11947 return extra->backingStore;
11948
11949 QWidgetRepaintManager *repaintManager = d->maybeRepaintManager();
11950 return repaintManager ? repaintManager->backingStore() : nullptr;
11951}
11952
11953void QWidgetPrivate::getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const
11954{
11955 if (left)
11956 *left = (int)leftLayoutItemMargin;
11957 if (top)
11958 *top = (int)topLayoutItemMargin;
11959 if (right)
11960 *right = (int)rightLayoutItemMargin;
11961 if (bottom)
11962 *bottom = (int)bottomLayoutItemMargin;
11963}
11964
11965void QWidgetPrivate::setLayoutItemMargins(int left, int top, int right, int bottom)
11966{
11967 if (leftLayoutItemMargin == left
11968 && topLayoutItemMargin == top
11969 && rightLayoutItemMargin == right
11970 && bottomLayoutItemMargin == bottom)
11971 return;
11972
11973 Q_Q(QWidget);
11974 leftLayoutItemMargin = (signed char)left;
11975 topLayoutItemMargin = (signed char)top;
11976 rightLayoutItemMargin = (signed char)right;
11977 bottomLayoutItemMargin = (signed char)bottom;
11978 q->updateGeometry();
11979}
11980
11981void QWidgetPrivate::setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt)
11982{
11983 Q_Q(QWidget);
11984 QStyleOption myOpt;
11985 if (!opt) {
11986 myOpt.initFrom(w: q);
11987 myOpt.rect.setRect(ax: 0, ay: 0, aw: 32768, ah: 32768); // arbitrary
11988 opt = &myOpt;
11989 }
11990
11991 QRect liRect = q->style()->subElementRect(subElement: element, option: opt, widget: q);
11992 if (liRect.isValid()) {
11993 leftLayoutItemMargin = (signed char)(opt->rect.left() - liRect.left());
11994 topLayoutItemMargin = (signed char)(opt->rect.top() - liRect.top());
11995 rightLayoutItemMargin = (signed char)(liRect.right() - opt->rect.right());
11996 bottomLayoutItemMargin = (signed char)(liRect.bottom() - opt->rect.bottom());
11997 } else {
11998 leftLayoutItemMargin = 0;
11999 topLayoutItemMargin = 0;
12000 rightLayoutItemMargin = 0;
12001 bottomLayoutItemMargin = 0;
12002 }
12003}
12004// resets the Qt::WA_QuitOnClose attribute to the default value for transient widgets.
12005void QWidgetPrivate::adjustQuitOnCloseAttribute()
12006{
12007 Q_Q(QWidget);
12008
12009 if (!q->parentWidget()) {
12010 Qt::WindowType type = q->windowType();
12011 if (type == Qt::Widget || type == Qt::SubWindow)
12012 type = Qt::Window;
12013 if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
12014 q->setAttribute(attribute: Qt::WA_QuitOnClose, on: false);
12015 }
12016}
12017
12018QOpenGLContext *QWidgetPrivate::shareContext() const
12019{
12020#ifdef QT_NO_OPENGL
12021 return 0;
12022#else
12023 if (!extra || !extra->topextra || !extra->topextra->window)
12024 return nullptr;
12025
12026 if (!extra->topextra->shareContext) {
12027 auto ctx = qt_make_unique<QOpenGLContext>();
12028 ctx->setShareContext(qt_gl_global_share_context());
12029 ctx->setFormat(extra->topextra->window->format());
12030 ctx->setScreen(extra->topextra->window->screen());
12031 ctx->create();
12032 extra->topextra->shareContext = std::move(ctx);
12033 }
12034 return extra->topextra->shareContext.get();
12035#endif // QT_NO_OPENGL
12036}
12037
12038#ifndef QT_NO_OPENGL
12039void QWidgetPrivate::sendComposeStatus(QWidget *w, bool end)
12040{
12041 QWidgetPrivate *wd = QWidgetPrivate::get(w);
12042 if (!wd->textureChildSeen)
12043 return;
12044 if (end)
12045 wd->endCompose();
12046 else
12047 wd->beginCompose();
12048 for (int i = 0; i < wd->children.size(); ++i) {
12049 w = qobject_cast<QWidget *>(o: wd->children.at(i));
12050 if (w && !w->isWindow() && !w->isHidden() && QWidgetPrivate::get(w)->textureChildSeen)
12051 sendComposeStatus(w, end);
12052 }
12053}
12054#endif // QT_NO_OPENGL
12055
12056Q_WIDGETS_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget)
12057{
12058 return widget->data;
12059}
12060
12061Q_WIDGETS_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget)
12062{
12063 return widget->d_func();
12064}
12065
12066
12067#if QT_CONFIG(graphicsview)
12068/*!
12069 \since 4.5
12070
12071 Returns the proxy widget for the corresponding embedded widget in a graphics
12072 view; otherwise returns \nullptr.
12073
12074 \sa QGraphicsProxyWidget::createProxyForChildWidget(),
12075 QGraphicsScene::addWidget()
12076 */
12077QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const
12078{
12079 Q_D(const QWidget);
12080 if (d->extra) {
12081 return d->extra->proxyWidget;
12082 }
12083 return nullptr;
12084}
12085#endif
12086
12087#ifndef QT_NO_GESTURES
12088/*!
12089 Subscribes the widget to a given \a gesture with specific \a flags.
12090
12091 \sa ungrabGesture(), QGestureEvent
12092 \since 4.6
12093*/
12094void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
12095{
12096 Q_D(QWidget);
12097 d->gestureContext.insert(key: gesture, value: flags);
12098 (void)QGestureManager::instance(); // create a gesture manager
12099}
12100
12101/*!
12102 Unsubscribes the widget from a given \a gesture type
12103
12104 \sa grabGesture(), QGestureEvent
12105 \since 4.6
12106*/
12107void QWidget::ungrabGesture(Qt::GestureType gesture)
12108{
12109 // if you modify this function, check the inlined version in ~QWidget, too
12110 Q_D(QWidget);
12111 if (d->gestureContext.remove(key: gesture)) {
12112 if (QGestureManager *manager = QGestureManager::instance())
12113 manager->cleanupCachedGestures(target: this, type: gesture);
12114 }
12115}
12116#endif // QT_NO_GESTURES
12117
12118/*!
12119 \fn void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
12120
12121 Frees up window system resources. Destroys the widget window if \a
12122 destroyWindow is true.
12123
12124 destroy() calls itself recursively for all the child widgets,
12125 passing \a destroySubWindows for the \a destroyWindow parameter.
12126 To have more control over destruction of subwidgets, destroy
12127 subwidgets selectively first.
12128
12129 This function is usually called from the QWidget destructor.
12130*/
12131void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
12132{
12133 Q_D(QWidget);
12134
12135 d->aboutToDestroy(destroyWindow);
12136 if (!isWindow() && parentWidget())
12137 parentWidget()->d_func()->invalidateBackingStore(d->effectiveRectFor(rect: geometry()));
12138 d->deactivateWidgetCleanup();
12139
12140 if ((windowType() == Qt::Popup) && qApp)
12141 qApp->d_func()->closePopup(popup: this);
12142
12143 if (this == QApplicationPrivate::active_window)
12144 QApplication::setActiveWindow(nullptr);
12145 if (QWidget::mouseGrabber() == this)
12146 releaseMouse();
12147 if (QWidget::keyboardGrabber() == this)
12148 releaseKeyboard();
12149
12150 setAttribute(attribute: Qt::WA_WState_Created, on: false);
12151
12152 if (windowType() != Qt::Desktop) {
12153 if (destroySubWindows) {
12154 QObjectList childList(children());
12155 for (int i = 0; i < childList.size(); i++) {
12156 QWidget *widget = qobject_cast<QWidget *>(o: childList.at(i));
12157 if (widget && widget->testAttribute(attribute: Qt::WA_NativeWindow)) {
12158 if (widget->windowHandle()) {
12159 widget->destroy();
12160 }
12161 }
12162 }
12163 }
12164 if (destroyWindow) {
12165 d->deleteTLSysExtra();
12166 } else {
12167 if (parentWidget() && parentWidget()->testAttribute(attribute: Qt::WA_WState_Created)) {
12168 d->hide_sys();
12169 }
12170 }
12171
12172 d->setWinId(0);
12173 }
12174}
12175
12176/*!
12177 \fn QPaintEngine *QWidget::paintEngine() const
12178
12179 Returns the widget's paint engine.
12180
12181 Note that this function should not be called explicitly by the
12182 user, since it's meant for reimplementation purposes only. The
12183 function is called by Qt internally, and the default
12184 implementation may not always return a valid pointer.
12185*/
12186QPaintEngine *QWidget::paintEngine() const
12187{
12188 qWarning(msg: "QWidget::paintEngine: Should no longer be called");
12189
12190#ifdef Q_OS_WIN
12191 // We set this bit which is checked in setAttribute for
12192 // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
12193 //
12194 // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
12195 // Windows which would mean suddenly their widgets stop working.
12196 //
12197 // 2. Users set paint on screen and subclass paintEngine() to
12198 // return 0, in which case we have a "hole" in the backingstore
12199 // allowing use of GDI or DirectX directly.
12200 //
12201 // 1 is WRONG, but to minimize silent failures, we have set this
12202 // bit to ignore the setAttribute call. 2. needs to be
12203 // supported because its our only means of embedding native
12204 // graphics stuff.
12205 const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
12206#endif
12207
12208 return nullptr; //##### @@@
12209}
12210
12211// Do not call QWindow::mapToGlobal() until QPlatformWindow is properly showing.
12212static inline bool canMapPosition(QWindow *window)
12213{
12214 return window->handle() && !qt_window_private(window)->resizeEventPending;
12215}
12216
12217#if QT_CONFIG(graphicsview)
12218static inline QGraphicsProxyWidget *graphicsProxyWidget(const QWidget *w)
12219{
12220 QGraphicsProxyWidget *result = nullptr;
12221 const QWidgetPrivate *d = qt_widget_private(widget: const_cast<QWidget *>(w));
12222 if (d->extra)
12223 result = d->extra->proxyWidget;
12224 return result;
12225}
12226#endif // QT_CONFIG(graphicsview)
12227
12228struct MapToGlobalTransformResult {
12229 QTransform transform;
12230 QWindow *window;
12231};
12232
12233static MapToGlobalTransformResult mapToGlobalTransform(const QWidget *w)
12234{
12235 MapToGlobalTransformResult result;
12236 result.window = nullptr;
12237 for ( ; w ; w = w->parentWidget()) {
12238#if QT_CONFIG(graphicsview)
12239 if (QGraphicsProxyWidget *qgpw = graphicsProxyWidget(w)) {
12240 if (const QGraphicsScene *scene = qgpw->scene()) {
12241 const QList <QGraphicsView *> views = scene->views();
12242 if (!views.isEmpty()) {
12243 result.transform *= qgpw->sceneTransform();
12244 result.transform *= views.first()->viewportTransform();
12245 w = views.first()->viewport();
12246 }
12247 }
12248 }
12249#endif // QT_CONFIG(graphicsview)
12250 QWindow *window = w->windowHandle();
12251 if (window && canMapPosition(window)) {
12252 result.window = window;
12253 break;
12254 }
12255
12256 const QPoint topLeft = w->geometry().topLeft();
12257 result.transform.translate(dx: topLeft.x(), dy: topLeft.y());
12258 if (w->isWindow())
12259 break;
12260 }
12261 return result;
12262}
12263
12264/*!
12265 \fn QPoint QWidget::mapToGlobal(const QPoint &pos) const
12266
12267 Translates the widget coordinate \a pos to global screen
12268 coordinates. For example, \c{mapToGlobal(QPoint(0,0))} would give
12269 the global coordinates of the top-left pixel of the widget.
12270
12271 \sa mapFromGlobal(), mapTo(), mapToParent()
12272*/
12273QPoint QWidget::mapToGlobal(const QPoint &pos) const
12274{
12275 const MapToGlobalTransformResult t = mapToGlobalTransform(w: this);
12276 const QPoint g = t.transform.map(p: pos);
12277 return t.window ? t.window->mapToGlobal(pos: g) : g;
12278}
12279
12280/*!
12281 \fn QPoint QWidget::mapFromGlobal(const QPoint &pos) const
12282
12283 Translates the global screen coordinate \a pos to widget
12284 coordinates.
12285
12286 \sa mapToGlobal(), mapFrom(), mapFromParent()
12287*/
12288QPoint QWidget::mapFromGlobal(const QPoint &pos) const
12289{
12290 const MapToGlobalTransformResult t = mapToGlobalTransform(w: this);
12291 const QPoint windowLocal = t.window ? t.window->mapFromGlobal(pos) : pos;
12292 return t.transform.inverted().map(p: windowLocal);
12293}
12294
12295QWidget *qt_pressGrab = nullptr;
12296QWidget *qt_mouseGrb = nullptr;
12297static bool mouseGrabWithCursor = false;
12298static QWidget *keyboardGrb = nullptr;
12299
12300static inline QWindow *grabberWindow(const QWidget *w)
12301{
12302 QWindow *window = w->windowHandle();
12303 if (!window)
12304 if (const QWidget *nativeParent = w->nativeParentWidget())
12305 window = nativeParent->windowHandle();
12306 return window;
12307}
12308
12309#ifndef QT_NO_CURSOR
12310static void grabMouseForWidget(QWidget *widget, const QCursor *cursor = nullptr)
12311#else
12312static void grabMouseForWidget(QWidget *widget)
12313#endif
12314{
12315 if (qt_mouseGrb)
12316 qt_mouseGrb->releaseMouse();
12317
12318 mouseGrabWithCursor = false;
12319 if (QWindow *window = grabberWindow(w: widget)) {
12320#ifndef QT_NO_CURSOR
12321 if (cursor) {
12322 mouseGrabWithCursor = true;
12323 QGuiApplication::setOverrideCursor(*cursor);
12324 }
12325#endif // !QT_NO_CURSOR
12326 window->setMouseGrabEnabled(true);
12327 }
12328
12329 qt_mouseGrb = widget;
12330 qt_pressGrab = nullptr;
12331}
12332
12333static void releaseMouseGrabOfWidget(QWidget *widget)
12334{
12335 if (qt_mouseGrb == widget) {
12336 if (QWindow *window = grabberWindow(w: widget)) {
12337#ifndef QT_NO_CURSOR
12338 if (mouseGrabWithCursor) {
12339 QGuiApplication::restoreOverrideCursor();
12340 mouseGrabWithCursor = false;
12341 }
12342#endif // !QT_NO_CURSOR
12343 window->setMouseGrabEnabled(false);
12344 }
12345 }
12346 qt_mouseGrb = nullptr;
12347}
12348
12349/*!
12350 \fn void QWidget::grabMouse()
12351
12352 Grabs the mouse input.
12353
12354 This widget receives all mouse events until releaseMouse() is
12355 called; other widgets get no mouse events at all. Keyboard
12356 events are not affected. Use grabKeyboard() if you want to grab
12357 that.
12358
12359 \warning Bugs in mouse-grabbing applications very often lock the
12360 terminal. Use this function with extreme caution, and consider
12361 using the \c -nograb command line option while debugging.
12362
12363 It is almost never necessary to grab the mouse when using Qt, as
12364 Qt grabs and releases it sensibly. In particular, Qt grabs the
12365 mouse when a mouse button is pressed and keeps it until the last
12366 button is released.
12367
12368 \note Only visible widgets can grab mouse input. If isVisible()
12369 returns \c false for a widget, that widget cannot call grabMouse().
12370
12371 \note On Windows, grabMouse() only works when the mouse is inside a window
12372 owned by the process.
12373 On \macos, grabMouse() only works when the mouse is inside the frame of that widget.
12374
12375 \sa releaseMouse(), grabKeyboard(), releaseKeyboard()
12376*/
12377void QWidget::grabMouse()
12378{
12379 grabMouseForWidget(widget: this);
12380}
12381
12382/*!
12383 \fn void QWidget::grabMouse(const QCursor &cursor)
12384 \overload grabMouse()
12385
12386 Grabs the mouse input and changes the cursor shape.
12387
12388 The cursor will assume shape \a cursor (for as long as the mouse
12389 focus is grabbed) and this widget will be the only one to receive
12390 mouse events until releaseMouse() is called().
12391
12392 \warning Grabbing the mouse might lock the terminal.
12393
12394 \note See the note in QWidget::grabMouse().
12395
12396 \sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
12397*/
12398#ifndef QT_NO_CURSOR
12399void QWidget::grabMouse(const QCursor &cursor)
12400{
12401 grabMouseForWidget(widget: this, cursor: &cursor);
12402}
12403#endif
12404
12405bool QWidgetPrivate::stealMouseGrab(bool grab)
12406{
12407 // This is like a combination of grab/releaseMouse() but with error checking
12408 // and it has no effect on the result of mouseGrabber().
12409 Q_Q(QWidget);
12410 QWindow *window = grabberWindow(w: q);
12411 return window ? window->setMouseGrabEnabled(grab) : false;
12412}
12413
12414/*!
12415 \fn void QWidget::releaseMouse()
12416
12417 Releases the mouse grab.
12418
12419 \sa grabMouse(), grabKeyboard(), releaseKeyboard()
12420*/
12421void QWidget::releaseMouse()
12422{
12423 releaseMouseGrabOfWidget(widget: this);
12424}
12425
12426/*!
12427 \fn void QWidget::grabKeyboard()
12428
12429 Grabs the keyboard input.
12430
12431 This widget receives all keyboard events until releaseKeyboard()
12432 is called; other widgets get no keyboard events at all. Mouse
12433 events are not affected. Use grabMouse() if you want to grab that.
12434
12435 The focus widget is not affected, except that it doesn't receive
12436 any keyboard events. setFocus() moves the focus as usual, but the
12437 new focus widget receives keyboard events only after
12438 releaseKeyboard() is called.
12439
12440 If a different widget is currently grabbing keyboard input, that
12441 widget's grab is released first.
12442
12443 \sa releaseKeyboard(), grabMouse(), releaseMouse(), focusWidget()
12444*/
12445void QWidget::grabKeyboard()
12446{
12447 if (keyboardGrb)
12448 keyboardGrb->releaseKeyboard();
12449 if (QWindow *window = grabberWindow(w: this))
12450 window->setKeyboardGrabEnabled(true);
12451 keyboardGrb = this;
12452}
12453
12454bool QWidgetPrivate::stealKeyboardGrab(bool grab)
12455{
12456 // This is like a combination of grab/releaseKeyboard() but with error
12457 // checking and it has no effect on the result of keyboardGrabber().
12458 Q_Q(QWidget);
12459 QWindow *window = grabberWindow(w: q);
12460 return window ? window->setKeyboardGrabEnabled(grab) : false;
12461}
12462
12463/*!
12464 \fn void QWidget::releaseKeyboard()
12465
12466 Releases the keyboard grab.
12467
12468 \sa grabKeyboard(), grabMouse(), releaseMouse()
12469*/
12470void QWidget::releaseKeyboard()
12471{
12472 if (keyboardGrb == this) {
12473 if (QWindow *window = grabberWindow(w: this))
12474 window->setKeyboardGrabEnabled(false);
12475 keyboardGrb = nullptr;
12476 }
12477}
12478
12479/*!
12480 \fn QWidget *QWidget::mouseGrabber()
12481
12482 Returns the widget that is currently grabbing the mouse input.
12483
12484 If no widget in this application is currently grabbing the mouse,
12485 \nullptr is returned.
12486
12487 \sa grabMouse(), keyboardGrabber()
12488*/
12489QWidget *QWidget::mouseGrabber()
12490{
12491 if (qt_mouseGrb)
12492 return qt_mouseGrb;
12493 return qt_pressGrab;
12494}
12495
12496/*!
12497 \fn QWidget *QWidget::keyboardGrabber()
12498
12499 Returns the widget that is currently grabbing the keyboard input.
12500
12501 If no widget in this application is currently grabbing the
12502 keyboard, \nullptr is returned.
12503
12504 \sa grabMouse(), mouseGrabber()
12505*/
12506QWidget *QWidget::keyboardGrabber()
12507{
12508 return keyboardGrb;
12509}
12510
12511/*!
12512 \fn void QWidget::activateWindow()
12513
12514 Sets the top-level widget containing this widget to be the active
12515 window.
12516
12517 An active window is a visible top-level window that has the
12518 keyboard input focus.
12519
12520 This function performs the same operation as clicking the mouse on
12521 the title bar of a top-level window. On X11, the result depends on
12522 the Window Manager. If you want to ensure that the window is
12523 stacked on top as well you should also call raise(). Note that the
12524 window must be visible, otherwise activateWindow() has no effect.
12525
12526 On Windows, if you are calling this when the application is not
12527 currently the active one then it will not make it the active
12528 window. It will change the color of the taskbar entry to indicate
12529 that the window has changed in some way. This is because Microsoft
12530 does not allow an application to interrupt what the user is currently
12531 doing in another application.
12532
12533 \sa isActiveWindow(), window(), show(), QWindowsWindowFunctions::setWindowActivationBehavior()
12534*/
12535void QWidget::activateWindow()
12536{
12537 QWindow *const wnd = window()->windowHandle();
12538
12539 if (wnd)
12540 wnd->requestActivate();
12541}
12542
12543/*!
12544
12545 Internal implementation of the virtual QPaintDevice::metric()
12546 function.
12547
12548 \a m is the metric to get.
12549*/
12550int QWidget::metric(PaintDeviceMetric m) const
12551{
12552 QWindow *topLevelWindow = nullptr;
12553 QScreen *screen = nullptr;
12554 if (QWidget *topLevel = window()) {
12555 topLevelWindow = topLevel->windowHandle();
12556 if (topLevelWindow)
12557 screen = topLevelWindow->screen();
12558 }
12559 if (!screen && QGuiApplication::primaryScreen())
12560 screen = QGuiApplication::primaryScreen();
12561
12562 if (!screen) {
12563 if (m == PdmDpiX || m == PdmDpiY)
12564 return 72;
12565 return QPaintDevice::metric(metric: m);
12566 }
12567 int val;
12568 if (m == PdmWidth) {
12569 val = data->crect.width();
12570 } else if (m == PdmWidthMM) {
12571 val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
12572 } else if (m == PdmHeight) {
12573 val = data->crect.height();
12574 } else if (m == PdmHeightMM) {
12575 val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
12576 } else if (m == PdmDepth) {
12577 return screen->depth();
12578 } else if (m == PdmDpiX) {
12579 for (const QWidget *p = this; p; p = p->parentWidget()) {
12580 if (p->d_func()->extra && p->d_func()->extra->customDpiX)
12581 return p->d_func()->extra->customDpiX;
12582 }
12583 return qRound(d: screen->logicalDotsPerInchX());
12584 } else if (m == PdmDpiY) {
12585 for (const QWidget *p = this; p; p = p->parentWidget()) {
12586 if (p->d_func()->extra && p->d_func()->extra->customDpiY)
12587 return p->d_func()->extra->customDpiY;
12588 }
12589 return qRound(d: screen->logicalDotsPerInchY());
12590 } else if (m == PdmPhysicalDpiX) {
12591 return qRound(d: screen->physicalDotsPerInchX());
12592 } else if (m == PdmPhysicalDpiY) {
12593 return qRound(d: screen->physicalDotsPerInchY());
12594 } else if (m == PdmDevicePixelRatio) {
12595 return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio();
12596 } else if (m == PdmDevicePixelRatioScaled) {
12597 return (QPaintDevice::devicePixelRatioFScale() *
12598 (topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio()));
12599 } else {
12600 val = QPaintDevice::metric(metric: m);// XXX
12601 }
12602 return val;
12603}
12604
12605/*!
12606 Initializes the \a painter pen, background and font to the same as
12607 the given widget's. This function is called automatically when the
12608 painter is opened on a QWidget.
12609*/
12610void QWidget::initPainter(QPainter *painter) const
12611{
12612 const QPalette &pal = palette();
12613 painter->d_func()->state->pen = QPen(pal.brush(cr: foregroundRole()), 1);
12614 painter->d_func()->state->bgBrush = pal.brush(cr: backgroundRole());
12615 QFont f(font(), const_cast<QWidget *>(this));
12616 painter->d_func()->state->deviceFont = f;
12617 painter->d_func()->state->font = f;
12618}
12619
12620/*!
12621 \internal
12622
12623 Do PaintDevice rendering with the specified \a offset.
12624*/
12625QPaintDevice *QWidget::redirected(QPoint *offset) const
12626{
12627 return d_func()->redirected(offset);
12628}
12629
12630/*!
12631 \internal
12632
12633 A painter that is shared among other instances of QPainter.
12634*/
12635QPainter *QWidget::sharedPainter() const
12636{
12637 // Someone sent a paint event directly to the widget
12638 if (!d_func()->redirectDev)
12639 return nullptr;
12640
12641 QPainter *sp = d_func()->sharedPainter();
12642 if (!sp || !sp->isActive())
12643 return nullptr;
12644
12645 if (sp->paintEngine()->paintDevice() != d_func()->redirectDev)
12646 return nullptr;
12647
12648 return sp;
12649}
12650
12651/*!
12652 \fn void QWidget::setMask(const QRegion &region)
12653 \overload
12654
12655 Causes only the parts of the widget which overlap \a region to be
12656 visible. If the region includes pixels outside the rect() of the
12657 widget, window system controls in that area may or may not be
12658 visible, depending on the platform.
12659
12660 Note that this effect can be slow if the region is particularly
12661 complex.
12662
12663 \sa windowOpacity
12664*/
12665void QWidget::setMask(const QRegion &newMask)
12666{
12667 Q_D(QWidget);
12668
12669 d->createExtra();
12670 if (newMask == d->extra->mask)
12671 return;
12672
12673#ifndef QT_NO_BACKINGSTORE
12674 const QRegion oldMask(d->extra->mask);
12675#endif
12676
12677 d->extra->mask = newMask;
12678 d->extra->hasMask = !newMask.isEmpty();
12679
12680 if (!testAttribute(attribute: Qt::WA_WState_Created))
12681 return;
12682
12683 d->setMask_sys(newMask);
12684
12685#ifndef QT_NO_BACKINGSTORE
12686 if (!isVisible())
12687 return;
12688
12689 if (!d->extra->hasMask) {
12690 // Mask was cleared; update newly exposed area.
12691 QRegion expose(rect());
12692 expose -= oldMask;
12693 if (!expose.isEmpty()) {
12694 d->setDirtyOpaqueRegion();
12695 update(rgn: expose);
12696 }
12697 return;
12698 }
12699
12700 if (!isWindow()) {
12701 // Update newly exposed area on the parent widget.
12702 QRegion parentExpose(rect());
12703 parentExpose -= newMask;
12704 if (!parentExpose.isEmpty()) {
12705 d->setDirtyOpaqueRegion();
12706 parentExpose.translate(p: data->crect.topLeft());
12707 parentWidget()->update(rgn: parentExpose);
12708 }
12709
12710 // Update newly exposed area on this widget
12711 if (!oldMask.isEmpty())
12712 update(rgn: newMask - oldMask);
12713 }
12714#endif
12715}
12716
12717void QWidgetPrivate::setMask_sys(const QRegion &region)
12718{
12719 Q_Q(QWidget);
12720 if (QWindow *window = q->windowHandle())
12721 window->setMask(region);
12722}
12723
12724/*!
12725 \fn void QWidget::setMask(const QBitmap &bitmap)
12726
12727 Causes only the pixels of the widget for which \a bitmap has a
12728 corresponding 1 bit to be visible. If the region includes pixels
12729 outside the rect() of the widget, window system controls in that
12730 area may or may not be visible, depending on the platform.
12731
12732 Note that this effect can be slow if the region is particularly
12733 complex.
12734
12735 The following code shows how an image with an alpha channel can be
12736 used to generate a mask for a widget:
12737
12738 \snippet widget-mask/main.cpp 0
12739
12740 The label shown by this code is masked using the image it contains,
12741 giving the appearance that an irregularly-shaped image is being drawn
12742 directly onto the screen.
12743
12744 Masked widgets receive mouse events only on their visible
12745 portions.
12746
12747 \sa clearMask(), windowOpacity(), {Shaped Clock Example}
12748*/
12749void QWidget::setMask(const QBitmap &bitmap)
12750{
12751 setMask(QRegion(bitmap));
12752}
12753
12754/*!
12755 \fn void QWidget::clearMask()
12756
12757 Removes any mask set by setMask().
12758
12759 \sa setMask()
12760*/
12761void QWidget::clearMask()
12762{
12763 Q_D(QWidget);
12764 if (!d->extra || !d->extra->hasMask)
12765 return;
12766 setMask(QRegion());
12767}
12768
12769void QWidgetPrivate::setWidgetParentHelper(QObject *widgetAsObject, QObject *newParent)
12770{
12771 Q_ASSERT(widgetAsObject->isWidgetType());
12772 Q_ASSERT(!newParent || newParent->isWidgetType());
12773 QWidget *widget = static_cast<QWidget*>(widgetAsObject);
12774 widget->setParent(static_cast<QWidget*>(newParent));
12775}
12776
12777void QWidgetPrivate::setNetWmWindowTypes(bool skipIfMissing)
12778{
12779 Q_Q(QWidget);
12780
12781 if (!q->windowHandle())
12782 return;
12783
12784 int wmWindowType = 0;
12785 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeDesktop))
12786 wmWindowType |= QXcbWindowFunctions::Desktop;
12787 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeDock))
12788 wmWindowType |= QXcbWindowFunctions::Dock;
12789 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeToolBar))
12790 wmWindowType |= QXcbWindowFunctions::Toolbar;
12791 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeMenu))
12792 wmWindowType |= QXcbWindowFunctions::Menu;
12793 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeUtility))
12794 wmWindowType |= QXcbWindowFunctions::Utility;
12795 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeSplash))
12796 wmWindowType |= QXcbWindowFunctions::Splash;
12797 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeDialog))
12798 wmWindowType |= QXcbWindowFunctions::Dialog;
12799 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeDropDownMenu))
12800 wmWindowType |= QXcbWindowFunctions::DropDownMenu;
12801 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypePopupMenu))
12802 wmWindowType |= QXcbWindowFunctions::PopupMenu;
12803 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeToolTip))
12804 wmWindowType |= QXcbWindowFunctions::Tooltip;
12805 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeNotification))
12806 wmWindowType |= QXcbWindowFunctions::Notification;
12807 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeCombo))
12808 wmWindowType |= QXcbWindowFunctions::Combo;
12809 if (q->testAttribute(attribute: Qt::WA_X11NetWmWindowTypeDND))
12810 wmWindowType |= QXcbWindowFunctions::Dnd;
12811
12812 if (wmWindowType == 0 && skipIfMissing)
12813 return;
12814
12815 QXcbWindowFunctions::setWmWindowType(window: q->windowHandle(), type: static_cast<QXcbWindowFunctions::WmWindowType>(wmWindowType));
12816}
12817
12818#ifndef QT_NO_DEBUG_STREAM
12819
12820static inline void formatWidgetAttributes(QDebug debug, const QWidget *widget)
12821{
12822 const QMetaObject *qtMo = qt_getEnumMetaObject(Qt::WA_AttributeCount);
12823 const QMetaEnum me = qtMo->enumerator(index: qtMo->indexOfEnumerator(name: "WidgetAttribute"));
12824 debug << ", attributes=[";
12825 int count = 0;
12826 for (int a = 0; a < Qt::WA_AttributeCount; ++a) {
12827 if (widget->testAttribute(attribute: static_cast<Qt::WidgetAttribute>(a))) {
12828 if (count++)
12829 debug << ',';
12830 debug << me.valueToKey(value: a);
12831 }
12832 }
12833 debug << ']';
12834}
12835
12836QDebug operator<<(QDebug debug, const QWidget *widget)
12837{
12838 const QDebugStateSaver saver(debug);
12839 debug.nospace();
12840 if (widget) {
12841 debug << widget->metaObject()->className() << '(' << (const void *)widget;
12842 if (!widget->objectName().isEmpty())
12843 debug << ", name=" << widget->objectName();
12844 if (debug.verbosity() > 2) {
12845 const QRect geometry = widget->geometry();
12846 const QRect frameGeometry = widget->frameGeometry();
12847 if (widget->isVisible())
12848 debug << ", visible";
12849 if (!widget->isEnabled())
12850 debug << ", disabled";
12851 debug << ", states=" << widget->windowState()
12852 << ", type=" << widget->windowType() << ", flags=" << widget->windowFlags();
12853 formatWidgetAttributes(debug, widget);
12854 if (widget->isWindow())
12855 debug << ", window";
12856 debug << ", " << geometry.width() << 'x' << geometry.height()
12857 << Qt::forcesign << geometry.x() << geometry.y() << Qt::noforcesign;
12858 if (frameGeometry != geometry) {
12859 const QMargins margins(geometry.x() - frameGeometry.x(),
12860 geometry.y() - frameGeometry.y(),
12861 frameGeometry.right() - geometry.right(),
12862 frameGeometry.bottom() - geometry.bottom());
12863 debug << ", margins=" << margins;
12864 }
12865 debug << ", devicePixelRatio=" << widget->devicePixelRatioF();
12866 if (const WId wid = widget->internalWinId())
12867 debug << ", winId=0x" << Qt::hex << wid << Qt::dec;
12868 }
12869 debug << ')';
12870 } else {
12871 debug << "QWidget(0x0)";
12872 }
12873 return debug;
12874}
12875#endif // !QT_NO_DEBUG_STREAM
12876
12877QT_END_NAMESPACE
12878
12879#include "moc_qwidget.cpp"
12880
12881

source code of qtbase/src/widgets/kernel/qwidget.cpp