From a3dad4d3da1bc6eaa15e811494b190d7d191a615 Mon Sep 17 00:00:00 2001
From: meizhigang <meizhigang@kylinsec.com.cn>
Date: Tue, 19 Dec 2023 21:01:29 +0800
Subject: [PATCH] fix(xsettings): Fix font enlargement on 4K screen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

 - 修复4K屏幕下字体变大问题

 Related #24084
---
 ...om.kylinsec.kiran.xsettings.gschema.xml.in |  4 ++
 include/xsettings-i.h                         |  3 +-
 plugins/xsettings/xsettings-manager.cpp       | 50 +++++++++++--------
 plugins/xsettings/xsettings-manager.h         |  2 +
 plugins/xsettings/xsettings-utils.cpp         |  5 ++
 plugins/xsettings/xsettings-utils.h           |  2 +
 plugins/xsettings/xsettings-xresource.cpp     |  1 +
 po/zh_CN.po                                   |  5 ++
 8 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/data/schemas/com.kylinsec.kiran.xsettings.gschema.xml.in b/data/schemas/com.kylinsec.kiran.xsettings.gschema.xml.in
index 18fa7ba..532f006 100644
--- a/data/schemas/com.kylinsec.kiran.xsettings.gschema.xml.in
+++ b/data/schemas/com.kylinsec.kiran.xsettings.gschema.xml.in
@@ -61,6 +61,10 @@
             <default>-1</default>
             <description>Resolution for Xft, in 1024 * dots/inch. -1 to use default value. Do not modify it manually.</description>
         </key>
+        <key name="font-dpi" type="d">
+            <default>96.00</default>
+            <description>The resolution used for converting font sizes to pixel sizes, in dots per inch.</description>
+        </key>
         <key name="gtk-cursor-theme-name" type="s">
             <default>'Kiran'</default>
             <description>Name of the cursor theme.</description>
diff --git a/include/xsettings-i.h b/include/xsettings-i.h
index a81ff90..51aacd8 100644
--- a/include/xsettings-i.h
+++ b/include/xsettings-i.h
@@ -41,6 +41,7 @@ extern "C"
 #define XSETTINGS_SCHEMA_XFT_HINT_STYLE "xft-hint-style"
 #define XSETTINGS_SCHEMA_XFT_RGBA "xft-rgba"
 #define XSETTINGS_SCHEMA_XFT_DPI "xft-dpi"
+#define XSETTINGS_SCHEMA_FONT_DPI "font-dpi"
 
 #define XSETTINGS_SCHEMA_GTK_CURSOR_THEME_NAME "gtk-cursor-theme-name"
 #define XSETTINGS_SCHEMA_GTK_CURSOR_THEME_SIZE "gtk-cursor-theme-size"
