summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/doc/src/external-resources.qdoc2
-rw-r--r--src/widgets/doc/src/qtwidgets-examples.qdoc12
-rw-r--r--src/widgets/doc/src/qtwidgets-toc.qdoc1
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp3
-rw-r--r--src/widgets/kernel/qapplication.cpp43
-rw-r--r--src/widgets/kernel/qtooltip.cpp13
-rw-r--r--src/widgets/kernel/qwidget.cpp19
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp4
-rw-r--r--src/widgets/util/qcompleter.cpp15
-rw-r--r--src/widgets/widgets/qcombobox.cpp14
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp3
-rw-r--r--src/widgets/widgets/qmenu.cpp21
12 files changed, 117 insertions, 33 deletions
diff --git a/src/widgets/doc/src/external-resources.qdoc b/src/widgets/doc/src/external-resources.qdoc
index 17459b6a5bc..96117546a29 100644
--- a/src/widgets/doc/src/external-resources.qdoc
+++ b/src/widgets/doc/src/external-resources.qdoc
@@ -8,7 +8,7 @@
*/
/*!
- \externalpage http://www.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm
+ \externalpage https://rk.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm
\title Sinclair Spectrum
*/
/*!
diff --git a/src/widgets/doc/src/qtwidgets-examples.qdoc b/src/widgets/doc/src/qtwidgets-examples.qdoc
index 45677c471ba..364c985b310 100644
--- a/src/widgets/doc/src/qtwidgets-examples.qdoc
+++ b/src/widgets/doc/src/qtwidgets-examples.qdoc
@@ -164,3 +164,15 @@
regular expressions for the Widget-based applications.
*/
+/*!
+ \group examples-user-input
+ \ingroup all-examples
+ \title User Input Examples
+ \brief Using user input in Qt Widgets applications.
+
+ \image imagegestures-example.png {Application handling touch gestures}
+
+ Qt provides the functionality for handling user input and drag-and-drop in
+ widget-based applications.
+
+*/
diff --git a/src/widgets/doc/src/qtwidgets-toc.qdoc b/src/widgets/doc/src/qtwidgets-toc.qdoc
index bc447b8bd58..beddf853a22 100644
--- a/src/widgets/doc/src/qtwidgets-toc.qdoc
+++ b/src/widgets/doc/src/qtwidgets-toc.qdoc
@@ -53,6 +53,7 @@
\li \l{Rich Text Examples}
\li \l{Graphics View Examples}
\li \l{Widget Tools Examples}
+ \li \l{User Input Examples}
\endlist
\endlist
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index e4159ad2cf0..51aea4079a1 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -3298,7 +3298,8 @@ void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
bool QAbstractItemView::isPersistentEditorOpen(const QModelIndex &index) const
{
Q_D(const QAbstractItemView);
- return d->editorForIndex(index).widget;
+ QWidget *editor = d->editorForIndex(index).widget;
+ return editor && d->persistent.contains(editor);
}
/*!
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 6fcfcf1b1ef..fa95a1d2538 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -1432,8 +1432,8 @@ void QApplicationPrivate::notifyWindowIconChanged()
// in case there are any plain QWindows in this QApplication-using
// application, also send the notification to them
- for (int i = 0; i < windowList.size(); ++i)
- QCoreApplication::sendEvent(windowList.at(i), &ev);
+ for (QWindow *w : std::as_const(windowList))
+ QCoreApplication::sendEvent(w, &ev);
}
/*!
@@ -1508,11 +1508,15 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
return;
}
- if (focus && (reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason)
- && qt_in_tab_key_event)
- focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
- else if (focus && reason == Qt::ShortcutFocusReason) {
- focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ if (focus) {
+ if ((reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason)
+ && qt_in_tab_key_event)
+ focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ else if (reason == Qt::ShortcutFocusReason) {
+ focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ } else {
+ focus->window()->setAttribute(Qt::WA_KeyboardFocusChange, false);
+ }
}
QWidget *prev = focus_widget;
focus_widget = focus;
@@ -1774,9 +1778,9 @@ void QApplicationPrivate::notifyLayoutDirectionChange()
// in case there are any plain QWindows in this QApplication-using
// application, also send the notification to them
- for (int i = 0; i < windowList.size(); ++i) {
+ for (QWindow *w: std::as_const(windowList)) {
QEvent ev(QEvent::ApplicationLayoutDirectionChange);
- QCoreApplication::sendEvent(windowList.at(i), &ev);
+ QCoreApplication::sendEvent(w, &ev);
}
}
@@ -1863,14 +1867,12 @@ void QApplicationPrivate::setActiveWindow(QWidget* act)
QEvent windowActivate(QEvent::WindowActivate);
QEvent windowDeactivate(QEvent::WindowDeactivate);
- for (int i = 0; i < toBeActivated.size(); ++i) {
- QWidget *w = toBeActivated.at(i);
+ for (QWidget *w : std::as_const(toBeActivated)) {
QApplication::sendSpontaneousEvent(w, &windowActivate);
QApplication::sendSpontaneousEvent(w, &activationChange);
}
- for(int i = 0; i < toBeDeactivated.size(); ++i) {
- QWidget *w = toBeDeactivated.at(i);
+ for (QWidget *w : std::as_const(toBeDeactivated)) {
QApplication::sendSpontaneousEvent(w, &windowDeactivate);
QApplication::sendSpontaneousEvent(w, &activationChange);
}
@@ -2082,8 +2084,7 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
}
QEvent leaveEvent(QEvent::Leave);
- for (int i = 0; i < leaveList.size(); ++i) {
- auto *w = leaveList.at(i);
+ for (QWidget *w : std::as_const(leaveList)) {
if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, nullptr)) {
QCoreApplication::sendEvent(w, &leaveEvent);
if (w->testAttribute(Qt::WA_Hover) &&
@@ -2125,8 +2126,7 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
// Whenever we leave an alien widget on X11/QPA, we need to reset its nativeParentWidget()'s cursor.
// This is not required on Windows as the cursor is reset on every single mouse move.
QWidget *parentOfLeavingCursor = nullptr;
- for (int i = 0; i < leaveList.size(); ++i) {
- auto *w = leaveList.at(i);
+ for (QWidget *w : std::as_const(leaveList)) {
if (!isAlien(w))
break;
if (w->testAttribute(Qt::WA_SetCursor)) {
@@ -3085,7 +3085,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
const QPoint offset = w->pos();
w = w->parentWidget();
QMutableTouchEvent::setTarget(touchEvent, w);
- for (int i = 0; i < touchEvent->pointCount(); ++i) {
+ for (qsizetype cnt = touchEvent->pointCount(), i = 0; i < cnt; ++i) {
auto &pt = touchEvent->point(i);
QMutableEventPoint::setPosition(pt, pt.position() + offset);
}
@@ -3164,8 +3164,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
res = d->notify_helper(w, &ge);
gestureEvent->m_spont = false;
eventAccepted = ge.isAccepted();
- for (int i = 0; i < gestures.size(); ++i) {
- QGesture *g = gestures.at(i);
+ for (QGesture *g : std::as_const(gestures)) {
// Ignore res [event return value] because handling of multiple gestures
// packed into a single QEvent depends on not consuming the event
if (eventAccepted || ge.isAccepted(g)) {
@@ -3708,7 +3707,7 @@ bool QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEven
{
bool containsPress = false;
- for (int i = 0; i < touchEvent->pointCount(); ++i) {
+ for (qsizetype cnt = touchEvent->pointCount(), i = 0; i < cnt; ++i) {
auto &pt = touchEvent->point(i);
QMutableEventPoint::setPosition(pt, widget->mapFromGlobal(pt.globalPosition()));
@@ -3768,7 +3767,7 @@ void QApplicationPrivate::activateImplicitTouchGrab(QWidget *widget, QTouchEvent
// If the widget dispatched the event further (see QGraphicsProxyWidget), then
// there might already be an implicit grabber. Don't override that. A widget that
// has partially recognized a gesture needs to grab all points.
- for (int i = 0; i < touchEvent->pointCount(); ++i) {
+ for (qsizetype cnt = touchEvent->pointCount(), i = 0; i < cnt; ++i) {
auto &ep = touchEvent->point(i);
if (!QMutableEventPoint::target(ep) && (ep.isAccepted() || grabMode == GrabAllPoints))
QMutableEventPoint::setTarget(ep, widget);
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 9e6aaf4b95f..d989feb7f91 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -20,6 +20,8 @@
#if QT_CONFIG(style_stylesheet)
#include <private/qstylesheetstyle_p.h>
#endif
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
#include <qlabel.h>
#include <QtWidgets/private/qlabel_p.h>
@@ -386,6 +388,17 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
p += offset;
+#if QT_CONFIG(wayland)
+ create();
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(windowHandle()->handle())) {
+ // based on the existing code below, by default position at 'p' stored at the bottom right of our rect
+ // then flip to the other arbitrary 4x24 space if constrained
+ const QRect controlGeometry(QRect(p.x() - 4, p.y() - 24, 4, 24));
+ waylandWindow->setParentControlGeometry(controlGeometry);
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ToolTip);
+ }
+#endif
+
QRect screenRect = screen->geometry();
if (p.x() + this->width() > screenRect.x() + screenRect.width())
p.rx() -= 4 + this->width();
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 36446c3e5c4..9499c88af12 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -13144,11 +13144,22 @@ int QWidget::metric(PaintDeviceMetric m) const
void QWidget::initPainter(QPainter *painter) const
{
const QPalette &pal = palette();
- painter->d_func()->state->pen = QPen(pal.brush(foregroundRole()), 1);
- painter->d_func()->state->bgBrush = pal.brush(backgroundRole());
+ QPainterPrivate *painterPrivate = QPainterPrivate::get(painter);
+
+ painterPrivate->state->pen = QPen(pal.brush(foregroundRole()), 1);
+ painterPrivate->state->bgBrush = pal.brush(backgroundRole());
QFont f(font(), this);
- painter->d_func()->state->deviceFont = f;
- painter->d_func()->state->font = f;
+ painterPrivate->state->deviceFont = f;
+ painterPrivate->state->font = f;
+
+ painterPrivate->setEngineDirtyFlags({
+ QPaintEngine::DirtyPen,
+ QPaintEngine::DirtyBrush,
+ QPaintEngine::DirtyFont,
+ });
+
+ if (painterPrivate->extended)
+ painterPrivate->extended->penChanged();
}
/*!
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 737ccb0e807..622f1548756 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -591,6 +591,10 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
}
}
+ // Event delivery above might have destroyed this object. See QTBUG-138419.
+ if (self.isNull())
+ return;
+
if (QApplication::activePopupWidget() != activePopupWidget
&& QApplicationPrivate::replayMousePress
&& QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ReplayMousePressOutsidePopup).toBool()) {
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 220f600ea41..735b574d293 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -122,6 +122,8 @@
#include "QtGui/qevent.h"
#include <private/qapplication_p.h>
#include <private/qwidget_p.h>
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
#if QT_CONFIG(lineedit)
#include "QtWidgets/qlineedit.h"
#endif
@@ -925,10 +927,15 @@ void QCompleterPrivate::showPopup(const QRect& rect)
popup->setGeometry(pos.x(), pos.y(), w, h);
if (!popup->isVisible()) {
- // Make sure popup has a transient parent set, Wayland needs it. QTBUG-130474
- popup->winId(); // force creation of windowHandle
- popup->windowHandle()->setTransientParent(widget->window()->windowHandle());
-
+#if QT_CONFIG(wayland)
+ popup->createWinId();
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(popup->windowHandle()->handle())) {
+ popup->windowHandle()->setTransientParent(widget->window()->windowHandle());
+ const QRect controlGeometry = QRect(widget->mapTo(widget->topLevelWidget(), QPoint(0,0)), widget->size());
+ waylandWindow->setParentControlGeometry(controlGeometry);
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ComboBox);
+ }
+#endif
popup->show();
}
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 6f25b8bde67..2f51b83a49d 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -7,6 +7,9 @@
#include <qstylepainter.h>
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformmenu.h>
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
+
#include <qlineedit.h>
#include <qapplication.h>
#include <qlistview.h>
@@ -2868,6 +2871,17 @@ void QComboBox::showPopup()
container->hide();
}
}
+
+#if QT_CONFIG(wayland)
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(container->windowHandle()->handle())) {
+ const QRect popup(style->subControlRect(QStyle::CC_ComboBox, &opt,
+ QStyle::SC_ComboBoxListBoxPopup, this));
+ const QRect controlGeometry = QRect(mapTo(window(), popup.topLeft()), popup.size());
+ waylandWindow->setParentControlGeometry(controlGeometry);
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ComboBox);
+ }
+#endif
+
container->show();
if (!neededHorizontalScrollBar && needHorizontalScrollBar()) {
listRect.adjust(0, 0, 0, sb->height());
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 055d8f3d11e..1708a53f163 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -572,6 +572,8 @@ bool QDockWidgetGroupWindow::hasNativeDecos() const
#endif
}
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Waggressive-loop-optimizations")
/*
The given widget is hovered over this floating group.
This function will save the state and create a gap in the actual state.
@@ -623,6 +625,7 @@ bool QDockWidgetGroupWindow::hover(QLayoutItem *widgetItem, const QPoint &mouseP
layoutInfo()->apply(opts & QMainWindow::AnimatedDocks);
return true;
}
+QT_WARNING_POP
void QDockWidgetGroupWindow::updateCurrentGapRect()
{
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 5cda8f33f4c..3177ed5c2d4 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -40,6 +40,8 @@
#include <private/qaction_p.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
#include <private/qstyle_p.h>
QT_BEGIN_NAMESPACE
@@ -2535,6 +2537,23 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
}
popupScreen = QGuiApplication::screenAt(pos);
q->setGeometry(QRect(pos, size));
+
+#if QT_CONFIG(wayland)
+ q->create();
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(q->windowHandle()->handle())) {
+ if (causedButton) {
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::Menu);
+ waylandWindow->setParentControlGeometry(causedButton->geometry());
+ } else if (caused) {
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::SubMenu);
+ waylandWindow->setParentControlGeometry(caused->d_func()->actionRect(caused->d_func()->currentAction));
+ } else if (auto menubar = qobject_cast<QMenuBar*>(causedPopup.widget)) {
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::Menu);
+ waylandWindow->setParentControlGeometry(menubar->actionGeometry(causedPopup.action));
+ }
+ }
+#endif
+
#if QT_CONFIG(effects)
int hGuess = q->isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;
int vGuess = QEffects::DownScroll;
@@ -2952,7 +2971,7 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e)
#endif
d->activateAction(action, QAction::Trigger);
}
- } else if (!action || action->isEnabled()) {
+ } else if ((!action || action->isEnabled()) && !action->isSeparator()) {
d->hideUpToMenuBar();
}
}