diff options
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 64 | ||||
-rw-r--r-- | src/widgets/kernel/qboxlayout.cpp | 54 | ||||
-rw-r--r-- | src/widgets/kernel/qformlayout.cpp | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qgesturemanager.cpp | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qgridlayout.cpp | 6 | ||||
-rw-r--r-- | src/widgets/kernel/qopenglwidget.cpp | 8 | ||||
-rw-r--r-- | src/widgets/kernel/qstackedlayout.cpp | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 32 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore.cpp | 6 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 8 |
10 files changed, 102 insertions, 85 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index f564475698..1efbca8490 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2165,10 +2165,12 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool // \a next). This is to ensure that we can tab in and out of compound widgets // without getting stuck in a tab-loop between parent and child. QWidget *focusProxy = test->d_func()->deepestFocusProxy(); - - if ((test->focusPolicy() & focus_flag) == focus_flag - && !(next && focusProxy && focusProxy->isAncestorOf(test)) - && !(!next && focusProxy && test->isAncestorOf(focusProxy)) + const bool canTakeFocus = ((focusProxy ? focusProxy->focusPolicy() : test->focusPolicy()) + & focus_flag) == focus_flag; + const bool composites = focusProxy ? (next ? focusProxy->isAncestorOf(test) + : test->isAncestorOf(focusProxy)) + : false; + if (canTakeFocus && !composites && test->isVisibleTo(toplevel) && test->isEnabled() && !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test)) && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) { @@ -2907,59 +2909,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) return true; // Platform plugin ate the event } - if(e->spontaneous()) { - // Capture the current mouse and keyboard states. Doing so here is - // required in order to support Qt Test synthesized events. Real mouse - // and keyboard state updates from the platform plugin are managed by - // QGuiApplicationPrivate::process(Mouse|Wheel|Key|Touch|Tablet)Event(); - // ### FIXME: Qt Test should not call qapp->notify(), but rather route - // the events through the proper QPA interface. This is required to - // properly generate all other events such as enter/leave etc. - switch (e->type()) { - case QEvent::MouseButtonPress: - { - QMouseEvent *me = static_cast<QMouseEvent*>(e); - QApplicationPrivate::modifier_buttons = me->modifiers(); - QApplicationPrivate::mouse_buttons |= me->button(); - break; - } - case QEvent::MouseButtonDblClick: - { - QMouseEvent *me = static_cast<QMouseEvent*>(e); - QApplicationPrivate::modifier_buttons = me->modifiers(); - QApplicationPrivate::mouse_buttons |= me->button(); - break; - } - case QEvent::MouseButtonRelease: - { - QMouseEvent *me = static_cast<QMouseEvent*>(e); - QApplicationPrivate::modifier_buttons = me->modifiers(); - QApplicationPrivate::mouse_buttons &= ~me->button(); - break; - } - case QEvent::KeyPress: - case QEvent::KeyRelease: - case QEvent::MouseMove: -#if QT_CONFIG(wheelevent) - case QEvent::Wheel: -#endif - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: -#if QT_CONFIG(tabletevent) - case QEvent::TabletMove: - case QEvent::TabletPress: - case QEvent::TabletRelease: -#endif - { - QInputEvent *ie = static_cast<QInputEvent*>(e); - QApplicationPrivate::modifier_buttons = ie->modifiers(); - break; - } - default: - break; - } - } + QGuiApplicationPrivate::captureGlobalModifierState(e); #ifndef QT_NO_GESTURES // walk through parents and check for gestures diff --git a/src/widgets/kernel/qboxlayout.cpp b/src/widgets/kernel/qboxlayout.cpp index a368f379ad..39a3b5203c 100644 --- a/src/widgets/kernel/qboxlayout.cpp +++ b/src/widgets/kernel/qboxlayout.cpp @@ -548,7 +548,11 @@ QLayoutItem* QBoxLayoutPrivate::replaceAt(int index, QLayoutItem *item) Constructs a new QBoxLayout with direction \a dir and parent widget \a parent. - \sa direction() + The layout is set directly as the top-level layout for \a parent. + There can be only one top-level layout for a widget. It is returned + by QWidget::layout(). + + \sa direction(), QWidget::setLayout() */ QBoxLayout::QBoxLayout(Direction dir, QWidget *parent) : QLayout(*new QBoxLayoutPrivate, 0, parent) @@ -1232,11 +1236,16 @@ QBoxLayout::Direction QBoxLayout::direction() const \snippet layouts/layouts.cpp 4 \snippet layouts/layouts.cpp 5 - First, we create the widgets we want in the layout. Then, we - create the QHBoxLayout object and add the widgets into the - layout. Finally, we call QWidget::setLayout() to install the - QHBoxLayout object onto the widget. At that point, the widgets in - the layout are reparented to have \c window as their parent. + First, we create the widgets we want to add to the layout. Then, + we create the QHBoxLayout object, setting \c window as parent by + passing it in the constructor; next we add the widgets to the + layout. \c window will be the parent of the widgets that are + added to the layout. + + If you don't pass parent \c window in the constrcutor, you can + at a later point use QWidget::setLayout() to install the QHBoxLayout + object onto \c window. At that point, the widgets in the layout are + reparented to have \c window as their parent. \image qhboxlayout-with-5-children.png Horizontal box layout with five child widgets @@ -1245,8 +1254,13 @@ QBoxLayout::Direction QBoxLayout::direction() const /*! - Constructs a new top-level horizontal box with - parent \a parent. + Constructs a new top-level horizontal box with parent \a parent. + + The layout is set directly as the top-level layout for \a parent. + There can be only one top-level layout for a widget. It is returned + by QWidget::layout(). + + \sa QWidget::setLayout() */ QHBoxLayout::QHBoxLayout(QWidget *parent) : QBoxLayout(LeftToRight, parent) @@ -1295,11 +1309,16 @@ QHBoxLayout::~QHBoxLayout() \snippet layouts/layouts.cpp 10 \snippet layouts/layouts.cpp 11 - First, we create the widgets we want in the layout. Then, we - create the QVBoxLayout object and add the widgets into the - layout. Finally, we call QWidget::setLayout() to install the - QVBoxLayout object onto the widget. At that point, the widgets in - the layout are reparented to have \c window as their parent. + First, we create the widgets we want to add to the layout. Then, + we create the QVBoxLayout object, setting \c window as parent by + passing it in the constructor; next we add the widgets to the + layout. \c window will be the parent of the widgets that are + added to the layout. + + If you don't pass parent \c window in the constrcutor, you can + at a later point use QWidget::setLayout() to install the QVBoxLayout + object onto \c window. At that point, the widgets in the layout are + reparented to have \c window as their parent. \image qvboxlayout-with-5-children.png Horizontal box layout with five child widgets @@ -1307,8 +1326,13 @@ QHBoxLayout::~QHBoxLayout() */ /*! - Constructs a new top-level vertical box with - parent \a parent. + Constructs a new top-level vertical box with parent \a parent. + + The layout is set directly as the top-level layout for \a parent. + There can be only one top-level layout for a widget. It is returned + by QWidget::layout(). + + \sa QWidget::setLayout() */ QVBoxLayout::QVBoxLayout(QWidget *parent) : QBoxLayout(TopToBottom, parent) diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 600934b8a1..1852f8cdc3 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -1191,6 +1191,10 @@ QLayoutItem* QFormLayoutPrivate::replaceAt(int index, QLayoutItem *newitem) /*! Constructs a new form layout with the given \a parent widget. + The layout is set directly as the top-level layout for \a parent. + There can be only one top-level layout for a widget. It is returned + by QWidget::layout(). + \sa QWidget::setLayout() */ QFormLayout::QFormLayout(QWidget *parent) diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 891858b035..cfa1759dd7 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -143,6 +143,7 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) { QList<QGestureRecognizer *> list = m_recognizers.values(type); + m_recognizers.remove(type); foreach (QGesture *g, m_gestureToRecognizer.keys()) { QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); if (list.contains(recognizer)) { diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index f1c6c96a6d..a410652dcb 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -1073,6 +1073,12 @@ QRect QGridLayoutPrivate::cellRect(int row, int col) const Constructs a new QGridLayout with parent widget, \a parent. The layout has one row and one column initially, and will expand when new items are inserted. + + The layout is set directly as the top-level layout for \a parent. + There can be only one top-level layout for a widget. It is returned + by QWidget::layout(). + + \sa QWidget::setLayout() */ QGridLayout::QGridLayout(QWidget *parent) : QLayout(*new QGridLayoutPrivate, 0, parent) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 7aef74c507..e58994b04c 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -788,10 +788,12 @@ void QOpenGLWidgetPrivate::initialize() if (initialized) return; - // Get our toplevel's context with which we will share in order to make the - // texture usable by the underlying window's backingstore. + // If no global shared context get our toplevel's context with which we + // will share in order to make the texture usable by the underlying window's backingstore. QWidget *tlw = q->window(); - QOpenGLContext *shareContext = get(tlw)->shareContext(); + QOpenGLContext *shareContext = qt_gl_global_share_context(); + if (!shareContext) + shareContext = get(tlw)->shareContext(); // If shareContext is null, showing content on-screen will not work. // However, offscreen rendering and grabFramebuffer() will stay fully functional. diff --git a/src/widgets/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp index 7430d833db..0b1641c141 100644 --- a/src/widgets/kernel/qstackedlayout.cpp +++ b/src/widgets/kernel/qstackedlayout.cpp @@ -44,6 +44,8 @@ #include "private/qwidget_p.h" #include "private/qlayoutengine_p.h" +#include <memory> + QT_BEGIN_NAMESPACE class QStackedLayoutPrivate : public QLayoutPrivate @@ -421,13 +423,13 @@ int QStackedLayout::count() const */ void QStackedLayout::addItem(QLayoutItem *item) { + std::unique_ptr<QLayoutItem> guard(item); QWidget *widget = item->widget(); if (Q_UNLIKELY(!widget)) { qWarning("QStackedLayout::addItem: Only widgets can be added"); return; } addWidget(widget); - delete item; } /*! diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index db08a1d04f..02a1980e09 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -910,6 +910,8 @@ void QWidget::setAutoFillBackground(bool enabled) and a compositing window manager. \li Windows: The widget needs to have the Qt::FramelessWindowHint window flag set for the translucency to work. + \li \macos: The widget needs to have the Qt::FramelessWindowHint window flag set + for the translucency to work. \endlist @@ -6715,6 +6717,9 @@ void QWidget::clearFocus() QApplication::sendEvent(this, &focusAboutToChange); } + QTLWExtra *extra = window()->d_func()->maybeTopData(); + QObject *originalFocusObject = (extra && extra->window) ? extra->window->focusObject() : nullptr; + QWidget *w = this; while (w) { // Just like setFocus(), we update (clear) the focus_child of our parents @@ -6723,14 +6728,12 @@ void QWidget::clearFocus() w = w->parentWidget(); } - // Since we've unconditionally cleared the focus_child of our parents, we need + // We've potentially cleared the focus_child of our parents, so we need // to report this to the rest of Qt. Note that the focus_child is not the same // thing as the application's focusWidget, which is why this piece of code is - // not inside the hasFocus() block below. - if (QTLWExtra *extra = window()->d_func()->maybeTopData()) { - if (extra->window) - emit extra->window->focusObjectChanged(extra->window->focusObject()); - } + // not inside a hasFocus() block. + if (originalFocusObject && originalFocusObject != extra->window->focusObject()) + emit extra->window->focusObjectChanged(extra->window->focusObject()); #if QT_CONFIG(graphicsview) QWExtra *topData = d_func()->extra; @@ -8934,6 +8937,23 @@ bool QWidget::event(QEvent *event) } } switch (event->type()) { + case QEvent::PlatformSurface: { + // Sync up QWidget's view of whether or not the widget has been created + switch (static_cast<QPlatformSurfaceEvent*>(event)->surfaceEventType()) { + case QPlatformSurfaceEvent::SurfaceCreated: + if (!testAttribute(Qt::WA_WState_Created)) + create(); + break; + case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: + if (testAttribute(Qt::WA_WState_Created)) { + // Child windows have already been destroyed by QWindow, + // so we skip them here. + destroy(false, false); + } + break; + } + break; + } case QEvent::MouseMove: mouseMoveEvent((QMouseEvent*)event); break; diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index b9505a6ed0..38ea5966ae 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -717,7 +717,11 @@ void QWidgetBackingStore::markDirtyOnScreen(const QRegion ®ion, QWidget *widg // Alien widgets. if (!hasPlatformWindow(widget) && !widget->isWindow()) { - QWidget *nativeParent = widget->nativeParentWidget(); // Alien widgets with the top-level as the native parent (common case). + QWidget *nativeParent = widget->nativeParentWidget(); + if (!nativeParent) + return; + + // Alien widgets with the top-level as the native parent (common case). if (nativeParent == tlw) { dirtyOnScreen += region.translated(topLevelOffset); return; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index c3f570ce4f..e74243203a 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -243,10 +243,14 @@ bool QWidgetWindow::event(QEvent *event) } switch (event->type()) { - case QEvent::Close: + case QEvent::Close: { + // The widget might be deleted in the close event handler. + QPointer<QObject> guard = this; handleCloseEvent(static_cast<QCloseEvent *>(event)); - QWindow::event(event); + if (guard) + QWindow::event(event); return true; + } case QEvent::Enter: case QEvent::Leave: |