@@ -114,4 +115,4 @@ extern "C"
 
 #ifdef __cplusplus
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/plugins/xsettings/xsettings-manager.cpp b/plugins/xsettings/xsettings-manager.cpp
index c4fafdd..c6fb134 100644
--- a/plugins/xsettings/xsettings-manager.cpp
+++ b/plugins/xsettings/xsettings-manager.cpp
@@ -271,6 +271,7 @@ void XSettingsManager::settings_changed(const Glib::ustring &key, bool is_notify
     case CONNECT(XSETTINGS_SCHEMA_WINDOW_SCALING_FACTOR, _hash):
     case CONNECT(XSETTINGS_SCHEMA_WINDOW_SCALING_FACTOR_QT_SYNC, _hash):
     case CONNECT(XSETTINGS_SCHEMA_XFT_DPI, _hash):
+    case CONNECT(XSETTINGS_SCHEMA_FONT_DPI, _hash):
         break;
 
     default:
@@ -283,6 +284,7 @@ void XSettingsManager::settings_changed(const Glib::ustring &key, bool is_notify
     {
     case CONNECT(XSETTINGS_SCHEMA_WINDOW_SCALING_FACTOR, _hash):
     case CONNECT(XSETTINGS_SCHEMA_GTK_CURSOR_THEME_SIZE, _hash):
+    case CONNECT(XSETTINGS_SCHEMA_FONT_DPI, _hash):
         this->scale_settings();
         break;
     case CONNECT(XSETTINGS_SCHEMA_XFT_RGBA, _hash):
@@ -300,12 +302,22 @@ void XSettingsManager::settings_changed(const Glib::ustring &key, bool is_notify
     }
 }
 
+double XSettingsManager::get_optimize_dpi()
+{
+    double dpi = get_font_dpi();
+    if (dpi < EPS)
+    {
+        dpi = XSettingsUtils::get_dpi_from_x_server();
+    }
+    return dpi;
+}
+
 void XSettingsManager::scale_settings()
 {
     auto scale = this->get_window_scale();
-    auto dpi = XSettingsUtils::get_dpi_from_x_server();
+    auto dpi = this->get_optimize_dpi();
     int32_t unscaled_dpi = int32_t(dpi * 1024);
-    int32_t scaled_dpi = int32_t(CLAMP(dpi * scale, DPI_LOW_REASONABLE_VALUE, DPI_HIGH_REASONABLE_VALUE) * 1024);
+    int32_t scaled_dpi = int32_t(XSettingsUtils::format_scale_dpi(scale, dpi) * 1024);
     auto scaled_cursor_size = this->get_gtk_cursor_theme_size() * scale;
 
     this->registry_.update(XSETTINGS_REGISTRY_PROP_GDK_WINDOW_SCALING_FACTOR, scale);
@@ -329,32 +341,30 @@ void XSettingsManager::scale_change_workarounds(int32_t scale)
     /* 第一次初始化时缩放率是没有变化的，所以不应该重启底部面板、文件管理器和窗口管理器，
     这样会导致进入会话时出现屏幕刷新的视觉效果，而且底部面板和文件管理器崩溃的概率较大*/
 
-    if (is_init)
+    // 如果开启QT缩放同步，则将缩放值同步到QT缩放相关的环境变量
+    if (this->get_window_scaling_factor_qt_sync())
     {
-        // 如果开启QT缩放同步，则将缩放值同步到QT缩放相关的环境变量
-        if (this->get_window_scaling_factor_qt_sync())
+        std::string error;
+        if (!XSettingsUtils::update_user_env_variable("QT_AUTO_SCREEN_SCALE_FACTOR", "0", error))
         {
-            std::string error;
-            if (!XSettingsUtils::update_user_env_variable("QT_AUTO_SCREEN_SCALE_FACTOR", "0", error))
-            {
-                KLOG_WARNING_XSETTINGS("There was a problem when setting QT_AUTO_SCREEN_SCALE_FACTOR=0: %s", error.c_str());
-            }
+            KLOG_WARNING_XSETTINGS("There was a problem when setting QT_AUTO_SCREEN_SCALE_FACTOR=0: %s", error.c_str());
+        }
 
-            /* FIXME: 由于QT_SCALE_FACTOR将会放大窗口以及pt大小字体，而缩放将会更改Xft.dpi属性，该属性也会导致qt pt字体大小放大，字体将会放大过多。
+        /* FIXME: 由于QT_SCALE_FACTOR将会放大窗口以及pt大小字体，而缩放将会更改Xft.dpi属性，该属性也会导致qt pt字体大小放大，字体将会放大过多。
             目前暂时解决方案：缩放两倍时固定Qt字体DPI 96，由QT_SCALE_FACTOR环境变量对窗口以及字体进行放大.
             后续应弃用QT_SCALE_FACTOR方案
             */
-            if (!XSettingsUtils::update_user_env_variable("QT_SCALE_FACTOR", scale == 2 ? "2" : "1", error))
-            {
-                KLOG_WARNING_XSETTINGS("There was a problem when setting QT_SCALE_FACTOR=%d: %s", scale, error.c_str());
-            }
-            else if (scale == 2 && !XSettingsUtils::update_user_env_variable("QT_FONT_DPI", "96", error))
-            {
-                KLOG_WARNING_XSETTINGS("There was a problem when setting QT_FONT_DPI=96: %s", error.c_str());
-            }
+        if (!XSettingsUtils::update_user_env_variable("QT_SCALE_FACTOR", scale == 2 ? "2" : "1", error))
+        {
+            KLOG_WARNING_XSETTINGS("There was a problem when setting QT_SCALE_FACTOR=%d: %s", scale, error.c_str());
+        }
+        else if (scale == 2 && !XSettingsUtils::update_user_env_variable("QT_FONT_DPI", "96", error))
+        {
+            KLOG_WARNING_XSETTINGS("There was a problem when setting QT_FONT_DPI=96: %s", error.c_str());
         }
     }
-    else
+
+    if (!is_init)
     {
         // 理想的情况是marco/mate-panel/caja监控缩放因子的变化而自动调整自己的大小，
         // 但实际上没有实现这个功能，所以当窗口缩放因子发生变化时重置它们
diff --git a/plugins/xsettings/xsettings-manager.h b/plugins/xsettings/xsettings-manager.h
index ce69ef9..0309045 100644
--- a/plugins/xsettings/xsettings-manager.h
+++ b/plugins/xsettings/xsettings-manager.h
@@ -53,6 +53,7 @@ public:
     std::string get_xft_hint_style() { return this->xsettings_settings_->get_string(XSETTINGS_SCHEMA_XFT_HINT_STYLE); }
     std::string get_xft_rgba() { return this->xsettings_settings_->get_string(XSETTINGS_SCHEMA_XFT_RGBA); }
     int32_t get_xft_dpi() { return this->xsettings_settings_->get_int(XSETTINGS_SCHEMA_XFT_DPI); }
+    double get_font_dpi() { return this->xsettings_settings_->get_double(XSETTINGS_SCHEMA_FONT_DPI); }
     std::string get_gtk_cursor_theme_name() { return this->xsettings_settings_->get_string(XSETTINGS_SCHEMA_GTK_CURSOR_THEME_NAME); }
     int32_t get_gtk_cursor_theme_size() { return this->xsettings_settings_->get_int(XSETTINGS_SCHEMA_GTK_CURSOR_THEME_SIZE); }
     int32_t get_window_scaling_factor() { return this->xsettings_settings_->get_int(XSETTINGS_SCHEMA_WINDOW_SCALING_FACTOR); }
@@ -63,6 +64,7 @@ private:
 
     void load_from_settings();
     void settings_changed(const Glib::ustring &key, bool is_notify);
+    double get_optimize_dpi();
     void scale_settings();
     void scale_change_workarounds(int32_t scale);
     void on_screen_changed();
diff --git a/plugins/xsettings/xsettings-utils.cpp b/plugins/xsettings/xsettings-utils.cpp
index 36af5aa..9d9505d 100644
--- a/plugins/xsettings/xsettings-utils.cpp
+++ b/plugins/xsettings/xsettings-utils.cpp
@@ -142,4 +142,9 @@ double XSettingsUtils::dpi_from_pixels_and_mm(int pixels, int mm)
 
     return dpi;
 }
+
+double XSettingsUtils::format_scale_dpi(int scale, double dpi)
+{
+    return double(CLAMP(dpi * scale, DPI_LOW_REASONABLE_VALUE, DPI_HIGH_REASONABLE_VALUE));
+}
 }  // namespace  Kiran
diff --git a/plugins/xsettings/xsettings-utils.h b/plugins/xsettings/xsettings-utils.h
index 8e77e5a..a8e3f2a 100644
--- a/plugins/xsettings/xsettings-utils.h
+++ b/plugins/xsettings/xsettings-utils.h
@@ -30,6 +30,8 @@ public:
                                          const std::string &value,
                                          std::string &error);
 
+    static double format_scale_dpi(int32_t scale, double dpi);
+
 private:
     static double dpi_from_pixels_and_mm(int pixels, int mm);
 };
