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
78QT_BEGIN_NAMESPACE
79
80// Extra QWidget data
81// - to minimize memory usage for members that are seldom used.
82// - top-level widgets have extra extra data to reduce cost further
83class QWidgetWindow;
84class QPaintEngine;
85class QPixmap;
86class QWidgetBackingStore;
87class QGraphicsProxyWidget;
88class QWidgetItemV2;
89class QOpenGLContext;
90
91class QStyle;
92
93class QUnifiedToolbarSurface;
94
95// implemented in qshortcut.cpp
96bool qWidgetShortcutContextMatcher(QObject *object, Qt::ShortcutContext context);
97
98class QUpdateLaterEvent : public QEvent
99{
100public:
101 explicit QUpdateLaterEvent(const QRegion& paintRegion)
102 : QEvent(UpdateLater), m_region(paintRegion)
103 {
104 }
105
106 ~QUpdateLaterEvent()
107 {
108 }
109
110 inline const QRegion &region() const { return m_region; }
111
112protected:
113 QRegion m_region;
114};
115
116
117
118class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
119{
120
121public:
122 QWidgetBackingStoreTracker();
123 ~QWidgetBackingStoreTracker();
124
125 void create(QWidget *tlw);
126 void destroy();
127
128 void registerWidget(QWidget *w);
129 void unregisterWidget(QWidget *w);
130 void unregisterWidgetSubtree(QWidget *w);
131
132 inline QWidgetBackingStore* data()
133 {
134 return m_ptr;
135 }
136
137 inline QWidgetBackingStore* operator->()
138 {
139 return m_ptr;
140 }
141
142 inline QWidgetBackingStore& operator*()
143 {
144 return *m_ptr;
145 }
146
147 inline operator bool() const
148 {
149 return (nullptr != m_ptr);
150 }
151
152private:
153 Q_DISABLE_COPY_MOVE(QWidgetBackingStoreTracker)
154
155private:
156 QWidgetBackingStore* m_ptr;
157 QSet<QWidget *> m_widgets;
158};
159
160struct QTLWExtra {
161 // *************************** Cross-platform variables *****************************
162
163 // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
164 QIcon *icon; // widget icon
165 QWidgetBackingStoreTracker backingStoreTracker;
166 QBackingStore *backingStore;
167 QPainter *sharedPainter;
168 QWidgetWindow *window;
169 QOpenGLContext *shareContext;
170
171 // Implicit pointers (shared_null).
172 QString caption; // widget caption
173 QString iconText; // widget icon text
174 QString role; // widget role
175 QString filePath; // widget file path
176
177 // Other variables.
178 short incw, inch; // size increments
179 short basew, baseh; // base sizes
180 // frame strut, don't use these directly, use QWidgetPrivate::frameStrut() instead.
181 QRect frameStrut;
182 QRect normalGeometry; // used by showMin/maximized/FullScreen
183 Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
184 // ### TODO replace initialScreenIndex with QScreen *, in case the screens change at runtime
185 int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent.
186
187 QVector<QPlatformTextureList *> widgetTextures;
188
189 // *************************** Cross-platform bit fields ****************************
190 uint opacity : 8;
191 uint posIncludesFrame : 1;
192 uint sizeAdjusted : 1;
193 uint inTopLevelResize : 1;
194 uint embedded : 1;
195
196 // *************************** Platform specific values (bit fields first) **********
197#if 0 /* Used to be included in Qt4 for Q_WS_X11 */ // <----------------------------------------------------------- X11
198 uint spont_unmapped: 1; // window was spontaneously unmapped
199 uint dnd : 1; // DND properties installed
200 uint validWMState : 1; // is WM_STATE valid?
201 uint waitingForMapNotify : 1; // show() has been called, haven't got the MapNotify yet
202 WId parentWinId; // parent window Id (valid after reparenting)
203 WId userTimeWindow; // window id that contains user-time timestamp when WM supports a _NET_WM_USER_TIME_WINDOW atom
204 QPoint fullScreenOffset;
205#ifndef QT_NO_XSYNC
206 WId syncUpdateCounter;
207 ulong syncRequestTimestamp;
208 qint32 newCounterValueHi;
209 quint32 newCounterValueLo;
210#endif
211#elif 0 /* Used to be included in Qt4 for Q_WS_WIN */ // <--------------------------------------------------------- WIN
212 uint hotkeyRegistered: 1; // Hot key from the STARTUPINFO has been registered.
213 HICON winIconBig; // internal big Windows icon
214 HICON winIconSmall; // internal small Windows icon
215#elif 0 /* Used to be included in Qt4 for Q_WS_MAC */ // <--------------------------------------------------------- MAC
216 uint resizer : 4;
217 uint isSetGeometry : 1;
218 uint isMove : 1;
219 quint32 wattr;
220 quint32 wclass;
221 WindowGroupRef group;
222 IconRef windowIcon; // the current window icon, if set with setWindowIcon_sys.
223 quint32 savedWindowAttributesFromMaximized; // Saved attributes from when the calling updateMaximizeButton_sys()
224 // This value is just to make sure we maximize and restore to the right location, yet we allow apps to be maximized and
225 // manually resized.
226 // The name is misleading, since this is set when maximizing the window. It is a hint to saveGeometry(..) to record the
227 // starting position as 0,0 instead of the normal starting position.
228 bool wasMaximized;
229#endif
230};
231
232struct QWExtra {
233 // *************************** Cross-platform variables *****************************
234
235 // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
236 void *glContext; // if the widget is hijacked by QGLWindowSurface
237 QTLWExtra *topextra; // only useful for TLWs
238#if QT_CONFIG(graphicsview)
239 QGraphicsProxyWidget *proxyWidget; // if the widget is embedded
240#endif
241#ifndef QT_NO_CURSOR
242 QCursor *curs;
243#endif
244 QPointer<QStyle> style;
245 QPointer<QWidget> focus_proxy;
246
247 // Implicit pointers (shared_empty/shared_null).
248 QRegion mask; // widget mask
249 QString styleSheet;
250
251 // Other variables.
252 qint32 minw;
253 qint32 minh; // minimum size
254 qint32 maxw;
255 qint32 maxh; // maximum size
256 quint16 customDpiX;
257 quint16 customDpiY;
258 QSize staticContentsSize;
259
260 // *************************** Cross-platform bit fields ****************************
261 uint explicitMinSize : 2;
262 uint explicitMaxSize : 2;
263 uint autoFillBackground : 1;
264 uint nativeChildrenForced : 1;
265 uint inRenderWithPainter : 1;
266 uint hasMask : 1;
267 uint hasWindowContainer : 1;
268
269 // *************************** Platform specific values (bit fields first) **********
270#if 0 /* Used to be included in Qt4 for Q_WS_WIN */ // <----------------------------------------------------------- WIN
271#if QT_CONFIG(draganddrop)
272 QOleDropTarget *dropTarget; // drop target
273 QList<QPointer<QWidget> > oleDropWidgets;
274#endif
275#elif 0 /* Used to be included in Qt4 for Q_WS_X11 */ // <--------------------------------------------------------- X11
276 uint compress_events : 1;
277 WId xDndProxy; // XDND forwarding to embedded windows
278#elif 0 /* Used to be included in Qt4 for Q_WS_MAC */ // <------------------------------------------------------ MAC
279 // Cocoa Mask stuff
280 QImage maskBits;
281 CGImageRef imageMask;
282#endif
283};
284
285/*!
286 \internal
287
288 Returns \c true if \a p or any of its parents enable the
289 Qt::BypassGraphicsProxyWidget window flag. Used in QWidget::show() and
290 QWidget::setParent() to determine whether it's necessary to embed the
291 widget into a QGraphicsProxyWidget or not.
292*/
293static inline bool bypassGraphicsProxyWidget(const QWidget *p)
294{
295 while (p) {
296 if (p->windowFlags() & Qt::BypassGraphicsProxyWidget)
297 return true;
298 p = p->parentWidget();
299 }
300 return false;
301}
302
303class Q_WIDGETS_EXPORT QWidgetPrivate : public QObjectPrivate
304{
305 Q_DECLARE_PUBLIC(QWidget)
306
307public:
308 // *************************** Cross-platform ***************************************
309 enum DrawWidgetFlags {
310 DrawAsRoot = 0x01,
311 DrawPaintOnScreen = 0x02,
312 DrawRecursive = 0x04,
313 DrawInvisible = 0x08,
314 DontSubtractOpaqueChildren = 0x10,
315 DontDrawOpaqueChildren = 0x20,
316 DontDrawNativeChildren = 0x40,
317 DontSetCompositionMode = 0x80
318 };
319
320 enum CloseMode {
321 CloseNoEvent,
322 CloseWithEvent,
323 CloseWithSpontaneousEvent
324 };
325
326 enum Direction {
327 DirectionNorth = 0x01,
328 DirectionEast = 0x10,
329 DirectionSouth = 0x02,
330 DirectionWest = 0x20
331 };
332
333 // Functions.
334 explicit QWidgetPrivate(int version = QObjectPrivateVersion);
335 ~QWidgetPrivate();
336
337 static QWidgetPrivate *get(QWidget *w) { return w->d_func(); }
338 static const QWidgetPrivate *get(const QWidget *w) { return w->d_func(); }
339
340 QWExtra *extraData() const;
341 QTLWExtra *topData() const;
342 QTLWExtra *maybeTopData() const;
343 QPainter *sharedPainter() const;
344 void setSharedPainter(QPainter *painter);
345 QWidgetBackingStore *maybeBackingStore() const;
346
347 enum class WindowHandleMode {
348 Direct,
349 Closest,
350 TopLevel
351 };
352 QWindow *windowHandle(WindowHandleMode mode = WindowHandleMode::Direct) const;
353
354 QScreen *associatedScreen() const;
355
356 template <typename T>
357 void repaint(T t);
358
359 template <typename T>
360 void update(T t);
361
362 void init(QWidget *desktopWidget, Qt::WindowFlags f);
363 void create();
364 void createRecursively();
365 void createWinId();
366
367 bool setScreenForPoint(const QPoint &pos);
368 bool setScreen(QScreen *screen);
369
370 void createTLExtra();
371 void createExtra();
372 void deleteExtra();
373 void createSysExtra();
374 void deleteSysExtra();
375 void createTLSysExtra();
376 void deleteTLSysExtra();
377 void updateSystemBackground();
378 void propagatePaletteChange();
379
380 void setPalette_helper(const QPalette &);
381 void resolvePalette();
382 QPalette naturalWidgetPalette(uint inheritedMask) const;
383
384 void setMask_sys(const QRegion &);
385
386 void raise_sys();
387 void lower_sys();
388 void stackUnder_sys(QWidget *);
389
390 QWidget *deepestFocusProxy() const;
391 void setFocus_sys();
392 void updateFocusChild();
393
394 void updateFont(const QFont &);
395 inline void setFont_helper(const QFont &font) {
396 if (directFontResolveMask == font.resolve() && data.fnt == font)
397 return;
398 updateFont(font);
399 }
400 QFont localFont() const;
401 void resolveFont();
402 QFont naturalWidgetFont(uint inheritedMask) const;
403
404 void setLayoutDirection_helper(Qt::LayoutDirection);
405 void resolveLayoutDirection();
406
407 void setLocale_helper(const QLocale &l, bool forceUpdate = false);
408 void resolveLocale();
409
410 void setStyle_helper(QStyle *newStyle, bool propagate);
411 void inheritStyle();
412
413 void setUpdatesEnabled_helper(bool );
414
415 bool updateBrushOrigin(QPainter *, const QBrush &brush) const;
416 void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const;
417 bool isAboutToShow() const;
418 QRegion prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags);
419 void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion,
420 QWidget::RenderFlags renderFlags);
421 void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion,
422 QWidget::RenderFlags renderFlags);
423 void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
424 QPainter *sharedPainter = nullptr, QWidgetBackingStore *backingStore = nullptr);
425 void sendPaintEvent(const QRegion &toBePainted);
426
427
428 void paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& children, int index,
429 const QRegion &rgn, const QPoint &offset, int flags,
430 QPainter *sharedPainter, QWidgetBackingStore *backingStore);
431
432#if QT_CONFIG(graphicsview)
433 static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin);
434#endif
435 void repaint_sys(const QRegion &rgn);
436
437 QRect clipRect() const;
438 QRegion clipRegion() const;
439 void setSystemClip(QPaintEngine *paintEngine, qreal devicePixelRatio, const QRegion &region);
440 void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const;
441 void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = nullptr,
442 bool alsoNonOpaque = false) const;
443 void clipToEffectiveMask(QRegion &region) const;
444 void updateIsOpaque();
445 void setOpaque(bool opaque);
446 void updateIsTranslucent();
447 bool paintOnScreen() const;
448#if QT_CONFIG(graphicseffect)
449 void invalidateGraphicsEffectsRecursively();
450#endif // QT_CONFIG(graphicseffect)
451
452 const QRegion &getOpaqueChildren() const;
453 void setDirtyOpaqueRegion();
454
455 bool close_helper(CloseMode mode);
456
457 void setWindowIcon_helper();
458 void setWindowIcon_sys();
459 void setWindowOpacity_sys(qreal opacity);
460 void adjustQuitOnCloseAttribute();
461
462 void scrollChildren(int dx, int dy);
463 void moveRect(const QRect &, int dx, int dy);
464 void scrollRect(const QRect &, int dx, int dy);
465 void invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize);
466
467 template <class T>
468 void invalidateBackingStore(const T &);
469
470 QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const;
471 void syncBackingStore();
472 void syncBackingStore(const QRegion &region);
473
474 // tells the input method about the widgets transform
475 void updateWidgetTransform(QEvent *event);
476
477 void reparentFocusWidgets(QWidget *oldtlw);
478
479 static int pointToRect(const QPoint &p, const QRect &r);
480
481 void setWinId(WId);
482 void showChildren(bool spontaneous);
483 void hideChildren(bool spontaneous);
484 void setParent_sys(QWidget *parent, Qt::WindowFlags);
485 void scroll_sys(int dx, int dy);
486 void scroll_sys(int dx, int dy, const QRect &r);
487 void deactivateWidgetCleanup();
488 void setGeometry_sys(int, int, int, int, bool);
489 void fixPosIncludesFrame();
490 void sendPendingMoveAndResizeEvents(bool recursive = false, bool disableUpdates = false);
491 void activateChildLayoutsRecursively();
492 void show_recursive();
493 void show_helper();
494 void show_sys();
495 void hide_sys();
496 void hide_helper();
497 void _q_showIfNotHidden();
498 void setVisible(bool);
499
500 void setEnabled_helper(bool);
501 static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0);
502
503 void updateFrameStrut();
504 QRect frameStrut() const;
505
506#ifdef QT_KEYPAD_NAVIGATION
507 static bool navigateToDirection(Direction direction);
508 static QWidget *widgetInNavigationDirection(Direction direction);
509 static bool canKeypadNavigate(Qt::Orientation orientation);
510 static bool inTabWidget(QWidget *widget);
511#endif
512
513 void setWindowIconText_sys(const QString &cap);
514 void setWindowIconText_helper(const QString &cap);
515 void setWindowTitle_sys(const QString &cap);
516 void setWindowFilePath_sys(const QString &filePath);
517
518#ifndef QT_NO_CURSOR
519 void setCursor_sys(const QCursor &cursor);
520 void unsetCursor_sys();
521#endif
522
523 void setWindowTitle_helper(const QString &cap);
524 void setWindowFilePath_helper(const QString &filePath);
525 void setWindowModified_helper();
526 virtual void setWindowFlags(Qt::WindowFlags windowFlags);
527
528 bool setMinimumSize_helper(int &minw, int &minh);
529 bool setMaximumSize_helper(int &maxw, int &maxh);
530 void setConstraints_sys();
531 bool pointInsideRectAndMask(const QPoint &) const;
532 QWidget *childAt_helper(const QPoint &, bool) const;
533 QWidget *childAtRecursiveHelper(const QPoint &p, bool) const;
534 void updateGeometry_helper(bool forceUpdate);
535
536 void getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const;
537 void setLayoutItemMargins(int left, int top, int right, int bottom);
538 void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = nullptr);
539
540 void updateContentsRect();
541 QMargins safeAreaMargins() const;
542
543 // aboutToDestroy() is called just before the contents of
544 // QWidget::destroy() is executed. It's used to signal QWidget
545 // sub-classes that their internals are about to be released.
546 virtual void aboutToDestroy() {}
547
548 inline QWidget *effectiveFocusWidget() {
549 QWidget *w = q_func();
550 while (w->focusProxy())
551 w = w->focusProxy();
552 return w;
553 }
554
555 void setModal_sys();
556
557 // This is an helper function that return the available geometry for
558 // a widget and takes care is this one is in QGraphicsView.
559 // If the widget is not embed in a scene then the geometry available is
560 // null, we let QDesktopWidget decide for us.
561 static QRect screenGeometry(const QWidget *widget)
562 {
563 QRect screen;
564#if QT_CONFIG(graphicsview)
565 QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget);
566 //It's embedded if it has an ancestor
567 if (ancestorProxy) {
568 if (!bypassGraphicsProxyWidget(widget) && ancestorProxy->scene() != nullptr) {
569 // One view, let be smart and return the viewport rect then the popup is aligned
570 if (ancestorProxy->scene()->views().size() == 1) {
571 QGraphicsView *view = ancestorProxy->scene()->views().at(0);
572 screen = view->mapToScene(view->viewport()->rect()).boundingRect().toRect();
573 } else {
574 screen = ancestorProxy->scene()->sceneRect().toRect();
575 }
576 }
577 }
578#else
579 Q_UNUSED(widget);
580#endif
581 return screen;
582 }
583
584 inline void setRedirected(QPaintDevice *replacement, const QPoint &offset)
585 {
586 Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent));
587 redirectDev = replacement;
588 redirectOffset = offset;
589 }
590
591 inline QPaintDevice *redirected(QPoint *offset) const
592 {
593 if (offset)
594 *offset = redirectDev ? redirectOffset : QPoint();
595 return redirectDev;
596 }
597
598 inline void restoreRedirected()
599 { redirectDev = nullptr; }
600
601 inline void enforceNativeChildren()
602 {
603 if (!extra)
604 createExtra();
605
606 if (extra->nativeChildrenForced)
607 return;
608 extra->nativeChildrenForced = 1;
609
610 for (int i = 0; i < children.size(); ++i) {
611 if (QWidget *child = qobject_cast<QWidget *>(children.at(i)))
612 child->setAttribute(Qt::WA_NativeWindow);
613 }
614 }
615
616 inline bool nativeChildrenForced() const
617 {
618 return extra ? extra->nativeChildrenForced : false;
619 }
620
621 inline QRect effectiveRectFor(const QRegion &region) const
622 {
623 return effectiveRectFor(region.boundingRect());
624 }
625
626 inline QRect effectiveRectFor(const QRect &rect) const
627 {
628#if QT_CONFIG(graphicseffect)
629 if (graphicsEffect && graphicsEffect->isEnabled())
630 return graphicsEffect->boundingRectFor(rect).toAlignedRect();
631#endif // QT_CONFIG(graphicseffect)
632 return rect;
633 }
634
635 QSize adjustedSize() const;
636
637 inline void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
638 {
639 Q_Q(QWidget);
640 if (button == Qt::LeftButton && qApp->autoSipEnabled()) {
641 QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
642 q->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
643 if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
644 QGuiApplication::inputMethod()->show();
645 }
646 }
647 }
648
649 void setWSGeometry();
650
651 inline QPoint mapToWS(const QPoint &p) const
652 { return p - data.wrect.topLeft(); }
653
654 inline QPoint mapFromWS(const QPoint &p) const
655 { return p + data.wrect.topLeft(); }
656
657 inline QRect mapToWS(const QRect &r) const
658 { return r.translated(-data.wrect.topLeft()); }
659
660 inline QRect mapFromWS(const QRect &r) const
661 { return r.translated(data.wrect.topLeft()); }
662
663 QOpenGLContext *shareContext() const;
664
665 virtual QObject *focusObject() { return nullptr; }
666
667#ifndef QT_NO_OPENGL
668 virtual GLuint textureId() const { return 0; }
669 virtual QPlatformTextureList::Flags textureListFlags() {
670 Q_Q(QWidget);
671 return q->testAttribute(Qt::WA_AlwaysStackOnTop)
672 ? QPlatformTextureList::StacksOnTop
673 : QPlatformTextureList::Flags(nullptr);
674 }
675 virtual QImage grabFramebuffer() { return QImage(); }
676 virtual void beginBackingStorePainting() { }
677 virtual void endBackingStorePainting() { }
678 virtual void beginCompose() { }
679 virtual void endCompose() { }
680 void setRenderToTexture() { renderToTexture = true; setTextureChildSeen(); }
681 void setTextureChildSeen()
682 {
683 Q_Q(QWidget);
684 if (textureChildSeen)
685 return;
686 textureChildSeen = 1;
687
688 if (!q->isWindow()) {
689 QWidget *parent = q->parentWidget();
690 if (parent)
691 get(parent)->setTextureChildSeen();
692 }
693 }
694 static void sendComposeStatus(QWidget *w, bool end);
695 // Called on setViewport().
696 virtual void initializeViewportFramebuffer() { }
697 // When using a QOpenGLWidget as viewport with QAbstractScrollArea, resize events are
698 // filtered away from the widget. This is fine for QGLWidget but bad for QOpenGLWidget
699 // since the fbo must be resized. We need an alternative way to notify.
700 virtual void resizeViewportFramebuffer() { }
701 // Called after each paint event.
702 virtual void resolveSamples() { }
703#endif
704
705 static void setWidgetParentHelper(QObject *widgetAsObject, QObject *newParent);
706
707 // Variables.
708 // Regular pointers (keep them together to avoid gaps on 64 bit architectures).
709 QWExtra *extra;
710 QWidget *focus_next;
711 QWidget *focus_prev;
712 QWidget *focus_child;
713 QLayout *layout;
714 QRegion *needsFlush;
715 QPaintDevice *redirectDev;
716 QWidgetItemV2 *widgetItem;
717 QPaintEngine *extraPaintEngine;
718 mutable const QMetaObject *polished;
719 QGraphicsEffect *graphicsEffect;
720 // All widgets are added into the allWidgets set. Once
721 // they receive a window id they are also added to the mapper.
722 // This should just ensure that all widgets are deleted by QApplication
723 static QWidgetMapper *mapper;
724 static QWidgetSet *allWidgets;
725#if !defined(QT_NO_IM)
726 Qt::InputMethodHints imHints;
727#endif
728#ifdef QT_KEYPAD_NAVIGATION
729 static QPointer<QWidget> editingWidget;
730#endif
731
732 // Implicit pointers (shared_null/shared_empty).
733 QRegion opaqueChildren;
734 QRegion dirty;
735#ifndef QT_NO_TOOLTIP
736 QString toolTip;
737 int toolTipDuration;
738#endif
739#if QT_CONFIG(statustip)
740 QString statusTip;
741#endif
742#if QT_CONFIG(whatsthis)
743 QString whatsThis;
744#endif
745#ifndef QT_NO_ACCESSIBILITY
746 QString accessibleName;
747 QString accessibleDescription;
748#endif
749
750 // Other variables.
751 uint directFontResolveMask;
752 uint inheritedFontResolveMask;
753 uint inheritedPaletteResolveMask;
754 short leftmargin;
755 short topmargin;
756 short rightmargin;
757 short bottommargin;
758 signed char leftLayoutItemMargin;
759 signed char topLayoutItemMargin;
760 signed char rightLayoutItemMargin;
761 signed char bottomLayoutItemMargin;
762 static int instanceCounter; // Current number of widget instances
763 static int maxInstances; // Maximum number of widget instances
764 Qt::HANDLE hd;
765 QWidgetData data;
766 QSizePolicy size_policy;
767 QLocale locale;
768 QPoint redirectOffset;
769#ifndef QT_NO_ACTION
770 QList<QAction*> actions;
771#endif
772#ifndef QT_NO_GESTURES
773 QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
774#endif
775
776 // Bit fields.
777 uint high_attributes[4]; // the low ones are in QWidget::widget_attributes
778 QPalette::ColorRole fg_role : 8;
779 QPalette::ColorRole bg_role : 8;
780 uint dirtyOpaqueChildren : 1;
781 uint isOpaque : 1;
782 uint retainSizeWhenHiddenChanged : 1;
783 uint inDirtyList : 1;
784 uint isScrolled : 1;
785 uint isMoved : 1;
786 uint usesDoubleBufferedGLContext : 1;
787 uint mustHaveWindowHandle : 1;
788 uint renderToTexture : 1;
789 uint textureChildSeen : 1;
790#ifndef QT_NO_IM
791 uint inheritsInputMethodHints : 1;
792#endif
793#ifndef QT_NO_OPENGL
794 uint renderToTextureReallyDirty : 1;
795 uint renderToTextureComposeActive : 1;
796#endif
797 uint childrenHiddenByWState : 1;
798 uint childrenShownByExpose : 1;
799
800 // *************************** Platform specific ************************************
801#if defined(Q_OS_WIN)
802 uint noPaintOnScreen : 1; // see qwidget.cpp ::paintEngine()
803#endif
804#if 0 /* Used to be included in Qt4 for Q_WS_X11 */ // <----------------------------------------------------------- X11
805 Qt::HANDLE picture;
806 static QWidget *mouseGrabber;
807 static QWidget *keyboardGrabber;
808
809 void setWindowRole();
810 void sendStartupMessage(const char *message) const;
811 void x11UpdateIsOpaque();
812 bool isBackgroundInherited() const;
813 void updateX11AcceptFocus();
814 QPoint mapToGlobal(const QPoint &pos) const;
815 QPoint mapFromGlobal(const QPoint &pos) const;
816#elif 0 /* Used to be included in Qt4 for Q_WS_WIN */ // <--------------------------------------------------------- WIN
817#ifndef QT_NO_GESTURES
818 uint nativeGesturePanEnabled : 1;
819#endif
820 bool shouldShowMaximizeButton();
821 void winUpdateIsOpaque();
822 void reparentChildren();
823#if QT_CONFIG(draganddrop)
824 QOleDropTarget *registerOleDnd(QWidget *widget);
825 void unregisterOleDnd(QWidget *widget, QOleDropTarget *target);
826#endif
827 void grabMouseWhileInWindow();
828 void registerTouchWindow();
829 void winSetupGestures();
830#elif defined(Q_OS_MAC) // <--------------------------------------------------------- MAC
831 void macUpdateSizeAttribute();
832#elif 0 /* Used to be included in Qt4 for Q_WS_MAC */ // <--------------------------------------------------------- MAC (old stuff)
833 // This is new stuff
834 uint needWindowChange : 1;
835
836 // Each wiget keeps a list of all its child and grandchild OpenGL widgets.
837 // This list is used to update the gl context whenever a parent and a granparent
838 // moves, and also to check for intersections with gl widgets within the window
839 // when a widget moves.
840 struct GlWidgetInfo
841 {
842 GlWidgetInfo(QWidget *widget) : widget(widget), lastUpdateWidget(0) { }
843 bool operator==(const GlWidgetInfo &other) const { return (widget == other.widget); }
844 QWidget * widget;
845 QWidget * lastUpdateWidget;
846 };
847
848 // dirtyOnWidget contains the areas in the widget that needs to be repained,
849 // in the same way as dirtyOnScreen does for the window. Areas are added in
850 // dirtyWidget_sys and cleared in the paint event. In scroll_sys we then use
851 // this information repaint invalid areas when widgets are scrolled.
852 QRegion dirtyOnWidget;
853 EventHandlerRef window_event;
854 QList<GlWidgetInfo> glWidgets;
855
856 //these are here just for code compat (HIViews)
857 Qt::HANDLE qd_hd;
858
859 void macUpdateHideOnSuspend();
860 void macUpdateOpaqueSizeGrip();
861 void macUpdateIgnoreMouseEvents();
862 void macUpdateMetalAttribute();
863 void macUpdateIsOpaque();
864 void macSetNeedsDisplay(QRegion region);
865 void setEnabled_helper_sys(bool enable);
866 bool isRealWindow() const;
867 void adjustWithinMaxAndMinSize(int &w, int &h);
868 void applyMaxAndMinSizeOnWindow();
869 void update_sys(const QRect &rect);
870 void update_sys(const QRegion &rgn);
871 void setGeometry_sys_helper(int, int, int, int, bool);
872 void updateMaximizeButton_sys();
873 void createWindow_sys();
874 void recreateMacWindow();
875 void setSubWindowStacking(bool set);
876 void setWindowLevel();
877 void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef);
878 void syncCocoaMask();
879 void finishCocoaMaskSetup();
880 // Did we add the drawRectOriginal method?
881 bool drawRectOriginalAdded;
882 // Is the original drawRect method available?
883 bool originalDrawMethod;
884 // Do we need to change the methods?
885 bool changeMethods;
886
887 // Unified toolbar variables
888 bool isInUnifiedToolbar;
889 QUnifiedToolbarSurface *unifiedSurface;
890 QPoint toolbar_offset;
891 QWidget *toolbar_ancestor;
892 bool flushRequested;
893 bool touchEventsEnabled;
894 void determineWindowClass();
895 void transferChildren();
896 bool qt_mac_dnd_event(uint, DragRef);
897 void toggleDrawers(bool);
898 //mac event functions
899 static bool qt_create_root_win();
900 static void qt_clean_root_win();
901 static bool qt_mac_update_sizer(QWidget *, int up = 0);
902 static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *);
903 static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *);
904 static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool);
905 void registerTouchWindow(bool enable = true);
906#endif
907 void setNetWmWindowTypes(bool skipIfMissing = false);
908
909 bool stealKeyboardGrab(bool grab);
910 bool stealMouseGrab(bool grab);
911};
912
913struct QWidgetPaintContext
914{
915 inline QWidgetPaintContext(QPaintDevice *d, const QRegion &r, const QPoint &o, int f,
916 QPainter *p, QWidgetBackingStore *b)
917 : pdev(d), rgn(r), offset(o), flags(f), sharedPainter(p), backingStore(b), painter(nullptr) {}
918
919 QPaintDevice *pdev;
920 QRegion rgn;
921 QPoint offset;
922 int flags;
923 QPainter *sharedPainter;
924 QWidgetBackingStore *backingStore;
925 QPainter *painter;
926};
927
928#if QT_CONFIG(graphicseffect)
929class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
930{
931public:
932 QWidgetEffectSourcePrivate(QWidget *widget)
933 : QGraphicsEffectSourcePrivate(), m_widget(widget), context(nullptr), updateDueToGraphicsEffect(false)
934 {}
935
936 void detach() override
937 { m_widget->d_func()->graphicsEffect = nullptr; }
938
939 const QGraphicsItem *graphicsItem() const override
940 { return nullptr; }
941
942 const QWidget *widget() const override
943 { return m_widget; }
944
945 void update() override
946 {
947 updateDueToGraphicsEffect = true;
948 m_widget->update();
949 updateDueToGraphicsEffect = false;
950 }
951
952 bool isPixmap() const override
953 { return false; }
954
955 void effectBoundingRectChanged() override
956 {
957 // ### This function should take a rect parameter; then we can avoid
958 // updating too much on the parent widget.
959 if (QWidget *parent = m_widget->parentWidget())
960 parent->update();
961 else
962 update();
963 }
964
965 const QStyleOption *styleOption() const override
966 { return nullptr; }
967
968 QRect deviceRect() const override
969 { return m_widget->window()->rect(); }
970
971 QRectF boundingRect(Qt::CoordinateSystem system) const override;
972 void draw(QPainter *p) override;
973 QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset,
974 QGraphicsEffect::PixmapPadMode mode) const override;
975
976 QWidget *m_widget;
977 QWidgetPaintContext *context;
978 QTransform lastEffectTransform;
979 bool updateDueToGraphicsEffect;
980};
981#endif // QT_CONFIG(graphicseffect)
982
983inline QWExtra *QWidgetPrivate::extraData() const
984{
985 return extra;
986}
987
988inline QTLWExtra *QWidgetPrivate::topData() const
989{
990 const_cast<QWidgetPrivate *>(this)->createTLExtra();
991 return extra->topextra;
992}
993
994inline QTLWExtra *QWidgetPrivate::maybeTopData() const
995{
996 return extra ? extra->topextra : nullptr;
997}
998
999inline QPainter *QWidgetPrivate::sharedPainter() const
1000{
1001 Q_Q(const QWidget);
1002 QTLWExtra *x = q->window()->d_func()->maybeTopData();
1003 return x ? x->sharedPainter : nullptr;
1004}
1005
1006inline void QWidgetPrivate::setSharedPainter(QPainter *painter)
1007{
1008 Q_Q(QWidget);
1009 QTLWExtra *x = q->window()->d_func()->topData();
1010 x->sharedPainter = painter;
1011}
1012
1013inline bool QWidgetPrivate::pointInsideRectAndMask(const QPoint &p) const
1014{
1015 Q_Q(const QWidget);
1016 return q->rect().contains(p) && (!extra || !extra->hasMask || q->testAttribute(Qt::WA_MouseNoMask)
1017 || extra->mask.contains(p));
1018}
1019
1020inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const
1021{
1022 Q_Q(const QWidget);
1023 QTLWExtra *x = q->window()->d_func()->maybeTopData();
1024 return x ? x->backingStoreTracker.data() : nullptr;
1025}
1026
1027QT_END_NAMESPACE
1028
1029#endif // QWIDGET_P_H
1030