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