[fix] reset to initial monitor on connection close via ResetToInitialMonitor to fix black screen

This commit is contained in:
dijunkun
2026-03-02 15:42:44 +08:00
parent b13dac2093
commit 33d51b8ce5
15 changed files with 111 additions and 4 deletions
@@ -56,6 +56,7 @@ int ScreenCapturerDxgi::Init(const int fps, cb_desktop_data cb) {
}
monitor_index_ = 0;
initial_monitor_index_ = monitor_index_;
return 0;
}
@@ -128,6 +129,28 @@ int ScreenCapturerDxgi::SwitchTo(int monitor_index) {
return 0;
}
int ScreenCapturerDxgi::ResetToInitialMonitor() {
if (display_info_list_.empty()) return -1;
int target = initial_monitor_index_;
if (target < 0 || target >= (int)display_info_list_.size()) return -1;
if (monitor_index_ == target) return 0;
if (running_) {
paused_ = true;
monitor_index_ = target;
ReleaseDuplication();
if (!CreateDuplicationForMonitor(monitor_index_)) {
paused_ = false;
return -2;
}
paused_ = false;
LOG_INFO("DXGI: reset to initial monitor {}:{}", monitor_index_.load(),
display_info_list_[monitor_index_].name);
} else {
monitor_index_ = target;
}
return 0;
}
bool ScreenCapturerDxgi::InitializeDxgi() {
UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef _DEBUG
@@ -40,6 +40,7 @@ class ScreenCapturerDxgi : public ScreenCapturer {
int Resume(int monitor_index) override;
int SwitchTo(int monitor_index) override;
int ResetToInitialMonitor() override;
std::vector<DisplayInfo> GetDisplayInfoList() override {
return display_info_list_;
@@ -65,6 +66,7 @@ class ScreenCapturerDxgi : public ScreenCapturer {
std::atomic<bool> running_{false};
std::atomic<bool> paused_{false};
std::atomic<int> monitor_index_{0};
int initial_monitor_index_ = 0;
std::atomic<bool> show_cursor_{true};
std::thread thread_;
int fps_ = 60;
@@ -73,6 +73,7 @@ int ScreenCapturerGdi::Init(const int fps, cb_desktop_data cb) {
return -2;
}
monitor_index_ = 0;
initial_monitor_index_ = monitor_index_;
return 0;
}
@@ -124,6 +125,16 @@ int ScreenCapturerGdi::SwitchTo(int monitor_index) {
return 0;
}
int ScreenCapturerGdi::ResetToInitialMonitor() {
if (display_info_list_.empty()) return -1;
int target = initial_monitor_index_;
if (target < 0 || target >= (int)display_info_list_.size()) return -1;
monitor_index_ = target;
LOG_INFO("GDI: reset to initial monitor {}:{}", monitor_index_.load(),
display_info_list_[monitor_index_].name);
return 0;
}
void ScreenCapturerGdi::CaptureLoop() {
int interval_ms = fps_ > 0 ? (1000 / fps_) : 16;
HDC screen_dc = GetDC(nullptr);
@@ -36,6 +36,7 @@ class ScreenCapturerGdi : public ScreenCapturer {
int Resume(int monitor_index) override;
int SwitchTo(int monitor_index) override;
int ResetToInitialMonitor() override;
std::vector<DisplayInfo> GetDisplayInfoList() override {
return display_info_list_;
@@ -52,6 +53,7 @@ class ScreenCapturerGdi : public ScreenCapturer {
std::atomic<bool> running_{false};
std::atomic<bool> paused_{false};
std::atomic<int> monitor_index_{0};
int initial_monitor_index_ = 0;
std::atomic<bool> show_cursor_{true};
std::thread thread_;
int fps_ = 60;
@@ -147,6 +147,7 @@ int ScreenCapturerWgc::Init(const int fps, cb_desktop_data cb) {
LOG_INFO("Default on monitor {}:{}", monitor_index_,
display_info_list_[monitor_index_].name);
initial_monitor_index_ = monitor_index_;
return 0;
}
@@ -267,6 +268,26 @@ int ScreenCapturerWgc::SwitchTo(int monitor_index) {
return 0;
}
int ScreenCapturerWgc::ResetToInitialMonitor() {
if (display_info_list_.empty()) return -1;
if (initial_monitor_index_ < 0 ||
initial_monitor_index_ >= static_cast<int>(display_info_list_.size())) {
return -1;
}
if (monitor_index_ == initial_monitor_index_) {
return 0;
}
if (running_) {
Pause(monitor_index_);
}
monitor_index_ = initial_monitor_index_;
LOG_INFO("Reset to initial monitor {}:{}", monitor_index_,
display_info_list_[monitor_index_].name);
if (running_) {
Resume(monitor_index_);
}
return 0;
}
void ScreenCapturerWgc::OnFrame(const WgcSession::wgc_session_frame& frame,
int id) {
if (!running_ || !on_data_) {
@@ -337,4 +358,4 @@ void ScreenCapturerWgc::CleanUp() {
sessions_.clear();
}
}
} // namespace crossdesk
} // namespace crossdesk
@@ -34,6 +34,7 @@ class ScreenCapturerWgc : public ScreenCapturer,
std::vector<DisplayInfo> GetDisplayInfoList() { return display_info_list_; }
int SwitchTo(int monitor_index);
int ResetToInitialMonitor() override;
void OnFrame(const WgcSession::wgc_session_frame& frame, int id);
@@ -45,6 +46,7 @@ class ScreenCapturerWgc : public ScreenCapturer,
MONITORINFOEX monitor_info_;
std::vector<DisplayInfo> display_info_list_;
int monitor_index_ = 0;
int initial_monitor_index_ = 0;
private:
class WgcSessionInfo {
@@ -72,4 +74,4 @@ class ScreenCapturerWgc : public ScreenCapturer,
std::mutex frame_mutex_;
};
} // namespace crossdesk
#endif
#endif
@@ -148,6 +148,11 @@ int ScreenCapturerWin::SwitchTo(int monitor_index) {
return impl_->SwitchTo(monitor_index);
}
int ScreenCapturerWin::ResetToInitialMonitor() {
if (!impl_) return -1;
return impl_->ResetToInitialMonitor();
}
std::vector<DisplayInfo> ScreenCapturerWin::GetDisplayInfoList() {
if (!impl_) return {};
return impl_->GetDisplayInfoList();
@@ -195,4 +200,4 @@ void ScreenCapturerWin::RebuildAliasesFromImpl() {
}
}
} // namespace crossdesk
} // namespace crossdesk
@@ -32,6 +32,7 @@ class ScreenCapturerWin : public ScreenCapturer {
int Resume(int monitor_index) override;
int SwitchTo(int monitor_index) override;
int ResetToInitialMonitor() override;
std::vector<DisplayInfo> GetDisplayInfoList() override;
@@ -51,4 +52,4 @@ class ScreenCapturerWin : public ScreenCapturer {
void RebuildAliasesFromImpl();
};
} // namespace crossdesk
#endif
#endif