@@ -33,7 +33,7 @@ namespace display_device {
3333 namespace vdd_utils {
3434
3535 const wchar_t *kVddPipeName = L" \\\\ .\\ pipe\\ ZakoVDDPipe" ;
36- const DWORD kPipeTimeoutMs = 5000 ;
36+ const DWORD kPipeTimeoutMs = 3000 ;
3737 const DWORD kPipeBufferSize = 4096 ;
3838 const std::chrono::milliseconds kDefaultDebounceInterval { 2000 };
3939
@@ -141,7 +141,7 @@ namespace display_device {
141141 }
142142
143143 bool
144- execute_pipe_command (const wchar_t *pipe_name, const wchar_t *command, std::string *response) {
144+ execute_pipe_command (const wchar_t *pipe_name, const wchar_t *command, std::string *response, bool *timed_out ) {
145145 auto hPipe = connect_to_pipe_with_retry (pipe_name);
146146 if (hPipe == INVALID_HANDLE_VALUE) {
147147 BOOST_LOG (error) << " 连接MTT虚拟显示管道失败,已重试多次" ;
@@ -180,10 +180,11 @@ namespace display_device {
180180 }
181181
182182 // 读取响应
183+ bool read_timed_out = false ;
183184 if (response) {
184185 char buffer[kPipeBufferSize ];
185- DWORD bytesRead;
186- if (!ReadFile (hPipe, buffer, sizeof (buffer), &bytesRead, &overlapped)) {
186+ DWORD bytesRead = 0 ;
187+ if (!ReadFile (hPipe, buffer, sizeof (buffer) - 1 , &bytesRead, &overlapped)) {
187188 if (GetLastError () != ERROR_IO_PENDING) {
188189 BOOST_LOG (warning) << " 读取响应失败,错误代码: " << GetLastError ();
189190 return false ;
@@ -194,9 +195,21 @@ namespace display_device {
194195 buffer[bytesRead] = ' \0 ' ;
195196 *response = std::string (buffer, bytesRead);
196197 }
198+ else {
199+ read_timed_out = true ;
200+ CancelIo (hPipe);
201+ }
202+ }
203+ else {
204+ // ReadFile completed synchronously
205+ buffer[bytesRead] = ' \0 ' ;
206+ *response = std::string (buffer, bytesRead);
197207 }
198208 }
199209
210+ if (timed_out) {
211+ *timed_out = read_timed_out;
212+ }
200213 return true ;
201214 }
202215
@@ -309,12 +322,14 @@ namespace display_device {
309322 }
310323
311324 // 尝试发送命令(带GUID或不带GUID)
312- bool success = execute_pipe_command (kVddPipeName , command.c_str (), &response);
325+ bool read_timed_out = false ;
326+ bool success = execute_pipe_command (kVddPipeName , command.c_str (), &response, &read_timed_out);
313327
314328 // 如果带GUID的命令失败,降级为不带GUID的命令(兼容旧版驱动)
315329 if (!success && !guid_str.empty ()) {
316330 BOOST_LOG (warning) << " 带GUID的命令失败,尝试降级为不带GUID的命令" ;
317- success = execute_pipe_command (kVddPipeName , L" CREATEMONITOR" , &response);
331+ read_timed_out = false ;
332+ success = execute_pipe_command (kVddPipeName , L" CREATEMONITOR" , &response, &read_timed_out);
318333 }
319334
320335 if (!success) {
@@ -325,7 +340,7 @@ namespace display_device {
325340#if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1
326341 system_tray::update_vdd_menu ();
327342#endif
328- BOOST_LOG (info) << " 创建虚拟显示器完成,响应: " << response;
343+ BOOST_LOG (info) << " 创建虚拟显示器完成,响应: " << response << " [return= " << (read_timed_out ? 1 : 0 ) << " ] " ;
329344 return true ;
330345 }
331346
@@ -627,7 +642,7 @@ namespace display_device {
627642 set_hdr_state (bool enable_hdr) {
628643 auto vdd_device_id = find_device_by_friendlyname (ZAKO_NAME);
629644 if (vdd_device_id.empty ()) {
630- BOOST_LOG (debug ) << " 未找到虚拟显示器设备,跳过HDR状态设置" ;
645+ BOOST_LOG (info ) << " 未找到虚拟显示器设备,跳过HDR状态设置" ;
631646 return true ;
632647 }
633648
@@ -636,13 +651,13 @@ namespace display_device {
636651
637652 auto hdr_state_it = current_hdr_states.find (vdd_device_id);
638653 if (hdr_state_it == current_hdr_states.end ()) {
639- BOOST_LOG (debug ) << " 虚拟显示器不支持HDR或状态未知" ;
654+ BOOST_LOG (info ) << " 虚拟显示器不支持HDR或状态未知" ;
640655 return true ;
641656 }
642657
643658 hdr_state_e target_state = enable_hdr ? hdr_state_e::enabled : hdr_state_e::disabled;
644659 if (hdr_state_it->second == target_state) {
645- BOOST_LOG (debug ) << " 虚拟显示器HDR状态已是目标状态" ;
660+ BOOST_LOG (info ) << " 虚拟显示器HDR状态已是目标状态" ;
646661 return true ;
647662 }
648663
@@ -662,33 +677,58 @@ namespace display_device {
662677 }
663678
664679 bool
665- apply_vdd_prep (const std::string &vdd_device_id, parsed_config_t ::vdd_prep_e vdd_prep) {
680+ apply_vdd_prep (const std::string &vdd_device_id, parsed_config_t ::vdd_prep_e vdd_prep,
681+ const device_info_map_t &pre_vdd_devices) {
666682 if (vdd_device_id.empty ()) {
667- BOOST_LOG (debug ) << " VDD设备ID为空,跳过vdd_prep处理" ;
683+ BOOST_LOG (info ) << " VDD设备ID为空,跳过vdd_prep处理" ;
668684 return true ;
669685 }
670686
671687 if (vdd_prep == parsed_config_t ::vdd_prep_e::no_operation) {
672- BOOST_LOG (debug ) << " vdd_prep设置为无操作,跳过物理显示器处理" ;
688+ BOOST_LOG (info ) << " vdd_prep设置为无操作,跳过物理显示器处理" ;
673689 return true ;
674690 }
675691
676- auto current_topology = get_current_topology ();
677- if (current_topology.empty ()) {
678- BOOST_LOG (warning) << " 无法获取当前显示器拓扑" ;
679- return false ;
680- }
681-
682- // 找出所有物理显示器(非VDD设备)
692+ // 从 pre_vdd_devices(VDD创建前保存的设备列表)中获取物理显示器,
693+ // 确保即使 VDD 创建后物理屏变 inactive 也能正确识别
683694 std::vector<std::string> physical_devices;
684- for (const auto &group : current_topology) {
685- for (const auto &id : group) {
686- if (id != vdd_device_id) {
687- physical_devices.push_back (id);
695+ std::string original_primary_id;
696+
697+ if (!pre_vdd_devices.empty ()) {
698+ // 使用 VDD 创建前保存的设备信息(可靠)
699+ for (const auto &[device_id, info] : pre_vdd_devices) {
700+ if (info.friendly_name != ZAKO_NAME) {
701+ physical_devices.push_back (device_id);
702+ if (info.device_state == device_state_e::primary) {
703+ original_primary_id = device_id;
704+ }
705+ }
706+ }
707+ BOOST_LOG (info) << " 使用pre-VDD设备列表: " << physical_devices.size () << " 个物理显示器"
708+ << (original_primary_id.empty () ? " " : " , 原主屏: " + original_primary_id);
709+ }
710+ else {
711+ // 回退:从当前设备枚举中获取(VDD创建前未保存时的兜底逻辑)
712+ BOOST_LOG (warning) << " 未提供pre-VDD设备列表,从当前设备枚举中查找物理显示器" ;
713+ const auto all_devices = enum_available_devices ();
714+ for (const auto &[device_id, info] : all_devices) {
715+ if (device_id != vdd_device_id && info.friendly_name != ZAKO_NAME) {
716+ physical_devices.push_back (device_id);
717+ if (info.device_state == device_state_e::primary) {
718+ original_primary_id = device_id;
719+ }
688720 }
689721 }
690722 }
691723
724+ // 确保原主屏在列表最前面(set_topology 中第一组拥有主屏优先权)
725+ if (!original_primary_id.empty ()) {
726+ auto it = std::find (physical_devices.begin (), physical_devices.end (), original_primary_id);
727+ if (it != physical_devices.begin () && it != physical_devices.end ()) {
728+ std::rotate (physical_devices.begin (), it, it + 1 );
729+ }
730+ }
731+
692732 if (physical_devices.empty ()) {
693733 BOOST_LOG (debug) << " 没有物理显示器需要处理" ;
694734 return true ;
0 commit comments