From f2ddd02eb76c5fbfbac24204e4b96378c4b15b8c Mon Sep 17 00:00:00 2001 From: zhangkun Date: Mon, 17 Aug 2026 14:41:25 +0800 Subject: [PATCH] fix(xsettings): apply X11 scaling live MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Refresh DPI settings after screen scale factors change. 2. Republish Xft DPI even when the persisted value is unchanged. 3. Add tests for DPI persistence and XSettings publication. Log: Apply X11 scale changes without restarting XSettings. Influence: X11 applications receive scaling updates live. fix(xsettings): 实时应用 X11 缩放 1. 屏幕缩放比例变化后立即刷新 DPI 设置。 2. 持久化数值未变化时仍重新发布 Xft DPI。 3. 添加 DPI 持久化和 XSettings 发布测试。 Log: X11 缩放变化无需重启 XSettings 即可生效。 Influence: X11 应用可以实时接收缩放变化。 --- src/plugin-qt/xsettings/CMakeLists.txt | 7 +++- .../xsettings/impl/xsettingsmanager.cpp | 12 +++--- .../xsettings/modules/common/common.h | 16 +++++++- src/plugin-qt/xsettings/tests/CMakeLists.txt | 20 ++++++++++ .../xsettings/tests/tst_xftdpiupdate.cpp | 39 +++++++++++++++++++ 5 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/plugin-qt/xsettings/tests/CMakeLists.txt create mode 100644 src/plugin-qt/xsettings/tests/tst_xftdpiupdate.cpp diff --git a/src/plugin-qt/xsettings/CMakeLists.txt b/src/plugin-qt/xsettings/CMakeLists.txt index b8a1cc97..d3c90eeb 100644 --- a/src/plugin-qt/xsettings/CMakeLists.txt +++ b/src/plugin-qt/xsettings/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +# SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later set(BIN_NAME "plugin-dde-xsettings") @@ -11,6 +11,7 @@ set(CMAKE_AUTORCC ON) include(GNUInstallDirs) file(GLOB_RECURSE SRCS "*.h" "*.cpp") +list(FILTER SRCS EXCLUDE REGEX "/tests/") find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core DBus) find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED COMPONENTS Gui Core) @@ -45,3 +46,7 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/misc/org.deepin.dde.XSettings1.service RENAME org.deepin.dde.XSettings1.service ) install_user_symlink(org.deepin.dde.XSettings1.service dde-session-pre.target.wants) + +if(BUILD_TESTING) + add_subdirectory(tests) +endif() diff --git a/src/plugin-qt/xsettings/impl/xsettingsmanager.cpp b/src/plugin-qt/xsettings/impl/xsettingsmanager.cpp index 2263d581..a2a2769b 100644 --- a/src/plugin-qt/xsettings/impl/xsettingsmanager.cpp +++ b/src/plugin-qt/xsettings/impl/xsettingsmanager.cpp @@ -203,6 +203,8 @@ void XSettingsManager::setScreenScaleFactors(const ScaleFactors &factors, bool e } setScreenScaleFactorsForQt(factors); + + updateDPI(); } void XSettingsManager::setString(const QString &prop, const QString &v) @@ -391,15 +393,11 @@ void XSettingsManager::updateDPI() int tempXftDpi = m_settingDconfig->value(dcKeyXftDpi).toInt(&bOk); if (bOk) { scaledDpi = static_cast((DPI_FALLBACK * 1024) * scale); - if (tempXftDpi != scaledDpi) { + const auto update = makeXftDpiUpdate(tempXftDpi, scaledDpi); + if (update.needsPersist) { m_settingDconfig->setValue(dcKeyXftDpi, scaledDpi); - XsSetting setting; - setting.prop = "Xft/DPI"; - setting.value = scaledDpi; - setting.type = HeadTypeInteger; - - xsSettngVec.push_back(setting); } + xsSettngVec.push_back(update.setting); } bOk = false; diff --git a/src/plugin-qt/xsettings/modules/common/common.h b/src/plugin-qt/xsettings/modules/common/common.h index 3aafddc5..313f7c7e 100644 --- a/src/plugin-qt/xsettings/modules/common/common.h +++ b/src/plugin-qt/xsettings/modules/common/common.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later #ifndef COMMON_H @@ -52,4 +52,18 @@ const int8_t HeadTypeInteger = 0; const int8_t HeadTypeString = 1; const int8_t HeadTypeColor = 2; +struct XftDpiUpdate +{ + bool needsPersist; + XsSetting setting; +}; + +inline XftDpiUpdate makeXftDpiUpdate(int storedDpi, int scaledDpi) +{ + return { + storedDpi != scaledDpi, + { HeadTypeInteger, QStringLiteral("Xft/DPI"), scaledDpi }, + }; +} + #endif // COMMON_H diff --git a/src/plugin-qt/xsettings/tests/CMakeLists.txt b/src/plugin-qt/xsettings/tests/CMakeLists.txt new file mode 100644 index 00000000..138577ee --- /dev/null +++ b/src/plugin-qt/xsettings/tests/CMakeLists.txt @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +find_package(Qt6 REQUIRED COMPONENTS Test) + +add_executable(tst-xftdpiupdate + tst_xftdpiupdate.cpp +) + +target_include_directories(tst-xftdpiupdate PRIVATE + .. +) + +target_link_libraries(tst-xftdpiupdate PRIVATE + Qt6::Core + Qt6::Test +) + +add_test(NAME xsettings-xftdpiupdate COMMAND tst-xftdpiupdate) diff --git a/src/plugin-qt/xsettings/tests/tst_xftdpiupdate.cpp b/src/plugin-qt/xsettings/tests/tst_xftdpiupdate.cpp new file mode 100644 index 00000000..2e58ad5e --- /dev/null +++ b/src/plugin-qt/xsettings/tests/tst_xftdpiupdate.cpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include + +#include "modules/common/common.h" + +class XftDpiUpdateTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void persistsChangedValue(); + void republishesUnchangedValue(); +}; + +void XftDpiUpdateTest::persistsChangedValue() +{ + const auto update = makeXftDpiUpdate(96 * 1024, 192 * 1024); + + QVERIFY(update.needsPersist); + QCOMPARE(update.setting.prop, QStringLiteral("Xft/DPI")); + QCOMPARE(update.setting.type, HeadTypeInteger); + QCOMPARE(std::get(update.setting.value), 192 * 1024); +} + +void XftDpiUpdateTest::republishesUnchangedValue() +{ + const auto update = makeXftDpiUpdate(192 * 1024, 192 * 1024); + + QVERIFY(!update.needsPersist); + QCOMPARE(update.setting.prop, QStringLiteral("Xft/DPI")); + QCOMPARE(std::get(update.setting.value), 192 * 1024); +} + +QTEST_APPLESS_MAIN(XftDpiUpdateTest) + +#include "tst_xftdpiupdate.moc"