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