QWebEngineView in dock widget affects paint buffer
-
Hi fellows,
i have a somewhat strange behavior when using a QWebEngineView within a QDockWidget.
Plattform is X11, Qt versions tested 5.15 and 6.4.
I have implemented a double buffering within a widget displaying a chart. I know Qt is already double buffered since Qt4, but there were no problems so far.
Now i have integrated a QWebEngineView within a QDockWidget in order to show some additional data to the chart.Behavior of the chart:
When the mouse moves over the chart, there is a cross drawn at the current mouse position. The painter used is set up with QPainter::RasterOp_SourceXorDestination.
The paint steps are as follows:- Paint the cross at the last mouse position -> this erases the last cross painted
- Set the last mouse position to the current position
- Paint the cross at the last mouse position
This was working without any problems until we use the QWebEngine.
Now the strange behavior comes into play:
- When the dock widget is docked into the application's mainwindow, there are visual artifacts remaining.
Qt5
The cross of the last paint call gets not erased. Moving the mouse is like drawing with a cross pencil.
Qt6
Like Qt5 - When the dock widget is undocked or closed
Qt5
Everythings ok.
Qt6
The cross of the last paint call gets not erased.
It seems like QWebEngine is somehow affecting the paint buffer or something like that deep in Qt, we dont't understand.
I have added a minimal compilable code example:
#include "MainWindow.hh" #include <QtWidgets/QDockWidget> #include <QtWebEngineWidgets/QWebEngineView> #include <QtGui/QMouseEvent> /** * @brief This class should provide a minimal code example to reproduce the problem with double * buffering when a QWebEngineView is docked inside one of the application's dock area. * * When a QWebEngineView is placed inside a dock widget and docked within the application's dock * area, unexpected visual artifacts are visible. It seems like the underlying buffer used by Qt * gets not correctly updated. * * Steps to reproduce: * 1. Compile and run the application * 2. Move the mouse over the upper central widget * 2.1 Visual artifacts (cross lines) occur * 3. Undock the bottom dock widget * 4. Move the mouse over the upper central widget => no artifacts * 5. Dock the dock widget back into application's dock area * 6. Repeat from step 2 */ class TestWidget : public QWidget { Q_OBJECT public: using QWidget::QWidget; protected: void paintEvent(QPaintEvent *) override { QColor fg{Qt::black}; QColor bg{Qt::white}; if (!pix) { pix = std::make_unique<QPixmap>(width(), height()); pix->fill(bg); } if (!lastMousePos.isNull()) { QPainter p{pix.get()}; p.setCompositionMode(QPainter::RasterOp_SourceXorDestination); QPen pen; pen.setColor( QColor(fg.red() ^ bg.red(), fg.green() ^ bg.green(), fg.blue() ^ bg.blue())); p.setPen(pen); p.setBrush(Qt::NoBrush); p.drawLine(lastMousePos.x(), 0, lastMousePos.x(), height()); p.drawLine(0, lastMousePos.y(), width(), lastMousePos.y()); } else { QPainter p{pix.get()}; p.eraseRect(rect()); } QPainter painter{this}; painter.drawPixmap(0, 0, *pix); } void mouseMoveEvent(QMouseEvent *event) override { repaint(); lastMousePos = event->pos(); repaint(); } void leaveEvent(QEvent *) override { lastMousePos = {}; repaint(); } void resizeEvent(QResizeEvent *event) override { pix.reset(); QWidget::resizeEvent(event); } private: QPoint lastMousePos; std::unique_ptr<QPixmap> pix; }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { auto centralWidget{new TestWidget{this}}; centralWidget->setMouseTracking(true); setCentralWidget(centralWidget); auto view{new QWebEngineView{this}}; view->setPage(new QWebEnginePage{this}); auto dock{new QDockWidget{this}}; dock->setWidget(view); addDockWidget(Qt::DockWidgetArea::BottomDockWidgetArea, dock); view->load({"https://www.qt.io"}); } MainWindow::~MainWindow() { } #include "MainWindow.moc"
MainWindow.hh
#pragma once #include <QtWidgets/QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); };
Any ideas on this one?
Thanks in advance