Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/core/qml/CopyOutput.qml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// Copyright (C) 2024-2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

import QtQuick
Expand Down Expand Up @@ -41,8 +41,6 @@ OutputItem {
return rotatedSize;
}

devicePixelRatio: output?.scale ?? devicePixelRatio

Rectangle {
id: content
anchors.fill: parent
Expand Down Expand Up @@ -99,7 +97,6 @@ OutputItem {

anchors.centerIn: parent
depends: [primaryScreenViewport]
devicePixelRatio: outputItem.devicePixelRatio
input: content
output: outputItem.output

Expand Down
3 changes: 0 additions & 3 deletions src/core/qml/PrimaryOutput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ OutputItem {
readonly property OutputViewport screenViewport: outputViewport
property bool forceSoftwareCursor: false

devicePixelRatio: output?.scale ?? devicePixelRatio

cursorDelegate: Cursor {
id: cursorItem

Expand Down Expand Up @@ -49,7 +47,6 @@ OutputItem {
id: outputViewport

output: rootOutputItem.output
devicePixelRatio: parent.devicePixelRatio
anchors.centerIn: parent

RotationAnimation {
Expand Down
38 changes: 38 additions & 0 deletions src/output/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ Output *Output::create(WOutput *output, QQmlEngine *engine, QObject *parent)
outputItem->setParentItem(contentItem);
outputItem->setOutput(output);

// Keep the item devicePixelRatio in sync with the output scale synchronously.
// The old QML binding (devicePixelRatio: output?.scale) was evaluated lazily,
// so after the scale is committed the render window's effectiveDevicePixelRatio
// (updated in C++ on scaleChanged) already reflected the new scale while the
// output item was still at the old size. That transient mismatch made the
// greeter/lock screen render at the wrong size at startup.
QObject::connect(output, &WOutput::scaleChanged, outputItem, [outputItem, output] {
outputItem->setDevicePixelRatio(output->scale());
});
outputItem->setDevicePixelRatio(output->scale());
connect(Helper::instance()->globalConfig(),
&TreelandConfig::forceSoftwareCursorChanged,
obj,
Expand All @@ -83,6 +93,20 @@ Output *Output::create(WOutput *output, QQmlEngine *engine, QObject *parent)
o->m_type = Type::Primary;
obj->setParent(o);

// Keep the OutputViewport's devicePixelRatio in sync with the output scale
// synchronously, for the same reason as the output item above. The viewport's
// implicit size is output->size() / DPR, so a stale (too-small) DPR makes the
// viewport larger than its parent OutputItem. With anchors.centerIn the viewport
// is then offset, and renderMatrix() maps content to the wrong screen position —
// the greeter/lock screen flashes from the bottom-right toward center at startup
// under fractional scales (e.g. 1.25).
if (auto *viewport = o->screenViewport()) {
QObject::connect(output, &WOutput::scaleChanged, viewport, [viewport, output] {
viewport->setDevicePixelRatio(output->scale());
});
viewport->setDevicePixelRatio(output->scale());
}

o->minimizedSurfaces->setFilter([](SurfaceWrapper *s) {
return s->isMinimized();
});
Expand Down Expand Up @@ -143,11 +167,25 @@ Output *Output::createCopy(WOutput *output, Output *proxy, QQmlEngine *engine, Q
outputItem->setParentItem(contentItem);
outputItem->setOutput(output);

// Keep the item devicePixelRatio in sync with the output scale synchronously
// (same as the PrimaryOutput path in Output::create).
QObject::connect(output, &WOutput::scaleChanged, outputItem, [outputItem, output] {
outputItem->setDevicePixelRatio(output->scale());
});
outputItem->setDevicePixelRatio(output->scale());
auto o = new Output(outputItem, parent);
o->m_type = Type::Proxy;
o->m_proxy = proxy;
obj->setParent(o);

// Same synchronous DPR sync for the copy output's viewport (see Output::create).
if (auto *viewport = o->screenViewport()) {
QObject::connect(output, &WOutput::scaleChanged, viewport, [viewport, output] {
viewport->setDevicePixelRatio(output->scale());
});
viewport->setDevicePixelRatio(output->scale());
}

o->updateOutputHardwareLayers();
connect(proxy->screenViewport(),
&WOutputViewport::hardwareLayersChanged,
Expand Down
Loading