diff options
Diffstat (limited to 'src/widgets')
21 files changed, 155 insertions, 97 deletions
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index e4862f16d1..34668f4473 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -1906,7 +1906,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "<p>Qt and the Qt logo are trademarks of Digia Plc and/or its subsidiary(-ies).</p>" "<p>Qt is a Digia product developed as an open source project. See <a href=\"http://%3/\">%3</a> " "for more information.</p>" - ).arg(QStringLiteral("2014"), + ).arg(QStringLiteral("2015"), QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io")); QMessageBox *msgBox = new QMessageBox(parent); diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 87b4b2b5a8..554dda0b8e 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -1311,7 +1311,7 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) if (x <= left + cornerMargin) { if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) { s = Qt::TopLeftSection; - } else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - windowFrameWidth)) { + } else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - cornerMargin)) { s = Qt::BottomLeftSection; } else if (x <= left + windowFrameWidth) { s = Qt::LeftSection; @@ -1319,7 +1319,7 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) } else if (x >= right - cornerMargin) { if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) { s = Qt::TopRightSection; - } else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - windowFrameWidth)) { + } else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - cornerMargin)) { s = Qt::BottomRightSection; } else if (x >= right - windowFrameWidth) { s = Qt::RightSection; diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 8a08badde2..2f9497b991 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2384,7 +2384,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) } #endif break; -#ifdef Q_DEAD_CODE_FROM_QT4_MAC +#ifdef Q_OS_MAC case Qt::Key_Enter: case Qt::Key_Return: // Propagate the enter if you couldn't edit the item and there are no @@ -2414,7 +2414,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) selectAll(); break; } -#ifdef Q_DEAD_CODE_FROM_QT4_MAC +#ifdef Q_OS_MAC if (event->key() == Qt::Key_O && event->modifiers() & Qt::ControlModifier && currentIndex().isValid()) { emit activated(currentIndex()); break; diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index e7d18092f1..add60d4d88 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -3198,7 +3198,7 @@ void QListView::selectionChanged(const QItemSelection &selected, QModelIndex sel = selected.indexes().value(0); if (sel.isValid()) { int entry = visualIndex(sel); - QAccessibleEvent event(this, QAccessible::Selection); + QAccessibleEvent event(this, QAccessible::SelectionAdd); event.setChild(entry); QAccessible::updateAccessibility(&event); } diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 062debf4ee..7944822760 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -3337,7 +3337,7 @@ void QTableView::selectionChanged(const QItemSelection &selected, QModelIndex sel = selected.indexes().value(0); if (sel.isValid()) { int entry = d->accessibleTable2Index(sel); - QAccessibleEvent event(this, QAccessible::Selection); + QAccessibleEvent event(this, QAccessible::SelectionAdd); event.setChild(entry); QAccessible::updateAccessibility(&event); } diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index b440ed6421..0fede7367d 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -3977,7 +3977,7 @@ void QTreeView::selectionChanged(const QItemSelection &selected, if (sel.isValid()) { int entry = d->accessibleTree2Index(sel); Q_ASSERT(entry >= 0); - QAccessibleEvent event(this, QAccessible::Selection); + QAccessibleEvent event(this, QAccessible::SelectionAdd); event.setChild(entry); QAccessible::updateAccessibility(&event); } diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index 007760ef16..bd10888636 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -2935,8 +2935,6 @@ void QTreeWidget::closePersistentEditor(QTreeWidgetItem *item, int column) Returns the widget displayed in the cell specified by \a item and the given \a column. - \note The tree takes ownership of the widget. - */ QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const { @@ -3276,8 +3274,18 @@ QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*> items) const QList<QModelIndex> indexes; for (int i = 0; i < items.count(); ++i) { QTreeWidgetItem *item = items.at(i); + if (!item) { + qWarning() << "QTreeWidget::mimeData: Null-item passed"; + return 0; + } + for (int c = 0; c < item->values.count(); ++c) { - indexes << indexFromItem(item, c); + const QModelIndex index = indexFromItem(item, c); + if (!index.isValid()) { + qWarning() << "QTreeWidget::mimeData: No index associated with item :" << item; + return 0; + } + indexes << index; } } return d->model->QAbstractItemModel::mimeData(indexes); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 392db60e2b..dfe507018b 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3304,12 +3304,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QWidget* w = static_cast<QWidget *>(receiver); QWheelEvent* wheel = static_cast<QWheelEvent*>(e); - // QTBUG-40656, combo and other popups should close when the main window gets a wheel event. - while (QWidget *popup = QApplication::activePopupWidget()) { + // QTBUG-40656, QTBUG-42731: ignore wheel events when a popup (QComboBox) is open. + if (const QWidget *popup = QApplication::activePopupWidget()) { if (w->window() != popup) - popup->close(); - else - break; + return true; } QPoint relpos = wheel->pos(); diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index 67264133ef..563707b021 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -39,6 +39,13 @@ QT_BEGIN_NAMESPACE +int QDesktopScreenWidget::screenNumber() const +{ + const QDesktopWidgetPrivate *desktopWidgetP + = static_cast<const QDesktopWidgetPrivate *>(qt_widget_private(QApplication::desktop())); + return desktopWidgetP->screens.indexOf(const_cast<QDesktopScreenWidget *>(this)); +} + const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const { if (!widget) { @@ -72,29 +79,22 @@ void QDesktopWidgetPrivate::_q_updateScreens() const QList<QScreen *> screenList = QGuiApplication::screens(); const int targetLength = screenList.length(); const int oldLength = screens.length(); - int currentLength = oldLength; // Add or remove screen widgets as necessary - if(currentLength > targetLength) { - QDesktopScreenWidget *screen; - while (currentLength-- > targetLength) { - screen = screens.takeLast(); - delete screen; - } - } - else if (currentLength < targetLength) { - while (currentLength < targetLength) { - QScreen *qScreen = screenList.at(currentLength); - QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget(currentLength++); - screenWidget->setGeometry(qScreen->geometry()); - QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)), - q, SLOT(_q_updateScreens()), Qt::QueuedConnection); - QObject::connect(qScreen, SIGNAL(availableGeometryChanged(QRect)), - q, SLOT(_q_availableGeometryChanged()), Qt::QueuedConnection); - QObject::connect(qScreen, SIGNAL(destroyed()), - q, SLOT(_q_updateScreens()), Qt::QueuedConnection); - screens.append(screenWidget); - } + while (screens.size() > targetLength) + delete screens.takeLast(); + + for (int currentLength = screens.size(); currentLength < targetLength; ++currentLength) { + QScreen *qScreen = screenList.at(currentLength); + QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget; + screenWidget->setGeometry(qScreen->geometry()); + QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)), + q, SLOT(_q_updateScreens()), Qt::QueuedConnection); + QObject::connect(qScreen, SIGNAL(availableGeometryChanged(QRect)), + q, SLOT(_q_availableGeometryChanged()), Qt::QueuedConnection); + QObject::connect(qScreen, SIGNAL(destroyed()), + q, SLOT(_q_updateScreens()), Qt::QueuedConnection); + screens.append(screenWidget); } QRegion virtualGeometry; diff --git a/src/widgets/kernel/qdesktopwidget_p.h b/src/widgets/kernel/qdesktopwidget_p.h index 0f3083cbb5..639af3f9a7 100644 --- a/src/widgets/kernel/qdesktopwidget_p.h +++ b/src/widgets/kernel/qdesktopwidget_p.h @@ -55,12 +55,12 @@ QT_BEGIN_NAMESPACE class QDesktopScreenWidget : public QWidget { Q_OBJECT public: - QDesktopScreenWidget(int screenNumber = -1) : QWidget(0, Qt::Desktop) + QDesktopScreenWidget() : QWidget(Q_NULLPTR, Qt::Desktop) { setVisible(false); - QTLWExtra *topData = d_func()->topData(); - topData->screenIndex = screenNumber; } + + int screenNumber() const; }; class QDesktopWidgetPrivate : public QWidgetPrivate { diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 8ed2f52cbb..b5c547077c 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -826,6 +826,7 @@ QImage QOpenGLWidgetPrivate::grabFramebuffer() resolveSamples(); q->makeCurrent(); QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatio(), false, false); + res.setDevicePixelRatio(q->devicePixelRatio()); return res; } diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index ca82dadabb..3d3b7bef81 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -35,7 +35,7 @@ #include "qapplication_p.h" #include "qbrush.h" #include "qcursor.h" -#include "qdesktopwidget.h" +#include "qdesktopwidget_p.h" #include "qevent.h" #include "qhash.h" #include "qlayout.h" @@ -1111,9 +1111,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) if (allWidgets) allWidgets->insert(q); - QWidget *desktopWidget = 0; + int targetScreen = -1; if (parentWidget && parentWidget->windowType() == Qt::Desktop) { - desktopWidget = parentWidget; + const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(parentWidget); + targetScreen = sw ? sw->screenNumber() : 0; parentWidget = 0; } @@ -1133,10 +1134,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) xinfo = desktopWidget->d_func()->xinfo; } #endif - if (desktopWidget) { - const int screen = desktopWidget->d_func()->topData()->screenIndex; + if (targetScreen >= 0) { + topData()->initialScreenIndex = targetScreen; if (QWindow *window = q->windowHandle()) - window->setScreen(QGuiApplication::screens().value(screen, 0)); + window->setScreen(QGuiApplication::screens().value(targetScreen, Q_NULLPTR)); } data.fstrut_dirty = true; @@ -1412,8 +1413,15 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO win->setGeometry(q->geometry()); else win->resize(q->size()); - if (win->isTopLevel()) - win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0)); + if (win->isTopLevel()) { + int screenNumber = topData()->initialScreenIndex; + topData()->initialScreenIndex = -1; + if (screenNumber < 0) { + screenNumber = q->windowType() != Qt::Desktop + ? QApplication::desktop()->screenNumber(q) : 0; + } + win->setScreen(QGuiApplication::screens().value(screenNumber, Q_NULLPTR)); + } QSurfaceFormat format = win->requestedFormat(); if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface @@ -1713,7 +1721,7 @@ void QWidgetPrivate::createTLExtra() x->embedded = 0; x->window = 0; x->shareContext = 0; - x->screenIndex = 0; + x->initialScreenIndex = -1; #ifdef Q_DEAD_CODE_FROM_QT4_MAC x->wasMaximized = false; #endif // Q_DEAD_CODE_FROM_QT4_MAC @@ -7736,10 +7744,17 @@ void QWidgetPrivate::show_helper() + const bool isWindow = q->isWindow(); +#ifndef QT_NO_GRAPHICSVIEW + bool isEmbedded = isWindow && q->graphicsProxyWidget() != Q_NULLPTR; +#else + bool isEmbedded = false; +#endif + // popup handling: new popups and tools need to be raised, and // existing popups must be closed. Also propagate the current // windows's KeyboardFocusChange status. - if (q->isWindow()) { + if (isWindow && !isEmbedded) { if ((q->windowType() == Qt::Tool) || (q->windowType() == Qt::Popup) || q->windowType() == Qt::ToolTip) { q->raise(); if (q->parentWidget() && q->parentWidget()->window()->testAttribute(Qt::WA_KeyboardFocusChange)) @@ -7754,10 +7769,8 @@ void QWidgetPrivate::show_helper() // Automatic embedding of child windows of widgets already embedded into // QGraphicsProxyWidget when they are shown the first time. - bool isEmbedded = false; #ifndef QT_NO_GRAPHICSVIEW - if (q->isWindow()) { - isEmbedded = q->graphicsProxyWidget() ? true : false; + if (isWindow) { if (!isEmbedded && !bypassGraphicsProxyWidget(q)) { QGraphicsProxyWidget *ancestorProxy = nearestGraphicsProxyWidget(q->parentWidget()); if (ancestorProxy) { @@ -10496,9 +10509,8 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) if (newparent && newparent->windowType() == Qt::Desktop) { // make sure the widget is created on the same screen as the // programmer specified desktop widget - - // get the desktop's screen number - targetScreen = newparent->window()->d_func()->topData()->screenIndex; + const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(newparent); + targetScreen = sw ? sw->screenNumber() : 0; newparent = 0; } @@ -10530,7 +10542,7 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) f |= Qt::Window; if (targetScreen == -1) { if (parent) - targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex; + targetScreen = QApplication::desktop()->screenNumber(q->parentWidget()->window()); } } @@ -10574,12 +10586,11 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) // move the window to the selected screen if (!newparent && targetScreen != -1) { - if (maybeTopData()) - maybeTopData()->screenIndex = targetScreen; // only if it is already created - if (q->testAttribute(Qt::WA_WState_Created)) { + if (q->testAttribute(Qt::WA_WState_Created)) q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0)); - } + else + topData()->initialScreenIndex = targetScreen; } } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 6e4c93e7be..febd94d1f7 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -212,7 +212,7 @@ struct QTLWExtra { #endif QWidgetWindow *window; QOpenGLContext *shareContext; - quint32 screenIndex; // index in qplatformscreenlist + int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent. }; struct QWExtra { diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index 34cfb2d99f..5460a43ef4 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -64,7 +64,7 @@ public: void updateGeometry() { Q_Q(QWindowContainer); - if (q->geometry().bottom() <= 0 || q->geometry().right() <= 0) + if (!q->isWindow() && (q->geometry().bottom() <= 0 || q->geometry().right() <= 0)) /* Qt (e.g. QSplitter) sometimes prefer to hide a widget by *not* calling setVisible(false). This is often done by setting its coordinates to a sufficiently negative value so that its clipped outside the parent. Since a QWindow is not clipped diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 40a2ca7f14..1321ffa497 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1675,13 +1675,14 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti else tdi->max = 10 * slider->rect.height(); - if (usePlainKnob || slider->orientation == Qt::Horizontal) { + int range = slider->maximum - slider->minimum; + if (range == 0) { + tdi->value = 0; + } else if (usePlainKnob || slider->orientation == Qt::Horizontal) { int endsCorrection = usePlainKnob ? 25 : 10; - tdi->value = (tdi->max + 2 * endsCorrection) * (slider->sliderPosition - slider->minimum) - / (slider->maximum - slider->minimum) - endsCorrection; + tdi->value = (tdi->max + 2 * endsCorrection) * (slider->sliderPosition - slider->minimum) / range - endsCorrection; } else { - tdi->value = (tdi->max + 30) * (slider->sliderPosition - slider->minimum) - / (slider->maximum - slider->minimum) - 20; + tdi->value = (tdi->max + 30) * (slider->sliderPosition - slider->minimum) / range - 20; } } tdi->attributes = kThemeTrackShowThumb; diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index ed5eca7318..d7d8e73767 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -505,13 +505,13 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h) nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap); if (!bufferBitmap) { - qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), failed to create dibsection"); + qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() failed.", w, h); bufferW = 0; bufferH = 0; return 0; } if (!bufferPixels) { - qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), did not allocate pixel data"); + qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() did not allocate pixel data.", w, h); bufferW = 0; bufferH = 0; return 0; @@ -696,16 +696,18 @@ bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels) - Painter does not have an HDC - Theme part is flipped (mirrored horizontally) else use drawBackgroundDirectly(). + \note drawBackgroundThruNativeBuffer() can return false for large + sizes due to buffer()/CreateDIBSection() failing. */ -void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) +bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) { if (themeData.rect.isEmpty()) - return; + return true; QPainter *painter = themeData.painter; Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter"); if (!painter || !painter->isActive()) - return; + return false; painter->save(); @@ -741,13 +743,9 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) } const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0); - if (dc) { - drawBackgroundDirectly(themeData); - } else { - drawBackgroundThruNativeBuffer(themeData); - } - + const bool result = dc ? drawBackgroundDirectly(themeData) : drawBackgroundThruNativeBuffer(themeData); painter->restore(); + return result; } /*! \internal @@ -755,7 +753,7 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) Do not use this if you need to perform other transformations on the resulting data. */ -void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData) +bool QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData) { QPainter *painter = themeData.painter; HDC dc = 0; @@ -830,6 +828,7 @@ void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData) } SelectClipRgn(dc, 0); DeleteObject(hrgn); + return true; } /*! \internal @@ -840,7 +839,7 @@ void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData) flips (horizonal mirroring only, vertical are handled by the theme engine). */ -void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData) +bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData) { QPainter *painter = themeData.painter; QRect rect = themeData.rect; @@ -964,7 +963,7 @@ void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa QImage img; if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! ------------------------- if (!buffer(w, h)) // Ensure a buffer of at least (w, h) in size - return; + return false; HDC dc = bufferHDC(); // Clear the buffer @@ -1017,7 +1016,7 @@ void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa memset(&data, 0, sizeof(data)); data.dataValid = true; alphaCache.insert(key, data); - return; + return true; } hasAlpha = hasAlphaChannel(rect); if (!hasAlpha && partIsTransparent) @@ -1132,6 +1131,7 @@ void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa data.hadInvalidAlpha = wasAlphaFixed; alphaCache.insert(key, data); } + return true; } @@ -1860,18 +1860,29 @@ case PE_Frame: if (!theme.isValid()) break; + // May fail due to too-large buffers for large widgets, fall back to Windows style. theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth); theme.partId = WP_FRAMELEFT; - d->drawBackground(theme); + if (!d->drawBackground(theme)) { + QWindowsStyle::drawPrimitive(pe, option, p, widget); + return; + } theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth); theme.partId = WP_FRAMERIGHT; - d->drawBackground(theme); + if (!d->drawBackground(theme)) { + QWindowsStyle::drawPrimitive(pe, option, p, widget); + return; + } theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth); theme.partId = WP_FRAMEBOTTOM; - d->drawBackground(theme); + if (!d->drawBackground(theme)) { + QWindowsStyle::drawPrimitive(pe, option, p, widget); + return; + } theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth); theme.partId = WP_CAPTION; - d->drawBackground(theme); + if (!d->drawBackground(theme)) + QWindowsStyle::drawPrimitive(pe, option, p, widget); return; } break; diff --git a/src/widgets/styles/qwindowsxpstyle_p_p.h b/src/widgets/styles/qwindowsxpstyle_p_p.h index 5027588c93..3bc4a7cd66 100644 --- a/src/widgets/styles/qwindowsxpstyle_p_p.h +++ b/src/widgets/styles/qwindowsxpstyle_p_p.h @@ -398,9 +398,9 @@ public: QRegion region(XPThemeData &themeData); void setTransparency(QWidget *widget, XPThemeData &themeData); - void drawBackground(XPThemeData &themeData); - void drawBackgroundThruNativeBuffer(XPThemeData &themeData); - void drawBackgroundDirectly(XPThemeData &themeData); + bool drawBackground(XPThemeData &themeData); + bool drawBackgroundThruNativeBuffer(XPThemeData &themeData); + bool drawBackgroundDirectly(XPThemeData &themeData); bool hasAlphaChannel(const QRect &rect); bool fixAlphaChannel(const QRect &rect); diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index c0f9538c0a..034894aa24 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -37,6 +37,7 @@ #ifndef QT_NO_SYSTEMTRAYICON #include "qmenu.h" +#include "qlist.h" #include "qevent.h" #include "qpoint.h" #include "qlabel.h" @@ -708,11 +709,7 @@ void QSystemTrayIconPrivate::updateIcon_sys_qpa() void QSystemTrayIconPrivate::updateMenu_sys_qpa() { if (menu) { - if (!menu->platformMenu()) { - QPlatformMenu *platformMenu = qpa_sys->createMenu(); - if (platformMenu) - menu->setPlatformMenu(platformMenu); - } + addPlatformMenu(menu); qpa_sys->updateMenu(menu->platformMenu()); } } @@ -745,6 +742,27 @@ void QSystemTrayIconPrivate::showMessage_sys_qpa(const QString &title, static_cast<QPlatformSystemTrayIcon::MessageIcon>(icon), msecs); } +void QSystemTrayIconPrivate::addPlatformMenu(QMenu *menu) const +{ + if (menu->platformMenu()) + return; // The platform menu already exists. + + // The recursion depth is the same as menu depth, so should not + // be higher than 3 levels. + QListIterator<QAction *> it(menu->actions()); + while (it.hasNext()) { + QAction *action = it.next(); + if (action->menu()) + addPlatformMenu(action->menu()); + } + + // This menu should be processed *after* its children, otherwise + // setMenu() is not called on respective QPlatformMenuItems. + QPlatformMenu *platformMenu = qpa_sys->createMenu(); + if (platformMenu) + menu->setPlatformMenu(platformMenu); +} + QT_END_NAMESPACE #endif // QT_NO_SYSTEMTRAYICON diff --git a/src/widgets/util/qsystemtrayicon_p.h b/src/widgets/util/qsystemtrayicon_p.h index fdf91d4c43..8bf2302ab5 100644 --- a/src/widgets/util/qsystemtrayicon_p.h +++ b/src/widgets/util/qsystemtrayicon_p.h @@ -99,6 +99,7 @@ private: void updateMenu_sys_qpa(); QRect geometry_sys_qpa() const; void showMessage_sys_qpa(const QString &title, const QString &msg, QSystemTrayIcon::MessageIcon icon, int secs); + void addPlatformMenu(QMenu *menu) const; }; class QBalloonTip : public QWidget diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index a73e085633..6747bdc2a7 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -1879,7 +1879,10 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event) unknown = false; } - if (unknown && !isReadOnly()) { + // QTBUG-35734: ignore Ctrl/Ctrl+Shift; accept only AltGr (Alt+Ctrl) on German keyboards + if (unknown && !isReadOnly() + && event->modifiers() != Qt::ControlModifier + && event->modifiers() != (Qt::ControlModifier | Qt::ShiftModifier)) { QString t = event->text(); if (!t.isEmpty() && t.at(0).isPrint()) { insert(t); diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index eabaa160a0..fe147472d1 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -1341,6 +1341,12 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e) process: { + // QTBUG-35734: ignore Ctrl/Ctrl+Shift; accept only AltGr (Alt+Ctrl) on German keyboards + if (e->modifiers() == Qt::ControlModifier + || e->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) { + e->ignore(); + return; + } QString text = e->text(); if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) { if (overwriteMode |