From eb3e27fd1977a58f04da4907ed563aad09875df3 Mon Sep 17 00:00:00 2001
From: meizhigang <meizhigang@kylinsec.com.cn>
Date: Thu, 24 Aug 2023 16:34:58 +0800
Subject: [PATCH] fix(display):Fix multi screen auto display while switch style
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

 - 适配切换模式自适应多屏显示

 Related #13176
---
 .../com.kylinsec.kiran.display.gschema.xml.in |  5 ++++
 include/display-i.h                           |  2 --
 plugins/display/display-manager.cpp           | 28 +++++++++++++++++--
 plugins/display/display-manager.h             |  2 ++
 plugins/display/display.xsd                   |  1 +
 5 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/data/schemas/com.kylinsec.kiran.display.gschema.xml.in b/data/schemas/com.kylinsec.kiran.display.gschema.xml.in
index 7c4930f..9df78d7 100644
--- a/data/schemas/com.kylinsec.kiran.display.gschema.xml.in
+++ b/data/schemas/com.kylinsec.kiran.display.gschema.xml.in
@@ -24,5 +24,10 @@
             <description>Set whether to adapt to screen changes </description>
         </key>
 
+        <key name="max-screen-record-number" type="i">
+            <default>100</default>
+            <description>Set max screen record number while save config.</description>
+        </key>
+
     </schema>
 </schemalist>
diff --git a/include/display-i.h b/include/display-i.h
index 4b0701e..e3bcb97 100644
--- a/include/display-i.h
+++ b/include/display-i.h
@@ -35,8 +35,6 @@ extern "C"
 #define DISPLAY_OBJECT_PATH "/com/kylinsec/Kiran/SessionDaemon/Display"
 #define DISPLAY_DBUS_INTERFACE_NAME "com.kylinsec.Kiran.SessionDaemon.Display"
 
-#define DISPLAY_SCHEMA_DYNAMIC_SCALING_WINDOW "dynamic-scaling-window"
-
     // 显示模式，只有在下列情况会使用显示模式进行设置：
     // 1. 程序第一次启动
     // 2. 有连接设备删除和添加时
diff --git a/plugins/display/display-manager.cpp b/plugins/display/display-manager.cpp
index 7450187..10a4b61 100644
--- a/plugins/display/display-manager.cpp
+++ b/plugins/display/display-manager.cpp
@@ -26,6 +26,8 @@ namespace Kiran
 {
 #define DISPLAY_SCHEMA_ID "com.kylinsec.kiran.display"
 #define DISPLAY_SCHEMA_STYLE "display-style"
+#define DISPLAY_SCHEMA_DYNAMIC_SCALING_WINDOW "dynamic-scaling-window"
+#define DISPLAY_SCHEMA_MAX_SCREEN_RECORD_NUMBER "max-screen-record-number"
 #define SCREEN_CHANGED_ADAPT "screen-changed-adaptation"
 
 #define DISPLAY_CONF_DIR "kylinsec/" PROJECT_NAME "/display"
@@ -34,10 +36,13 @@ namespace Kiran
 #define MONITOR_JOIN_CHAR ","
 #define XRANDR_CMD "xrandr"
 
+#define DEFAULT_MAX_SCREEN_RECORD_NUMBER 100
+
 DisplayManager::DisplayManager(XrandrManager *xrandr_manager) : xrandr_manager_(xrandr_manager),
                                                                 default_style_(DisplayStyle::DISPLAY_STYLE_EXTEND),
                                                                 window_scaling_factor_(0),
                                                                 dynamic_scaling_window_(false),
+                                                                max_screen_record_number_(DEFAULT_MAX_SCREEN_RECORD_NUMBER),
                                                                 dbus_connect_id_(0),
                                                                 object_register_id_(0)
 {
@@ -276,6 +281,7 @@ void DisplayManager::load_settings()
     this->default_style_ = DisplayStyle(this->display_settings_->get_enum(DISPLAY_SCHEMA_STYLE));
     this->dynamic_scaling_window_ = this->display_settings_->get_boolean(DISPLAY_SCHEMA_DYNAMIC_SCALING_WINDOW);
     this->window_scaling_factor_ = this->xsettings_settings_->get_int(XSETTINGS_SCHEMA_WINDOW_SCALING_FACTOR);
+    this->max_screen_record_number_ = this->display_settings_->get_int(DISPLAY_SCHEMA_MAX_SCREEN_RECORD_NUMBER);
 }
 
 void DisplayManager::load_monitors()
@@ -465,6 +471,7 @@ bool DisplayManager::apply_screen_config(const ScreenConfigInfo &screen_config,
 
 void DisplayManager::fill_screen_config(ScreenConfigInfo &screen_config)
 {
+    screen_config.timestamp((uint32_t)time(NULL));
     screen_config.primary(this->primary_);
     screen_config.window_scaling_factor(this->window_scaling_factor_);
 
@@ -523,7 +530,7 @@ bool DisplayManager::save_config(CCErrorCode &error_code)
     auto monitors_uid = this->get_monitors_uid();
     auto &c_screens = this->display_config_->screen();
     bool matched = false;
-    ScreenConfigInfo used_config("", 0);
+    ScreenConfigInfo used_config(0, "", 0);
 
     this->fill_screen_config(used_config);
     for (auto &c_screen : c_screens)
@@ -543,6 +550,23 @@ bool DisplayManager::save_config(CCErrorCode &error_code)
         this->display_config_->screen().push_back(used_config);
     }
 
+    if (c_screens.size() > this->max_screen_record_number_)
+    {
+        auto oldest_screen = c_screens.begin();
+        for (auto iter = c_screens.begin(); iter != c_screens.end(); iter++)
+        {
+            if ((*iter).timestamp() < (*oldest_screen).timestamp())
+            {
+                oldest_screen = iter;
+            }
+        }
+
+        if (oldest_screen != c_screens.end())
+        {
+            c_screens.erase(oldest_screen);
+        }
+    }
+
     RETURN_VAL_IF_FALSE(this->save_to_file(error_code), false);
 
     return true;
@@ -770,8 +794,8 @@ void DisplayManager::switch_to_auto()
     KLOG_PROFILE("");
 
     CCErrorCode error_code;
+
     RETURN_IF_TRUE(this->switch_to_custom(error_code));
-    RETURN_IF_TRUE(this->switch_to_mirrors(error_code));
     this->switch_to_extend();
 }
 
diff --git a/plugins/display/display-manager.h b/plugins/display/display-manager.h
index 3d866ff..5fbf741 100644
--- a/plugins/display/display-manager.h
+++ b/plugins/display/display-manager.h
@@ -145,6 +145,8 @@ private:
     int32_t window_scaling_factor_;
     // 开启动态缩放窗口
     bool dynamic_scaling_window_;
+    // 可存储屏幕个数最大值
+    uint32_t max_screen_record_number_;
 
     std::map<uint32_t, std::shared_ptr<DisplayMonitor>> monitors_;
 
diff --git a/plugins/display/display.xsd b/plugins/display/display.xsd
index c39f85e..521ec7f 100644
--- a/plugins/display/display.xsd
+++ b/plugins/display/display.xsd
@@ -38,6 +38,7 @@
 
     <xsd:complexType name="ScreenConfigInfo">
         <xsd:sequence>
+            <xsd:element name="timestamp" type="xsd:unsignedInt" default="0"/>
             <xsd:element name="primary" type="xsd:string" default="" />
             <xsd:element name="window_scaling_factor" type="xsd:int" default="0" />
             <xsd:element name="monitor" type="MonitorConfigInfo" maxOccurs="unbounded" />
-- 
2.27.0

