Offscreen: Fix implementation of QScreen::grabWindow
If id == 0, then we should grab the specified rect from the screen. To do that, find all windows intersecting with the screen geometry, and compose their backing store images into a screen-size pixmap. Otherwise, find the respective backing store and grab only that. Remove the old code respecting the desktop widget, which is no longer a thing in Qt 6. The code was also wrongly grabbing only the first containing - not intersecting - window's backing store into the screen pixmap. Enable the QScreen::grabImage test for the offscreen platform, where it now passes. Task-number: QTBUG-99962 Change-Id: I16eca7b082d65095a62c73624f86a4423e997a7a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>bb10
parent
5d1bb2ed57
commit
8359e44324
|
|
@ -42,6 +42,7 @@
|
|||
#include "qoffscreenwindow.h"
|
||||
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/private/qpixmap_raster_p.h>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
|
||||
|
|
@ -116,22 +117,25 @@ QPixmap QOffscreenScreen::grabWindow(WId id, int x, int y, int width, int height
|
|||
{
|
||||
QRect rect(x, y, width, height);
|
||||
|
||||
QOffscreenWindow *window = QOffscreenWindow::windowForWinId(id);
|
||||
if (!window || window->window()->type() == Qt::Desktop) {
|
||||
// id == 0 -> grab the screen, so all windows intersecting rect
|
||||
if (!id) {
|
||||
if (width == -1)
|
||||
rect.setWidth(m_geometry.width());
|
||||
if (height == -1)
|
||||
rect.setHeight(m_geometry.height());
|
||||
QPixmap screenImage(rect.size());
|
||||
QPainter painter(&screenImage);
|
||||
painter.translate(-x, -y);
|
||||
const QWindowList wl = QGuiApplication::topLevelWindows();
|
||||
QWindow *containing = nullptr;
|
||||
for (QWindow *w : wl) {
|
||||
if (w->type() != Qt::Desktop && w->isExposed() && w->geometry().contains(rect)) {
|
||||
containing = w;
|
||||
break;
|
||||
if (w->isExposed() && w->geometry().intersects(rect)) {
|
||||
QOffscreenBackingStore *store = QOffscreenBackingStore::backingStoreForWinId(w->winId());
|
||||
const QImage windowImage = store ? store->toImage() : QImage();
|
||||
if (!windowImage.isNull())
|
||||
painter.drawImage(w->position(), windowImage);
|
||||
}
|
||||
}
|
||||
|
||||
if (!containing)
|
||||
return QPixmap();
|
||||
|
||||
id = containing->winId();
|
||||
rect = rect.translated(-containing->geometry().topLeft());
|
||||
return screenImage;
|
||||
}
|
||||
|
||||
QOffscreenBackingStore *store = QOffscreenBackingStore::backingStoreForWinId(id);
|
||||
|
|
|
|||
|
|
@ -205,9 +205,6 @@ void tst_QScreen::orientationChange()
|
|||
|
||||
void tst_QScreen::grabWindow_data()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("offscreen"), Qt::CaseInsensitive))
|
||||
QSKIP("Offscreen: Screen grabbing not implemented.");
|
||||
|
||||
QTest::addColumn<int>("screenIndex");
|
||||
QTest::addColumn<QByteArray>("screenName");
|
||||
QTest::addColumn<bool>("grabWindow");
|
||||
|
|
|
|||
Loading…
Reference in New Issue