summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/configure.json2
-rw-r--r--src/widgets/doc/qtwidgets.qdocconf2
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp18
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp37
-rw-r--r--src/widgets/kernel/qwidget.cpp127
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp6
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp8
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp6
-rw-r--r--src/widgets/util/qcompleter_p.h3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp13
-rw-r--r--src/widgets/widgets/qcombobox.cpp52
-rw-r--r--src/widgets/widgets/qcombobox_p.h1
-rw-r--r--src/widgets/widgets/qmenu_mac.mm5
-rw-r--r--src/widgets/widgets/qmenubar.cpp3
-rw-r--r--src/widgets/widgets/qtabwidget.cpp83
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp17
16 files changed, 236 insertions, 147 deletions
diff --git a/src/widgets/configure.json b/src/widgets/configure.json
index 4c596c09a5..b3a5227d26 100644
--- a/src/widgets/configure.json
+++ b/src/widgets/configure.json
@@ -129,7 +129,7 @@
"label": "QDateTimeEdit",
"purpose": "Supports editing dates and times.",
"section": "Widgets",
- "condition": "features.calendarwidget && features.datestring && features.textdate",
+ "condition": "features.calendarwidget && features.datestring && features.textdate && features.datetimeparser",
"output": [ "publicFeature", "feature" ]
},
"stackedwidget": {
diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf
index d0cf9671b1..a49eb439af 100644
--- a/src/widgets/doc/qtwidgets.qdocconf
+++ b/src/widgets/doc/qtwidgets.qdocconf
@@ -47,3 +47,5 @@ imagedirs += images \
navigation.landingpage = "Qt Widgets"
navigation.cppclassespage = "Qt Widgets C++ Classes"
+manifestmeta.highlighted.names = "QtWidgets/Calendar Widget Example" \
+ "QtWidgets/Simple Tree Model Example"
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index fe27be8522..15e6b0eb99 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -2230,7 +2230,7 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
QAbstractScrollArea::focusInEvent(event);
const QItemSelectionModel* model = selectionModel();
- const bool currentIndexValid = currentIndex().isValid();
+ bool currentIndexValid = currentIndex().isValid();
if (model
&& !d->currentIndexSet
@@ -2238,19 +2238,16 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
bool autoScroll = d->autoScroll;
d->autoScroll = false;
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
- if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason)
+ if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) {
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ currentIndexValid = true;
+ }
d->autoScroll = autoScroll;
}
- if (model && currentIndexValid) {
- if (currentIndex().flags() != Qt::ItemIsEditable)
- setAttribute(Qt::WA_InputMethodEnabled, false);
- else
- setAttribute(Qt::WA_InputMethodEnabled);
- }
-
- if (!currentIndexValid)
+ if (model && currentIndexValid)
+ setAttribute(Qt::WA_InputMethodEnabled, (currentIndex().flags() & Qt::ItemIsEditable));
+ else if (!currentIndexValid)
setAttribute(Qt::WA_InputMethodEnabled, false);
d->viewport->update();
@@ -3665,6 +3662,7 @@ void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelI
d->shouldScrollToCurrentOnShow = d->autoScroll;
}
}
+ setAttribute(Qt::WA_InputMethodEnabled, (current.isValid() && (current.flags() & Qt::ItemIsEditable)));
}
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index fca36c7472..5bf66d68e3 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -244,6 +244,36 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
return state;
}
+static bool logIgnoredEvent(QEvent::Type t)
+{
+ bool result = false;
+ switch (t) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchCancel:
+ case QEvent::TouchEnd:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ case QEvent::TabletMove:
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseMove:
+ result = true;
+ break;
+ default:
+ break;
+
+ }
+ return result;
+}
+
bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
Qt::GestureType> &contexts,
QEvent *event)
@@ -289,10 +319,13 @@ bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: not gesture: " << state << event;
notGestures << state;
} else if (recognizerState == QGestureRecognizer::Ignore) {
- qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event;
+ if (logIgnoredEvent(event->type()))
+ qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event;
} else {
- qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer"
+ if (logIgnoredEvent(event->type())) {
+ qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer"
<< "ignored the event: " << state << event;
+ }
}
if (resultHint & QGestureRecognizer::ConsumeEventHint) {
qCDebug(lcGestureManager) << "QGestureManager: we were asked to consume the event: "
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 0aa5f57e98..6a633fb575 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1876,39 +1876,15 @@ static void deleteBackingStore(QWidgetPrivate *d)
{
QTLWExtra *topData = d->topData();
- // The context must be current when destroying the backing store as it may attempt to
- // release resources like textures and shader programs. The window may not be suitable
- // anymore as there will often not be a platform window underneath at this stage. Fall
- // back to a QOffscreenSurface in this case.
- QScopedPointer<QOffscreenSurface> tempSurface;
-#ifndef QT_NO_OPENGL
- if (d->textureChildSeen && topData->shareContext) {
- if (topData->window->handle()) {
- topData->shareContext->makeCurrent(topData->window);
- } else {
- tempSurface.reset(new QOffscreenSurface);
- tempSurface->setFormat(topData->shareContext->format());
- tempSurface->create();
- topData->shareContext->makeCurrent(tempSurface.data());
- }
- }
-#endif
-
delete topData->backingStore;
topData->backingStore = 0;
-
-#ifndef QT_NO_OPENGL
- if (d->textureChildSeen && topData->shareContext)
- topData->shareContext->doneCurrent();
-#endif
}
void QWidgetPrivate::deleteTLSysExtra()
{
if (extra && extra->topextra) {
//the qplatformbackingstore may hold a reference to the window, so the backingstore
- //needs to be deleted first. If the backingstore holds GL resources, we need to
- // make the context current here. This is taken care of by deleteBackingStore().
+ //needs to be deleted first.
extra->topextra->backingStoreTracker.destroy();
deleteBackingStore(this);
@@ -5912,7 +5888,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
pixmapOffset -= effectRect.topLeft();
- const qreal dpr = context->painter->device()->devicePixelRatio();
+ const qreal dpr = context->painter->device()->devicePixelRatioF();
QPixmap pixmap(effectRect.size() * dpr);
pixmap.setDevicePixelRatio(dpr);
@@ -6945,6 +6921,9 @@ bool QWidget::isActiveWindow() const
/*!
Puts the \a second widget after the \a first widget in the focus order.
+ It effectively removes the \a second widget from its focus chain and
+ inserts it after the \a first widget.
+
Note that since the tab order of the \a second widget is changed, you
should order a chain like this:
@@ -6957,11 +6936,19 @@ bool QWidget::isActiveWindow() const
If \a first or \a second has a focus proxy, setTabOrder()
correctly substitutes the proxy.
+ \note Since Qt 5.10: A widget that has a child as focus proxy is understood as
+ a compound widget. When setting a tab order between one or two compound widgets, the
+ local tab order inside each will be preserved. This means that if both widgets are
+ compound widgets, the resulting tab order will be from the last child inside
+ \a first, to the first child inside \a second.
+
\sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus in Widgets}
*/
void QWidget::setTabOrder(QWidget* first, QWidget *second)
{
- if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus)
+ if (!first || !second || first == second
+ || first->focusPolicy() == Qt::NoFocus
+ || second->focusPolicy() == Qt::NoFocus)
return;
if (Q_UNLIKELY(first->window() != second->window())) {
@@ -6969,54 +6956,56 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
return;
}
- QWidget *fp = first->focusProxy();
- if (fp) {
- // If first is redirected, set first to the last child of first
- // that can take keyboard focus so that second is inserted after
- // that last child, and the focus order within first is (more
- // likely to be) preserved.
- QList<QWidget *> l = first->findChildren<QWidget *>();
- for (int i = l.size()-1; i >= 0; --i) {
- QWidget * next = l.at(i);
- if (next->window() == fp->window()) {
- fp = next;
- if (fp->focusPolicy() != Qt::NoFocus)
- break;
- }
- }
- first = fp;
- }
+ auto determineLastFocusChild = [](QWidget *target, QWidget *&lastFocusChild)
+ {
+ // Since we need to repeat the same logic for both 'first' and 'second', we add a function that
+ // determines the last focus child for a widget, taking proxies and compound widgets into account.
+ // If the target is not a compound widget (it doesn't have a focus proxy that points to a child),
+ // 'lastFocusChild' will be set to the target itself.
+ lastFocusChild = target;
+
+ QWidget *focusProxy = target->d_func()->deepestFocusProxy();
+ if (!focusProxy || !target->isAncestorOf(focusProxy))
+ return;
- if (fp == second)
- return;
+ lastFocusChild = focusProxy;
- if (QWidget *sp = second->focusProxy())
- second = sp;
+ for (QWidget *focusNext = lastFocusChild->d_func()->focus_next;
+ focusNext != focusProxy && target->isAncestorOf(focusNext) && focusNext->window() == focusProxy->window();
+ focusNext = focusNext->d_func()->focus_next) {
+ if (focusNext->focusPolicy() != Qt::NoFocus)
+ lastFocusChild = focusNext;
+ }
+ };
-// QWidget *fp = first->d_func()->focus_prev;
- QWidget *fn = first->d_func()->focus_next;
+ QWidget *lastFocusChildOfFirst, *lastFocusChildOfSecond;
+ determineLastFocusChild(first, lastFocusChildOfFirst);
+ determineLastFocusChild(second, lastFocusChildOfSecond);
- if (fn == second || first == second)
+ // If the tab order is already correct, exit early
+ if (lastFocusChildOfFirst->d_func()->focus_next == second)
return;
- QWidget *sp = second->d_func()->focus_prev;
- QWidget *sn = second->d_func()->focus_next;
-
- fn->d_func()->focus_prev = second;
- first->d_func()->focus_next = second;
-
- second->d_func()->focus_next = fn;
- second->d_func()->focus_prev = first;
-
- sp->d_func()->focus_next = sn;
- sn->d_func()->focus_prev = sp;
-
-
- Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first);
- Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first);
-
- Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second);
- Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second);
+ // Note that we need to handle two different sections in the tab chain; The section
+ // that 'first' belongs to (firstSection), where we are about to insert 'second', and
+ // the section that 'second' used be a part of (secondSection). When we pull 'second'
+ // out of the second section and insert it into the first, we also need to ensure
+ // that we leave the second section in a connected state.
+ QWidget *firstChainOldSecond = lastFocusChildOfFirst->d_func()->focus_next;
+ QWidget *secondChainNewFirst = second->d_func()->focus_prev;
+ QWidget *secondChainNewSecond = lastFocusChildOfSecond->d_func()->focus_next;
+
+ // Insert 'second' after 'first'
+ lastFocusChildOfFirst->d_func()->focus_next = second;
+ second->d_func()->focus_prev = lastFocusChildOfFirst;
+
+ // The widget that used to be 'second' in the first section, should now become 'third'
+ lastFocusChildOfSecond->d_func()->focus_next = firstChainOldSecond;
+ firstChainOldSecond->d_func()->focus_prev = lastFocusChildOfSecond;
+
+ // Repair the second section after we pulled 'second' out of it
+ secondChainNewFirst->d_func()->focus_next = secondChainNewSecond;
+ secondChainNewSecond->d_func()->focus_prev = secondChainNewFirst;
}
/*!\internal
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index b851a5c0af..3b093283cd 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -143,10 +143,8 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
// WA_TranslucentBackground. Therefore the compositor needs to know whether the app intends
// to rely on translucency, in order to decide if it should clear to transparent or opaque.
const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground);
- // Use the tlw's context, not widget's. The difference is important with native child
- // widgets where tlw != widget.
- backingStore->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset, widgetTextures,
- tlw->d_func()->shareContext(), translucentBackground);
+ backingStore->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset,
+ widgetTextures, translucentBackground);
widget->window()->d_func()->sendComposeStatus(widget->window(), true);
} else
#endif
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index e5027e35df..80ed39bf76 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -96,6 +96,7 @@ public:
}
QRectF closestAcceptableGeometry(const QRectF &rect) const override;
+ QOpenGLContext *shareContext() const override;
};
QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const
@@ -127,6 +128,13 @@ QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const
return result;
}
+QOpenGLContext *QWidgetWindowPrivate::shareContext() const
+{
+ Q_Q(const QWidgetWindow);
+ const QWidgetPrivate *widgetPrivate = QWidgetPrivate::get(q->widget());
+ return widgetPrivate->shareContext();
+}
+
QWidgetWindow::QWidgetWindow(QWidget *widget)
: QWindow(*new QWidgetWindowPrivate(), 0)
, m_widget(widget)
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index d2ad7a466e..d388327687 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -89,7 +89,7 @@ public:
void updateUsesNativeWidgets()
{
- if (usesNativeWidgets || window->parent() == 0)
+ if (window->parent() == 0)
return;
Q_Q(QWindowContainer);
if (q->internalWinId()) {
@@ -97,6 +97,7 @@ public:
usesNativeWidgets = true;
return;
}
+ bool nativeWidgetSet = false;
QWidget *p = q->parentWidget();
while (p) {
if (false
@@ -108,11 +109,12 @@ public:
#endif
) {
q->winId();
- usesNativeWidgets = true;
+ nativeWidgetSet = true;
break;
}
p = p->parentWidget();
}
+ usesNativeWidgets = nativeWidgetSet;
}
void markParentChain() {
diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h
index a1112cb9c7..765363744b 100644
--- a/src/widgets/util/qcompleter_p.h
+++ b/src/widgets/util/qcompleter_p.h
@@ -101,6 +101,9 @@ public:
void _q_autoResizePopup();
void _q_fileSystemModelDirectoryLoaded(const QString &path);
void setCurrentIndex(QModelIndex, bool = true);
+
+ static QCompleterPrivate *get(QCompleter *o) { return o->d_func(); }
+ static const QCompleterPrivate *get(const QCompleter *o) { return o->d_func(); }
};
class QIndexMapper
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index c72c060f9a..3427579d1f 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -39,7 +39,9 @@
#include <qplatformdefs.h>
#include <private/qabstractspinbox_p.h>
+#if QT_CONFIG(datetimeparser)
#include <private/qdatetimeparser_p.h>
+#endif
#include <private/qlineedit_p.h>
#include <qabstractspinbox.h>
@@ -47,9 +49,6 @@
#include <qstylehints.h>
#include <qclipboard.h>
#include <qdatetime.h>
-#if QT_CONFIG(datetimeedit)
-#include <qdatetimeedit.h>
-#endif
#include <qevent.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
@@ -1962,12 +1961,15 @@ QVariant operator+(const QVariant &arg1, const QVariant &arg2)
break;
}
case QVariant::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: {
QDateTime a2 = arg2.toDateTime();
QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATETIME_MIN.daysTo(a2));
a1.setTime(a1.time().addMSecs(QTime().msecsTo(a2.time())));
ret = QVariant(a1);
+ break;
}
+#endif // datetimeparser
default: break;
}
return ret;
@@ -2022,6 +2024,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = static_cast<int>(qBound<double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX));
break;
case QVariant::Double: ret = QVariant(arg1.toDouble() * multiplier); break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: {
double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
int daysInt = (int)days;
@@ -2031,6 +2034,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = QDateTime(QDate().addDays(int(days)), QTime().addMSecs(msecs));
break;
}
+#endif // datetimeparser
default: ret = arg1; break;
}
@@ -2053,11 +2057,14 @@ double operator/(const QVariant &arg1, const QVariant &arg2)
a1 = arg1.toDouble();
a2 = arg2.toDouble();
break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime:
a1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate());
a2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate());
a1 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg1.toDateTime().time()) / (long)(3600 * 24 * 1000);
a2 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg2.toDateTime().time()) / (long)(3600 * 24 * 1000);
+ break;
+#endif // datetimeparser
default: break;
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index cd2e20694e..9afb4b3ae6 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -72,6 +72,7 @@
#include <private/qabstractitemmodel_p.h>
#include <private/qabstractscrollarea_p.h>
#include <private/qlineedit_p.h>
+#include <private/qcompleter_p.h>
#include <qdebug.h>
#if QT_CONFIG(effects)
# include <private/qeffects_p.h>
@@ -427,6 +428,20 @@ void QComboBoxPrivateContainer::resizeEvent(QResizeEvent *e)
QFrame::resizeEvent(e);
}
+void QComboBoxPrivateContainer::paintEvent(QPaintEvent *e)
+{
+ QStyleOptionComboBox cbOpt = comboStyleOption();
+ if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &cbOpt, combo)
+ && mask().isEmpty()) {
+ QStyleOption opt;
+ opt.initFrom(this);
+ QPainter p(this);
+ style()->drawPrimitive(QStyle::PE_PanelMenu, &opt, &p, this);
+ }
+
+ QFrame::paintEvent(e);
+}
+
void QComboBoxPrivateContainer::leaveEvent(QEvent *)
{
// On Mac using the Mac style we want to clear the selection
@@ -1227,8 +1242,27 @@ Qt::MatchFlags QComboBoxPrivate::matchFlags() const
void QComboBoxPrivate::_q_editingFinished()
{
Q_Q(QComboBox);
- if (lineEdit && !lineEdit->text().isEmpty() && itemText(currentIndex) != lineEdit->text()) {
- const int index = q_func()->findText(lineEdit->text(), matchFlags());
+ if (!lineEdit)
+ return;
+ const auto leText = lineEdit->text();
+ if (!leText.isEmpty() && itemText(currentIndex) != leText) {
+#if QT_CONFIG(completer)
+ const auto *leCompleter = lineEdit->completer();
+ const auto *popup = leCompleter ? QCompleterPrivate::get(leCompleter)->popup : nullptr;
+ if (popup && popup->isVisible()) {
+ // QLineEdit::editingFinished() will be emitted before the code flow returns
+ // to QCompleter::eventFilter(), where QCompleter::activated() may be emitted.
+ // We know that the completer popup will still be visible at this point, and
+ // that any selection should be valid.
+ const QItemSelectionModel *selModel = popup->selectionModel();
+ const QModelIndex curIndex = popup->currentIndex();
+ const bool completerIsActive = selModel && selModel->selectedIndexes().contains(curIndex);
+
+ if (completerIsActive)
+ return;
+ }
+#endif
+ const int index = q_func()->findText(leText, matchFlags());
if (index != -1) {
q->setCurrentIndex(index);
emitActivated(currentIndex);
@@ -3163,13 +3197,13 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
Q_D(QComboBox);
#if QT_CONFIG(completer)
- if (d->lineEdit
- && d->lineEdit->completer()
- && d->lineEdit->completer()->popup()
- && d->lineEdit->completer()->popup()->isVisible()) {
- // provide same autocompletion support as line edit
- d->lineEdit->event(e);
- return;
+ if (const auto *cmpltr = completer()) {
+ const auto *popup = QCompleterPrivate::get(cmpltr)->popup;
+ if (popup && popup->isVisible()) {
+ // provide same autocompletion support as line edit
+ d->lineEdit->event(e);
+ return;
+ }
}
#endif
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 835bbf866e..3f75a357e4 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -248,6 +248,7 @@ protected:
void timerEvent(QTimerEvent *timerEvent) override;
void leaveEvent(QEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
+ void paintEvent(QPaintEvent *e) override;
QStyleOptionComboBox comboStyleOption() const;
Q_SIGNALS:
diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm
index 7d932c670f..0d680fb4dc 100644
--- a/src/widgets/widgets/qmenu_mac.mm
+++ b/src/widgets/widgets/qmenu_mac.mm
@@ -135,6 +135,11 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem*
containerWindow->setFlags(wf | Qt::SubWindow);
[(NSView *)widget->winId() setAutoresizingMask:NSViewWidthSizable];
+ if (QPlatformNativeInterface::NativeResourceForIntegrationFunction function = resolvePlatformFunction("setEmbeddedInForeignView")) {
+ typedef void (*SetEmbeddedInForeignViewFunction)(QPlatformWindow *window, bool embedded);
+ reinterpret_cast<SetEmbeddedInForeignViewFunction>(function)(containerWindow->handle(), true);
+ }
+
item->setNativeContents((WId)containerView);
container->show();
}
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 137d38e558..c469c0b793 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -289,7 +289,7 @@ void QMenuBarPrivate::setKeyboardMode(bool b)
keyboardState = b;
if(b) {
QWidget *fw = QApplication::focusWidget();
- if (fw != q)
+ if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
keyboardFocusWidget = fw;
focusFirstAction();
q->setFocus(Qt::MenuBarFocusReason);
@@ -1707,6 +1707,7 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id)
}
}
+ keyboardFocusWidget = QApplication::focusWidget();
setCurrentAction(act, true, true);
if (act && !act->menu()) {
activateAction(act, QAction::Trigger);
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index fd783da49a..60a924510a 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -196,6 +196,8 @@ public:
void _q_tabMoved(int from, int to);
void init();
+ void initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const;
+
QTabBar *tabs;
QStackedWidget *stack;
QRect panelRect;
@@ -258,6 +260,43 @@ bool QTabWidget::hasHeightForWidth() const
return has;
}
+/*!
+ \internal
+
+ Initialize only time inexpensive parts of the style option
+ for QTabWidget::setUpLayout()'s non-visible code path.
+*/
+void QTabWidgetPrivate::initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const
+{
+ Q_Q(const QTabWidget);
+ option->initFrom(q);
+
+ if (q->documentMode())
+ option->lineWidth = 0;
+ else
+ option->lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q);
+
+ switch (pos) {
+ case QTabWidget::North:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
+ : QTabBar::TriangularNorth;
+ break;
+ case QTabWidget::South:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
+ : QTabBar::TriangularSouth;
+ break;
+ case QTabWidget::West:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedWest
+ : QTabBar::TriangularWest;
+ break;
+ case QTabWidget::East:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedEast
+ : QTabBar::TriangularEast;
+ break;
+ }
+
+ option->tabBarRect = q->tabBar()->geometry();
+}
/*!
Initialize \a option with the values from this QTabWidget. This method is useful
@@ -272,12 +311,7 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
return;
Q_D(const QTabWidget);
- option->initFrom(this);
-
- if (documentMode())
- option->lineWidth = 0;
- else
- option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this);
+ d->initBasicStyleOption(option);
int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0, this);
QSize t(0, d->stack->frameWidth());
@@ -308,31 +342,10 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
option->leftCornerWidgetSize = QSize(0, 0);
}
- switch (d->pos) {
- case QTabWidget::North:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
- : QTabBar::TriangularNorth;
- break;
- case QTabWidget::South:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
- : QTabBar::TriangularSouth;
- break;
- case QTabWidget::West:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedWest
- : QTabBar::TriangularWest;
- break;
- case QTabWidget::East:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedEast
- : QTabBar::TriangularEast;
- break;
- }
-
option->tabBarSize = t;
- QRect tbRect = tabBar()->geometry();
QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
- option->tabBarRect = tbRect;
- selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft());
+ selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + option->tabBarRect.topLeft());
option->selectedTabRect = selectedTabRect;
}
@@ -764,17 +777,19 @@ void QTabWidget::setUpLayout(bool onlyCheck)
if (onlyCheck && !d->dirty)
return; // nothing to do
- QStyleOptionTabWidgetFrame option;
- initStyleOption(&option);
-
- // this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
- d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
-
if (!isVisible()) {
+ // this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
+ QStyleOptionTabWidgetFrame basicOption;
+ d->initBasicStyleOption(&basicOption);
+ d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &basicOption);
d->dirty = true;
return; // we'll do it later
}
+ QStyleOptionTabWidgetFrame option;
+ initStyleOption(&option);
+ d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
+
QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this);
d->panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this);
QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this);
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 1b7a41d547..4f4a6f70b5 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -44,6 +44,7 @@
#endif
#include "qclipboard.h"
#include <private/qguiapplication_p.h>
+#include <private/qcompleter_p.h>
#include <qpa/qplatformtheme.h>
#include <qstylehints.h>
#ifndef QT_NO_ACCESSIBILITY
@@ -1484,7 +1485,8 @@ void QWidgetLineControl::complete(int key)
} else {
#ifndef QT_KEYPAD_NAVIGATION
if (text.isEmpty()) {
- m_completer->popup()->hide();
+ if (auto *popup = QCompleterPrivate::get(m_completer)->popup)
+ popup->hide();
return;
}
#endif
@@ -1630,25 +1632,16 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
#if QT_CONFIG(completer)
if (m_completer) {
QCompleter::CompletionMode completionMode = m_completer->completionMode();
+ auto *popup = QCompleterPrivate::get(m_completer)->popup;
if ((completionMode == QCompleter::PopupCompletion
|| completionMode == QCompleter::UnfilteredPopupCompletion)
- && m_completer->popup()
- && m_completer->popup()->isVisible()) {
+ && popup && popup->isVisible()) {
// The following keys are forwarded by the completer to the widget
// Ignoring the events lets the completer provide suitable default behavior
switch (event->key()) {
case Qt::Key_Escape:
event->ignore();
return;
- case Qt::Key_Enter:
- case Qt::Key_Return:
- case Qt::Key_F4:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- m_completer->popup()->hide(); // just hide. will end up propagating to parent
default:
break; // normal key processing
}