diff --git a/autotests/integration/scene_qpainter_test.cpp b/autotests/integration/scene_qpainter_test.cpp --- a/autotests/integration/scene_qpainter_test.cpp +++ b/autotests/integration/scene_qpainter_test.cpp @@ -49,6 +49,7 @@ void testCursorMoving(); void testWindow_data(); void testWindow(); + void testWindowScaled(); void testCompositorRestart_data(); void testCompositorRestart(); }; @@ -190,6 +191,44 @@ QCOMPARE(referenceImage, *scene->backend()->buffer()); } +void SceneQPainterTest::testWindowScaled() +{ + KWin::Cursor::setPos(10, 10); + // this test verifies that a window is rendered correctly + using namespace KWayland::Client; + QVERIFY(Test::waitForWaylandPointer()); + QScopedPointer s(Test::createSurface()); + QScopedPointer ss(Test::createShellSurface(s.data())); + QScopedPointer p(Test::waylandSeat()->createPointer()); + + auto scene = qobject_cast(KWin::Compositor::self()->scene()); + QVERIFY(scene); + QSignalSpy frameRenderedSpy(scene, &Scene::frameRendered); + QVERIFY(frameRenderedSpy.isValid()); + + // now let's set a cursor image + QScopedPointer cs(Test::createSurface()); + QVERIFY(!cs.isNull()); + Test::render(cs.data(), QSize(10, 10), Qt::red); + p->setCursor(cs.data(), QPoint(5, 5)); + + // now let's map the window + s->setScale(2); + QVERIFY(Test::renderAndWaitForShown(s.data(), QSize(400, 600), Qt::blue)); + + // which should trigger a frame + if (frameRenderedSpy.isEmpty()) { + QVERIFY(frameRenderedSpy.wait()); + } + QImage referenceImage(QSize(1280, 1024), QImage::Format_RGB32); + referenceImage.fill(Qt::black); + QPainter painter(&referenceImage); + painter.fillRect(0, 0, 200, 300, Qt::blue); + painter.fillRect(5, 5, 10, 10, Qt::red); //cursor + + QCOMPARE(referenceImage, *scene->backend()->buffer()); +} + void SceneQPainterTest::testCompositorRestart_data() { QTest::addColumn("type"); diff --git a/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.cpp b/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.cpp --- a/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.cpp +++ b/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.cpp @@ -46,7 +46,7 @@ for (int i = 0; i < screens()->count(); ++i) { Output *output = new Output; output->window = m_backend->windowForScreen(i); - output->buffer = QImage(screens()->size(i), QImage::Format_RGB32); + output->buffer = QImage(screens()->size(i) * screens()->scale(i), QImage::Format_RGB32); output->buffer.fill(Qt::black); m_outputs << output; } diff --git a/plugins/platforms/x11/windowed/x11windowed_backend.cpp b/plugins/platforms/x11/windowed/x11windowed_backend.cpp --- a/plugins/platforms/x11/windowed/x11windowed_backend.cpp +++ b/plugins/platforms/x11/windowed/x11windowed_backend.cpp @@ -127,10 +127,11 @@ XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE }; - o.size = initialWindowSize(); + o.scale = initialOutputScale(); + o.size = initialWindowSize() * o.scale; if (!m_windows.isEmpty()) { const auto &p = m_windows.last(); - o.internalPosition = QPoint(p.internalPosition.x() + p.size.width(), 0); + o.internalPosition = QPoint(p.internalPosition.x() + p.size.width() / p.scale, 0); } xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, o.window, m_screen->root, 0, 0, o.size.width(), o.size.height(), @@ -388,11 +389,11 @@ QSize s = QSize(event->width, event->height); if (s != (*it).size) { (*it).size = s; - int x = (*it).internalPosition.x() + s.width(); + int x = (*it).internalPosition.x() + (*it).size.width() / (*it).scale; it++; for (; it != m_windows.end(); ++it) { (*it).internalPosition.setX(x); - x += (*it).size.width(); + x += (*it).size.width() / (*it).scale; } emit sizeChanged(); } diff --git a/scene_qpainter.cpp b/scene_qpainter.cpp --- a/scene_qpainter.cpp +++ b/scene_qpainter.cpp @@ -253,7 +253,8 @@ if (!pixmap->subSurface().isNull()) { p += pixmap->subSurface()->position(); } - painter->drawImage(p, pixmap->image()); + + painter->drawImage(QRect(pos, pixmap->size()), pixmap->image()); const auto &children = pixmap->children(); for (auto it = children.begin(); it != children.end(); ++it) { auto pixmap = static_cast(*it);