summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/accessible/complexwidgets.cpp10
-rw-r--r--src/widgets/accessible/complexwidgets_p.h1
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/itemviews/qheaderview.cpp41
-rw-r--r--src/widgets/itemviews/qtreeview.cpp20
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.cpp29
-rw-r--r--src/widgets/kernel/qwidget.cpp31
-rw-r--r--src/widgets/styles/qcommonstyle.cpp2
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp22
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp4
-rw-r--r--src/widgets/widgets/qdockwidget.cpp8
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp15
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);
}
}