From 1d1dcd8d6c64a35b94b351f72cc447771834df49 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 11 Mar 2019 14:27:04 +0100 Subject: Fix context loss in QOpenGLWidget upon tlw change with AA_ShareOpenGLContexts The logic introduced in 2ea90c56 has an issue: it resets (destroy the context and co.) upong TLW change even when AA_ShareOpenGLContexts is set, and that is just wrong and goes against what the docs claim. Fixes: QTBUG-74307 Change-Id: Ib519045c1d9842664cbe602d4e6425660cf638b5 Reviewed-by: Allan Sandfeld Jensen --- src/widgets/kernel/qopenglwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 89f860150f..7aef74c507 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -1448,7 +1448,8 @@ bool QOpenGLWidget::event(QEvent *e) { // Special case: did grabFramebuffer() for a hidden widget that then became visible. // Recreate all resources since the context now needs to share with the TLW's. - d->reset(); + if (!qGuiApp->testAttribute(Qt::AA_ShareOpenGLContexts)) + d->reset(); } if (!d->initialized && !size().isEmpty() && window()->windowHandle()) { d->initialize(); -- cgit v1.2.3 From 605634a88a05f175de77e1c7af59fd2a2e0cbc41 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 25 Mar 2019 14:44:14 +0100 Subject: Doc: Note Q[Plain]TextEdit keeping formatting in some cases Fixes: QTBUG-72427 Change-Id: Ifddabb175c480b64282bd8c8fdb9edab4c7ecf44 Reviewed-by: Venugopal Shivashankar --- src/widgets/widgets/qplaintextedit.cpp | 16 ++++++++++++++-- src/widgets/widgets/qtextedit.cpp | 23 +++++++++++++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 57f2dec8f7..0b5e69b6c3 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -1239,6 +1239,8 @@ void QPlainTextEditPrivate::ensureViewportLayouted() This property gets and sets the plain text editor's contents. The previous contents are removed and undo/redo history is reset when this property is set. + currentCharFormat() is also reset, unless textCursor() is already at the + beginning of the document. By default, for an editor with no contents, this property contains an empty string. */ @@ -1518,7 +1520,12 @@ void QPlainTextEdit::paste() /*! Deletes all the text in the text edit. - Note that the undo/redo history is cleared by this function. + Notes: + \list + \li The undo/redo history is also cleared. + \li currentCharFormat() is reset, unless textCursor() + is already at the beginning of the document. + \endlist \sa cut(), setPlainText() */ @@ -1651,7 +1658,12 @@ void QPlainTextEdit::timerEvent(QTimerEvent *e) \a text is interpreted as plain text. - Note that the undo/redo history is cleared by this function. + Notes: + \list + \li The undo/redo history is also cleared. + \li currentCharFormat() is reset, unless textCursor() + is already at the beginning of the document. + \endlist \sa toPlainText() */ diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index e3a45680ef..ab636660d7 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -548,7 +548,8 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect) This property gets and sets the text editor's contents as plain text. Previous contents are removed and undo/redo history is reset - when the property is set. + when the property is set. currentCharFormat() is also reset, unless + textCursor() is already at the beginning of the document. If the text edit has another content type, it will not be replaced by plain text if you call toPlainText(). The only exception to this @@ -1026,7 +1027,12 @@ void QTextEdit::paste() /*! Deletes all the text in the text edit. - Note that the undo/redo history is cleared by this function. + Notes: + \list + \li The undo/redo history is also cleared. + \li currentCharFormat() is reset, unless textCursor() + is already at the beginning of the document. + \endlist \sa cut(), setPlainText(), setHtml() */ @@ -1131,9 +1137,13 @@ void QTextEdit::timerEvent(QTimerEvent *e) Changes the text of the text edit to the string \a text. Any previous text is removed. - \a text is interpreted as plain text. - - Note that the undo/redo history is cleared by this function. + Notes: + \list + \li \a text is interpreted as plain text. + \li The undo/redo history is also cleared. + \li currentCharFormat() is reset, unless textCursor() + is already at the beginning of the document. + \endlist \sa toPlainText() */ @@ -1167,7 +1177,8 @@ QString QTextEdit::toPlainText() const setHtml() changes the text of the text edit. Any previous text is removed and the undo/redo history is cleared. The input text is - interpreted as rich text in html format. + interpreted as rich text in html format. currentCharFormat() is also + reset, unless textCursor() is already at the beginning of the document. \note It is the responsibility of the caller to make sure that the text is correctly decoded when a QString containing HTML is created -- cgit v1.2.3 From 73698cb3401b9445ba0ad6b0a6cc3e125e50a745 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 2 Apr 2019 19:36:29 +0300 Subject: Fix effects for highdpi graphical items Create a highdpi pixmap as a source for graphical effects. Fixes: QTBUG-74963 Change-Id: Ie144df3dbe61421fb28e639e640857aca6e6320f Reviewed-by: Friedemann Kleint --- src/widgets/graphicsview/qgraphicsitem.cpp | 11 +++++++---- src/widgets/graphicsview/qgraphicsitem_p.h | 2 +- src/widgets/graphicsview/qgraphicsscene.cpp | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 86f3d6a2f0..30b35ad92f 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -11334,7 +11334,7 @@ void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter) } // sourceRect must be in the given coordinate system -QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const +QRectF QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const { QRectF effectRectF; @@ -11362,7 +11362,7 @@ QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem sy *unpadded = true; } - return effectRectF.toAlignedRect(); + return effectRectF; } QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, @@ -11380,7 +11380,8 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP bool unpadded; const QRectF sourceRect = boundingRect(system); - QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded); + QRectF effectRectF = paddedEffectRect(system, mode, sourceRect, &unpadded); + QRect effectRect = effectRectF.toAlignedRect(); if (offset) *offset = effectRect.topLeft(); @@ -11396,7 +11397,9 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP if (effectRect.isEmpty()) return QPixmap(); - QPixmap pixmap(effectRect.size()); + const auto dpr = info ? info->painter->device()->devicePixelRatioF() : 1.0; + QPixmap pixmap(QRectF(effectRectF.topLeft(), effectRectF.size() * dpr).toAlignedRect().size()); + pixmap.setDevicePixelRatio(dpr); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing); diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h index d586a22544..54c25bf6e1 100644 --- a/src/widgets/graphicsview/qgraphicsitem_p.h +++ b/src/widgets/graphicsview/qgraphicsitem_p.h @@ -644,7 +644,7 @@ public: QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const override; - QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const; + QRectF paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const; QGraphicsItem *item; QGraphicsItemPaintInfo *info; diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index bba992144d..3dce958b08 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -4847,7 +4847,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * && painter->worldTransform().type() <= QTransform::TxTranslate) { QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates); - QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect); + QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect).toAlignedRect(); sourced->setCachedOffset(effectRect.topLeft()); } else { -- cgit v1.2.3 From 21dcb96ddca357a6e8ace4b1c7252ec465e77727 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 15 Oct 2018 16:39:03 +0200 Subject: QStyleSheetStyle::repolish: only run on direct children When re-parenting, some widgets change their children. For example QLabel, when set to rich text, will not update, until receiving a polish call, at which time getting a list of all children recursively and then trying to call functions on them will crash, since the children change in the middle of this operation. Fixes: QTBUG-69204 Fixes: QTBUG-74667 Change-Id: I95dd83ebeed14c017e22552ddd47658ae8a09353 Reviewed-by: Shawn Rutledge --- src/widgets/styles/qstylesheetstyle.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 73b147e622..4518d8c736 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -2905,7 +2905,10 @@ void QStyleSheetStyle::polish(QPalette &pal) void QStyleSheetStyle::repolish(QWidget *w) { - QList children = w->findChildren(QString()); + QList children; + children.reserve(w->children().size() + 1); + for (auto child: qAsConst(w->children())) + children.append(child); children.append(w); styleSheetCaches->styleSheetCache.remove(w); updateObjects(children); -- cgit v1.2.3 From ba6e0e4aac4d06782325c7032c8ea475f2d3eab0 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 13 Apr 2019 19:37:37 +0200 Subject: QHeaderView: fix assert when restoring section sizes over less columns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If columns are removed and we get notified via layoutChanged, the code tries to restore old section sizes, and went out of bounds, leading to an assert in QVector. Simply add an if() to skip restoring out-of-bounds columns. This comes from https://bugs.kde.org/show_bug.cgi?id=395181, which translates into the unittest that is part of this commit. Change-Id: Ide42176a758f87b21957c40508127d67f1d5a2d9 Reviewed-by: Christian Ehrlicher Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qheaderview.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 62abf56751..99309633a7 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2283,13 +2283,15 @@ void QHeaderViewPrivate::_q_sectionsChanged(const QList & : index.row()); // the new visualIndices are already adjusted / reset by initializeSections() const int newVisualIndex = visualIndex(newLogicalIndex); - auto &newSection = sectionItems[newVisualIndex]; - newSection = item.section; - - if (newSection.isHidden) { - // otherwise setSectionHidden will return without doing anything - newSection.isHidden = false; - q->setSectionHidden(newLogicalIndex, true); + if (newVisualIndex < sectionItems.count()) { + auto &newSection = sectionItems[newVisualIndex]; + newSection = item.section; + + if (newSection.isHidden) { + // otherwise setSectionHidden will return without doing anything + newSection.isHidden = false; + q->setSectionHidden(newLogicalIndex, true); + } } } -- cgit v1.2.3 From ed66c932b1460ce5dcb3f7f1cb4c37f726683175 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 15 Apr 2019 21:07:40 +0200 Subject: QListWidgetItem constructors: don't emit dataChanged(invalid, invalid) This is a regression introduced by 63967313f57add which blocked signals on the view, but not on the model. Change-Id: Ib2f93fe6ef842264aaba200c98ee4a19065ca220 Reviewed-by: Shawn Rutledge Reviewed-by: Konstantin Shegunov Reviewed-by: Laurent Montel Reviewed-by: Christian Ehrlicher --- src/widgets/itemviews/qlistwidget.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index a9899983c2..e46d25bef1 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -650,11 +650,13 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *listview, int |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { + QListModel *model = listModel(); { QSignalBlocker b(view); + QSignalBlocker bm(model); setData(Qt::DisplayRole, text); } - if (QListModel *model = listModel()) + if (model) model->insert(model->rowCount(), this); } @@ -683,12 +685,14 @@ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { + QListModel *model = listModel(); { QSignalBlocker b(view); + QSignalBlocker bm(model); setData(Qt::DisplayRole, text); setData(Qt::DecorationRole, icon); } - if (QListModel *model = listModel()) + if (model) model->insert(model->rowCount(), this); } -- cgit v1.2.3 From 2947435d8737f9b97a80532864ec2302f6719355 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 4 Feb 2019 18:42:35 +0300 Subject: QSystemTrayIcon/X11: Create tray icon window when system tray appears ... and destroy it otherwise. Fixes: QTBUG-61898 Fixes: QTBUG-73459 Done-with: Gatis Paeglis Change-Id: I6bd8f397f7ccdb123f6a60d4fa466f7b0d760dfc Reviewed-by: Gatis Paeglis --- src/widgets/util/qsystemtrayicon_p.h | 4 ++ src/widgets/util/qsystemtrayicon_x11.cpp | 75 ++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 22 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/util/qsystemtrayicon_p.h b/src/widgets/util/qsystemtrayicon_p.h index 5bdf020a47..e31532ea19 100644 --- a/src/widgets/util/qsystemtrayicon_p.h +++ b/src/widgets/util/qsystemtrayicon_p.h @@ -69,6 +69,7 @@ QT_BEGIN_NAMESPACE class QSystemTrayIconSys; +class QSystemTrayWatcher; class QPlatformSystemTrayIcon; class QToolButton; class QLabel; @@ -90,6 +91,8 @@ public: void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon, QSystemTrayIcon::MessageIcon msgIcon, int msecs); + void destroyIcon(); + static bool isSystemTrayAvailable_sys(); static bool supportsMessages_sys(); @@ -101,6 +104,7 @@ public: QSystemTrayIconSys *sys; QPlatformSystemTrayIcon *qpa_sys; bool visible; + QSystemTrayWatcher *trayWatcher; private: void install_sys_qpa(); diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index 86532456c7..70e5f3678e 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -92,9 +92,6 @@ protected: virtual void resizeEvent(QResizeEvent *) override; virtual void moveEvent(QMoveEvent *) override; -private slots: - void systemTrayWindowChanged(QScreen *screen); - private: QSystemTrayIcon *q; }; @@ -116,15 +113,6 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) setMouseTracking(true); } -void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *) -{ - if (!locateSystemTray()) { - QBalloonTip::hideBalloon(); - hide(); // still no luck - destroy(); - } -} - QRect QSystemTrayIconSys::globalGeometry() const { return QRect(mapToGlobal(QPoint(0, 0)), size()); @@ -199,10 +187,41 @@ void QSystemTrayIconSys::resizeEvent(QResizeEvent *event) } //////////////////////////////////////////////////////////////////////////// +class QSystemTrayWatcher: public QObject +{ + Q_OBJECT +public: + QSystemTrayWatcher(QSystemTrayIcon *trayIcon) + : QObject(trayIcon) + , mTrayIcon(trayIcon) + { + // This code uses string-based syntax because we want to connect to a signal + // which is defined in XCB plugin - QXcbNativeInterface::systemTrayWindowChanged(). + connect(qGuiApp->platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)), + this, SLOT(systemTrayWindowChanged(QScreen*))); + } + +private slots: + void systemTrayWindowChanged(QScreen *) + { + auto icon = static_cast(QObjectPrivate::get(mTrayIcon)); + icon->destroyIcon(); + if (icon->visible && locateSystemTray()) { + icon->sys = new QSystemTrayIconSys(mTrayIcon); + icon->sys->show(); + } + } + +private: + QSystemTrayIcon *mTrayIcon = nullptr; +}; +//////////////////////////////////////////////////////////////////////////// + QSystemTrayIconPrivate::QSystemTrayIconPrivate() : sys(0), qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()), - visible(false) + visible(false), + trayWatcher(nullptr) { } @@ -213,16 +232,21 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate() void QSystemTrayIconPrivate::install_sys() { + Q_Q(QSystemTrayIcon); + if (qpa_sys) { install_sys_qpa(); return; } - Q_Q(QSystemTrayIcon); - if (!sys && locateSystemTray()) { - sys = new QSystemTrayIconSys(q); - QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)), - sys, SLOT(systemTrayWindowChanged(QScreen*))); - sys->show(); + + if (!sys) { + if (!trayWatcher) + trayWatcher = new QSystemTrayWatcher(q); + + if (locateSystemTray()) { + sys = new QSystemTrayIconSys(q); + sys->show(); + } } } @@ -241,14 +265,21 @@ void QSystemTrayIconPrivate::remove_sys() remove_sys_qpa(); return; } + + destroyIcon(); +} + +void QSystemTrayIconPrivate::destroyIcon() +{ if (!sys) return; QBalloonTip::hideBalloon(); - sys->hide(); // this should do the trick, but... - delete sys; // wm may resize system tray only for DestroyEvents - sys = 0; + sys->hide(); + delete sys; + sys = nullptr; } + void QSystemTrayIconPrivate::updateIcon_sys() { if (qpa_sys) { -- cgit v1.2.3