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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/widgets/kernel/qwidget_p.h