diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/accessible/complexwidgets.cpp | 10 | ||||
-rw-r--r-- | src/widgets/accessible/complexwidgets_p.h | 1 | ||||
-rw-r--r-- | src/widgets/dialogs/qfiledialog.cpp | 2 | ||||
-rw-r--r-- | src/widgets/itemviews/qheaderview.cpp | 41 | ||||
-rw-r--r-- | src/widgets/itemviews/qtreeview.cpp | 20 | ||||
-rw-r--r-- | src/widgets/kernel/qtestsupport_widgets.cpp | 29 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 31 | ||||
-rw-r--r-- | src/widgets/styles/qcommonstyle.cpp | 2 | ||||
-rw-r--r-- | src/widgets/styles/qstylesheetstyle.cpp | 22 | ||||
-rw-r--r-- | src/widgets/util/qsystemtrayicon.cpp | 4 | ||||
-rw-r--r-- | src/widgets/widgets/qdockwidget.cpp | 8 | ||||
-rw-r--r-- | src/widgets/widgets/qmainwindowlayout.cpp | 15 |
12 files changed, 144 insertions, 41 deletions
diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp index 63836015dd..097c589306 100644 --- a/src/widgets/accessible/complexwidgets.cpp +++ b/src/widgets/accessible/complexwidgets.cpp @@ -354,6 +354,16 @@ int QAccessibleComboBox::indexOfChild(const QAccessibleInterface *child) const return -1; } +QAccessibleInterface *QAccessibleComboBox::focusChild() const +{ + // The editable combobox is the focus proxy of its lineedit, so the + // lineedit itself never gets focus. But it is the accessible focus + // child of an editable combobox. + if (comboBox()->isEditable()) + return child(1); + return nullptr; +} + /*! \reimp */ QString QAccessibleComboBox::text(QAccessible::Text t) const { diff --git a/src/widgets/accessible/complexwidgets_p.h b/src/widgets/accessible/complexwidgets_p.h index 1c138e6af2..f6d5226f9b 100644 --- a/src/widgets/accessible/complexwidgets_p.h +++ b/src/widgets/accessible/complexwidgets_p.h @@ -135,6 +135,7 @@ public: QAccessibleInterface *childAt(int x, int y) const override; int indexOfChild(const QAccessibleInterface *child) const override; QAccessibleInterface* child(int index) const override; + QAccessibleInterface* focusChild() const override; QString text(QAccessible::Text t) const override; diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 0bf8f2440b..6d8e91a223 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -227,7 +227,7 @@ Q_GLOBAL_STATIC(QUrl, lastVisitedDir) \value DontConfirmOverwrite Don't ask for confirmation if an existing file is selected. By default confirmation is requested. - Note: This opption is not supported on macOS when using the + Note: This option is not supported on macOS when using the native file dialog. \value DontUseNativeDialog Don't use the native file dialog. By diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 8fc0df84e2..7dc2c06860 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1797,21 +1797,27 @@ bool QHeaderView::restoreState(const QByteArray &state) Q_D(QHeaderView); if (state.isEmpty()) return false; - QByteArray data = state; - QDataStream stream(&data, QIODevice::ReadOnly); - int marker; - int ver; - stream >> marker; - stream >> ver; - if (stream.status() != QDataStream::Ok + + for (const auto dataStreamVersion : {QDataStream::Qt_5_0, QDataStream::Qt_6_0}) { + + QByteArray data = state; + QDataStream stream(&data, QIODevice::ReadOnly); + stream.setVersion(dataStreamVersion); + int marker; + int ver; + stream >> marker; + stream >> ver; + if (stream.status() != QDataStream::Ok || marker != QHeaderViewPrivate::VersionMarker - || ver != 0) // current version is 0 - return false; + || ver != 0) { // current version is 0 + return false; + } - if (d->read(stream)) { - emit sortIndicatorChanged(d->sortIndicatorSection, d->sortIndicatorOrder ); - d->viewport->update(); - return true; + if (d->read(stream)) { + emit sortIndicatorChanged(d->sortIndicatorSection, d->sortIndicatorOrder ); + d->viewport->update(); + return true; + } } return false; } @@ -4165,6 +4171,15 @@ bool QHeaderViewPrivate::read(QDataStream &in) in >> global; + // Check parameter consistency + // Global orientation out of bounds? + if (global < 0 || global > QHeaderView::ResizeToContents) + return false; + + // Alignment out of bounds? + if (align < 0 || align > Qt::AlignVertical_Mask) + return false; + in >> sectionItemsIn; // In Qt4 we had a vector of spans where one span could hold information on more sections. // Now we have an itemvector where one items contains information about one section diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 500a6152d8..bd7f48d878 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1695,8 +1695,11 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, } } - // ### special case: treeviews with multiple columns draw - // the selections differently than with only one column + // ### special case: if we select entire rows, then we need to draw the + // selection in the first column all the way to the second column, rather + // than just around the item text. We abuse showDecorationSelected to + // indicate this to the style. Below we will reset this value temporarily + // to only respect the styleHint while we are rendering the decoration. opt.showDecorationSelected = (d->selectionBehavior & SelectRows) || option.showDecorationSelected; @@ -1781,8 +1784,16 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, } // draw background for the branch (selection + alternate row) opt.rect = branches; - if (style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, &opt, this)) - style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this); + + // We use showDecorationSelected both to store the style hint, and to indicate + // that the entire row has to be selected (see overrides of the value if + // selectionBehavior == SelectRow). + // While we are only painting the background we don't care for the + // selectionBehavior factor, so respect only the style value, and reset later. + const bool oldShowDecorationSelected = opt.showDecorationSelected; + opt.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, + &opt, this); + style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this); // draw background of the item (only alternate row). rest of the background // is provided by the delegate @@ -1791,6 +1802,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, opt.rect.setRect(reverse ? position : i + position, y, width - i, height); style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this); opt.state = oldState; + opt.showDecorationSelected = oldShowDecorationSelected; if (d->indent != 0) drawBranches(painter, branches, index); diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp index c9116fcef6..1d39285670 100644 --- a/src/widgets/kernel/qtestsupport_widgets.cpp +++ b/src/widgets/kernel/qtestsupport_widgets.cpp @@ -52,9 +52,16 @@ QT_BEGIN_NAMESPACE /*! \since 5.0 - Waits for \a timeout milliseconds or until the \a widget's window is active. + Returns \c true if \a widget is active within \a timeout milliseconds. Otherwise returns \c false. - Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false. + The method is useful in tests that call QWidget::show() and rely on the widget actually being + active (i.e. being visible and having focus) before proceeding. + + \note The method will time out and return \c false if another window prevents \a widget from + becoming active. + + \note Since focus is an exclusive property, \a widget may loose its focus to another window at + any time - even after the method has returned \c true. \sa qWaitForWindowExposed(), QWidget::isActiveWindow() */ @@ -68,20 +75,16 @@ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout) /*! \since 5.0 - Waits for \a timeout milliseconds or until the \a widget's window is exposed. - Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false. - - This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some - time after being asked to show itself on the screen. + Returns \c true if \a widget is exposed within \a timeout milliseconds. Otherwise returns \c false. - Note that a window that is mapped to screen may still not be considered exposed if the window client - area is completely covered by other windows, or if the window is otherwise not visible. This function - will then time out when waiting for such a window. + The method is useful in tests that call QWidget::show() and rely on the widget actually being + being visible before proceeding. - A specific configuration where this happens is when using QGLWidget as a viewport widget on macOS: - The viewport widget gets the expose event, not the parent widget. + \note A window mapped to screen may still not be considered exposed, if the window client area is + not visible, e.g. because it is completely covered by other windows. + In such cases, the method will time out and return \c false. - \sa qWaitForWindowActive() + \sa qWaitForWindowActive(), QWidget::isVisible(), QWindow::isExposed() */ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout) { diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 79c6c89db2..c2672933ac 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6263,6 +6263,33 @@ void QWidget::setFocusProxy(QWidget * w) d->createExtra(); d->extra->focus_proxy = w; + if (w && isAncestorOf(w)) { + // If the focus proxy is a child of this (so this is a compound widget), then + // we need to make sure that this widget is immediately in front of its own children + // in the focus chain. Otherwise focusNextPrev_helper might jump over unrelated + // widgets that are positioned between this compound widget, and its proxy in + // the focus chain. + const QWidget *parentOfW = w->parentWidget(); + Q_ASSERT(parentOfW); // can't be nullptr since we are an ancestor of w + QWidget *firstChild = nullptr; + const auto childList = children(); + for (QObject *child : childList) { + if ((firstChild = qobject_cast<QWidget *>(child))) + break; + } + Q_ASSERT(firstChild); // can't be nullptr since w is a child + QWidget *oldNext = d->focus_next; + QWidget *oldPrev = d->focus_prev; + oldNext->d_func()->focus_prev = oldPrev; + oldPrev->d_func()->focus_next = oldNext; + + oldPrev = firstChild->d_func()->focus_prev; + d->focus_next = firstChild; + d->focus_prev = oldPrev; + oldPrev->d_func()->focus_next = this; + firstChild->d_func()->focus_prev = this; + } + if (moveFocusToProxy) setFocus(Qt::OtherFocusReason); } @@ -6954,8 +6981,8 @@ void QWidgetPrivate::reparentFocusWidgets(QWidget * oldtlw) n->d_func()->focus_next = topLevel; } else { //repair the new list - n->d_func()->focus_next = q; - focus_prev = n; + n->d_func()->focus_next = q; + focus_prev = n; } } diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index dfee61fa74..538c934c0f 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -711,7 +711,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) cg = QPalette::Inactive; - if ((vopt->state & QStyle::State_Selected) && proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, opt, widget)) + if ((vopt->state & QStyle::State_Selected) && vopt->showDecorationSelected) p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight)); else if (vopt->features & QStyleOptionViewItem::Alternate) p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 78503e07c4..40bde5e066 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -1508,7 +1508,11 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q p->setBrush(cg, w->foregroundRole(), pal->foreground); p->setBrush(cg, QPalette::WindowText, pal->foreground); p->setBrush(cg, QPalette::Text, pal->foreground); - p->setBrush(cg, QPalette::PlaceholderText, pal->foreground); + QColor phColor(pal->foreground.color()); + phColor.setAlpha((phColor.alpha() + 1) / 2); + QBrush placeholder = pal->foreground; + placeholder.setColor(phColor); + p->setBrush(cg, QPalette::PlaceholderText, placeholder); } if (pal->selectionBackground.style() != Qt::NoBrush) p->setBrush(cg, QPalette::Highlight, pal->selectionBackground); @@ -4742,10 +4746,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch); if (subRule.hasDrawable()) { - if ((vopt->state & QStyle::State_Selected) && vopt->showDecorationSelected) - p->fillRect(vopt->rect, vopt->palette.highlight()); - else if (vopt->features & QStyleOptionViewItem::Alternate) - p->fillRect(vopt->rect, vopt->palette.alternateBase()); + proxy()->drawPrimitive(PE_PanelItemViewRow, vopt, p, w); subRule.drawRule(p, opt->rect); } else { baseStyle()->drawPrimitive(pe, vopt, p, w); @@ -4813,6 +4814,17 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op pseudoElement = PseudoElement_DockWidgetSeparator; break; + case PE_PanelItemViewRow: + // For compatibility reasons, QTreeView draws different parts of + // the background of an item row separately, before calling the + // delegate to draw the item. The row background of an item is + // however not separately styleable through a style sheet, but + // only indirectly through the background of the item. To get the + // same background for all parts drawn by QTreeView, we have to + // use the background rule for the item here. + if (renderRule(w, opt, PseudoElement_ViewItem).hasBackground()) + pseudoElement = PseudoElement_ViewItem; + break; case PE_PanelItemViewItem: pseudoElement = PseudoElement_ViewItem; break; diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index cce7b202a0..80e2cb0825 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -128,7 +128,9 @@ static QIcon messageIcon2qIcon(QSystemTrayIcon::MessageIcon icon) Only on X11, when a tooltip is requested, the QSystemTrayIcon receives a QHelpEvent of type QEvent::ToolTip. Additionally, the QSystemTrayIcon receives wheel events of - type QEvent::Wheel. These are not supported on any other platform. + type QEvent::Wheel. These are not supported on any other platform. Note: Since GNOME + Shell version 3.26, not all QSystemTrayIcon::ActivationReason are supported by the + system without shell extensions installed. \sa QDesktopServices, {Desktop Integration}, {System Tray Icon Example} */ diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 8c327026ff..3374315d88 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -1044,12 +1044,18 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) pos = event->globalPosition().toPoint() - state->pressPos - windowMarginOffset; } + // If the newly floating dock widget has got a native title bar, + // offset the position by the native title bar's height or width + const int dx = q->geometry().x() - q->x(); + const int dy = q->geometry().y() - q->y(); + pos.rx() += dx; + pos.ry() += dy; + QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent); if (floatingTab && !q->isFloating()) floatingTab->move(pos); else q->move(pos); - if (state && !state->ctrlDrag) mwlayout->hover(state->widgetItem, event->globalPosition().toPoint()); diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 412c0294f7..27a67ea988 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -2625,6 +2625,21 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group) } else #endif // QT_CONFIG(tabwidget) { + // Dock widget is unplugged from the main window + // => geometry needs to be adjusted by separator size + switch (dockWidgetArea(dw)) { + case Qt::LeftDockWidgetArea: + case Qt::RightDockWidgetArea: + r.adjust(0, 0, 0, -sep); + break; + case Qt::TopDockWidgetArea: + case Qt::BottomDockWidgetArea: + r.adjust(0, 0, -sep, 0); + break; + case Qt::NoDockWidgetArea: + case Qt::DockWidgetArea_Mask: + break; + } dw->d_func()->unplug(r); } } |