diff --git a/plugins/xsettings/xsettings-xresource.cpp b/plugins/xsettings/xsettings-xresource.cpp
index 284a67a..d66913a 100644
--- a/plugins/xsettings/xsettings-xresource.cpp
+++ b/plugins/xsettings/xsettings-xresource.cpp
@@ -120,6 +120,7 @@ void XSettingsXResource::on_xsettings_changed(const std::string &key)
     case CONNECT(XSETTINGS_SCHEMA_XFT_HINTING, _hash):
     case CONNECT(XSETTINGS_SCHEMA_XFT_HINT_STYLE, _hash):
     case CONNECT(XSETTINGS_SCHEMA_XFT_RGBA, _hash):
+    case CONNECT(XSETTINGS_SCHEMA_XFT_DPI, _hash):
     case CONNECT(XSETTINGS_SCHEMA_GTK_CURSOR_THEME_NAME, _hash):
     case CONNECT(XSETTINGS_SCHEMA_GTK_CURSOR_THEME_SIZE, _hash):
         this->update_properties();
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 94b1e0a..ae7a191 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -570,6 +570,11 @@ msgid ""
 "applications."
 msgstr "此设置确定MATE是否控制QT应用程序的比例因子。"
 
+#: ../data/com.kylinsec.kiran.xsettings.gschema.xml.in.h:41
+msgid ""
+"The resolution used for converting font sizes to pixel sizes, in dots per inch."
+msgstr "用于将字体大小转换为像素大小的分辨率，单位为每英寸点数。"
+
 #: ../data/com.kylinsec.Kiran.SystemDaemon.Accounts.policy.in.h:1
 msgid "Change your own user data"
 msgstr "更改本用户数据"
-- 
2.27.0

