1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtWidgets module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QWIDGET_P_H
41#define QWIDGET_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
49// file may change from version to version without notice, or even be removed.
50//
51// We mean it.
52//
53
54
55
56#include <QtWidgets/private/qtwidgetsglobal_p.h>
57#include "QtWidgets/qwidget.h"
58#include "private/qobject_p.h"
59#include "QtCore/qrect.h"
60#include "QtCore/qlocale.h"
61#include "QtCore/qset.h"
62#include "QtGui/qregion.h"
63#include "QtGui/qinputmethod.h"
64#include "QtGui/qopengl.h"
65#include "QtGui/qsurfaceformat.h"
66#include "QtGui/qscreen.h"
67#include "QtWidgets/qsizepolicy.h"
68#include "QtWidgets/qstyle.h"
69#include "QtWidgets/qapplication.h"
70#if QT_CONFIG(graphicseffect)
71#include <private/qgraphicseffect_p.h>
72#endif
73#if QT_CONFIG(graphicsview)
74#include "QtWidgets/qgraphicsproxywidget.h"
75#include "QtWidgets/qgraphicsscene.h"
76#include "QtWidgets/qgraphicsview.h"
77#endif
78#include <private/qgesture_p.h>
79#include <qpa/qplatformbackingstore.h>
80
81#include <vector>
82#include <memory>
83
84QT_BEGIN_NAMESPACE
85
86Q_DECLARE_LOGGING_CATEGORY(lcWidgetPainting);
87
88// Extra QWidget data
89// - to minimize memory usage for members that are seldom used.
90// - top-level widgets have extra extra data to reduce cost further
91class QWidgetWindow;
92class QPaintEngine;
93class QPixmap;
94class QWidgetRepaintManager;
95class QGraphicsProxyWidget;
96class QWidgetItemV2;
97class QOpenGLContext;
98
99class QStyle;
100
101class QUnifiedToolbarSurface;
102
103// implemented in qshortcut.cpp
104bool qWidgetShortcutContextMatcher(QObject *object, Qt::ShortcutContext context);
105
106class QUpdateLaterEvent : public QEvent
107{
108public:
109 explicit QUpdateLaterEvent(const QRegion& paintRegion)
110 : QEvent(UpdateLater), m_region(paintRegion)
111 {
112 }
113
114 ~QUpdateLaterEvent()
115 {
116 }
117
118 inline const QRegion &region() const { return m_region; }
119
120protected:
121 QRegion m_region;
122};
123
124struct QTLWExtra {
125 // *************************** Cross-platform variables *****************************
126
127 // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
128 std::unique_ptr<QIcon> icon; // widget icon
129 std::unique_ptr<QWidgetRepaintManager> repaintManager;
130 QBackingStore *backingStore;
131 QPainter *sharedPainter;
132 QWidgetWindow *window;
133#ifndef QT_NO_OPENGL
134 mutable std::unique_ptr<QOpenGLContext> shareContext;
135#endif
136
137 // Implicit pointers (shared_null).
138 QString caption; // widget caption
139 QString iconText; // widget icon text
140 QString role; // widget role
141 QString filePath; // widget file path
142
143 // Other variables.
144 short incw, inch; // size increments
145 short basew, baseh; // base sizes
146 // frame strut, don't use these directly, use QWidgetPrivate::frameStrut() instead.
147 QRect frameStrut;
148 QRect normalGeometry; // used by showMin/maximized/FullScreen
149 Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
150 QScreen *initialScreen; // Screen when passing a QDesktop[Screen]Widget as parent.
151
152#ifndef QT_NO_OPENGL
153 std::vector<std::unique_ptr<QPlatformTextureList>> widgetTextures;
154#endif
155
156 // *************************** Cross-platform bit fields ****************************
157 uint opacity : 8;
158 uint posIncludesFrame : 1;
159 uint sizeAdjusted : 1;
160 uint embedded : 1;
161};
162
163struct QWExtra {
164 // *************************** Cross-platform variables *****************************
165
166 // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
167 void *glContext; // if the widget is hijacked by QGLWindowSurface
168 std::unique_ptr<QTLWExtra> topextra; // only useful for TLWs
169#if QT_CONFIG(graphicsview)
170 QGraphicsProxyWidget *proxyWidget; // if the widget is embedded
171#endif
172#ifndef QT_NO_CURSOR
173 std::unique_ptr<QCursor> curs;
174#endif
175 QPointer<QStyle> style;
176 QPointer<QWidget> focus_proxy;
177
178 // Implicit pointers (shared_empty/shared_null).
179 QRegion mask; // widget mask
180 QString styleSheet;
181
182 // Other variables.
183 qint32 minw;
184 qint32 minh; // minimum size
185 qint32 maxw;
186 qint32 maxh; // maximum size
187 quint16 customDpiX;
188 quint16 customDpiY;
189 QSize staticContentsSize;
190
191 // *************************** Cross-platform bit fields ****************************
192 uint explicitMinSize : 2;
193 uint explicitMaxSize : 2;
194 uint autoFillBackground : 1;
195 uint nativeChildrenForced : 1;
196 uint inRenderWithPainter : 1;
197 uint hasMask : 1;
198 uint hasWindowContainer : 1;
199};
200
201/*!
202 \internal
203
204 Returns \c true if \a p or any of its parents enable the
205 Qt::BypassGraphicsProxyWidget window flag. Used in QWidget::show() and
206 QWidget::setParent() to determine whether it's necessary to embed the
207 widget into a QGraphicsProxyWidget or not.
208*/
209static inline bool bypassGraphicsProxyWidget(const QWidget *p)
210{
211 while (p) {
212 if (p->windowFlags() & Qt::BypassGraphicsProxyWidget)
213 return true;
214 p = p->parentWidget();
215 }
216 return false;
217}
218
219class Q_WIDGETS_EXPORT QWidgetPrivate : public QObjectPrivate
220{
221 Q_DECLARE_PUBLIC(QWidget)
222 Q_GADGET
223
224public:
225 // *************************** Cross-platform ***************************************
226 enum DrawWidgetFlag {
227 DrawAsRoot = 0x01,
228 DrawPaintOnScreen = 0x02,
229 DrawRecursive = 0x04,
230 DrawInvisible = 0x08,
231 DontSubtractOpaqueChildren = 0x10,
232 DontDrawOpaqueChildren = 0x20,
233 DontDrawNativeChildren = 0x40,
234 DontSetCompositionMode = 0x80
235 };
236 Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag)
237 Q_FLAG(DrawWidgetFlags)
238
239 enum CloseMode {
240 CloseNoEvent,
241 CloseWithEvent,
242 CloseWithSpontaneousEvent
243 };
244 Q_ENUM(CloseMode)
245
246 enum Direction {
247 DirectionNorth = 0x01,
248 DirectionEast = 0x10,
249 DirectionSouth = 0x02,
250 DirectionWest = 0x20
251 };
252 Q_ENUM(Direction)
253
254 // Functions.
255 explicit QWidgetPrivate(int version = QObjectPrivateVersion);
256 ~QWidgetPrivate();
257
258 static QWidgetPrivate *get(QWidget *w) { return w->d_func(); }
259 static const QWidgetPrivate *get(const QWidget *w) { return w->d_func(); }
260
261 QWExtra *extraData() const;
262 QTLWExtra *topData() const;
263 QTLWExtra *maybeTopData() const;
264 QPainter *sharedPainter() const;
265 void setSharedPainter(QPainter *painter);
266 QWidgetRepaintManager *maybeRepaintManager() const;
267
268 enum class WindowHandleMode {
269 Direct,
270 Closest,
271 TopLevel
272 };
273 QWindow *windowHandle(WindowHandleMode mode = WindowHandleMode::Direct) const;
274 QWindow *_q_closestWindowHandle() const; // Private slot in QWidget
275
276 QScreen *associatedScreen() const;
277
278 template <typename T>
279 void repaint(T t);
280
281 template <typename T>
282 void update(T t);
283
284 void init(QWidget *desktopWidget, Qt::WindowFlags f);
285 void create();
286 void createRecursively();
287 void createWinId();
288
289 bool setScreenForPoint(const QPoint &pos);
290 bool setScreen(QScreen *screen);
291
292 void createTLExtra();
293 void createExtra();
294 void deleteExtra();
295 void createSysExtra();
296 void deleteSysExtra();
297 void createTLSysExtra();
298 void deleteTLSysExtra();
299 void updateSystemBackground();
300 void propagatePaletteChange();
301
302 void setPalette_helper(const QPalette &);
303 void resolvePalette();
304 QPalette naturalWidgetPalette(QPalette::ResolveMask inheritedMask) const;
305
306 void setMask_sys(const QRegion &);
307
308 void raise_sys();
309 void lower_sys();
310 void stackUnder_sys(QWidget *);
311
312 QWidget *deepestFocusProxy() const;
313 void setFocus_sys();
314 void updateFocusChild();
315
316 void updateFont(const QFont &);
317 inline void setFont_helper(const QFont &font) {
318 if (directFontResolveMask == font.resolveMask() && data.fnt == font)
319 return;
320 updateFont(font);
321 }
322 QFont localFont() const;
323 void resolveFont();
324 QFont naturalWidgetFont(uint inheritedMask) const;
325
326 void setLayoutDirection_helper(Qt::LayoutDirection);
327 void resolveLayoutDirection();
328
329 void setLocale_helper(const QLocale &l, bool forceUpdate = false);
330 void resolveLocale();
331
332 void setStyle_helper(QStyle *newStyle, bool propagate);
333 void inheritStyle();
334
335 void setUpdatesEnabled_helper(bool );
336
337 bool updateBrushOrigin(QPainter *, const QBrush &brush) const;
338 void paintBackground(QPainter *, const QRegion &, DrawWidgetFlags flags = DrawAsRoot) const;
339 bool isAboutToShow() const;
340 QRegion prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags);
341 void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion,
342 QWidget::RenderFlags renderFlags);
343 void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion,
344 QWidget::RenderFlags renderFlags);
345 void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, DrawWidgetFlags flags,
346 QPainter *sharedPainter = nullptr, QWidgetRepaintManager *repaintManager = nullptr);
347 void sendPaintEvent(const QRegion &toBePainted);
348
349
350 void paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& children, int index,
351 const QRegion &rgn, const QPoint &offset, DrawWidgetFlags flags,
352 QPainter *sharedPainter, QWidgetRepaintManager *repaintManager);
353
354#if QT_CONFIG(graphicsview)
355 static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin);
356#endif
357 bool shouldPaintOnScreen() const;
358 void paintOnScreen(const QRegion &rgn);
359
360 QRect clipRect() const;
361 QRegion clipRegion() const;
362 void setSystemClip(QPaintEngine *paintEngine, qreal devicePixelRatio, const QRegion &region);
363 void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const;
364 void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = nullptr,
365 bool alsoNonOpaque = false) const;
366 void clipToEffectiveMask(QRegion &region) const;
367 void updateIsOpaque();
368 void setOpaque(bool opaque);
369 void updateIsTranslucent();
370#if QT_CONFIG(graphicseffect)
371 void invalidateGraphicsEffectsRecursively();
372#endif // QT_CONFIG(graphicseffect)
373
374 const QRegion &getOpaqueChildren() const;
375 void setDirtyOpaqueRegion();
376
377 bool close_helper(CloseMode mode);
378
379 void setWindowIcon_helper();
380 void setWindowIcon_sys();
381 void setWindowOpacity_sys(qreal opacity);
382 void adjustQuitOnCloseAttribute();
383
384 void scrollChildren(int dx, int dy);
385 void moveRect(const QRect &, int dx, int dy);
386 void scrollRect(const QRect &, int dx, int dy);
387 void invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize);
388
389 template <class T>
390 void invalidateBackingStore(const T &);
391
392 QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const;
393 void syncBackingStore();
394 void syncBackingStore(const QRegion &region);
395
396 bool shouldDiscardSyncRequest() const;
397
398 // tells the input method about the widgets transform
399 void updateWidgetTransform(QEvent *event);
400
401 void reparentFocusWidgets(QWidget *oldtlw);
402
403 void setWinId(WId);
404 void showChildren(bool spontaneous);
405 void hideChildren(bool spontaneous);
406 void setParent_sys(QWidget *parent, Qt::WindowFlags);
407 void scroll_sys(int dx, int dy);
408 void scroll_sys(int dx, int dy, const QRect &r);
409 void deactivateWidgetCleanup();
410 void setGeometry_sys(int, int, int, int, bool);
411 void fixPosIncludesFrame();
412 void sendPendingMoveAndResizeEvents(bool recursive = false, bool disableUpdates = false);
413 void activateChildLayoutsRecursively();
414 void show_recursive();
415 void show_helper();
416 void show_sys();
417 void hide_sys();
418 void hide_helper();
419 void _q_showIfNotHidden();
420 void setVisible(bool);
421
422 void setEnabled_helper(bool);
423 static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = nullptr);
424
425 void updateFrameStrut();
426 QRect frameStrut() const;
427
428#ifdef QT_KEYPAD_NAVIGATION
429 static bool navigateToDirection(Direction direction);
430 static QWidget *widgetInNavigationDirection(Direction direction);
431 static bool canKeypadNavigate(Qt::Orientation orientation);
432 static bool inTabWidget(QWidget *widget);
433#endif
434
435 void setWindowIconText_sys(const QString &cap);
436 void setWindowIconText_helper(const QString &cap);
437 void setWindowTitle_sys(const QString &cap);
438 void setWindowFilePath_sys(const QString &filePath);
439
440#ifndef QT_NO_CURSOR
441 void setCursor_sys(const QCursor &cursor);
442 void unsetCursor_sys();
443#endif
444
445 void setWindowTitle_helper(const QString &cap);
446 void setWindowFilePath_helper(const QString &filePath);
447 void setWindowModified_helper();
448 virtual void setWindowFlags(Qt::WindowFlags windowFlags);
449
450 bool setMinimumSize_helper(int &minw, int &minh);
451 bool setMaximumSize_helper(int &maxw, int &maxh);
452 void setConstraints_sys();
453 bool pointInsideRectAndMask(const QPoint &) const;
454 QWidget *childAt_helper(const QPoint &, bool) const;
455 QWidget *childAtRecursiveHelper(const QPoint &p, bool) const;
456 void updateGeometry_helper(bool forceUpdate);
457
458 void getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const;
459 void setLayoutItemMargins(int left, int top, int right, int bottom);
460 void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = nullptr);
461
462 void updateContentsRect();
463 QMargins safeAreaMargins() const;
464
465 // aboutToDestroy() is called just before the contents of
466 // QWidget::destroy() is executed. It's used to signal QWidget
467 // sub-classes that their internals are about to be released.
468 virtual void aboutToDestroy() {}
469
470 inline QWidget *effectiveFocusWidget() {
471 QWidget *w = q_func();
472 while (w->focusProxy())
473 w = w->focusProxy();
474 return w;
475 }
476
477 void setModal_sys();
478
479 // These helper functions return the (available) geometry for the screen
480 // the widget is on, and takes care if this one is embedded in a QGraphicsView.
481 static QRect graphicsViewParentRect(const QWidget *widget)
482 {
483 QRect rect;
484#if QT_CONFIG(graphicsview)
485 QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget);
486 //It's embedded if it has an ancestor
487 if (ancestorProxy) {
488 if (!bypassGraphicsProxyWidget(widget) && ancestorProxy->scene() != nullptr) {
489 // One view, let be smart and return the viewport rect then the popup is aligned
490 if (ancestorProxy->scene()->views().size() == 1) {
491 QGraphicsView *view = ancestorProxy->scene()->views().at(0);
492 rect = view->mapToScene(view->viewport()->rect()).boundingRect().toRect();
493 } else {
494 rect = ancestorProxy->scene()->sceneRect().toRect();
495 }
496 }
497 }
498#else
499 Q_UNUSED(widget);
500#endif
501 return rect;
502 }
503
504 static QRect screenGeometry(const QWidget *widget)
505 {
506 return screenGeometry(widget, QPoint(), false);
507 }
508
509 static QRect availableScreenGeometry(const QWidget *widget)
510 {
511 return availableScreenGeometry(widget, QPoint(), false);
512 }
513
514 static QRect screenGeometry(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true)
515 {
516 QRect rect = graphicsViewParentRect(widget);
517 if (!rect.isNull())
518 return rect;
519
520 QScreen *screen = nullptr;
521 if (hasPosition)
522 screen = widget->screen()->virtualSiblingAt(globalPosition);
523 if (!screen)
524 screen = widget->screen();
525
526 return screen->geometry();
527 }
528
529 static QRect availableScreenGeometry(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true)
530 {
531 QRect rect = graphicsViewParentRect(widget);
532 if (!rect.isNull())
533 return rect;
534
535 QScreen *screen = nullptr;
536 if (hasPosition)
537 screen = widget->screen()->virtualSiblingAt(globalPosition);
538 if (!screen)
539 screen = widget->screen();
540
541 return screen->availableGeometry();
542 }
543
544 inline void setRedirected(QPaintDevice *replacement, const QPoint &offset)
545 {
546 Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent));
547 redirectDev = replacement;
548 redirectOffset = offset;
549 }
550
551 inline QPaintDevice *redirected(QPoint *offset) const
552 {
553 if (offset)
554 *offset = redirectDev ? redirectOffset : QPoint();
555 return redirectDev;
556 }
557
558 inline void restoreRedirected()
559 { redirectDev = nullptr; }
560
561 inline void enforceNativeChildren()
562 {
563 if (!extra)
564 createExtra();
565
566 if (extra->nativeChildrenForced)
567 return;
568 extra->nativeChildrenForced = 1;
569
570 for (int i = 0; i < children.size(); ++i) {
571 if (QWidget *child = qobject_cast<QWidget *>(children.at(i)))
572 child->setAttribute(Qt::WA_NativeWindow);
573 }
574 }
575
576 inline bool nativeChildrenForced() const
577 {
578 return extra ? extra->nativeChildrenForced : false;
579 }
580
581 inline QRect effectiveRectFor(const QRegion &region) const
582 {
583 return effectiveRectFor(region.boundingRect());
584 }
585
586 inline QRect effectiveRectFor(const QRect &rect) const
587 {
588#if QT_CONFIG(graphicseffect)
589 if (graphicsEffect && graphicsEffect->isEnabled())
590 return graphicsEffect->boundingRectFor(rect).toAlignedRect();
591#endif // QT_CONFIG(graphicseffect)
592 return rect;
593 }
594
595 QSize adjustedSize() const;
596
597 inline void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
598 {
599 Q_Q(QWidget);
600 if (button == Qt::LeftButton && qApp->autoSipEnabled()) {
601 QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
602 q->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
603 if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
604 QGuiApplication::inputMethod()->show();
605 }
606 }
607 }
608
609 void setWSGeometry();
610
611 inline QPoint mapToWS(const QPoint &p) const
612 { return p - data.wrect.topLeft(); }
613
614 inline QPoint mapFromWS(const QPoint &p) const
615 { return p + data.wrect.topLeft(); }
616
617 inline QRect mapToWS(const QRect &r) const
618 { return r.translated(-data.wrect.topLeft()); }
619
620 inline QRect mapFromWS(const QRect &r) const
621 { return r.translated(data.wrect.topLeft()); }
622
623 QOpenGLContext *shareContext() const;
624
625 virtual QObject *focusObject() { return nullptr; }
626
627#ifndef QT_NO_OPENGL
628 virtual GLuint textureId() const { return 0; }
629 virtual QPlatformTextureList::Flags textureListFlags() {
630 Q_Q(QWidget);
631 return q->testAttribute(Qt::WA_AlwaysStackOnTop)
632 ? QPlatformTextureList::StacksOnTop
633 : QPlatformTextureList::Flags();
634 }
635 virtual QImage grabFramebuffer() { return QImage(); }
636 virtual void beginBackingStorePainting() { }
637 virtual void endBackingStorePainting() { }
638 virtual void beginCompose() { }
639 virtual void endCompose() { }
640 void setRenderToTexture() { renderToTexture = true; setTextureChildSeen(); }
641 void setTextureChildSeen()
642 {
643 Q_Q(QWidget);
644 if (textureChildSeen)
645 return;
646 textureChildSeen = 1;
647
648 if (!q->isWindow()) {
649 QWidget *parent = q->parentWidget();
650 if (parent)
651 get(parent)->setTextureChildSeen();
652 }
653 }
654 static void sendComposeStatus(QWidget *w, bool end);
655 // Called on setViewport().
656 virtual void initializeViewportFramebuffer() { }
657 // When using a QOpenGLWidget as viewport with QAbstractScrollArea, resize events are
658 // filtered away from the widget. This is fine for QGLWidget but bad for QOpenGLWidget
659 // since the fbo must be resized. We need an alternative way to notify.
660 virtual void resizeViewportFramebuffer() { }
661 // Called after each paint event.
662 virtual void resolveSamples() { }
663#endif
664
665 static void setWidgetParentHelper(QObject *widgetAsObject, QObject *newParent);
666
667 // Variables.
668 // Regular pointers (keep them together to avoid gaps on 64 bit architectures).
669 std::unique_ptr<QWExtra> extra;
670 QWidget *focus_next;
671 QWidget *focus_prev;
672 QWidget *focus_child;
673 QLayout *layout;
674 QRegion *needsFlush;
675 QPaintDevice *redirectDev;
676 QWidgetItemV2 *widgetItem;
677 QPaintEngine *extraPaintEngine;
678 mutable const QMetaObject *polished;
679 QGraphicsEffect *graphicsEffect;
680 // All widgets are added into the allWidgets set. Once
681 // they receive a window id they are also added to the mapper.
682 // This should just ensure that all widgets are deleted by QApplication
683 static QWidgetMapper *mapper;
684 static QWidgetSet *allWidgets;
685#if !defined(QT_NO_IM)
686 Qt::InputMethodHints imHints;
687#endif
688#ifdef QT_KEYPAD_NAVIGATION
689 static QPointer<QWidget> editingWidget;
690#endif
691
692 // Implicit pointers (shared_null/shared_empty).
693 QRegion opaqueChildren;
694 QRegion dirty;
695#if QT_CONFIG(tooltip)
696 QString toolTip;
697 int toolTipDuration;
698#endif
699#if QT_CONFIG(statustip)
700 QString statusTip;
701#endif
702#if QT_CONFIG(whatsthis)
703 QString whatsThis;
704#endif
705#ifndef QT_NO_ACCESSIBILITY
706 QString accessibleName;
707 QString accessibleDescription;
708#endif
709
710 // Other variables.
711 uint directFontResolveMask;
712 uint inheritedFontResolveMask;
713 decltype(std::declval<QPalette>().resolveMask()) directPaletteResolveMask;
714 QPalette::ResolveMask inheritedPaletteResolveMask;
715 short leftmargin;
716 short topmargin;
717 short rightmargin;
718 short bottommargin;
719 signed char leftLayoutItemMargin;
720 signed char topLayoutItemMargin;
721 signed char rightLayoutItemMargin;
722 signed char bottomLayoutItemMargin;
723 static int instanceCounter; // Current number of widget instances
724 static int maxInstances; // Maximum number of widget instances
725 Qt::HANDLE hd;
726 QWidgetData data;
727 QSizePolicy size_policy;
728 QLocale locale;
729 QPoint redirectOffset;
730#ifndef QT_NO_ACTION
731 QList<QAction*> actions;
732#endif
733#ifndef QT_NO_GESTURES
734 QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
735#endif
736
737 // Bit fields.
738 uint high_attributes[4]; // the low ones are in QWidget::widget_attributes
739 QPalette::ColorRole fg_role : 8;
740 QPalette::ColorRole bg_role : 8;
741 uint dirtyOpaqueChildren : 1;
742 uint isOpaque : 1;
743 uint retainSizeWhenHiddenChanged : 1;
744 uint inDirtyList : 1;
745 uint isScrolled : 1;
746 uint isMoved : 1;
747 uint usesDoubleBufferedGLContext : 1;
748 uint mustHaveWindowHandle : 1;
749 uint renderToTexture : 1;
750 uint textureChildSeen : 1;
751#ifndef QT_NO_IM
752 uint inheritsInputMethodHints : 1;
753#endif
754#ifndef QT_NO_OPENGL
755 uint renderToTextureReallyDirty : 1;
756 uint renderToTextureComposeActive : 1;
757#endif
758 uint childrenHiddenByWState : 1;
759 uint childrenShownByExpose : 1;
760
761 // *************************** Platform specific ************************************
762#if defined(Q_OS_WIN)
763 uint noPaintOnScreen : 1; // see qwidget.cpp ::paintEngine()
764#elif defined(Q_OS_MAC)
765 void macUpdateSizeAttribute();
766#endif
767 void setNetWmWindowTypes(bool skipIfMissing = false);
768
769 bool stealKeyboardGrab(bool grab);
770 bool stealMouseGrab(bool grab);
771};
772
773Q_DECLARE_OPERATORS_FOR_FLAGS(QWidgetPrivate::DrawWidgetFlags)
774
775struct QWidgetPaintContext
776{
777 inline QWidgetPaintContext(QPaintDevice *d, const QRegion &r, const QPoint &o, QWidgetPrivate::DrawWidgetFlags f,
778 QPainter *p, QWidgetRepaintManager *rpm)
779 : pdev(d), rgn(r), offset(o), flags(f), sharedPainter(p), repaintManager(rpm), painter(nullptr) {}
780
781 QPaintDevice *pdev;
782 QRegion rgn;
783 QPoint offset;
784 QWidgetPrivate::DrawWidgetFlags flags;
785 QPainter *sharedPainter;
786 QWidgetRepaintManager *repaintManager;
787 QPainter *painter;
788};
789
790#if QT_CONFIG(graphicseffect)
791class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
792{
793public:
794 QWidgetEffectSourcePrivate(QWidget *widget)
795 : QGraphicsEffectSourcePrivate(), m_widget(widget), context(nullptr), updateDueToGraphicsEffect(false)
796 {}
797
798 void detach() override
799 { m_widget->d_func()->graphicsEffect = nullptr; }
800
801 const QGraphicsItem *graphicsItem() const override
802 { return nullptr; }
803
804 const QWidget *widget() const override
805 { return m_widget; }
806
807 void update() override
808 {
809 updateDueToGraphicsEffect = true;
810 m_widget->update();
811 updateDueToGraphicsEffect = false;
812 }
813
814 bool isPixmap() const override
815 { return false; }
816
817 void effectBoundingRectChanged() override
818 {
819 // ### This function should take a rect parameter; then we can avoid
820 // updating too much on the parent widget.
821 if (QWidget *parent = m_widget->parentWidget())
822 parent->update();
823 else
824 update();
825 }
826
827 const QStyleOption *styleOption() const override
828 { return nullptr; }
829
830 QRect deviceRect() const override
831 { return m_widget->window()->rect(); }
832
833 QRectF boundingRect(Qt::CoordinateSystem system) const override;
834 void draw(QPainter *p) override;
835 QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset,
836 QGraphicsEffect::PixmapPadMode mode) const override;
837
838 QWidget *m_widget;
839 QWidgetPaintContext *context;
840 QTransform lastEffectTransform;
841 bool updateDueToGraphicsEffect;
842};
843#endif // QT_CONFIG(graphicseffect)
844
845inline QWExtra *QWidgetPrivate::extraData() const
846{
847 return extra.get();
848}
849
850inline QTLWExtra *QWidgetPrivate::topData() const
851{
852 const_cast<QWidgetPrivate *>(this)->createTLExtra();
853 return extra->topextra.get();
854}
855
856inline QTLWExtra *QWidgetPrivate::maybeTopData() const
857{
858 return extra ? extra->topextra.get() : nullptr;
859}
860
861inline QPainter *QWidgetPrivate::sharedPainter() const
862{
863 Q_Q(const QWidget);
864 QTLWExtra *x = q->window()->d_func()->maybeTopData();
865 return x ? x->sharedPainter : nullptr;
866}
867
868inline void QWidgetPrivate::setSharedPainter(QPainter *painter)
869{
870 Q_Q(QWidget);
871 QTLWExtra *x = q->window()->d_func()->topData();
872 x->sharedPainter = painter;
873}
874
875inline bool QWidgetPrivate::pointInsideRectAndMask(const QPoint &p) const
876{
877 Q_Q(const QWidget);
878 return q->rect().contains(p) && (!extra || !extra->hasMask || q->testAttribute(Qt::WA_MouseNoMask)
879 || extra->mask.contains(p));
880}
881
882inline QWidgetRepaintManager *QWidgetPrivate::maybeRepaintManager() const
883{
884 Q_Q(const QWidget);
885 QTLWExtra *x = q->window()->d_func()->maybeTopData();
886 return x ? x->repaintManager.get() : nullptr;
887}
888
889QT_END_NAMESPACE
890
891#endif // QWIDGET_P_H
892