mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-07-02 03:51:33 +08:00
[fix] fix intermittent crash on incoming connection by guarding shared connection status state across threads
This commit is contained in:
@@ -211,7 +211,7 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
|||||||
props->control_window_max_width_ = title_bar_height_ * 10.0f;
|
props->control_window_max_width_ = title_bar_height_ * 10.0f;
|
||||||
props->control_window_max_height_ = title_bar_height_ * 7.0f;
|
props->control_window_max_height_ = title_bar_height_ * 7.0f;
|
||||||
|
|
||||||
props->connection_status_ = ConnectionStatus::Connecting;
|
props->connection_status_.store(ConnectionStatus::Connecting);
|
||||||
show_connection_status_window_ = true;
|
show_connection_status_window_ = true;
|
||||||
|
|
||||||
if (!props->peer_) {
|
if (!props->peer_) {
|
||||||
@@ -231,7 +231,7 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
|||||||
AddDataStream(props->peer_, props->file_feedback_label_.c_str(), true);
|
AddDataStream(props->peer_, props->file_feedback_label_.c_str(), true);
|
||||||
AddDataStream(props->peer_, props->clipboard_label_.c_str(), true);
|
AddDataStream(props->peer_, props->clipboard_label_.c_str(), true);
|
||||||
|
|
||||||
props->connection_status_ = ConnectionStatus::Connecting;
|
props->connection_status_.store(ConnectionStatus::Connecting);
|
||||||
|
|
||||||
peer_to_init = props->peer_;
|
peer_to_init = props->peer_;
|
||||||
local_id = props->local_id_;
|
local_id = props->local_id_;
|
||||||
|
|||||||
+10
-5
@@ -13,6 +13,9 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@@ -2175,11 +2178,13 @@ void Render::HandleWindowsServiceIntegration() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool has_connected_remote =
|
const bool has_connected_remote = [&] {
|
||||||
std::any_of(connection_status_.begin(), connection_status_.end(),
|
std::shared_lock lock(connection_status_mutex_);
|
||||||
[](const auto& entry) {
|
return std::any_of(connection_status_.begin(), connection_status_.end(),
|
||||||
return entry.second == ConnectionStatus::Connected;
|
[](const auto& entry) {
|
||||||
});
|
return entry.second == ConnectionStatus::Connected;
|
||||||
|
});
|
||||||
|
}();
|
||||||
if (!has_connected_remote) {
|
if (!has_connected_remote) {
|
||||||
ResetLocalWindowsServiceState(false);
|
ResetLocalWindowsServiceState(false);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+10
-1
@@ -184,7 +184,11 @@ class Render {
|
|||||||
SDL_Rect stream_render_rect_;
|
SDL_Rect stream_render_rect_;
|
||||||
SDL_Rect stream_render_rect_last_;
|
SDL_Rect stream_render_rect_last_;
|
||||||
ImVec2 control_window_pos_;
|
ImVec2 control_window_pos_;
|
||||||
ConnectionStatus connection_status_ = ConnectionStatus::Closed;
|
// Written from the minirtc/libnice callback thread (OnConnectionStatusCb)
|
||||||
|
// and the SDL main thread (remote_peer_panel connect button); read from
|
||||||
|
// the SDL main render thread (stream/control windows) and the SDL audio
|
||||||
|
// thread (SdlCaptureAudioIn). Atomic so those reads/writes are defined.
|
||||||
|
std::atomic<ConnectionStatus> connection_status_ = ConnectionStatus::Closed;
|
||||||
TraversalMode traversal_mode_ = TraversalMode::UnknownMode;
|
TraversalMode traversal_mode_ = TraversalMode::UnknownMode;
|
||||||
int fps_ = 0;
|
int fps_ = 0;
|
||||||
int frame_count_ = 0;
|
int frame_count_ = 0;
|
||||||
@@ -816,6 +820,11 @@ class Render {
|
|||||||
void WaitForThumbnailSaveTasks();
|
void WaitForThumbnailSaveTasks();
|
||||||
|
|
||||||
/* ------ server mode ------ */
|
/* ------ server mode ------ */
|
||||||
|
// connection_status_ / connection_host_names_ are read on the main
|
||||||
|
// render thread (DrawServerWindow, HandleWindowsServiceIntegration) and
|
||||||
|
// written from minirtc/libnice callback threads (OnConnectionStatusCb,
|
||||||
|
// OnReceiveDataBufferCb). Guard every access with this shared mutex.
|
||||||
|
std::shared_mutex connection_status_mutex_;
|
||||||
std::unordered_map<std::string, ConnectionStatus> connection_status_;
|
std::unordered_map<std::string, ConnectionStatus> connection_status_;
|
||||||
std::unordered_map<std::string, std::string> connection_host_names_;
|
std::unordered_map<std::string, std::string> connection_host_names_;
|
||||||
std::string selected_server_remote_id_ = "";
|
std::string selected_server_remote_id_ = "";
|
||||||
|
|||||||
+72
-35
@@ -6,6 +6,9 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
@@ -489,7 +492,7 @@ void Render::SendKeyboardHeartbeat(bool force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto props = props_it->second;
|
const auto props = props_it->second;
|
||||||
if (props->connection_status_ != ConnectionStatus::Connected ||
|
if (props->connection_status_.load() != ConnectionStatus::Connected ||
|
||||||
!props->peer_) {
|
!props->peer_) {
|
||||||
last_keyboard_heartbeat_tick_ = now;
|
last_keyboard_heartbeat_tick_ = now;
|
||||||
return;
|
return;
|
||||||
@@ -531,7 +534,7 @@ int Render::SendKeyCommand(int key_code, bool is_down, uint32_t scan_code,
|
|||||||
if (!target_id.empty()) {
|
if (!target_id.empty()) {
|
||||||
if (client_properties_.find(target_id) != client_properties_.end()) {
|
if (client_properties_.find(target_id) != client_properties_.end()) {
|
||||||
auto props = client_properties_[target_id];
|
auto props = client_properties_[target_id];
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected &&
|
if (props->connection_status_.load() == ConnectionStatus::Connected &&
|
||||||
props->peer_) {
|
props->peer_) {
|
||||||
std::string msg = remote_action.to_json();
|
std::string msg = remote_action.to_json();
|
||||||
int ret = SendReliableDataFrame(props->peer_, msg.c_str(), msg.size(),
|
int ret = SendReliableDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||||
@@ -928,10 +931,10 @@ void Render::SdlCaptureAudioIn(void* userdata, Uint8* stream, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (1) {
|
if (1) {
|
||||||
// std::shared_lock lock(render->client_properties_mutex_);
|
std::shared_lock lock(render->client_properties_mutex_);
|
||||||
for (const auto& it : render->client_properties_) {
|
for (const auto& it : render->client_properties_) {
|
||||||
auto props = it.second;
|
auto props = it.second;
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
if (props->connection_status_.load() == ConnectionStatus::Connected) {
|
||||||
if (props->peer_) {
|
if (props->peer_) {
|
||||||
SendAudioFrame(props->peer_, (const char*)stream, len,
|
SendAudioFrame(props->peer_, (const char*)stream, len,
|
||||||
render->audio_label_.c_str());
|
render->audio_label_.c_str());
|
||||||
@@ -1324,12 +1327,20 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::shared_lock lock(render->client_properties_mutex_);
|
|
||||||
if (remote_action.type == ControlType::host_infomation) {
|
if (remote_action.type == ControlType::host_infomation) {
|
||||||
if (render->client_properties_.find(remote_id) !=
|
bool is_client_mode = false;
|
||||||
render->client_properties_.end()) {
|
std::shared_ptr<SubStreamWindowProperties> props;
|
||||||
|
{
|
||||||
|
std::shared_lock lock(render->client_properties_mutex_);
|
||||||
|
auto props_it = render->client_properties_.find(remote_id);
|
||||||
|
if (props_it != render->client_properties_.end()) {
|
||||||
|
is_client_mode = true;
|
||||||
|
props = props_it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_client_mode) {
|
||||||
// client mode
|
// client mode
|
||||||
auto props = render->client_properties_.find(remote_id)->second;
|
|
||||||
if (props && props->remote_host_name_.empty()) {
|
if (props && props->remote_host_name_.empty()) {
|
||||||
props->remote_host_name_ = std::string(remote_action.i.host_name,
|
props->remote_host_name_ = std::string(remote_action.i.host_name,
|
||||||
remote_action.i.host_name_size);
|
remote_action.i.host_name_size);
|
||||||
@@ -1345,10 +1356,13 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
|||||||
FreeRemoteAction(remote_action);
|
FreeRemoteAction(remote_action);
|
||||||
} else {
|
} else {
|
||||||
// server mode
|
// server mode
|
||||||
render->connection_host_names_[remote_id] = std::string(
|
std::string host_name(remote_action.i.host_name,
|
||||||
remote_action.i.host_name, remote_action.i.host_name_size);
|
remote_action.i.host_name_size);
|
||||||
LOG_INFO("Remote hostname: [{}]",
|
{
|
||||||
render->connection_host_names_[remote_id]);
|
std::unique_lock lock(render->connection_status_mutex_);
|
||||||
|
render->connection_host_names_[remote_id] = host_name;
|
||||||
|
}
|
||||||
|
LOG_INFO("Remote hostname: [{}]", host_name);
|
||||||
FreeRemoteAction(remote_action);
|
FreeRemoteAction(remote_action);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1480,14 +1494,19 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
if (!render) return;
|
if (!render) return;
|
||||||
|
|
||||||
std::string remote_id(user_id, user_id_size);
|
std::string remote_id(user_id, user_id_size);
|
||||||
// std::shared_lock lock(render->client_properties_mutex_);
|
std::shared_ptr<SubStreamWindowProperties> props;
|
||||||
auto it = render->client_properties_.find(remote_id);
|
{
|
||||||
auto props = (it != render->client_properties_.end()) ? it->second : nullptr;
|
std::shared_lock lock(render->client_properties_mutex_);
|
||||||
|
auto it = render->client_properties_.find(remote_id);
|
||||||
|
if (it != render->client_properties_.end()) {
|
||||||
|
props = it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (props) {
|
if (props) {
|
||||||
render->is_client_mode_ = true;
|
render->is_client_mode_ = true;
|
||||||
render->show_connection_status_window_ = true;
|
render->show_connection_status_window_ = true;
|
||||||
props->connection_status_ = status;
|
props->connection_status_.store(status);
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ConnectionStatus::Connected: {
|
case ConnectionStatus::Connected: {
|
||||||
@@ -1603,7 +1622,10 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
} else {
|
} else {
|
||||||
render->is_client_mode_ = false;
|
render->is_client_mode_ = false;
|
||||||
render->show_connection_status_window_ = true;
|
render->show_connection_status_window_ = true;
|
||||||
render->connection_status_[remote_id] = status;
|
{
|
||||||
|
std::unique_lock lock(render->connection_status_mutex_);
|
||||||
|
render->connection_status_[remote_id] = status;
|
||||||
|
}
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ConnectionStatus::Connected: {
|
case ConnectionStatus::Connected: {
|
||||||
@@ -1659,11 +1681,14 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
render->start_speaker_capturer_ = true;
|
render->start_speaker_capturer_ = true;
|
||||||
render->remote_client_id_ = remote_id;
|
render->remote_client_id_ = remote_id;
|
||||||
render->start_mouse_controller_ = true;
|
render->start_mouse_controller_ = true;
|
||||||
if (std::all_of(render->connection_status_.begin(),
|
{
|
||||||
render->connection_status_.end(), [](const auto& kv) {
|
std::shared_lock lock(render->connection_status_mutex_);
|
||||||
return kv.first.find("web") != std::string::npos;
|
if (std::all_of(render->connection_status_.begin(),
|
||||||
})) {
|
render->connection_status_.end(), [](const auto& kv) {
|
||||||
render->show_cursor_ = true;
|
return kv.first.find("web") != std::string::npos;
|
||||||
|
})) {
|
||||||
|
render->show_cursor_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1672,12 +1697,18 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
case ConnectionStatus::Failed:
|
case ConnectionStatus::Failed:
|
||||||
case ConnectionStatus::Closed: {
|
case ConnectionStatus::Closed: {
|
||||||
render->ReleaseRemotePressedKeys(remote_id, "connection_closed");
|
render->ReleaseRemotePressedKeys(remote_id, "connection_closed");
|
||||||
if (std::all_of(render->connection_status_.begin(),
|
bool all_disconnected = false;
|
||||||
render->connection_status_.end(), [](const auto& kv) {
|
{
|
||||||
return kv.second == ConnectionStatus::Closed ||
|
std::shared_lock lock(render->connection_status_mutex_);
|
||||||
kv.second == ConnectionStatus::Failed ||
|
all_disconnected = std::all_of(
|
||||||
kv.second == ConnectionStatus::Disconnected;
|
render->connection_status_.begin(),
|
||||||
})) {
|
render->connection_status_.end(), [](const auto& kv) {
|
||||||
|
return kv.second == ConnectionStatus::Closed ||
|
||||||
|
kv.second == ConnectionStatus::Failed ||
|
||||||
|
kv.second == ConnectionStatus::Disconnected;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (all_disconnected) {
|
||||||
render->need_to_destroy_server_window_ = true;
|
render->need_to_destroy_server_window_ = true;
|
||||||
render->is_server_mode_ = false;
|
render->is_server_mode_ = false;
|
||||||
#if defined(__linux__) && !defined(__APPLE__)
|
#if defined(__linux__) && !defined(__APPLE__)
|
||||||
@@ -1704,18 +1735,24 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
render->audio_capture_ = false;
|
render->audio_capture_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
render->connection_status_.erase(remote_id);
|
{
|
||||||
render->connection_host_names_.erase(remote_id);
|
std::unique_lock lock(render->connection_status_mutex_);
|
||||||
|
render->connection_status_.erase(remote_id);
|
||||||
|
render->connection_host_names_.erase(remote_id);
|
||||||
|
}
|
||||||
if (render->screen_capturer_) {
|
if (render->screen_capturer_) {
|
||||||
render->screen_capturer_->ResetToInitialMonitor();
|
render->screen_capturer_->ResetToInitialMonitor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::all_of(render->connection_status_.begin(),
|
{
|
||||||
render->connection_status_.end(), [](const auto& kv) {
|
std::shared_lock lock(render->connection_status_mutex_);
|
||||||
return kv.first.find("web") == std::string::npos;
|
if (std::all_of(render->connection_status_.begin(),
|
||||||
})) {
|
render->connection_status_.end(), [](const auto& kv) {
|
||||||
render->show_cursor_ = false;
|
return kv.first.find("web") == std::string::npos;
|
||||||
|
})) {
|
||||||
|
render->show_cursor_ = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
|||||||
RemoteAction remote_action;
|
RemoteAction remote_action;
|
||||||
remote_action.type = ControlType::display_id;
|
remote_action.type = ControlType::display_id;
|
||||||
remote_action.d = i;
|
remote_action.d = i;
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
if (props->connection_status_.load() == ConnectionStatus::Connected) {
|
||||||
std::string msg = remote_action.to_json();
|
std::string msg = remote_action.to_json();
|
||||||
SendReliableDataFrame(props->peer_, msg.c_str(), msg.size(),
|
SendReliableDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||||
props->control_data_label_.c_str());
|
props->control_data_label_.c_str());
|
||||||
@@ -215,7 +215,7 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
|||||||
|
|
||||||
auto send_service_command = [&](ServiceCommandFlag flag,
|
auto send_service_command = [&](ServiceCommandFlag flag,
|
||||||
const char* log_action) {
|
const char* log_action) {
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected &&
|
if (props->connection_status_.load() == ConnectionStatus::Connected &&
|
||||||
props->peer_) {
|
props->peer_) {
|
||||||
RemoteAction remote_action;
|
RemoteAction remote_action;
|
||||||
remote_action.type = ControlType::service_command;
|
remote_action.type = ControlType::service_command;
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ bool Render::ConnectionStatusWindow(
|
|||||||
|
|
||||||
ImGui::SetWindowFontScale(0.5f);
|
ImGui::SetWindowFontScale(0.5f);
|
||||||
std::string text;
|
std::string text;
|
||||||
|
const ConnectionStatus status = props->connection_status_.load();
|
||||||
|
|
||||||
if (ConnectionStatus::Connecting == props->connection_status_) {
|
if (ConnectionStatus::Connecting == status) {
|
||||||
text = localization::p2p_connecting[localization_language_index_];
|
text = localization::p2p_connecting[localization_language_index_];
|
||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
@@ -48,7 +49,7 @@ bool Render::ConnectionStatusWindow(
|
|||||||
}
|
}
|
||||||
ret_flag = true;
|
ret_flag = true;
|
||||||
}
|
}
|
||||||
} else if (ConnectionStatus::Gathering == props->connection_status_) {
|
} else if (ConnectionStatus::Gathering == status) {
|
||||||
text = localization::p2p_gathering[localization_language_index_];
|
text = localization::p2p_gathering[localization_language_index_];
|
||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
@@ -64,7 +65,7 @@ bool Render::ConnectionStatusWindow(
|
|||||||
}
|
}
|
||||||
ret_flag = true;
|
ret_flag = true;
|
||||||
}
|
}
|
||||||
} else if (ConnectionStatus::Connected == props->connection_status_) {
|
} else if (ConnectionStatus::Connected == status) {
|
||||||
text = localization::p2p_connected[localization_language_index_];
|
text = localization::p2p_connected[localization_language_index_];
|
||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
@@ -74,7 +75,7 @@ bool Render::ConnectionStatusWindow(
|
|||||||
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||||
show_connection_status_window_ = false;
|
show_connection_status_window_ = false;
|
||||||
}
|
}
|
||||||
} else if (ConnectionStatus::Disconnected == props->connection_status_) {
|
} else if (ConnectionStatus::Disconnected == status) {
|
||||||
text = localization::p2p_disconnected[localization_language_index_];
|
text = localization::p2p_disconnected[localization_language_index_];
|
||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
@@ -84,7 +85,7 @@ bool Render::ConnectionStatusWindow(
|
|||||||
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||||
show_connection_status_window_ = false;
|
show_connection_status_window_ = false;
|
||||||
}
|
}
|
||||||
} else if (ConnectionStatus::Failed == props->connection_status_) {
|
} else if (ConnectionStatus::Failed == status) {
|
||||||
text = localization::p2p_failed[localization_language_index_];
|
text = localization::p2p_failed[localization_language_index_];
|
||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
@@ -94,7 +95,7 @@ bool Render::ConnectionStatusWindow(
|
|||||||
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||||
show_connection_status_window_ = false;
|
show_connection_status_window_ = false;
|
||||||
}
|
}
|
||||||
} else if (ConnectionStatus::Closed == props->connection_status_) {
|
} else if (ConnectionStatus::Closed == status) {
|
||||||
text = localization::p2p_closed[localization_language_index_];
|
text = localization::p2p_closed[localization_language_index_];
|
||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
@@ -104,7 +105,7 @@ bool Render::ConnectionStatusWindow(
|
|||||||
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||||
show_connection_status_window_ = false;
|
show_connection_status_window_ = false;
|
||||||
}
|
}
|
||||||
} else if (ConnectionStatus::IncorrectPassword == props->connection_status_) {
|
} else if (ConnectionStatus::IncorrectPassword == status) {
|
||||||
if (!password_validating_) {
|
if (!password_validating_) {
|
||||||
if (password_validating_time_ == 1) {
|
if (password_validating_time_ == 1) {
|
||||||
text = localization::input_password[localization_language_index_];
|
text = localization::input_password[localization_language_index_];
|
||||||
@@ -167,8 +168,7 @@ bool Render::ConnectionStatusWindow(
|
|||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
}
|
}
|
||||||
} else if (ConnectionStatus::NoSuchTransmissionId ==
|
} else if (ConnectionStatus::NoSuchTransmissionId == status) {
|
||||||
props->connection_status_) {
|
|
||||||
text = localization::no_such_id[localization_language_index_];
|
text = localization::no_such_id[localization_language_index_];
|
||||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <memory>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -149,14 +151,17 @@ int Render::RemoteClientInfoWindow() {
|
|||||||
float font_scale = localization_language_index_ == 0 ? 0.5f : 0.45f;
|
float font_scale = localization_language_index_ == 0 ? 0.5f : 0.45f;
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> remote_entries;
|
std::vector<std::pair<std::string, std::string>> remote_entries;
|
||||||
remote_entries.reserve(connection_status_.size());
|
{
|
||||||
for (const auto& kv : connection_status_) {
|
std::shared_lock lock(connection_status_mutex_);
|
||||||
const auto host_it = connection_host_names_.find(kv.first);
|
remote_entries.reserve(connection_status_.size());
|
||||||
const std::string display_name =
|
for (const auto& kv : connection_status_) {
|
||||||
(host_it != connection_host_names_.end() && !host_it->second.empty())
|
const auto host_it = connection_host_names_.find(kv.first);
|
||||||
? host_it->second
|
const std::string display_name =
|
||||||
: kv.first;
|
(host_it != connection_host_names_.end() && !host_it->second.empty())
|
||||||
remote_entries.emplace_back(kv.first, display_name);
|
? host_it->second
|
||||||
|
: kv.first;
|
||||||
|
remote_entries.emplace_back(kv.first, display_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto find_display_name_by_remote_id =
|
auto find_display_name_by_remote_id =
|
||||||
@@ -220,10 +225,14 @@ int Render::RemoteClientInfoWindow() {
|
|||||||
ImGui::SetWindowFontScale(font_scale);
|
ImGui::SetWindowFontScale(font_scale);
|
||||||
|
|
||||||
if (!selected_server_remote_id_.empty()) {
|
if (!selected_server_remote_id_.empty()) {
|
||||||
auto it = connection_status_.find(selected_server_remote_id_);
|
ConnectionStatus status = ConnectionStatus::Closed;
|
||||||
const ConnectionStatus status = (it == connection_status_.end())
|
{
|
||||||
? ConnectionStatus::Closed
|
std::shared_lock lock(connection_status_mutex_);
|
||||||
: it->second;
|
auto it = connection_status_.find(selected_server_remote_id_);
|
||||||
|
if (it != connection_status_.end()) {
|
||||||
|
status = it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Text(
|
ImGui::Text(
|
||||||
"%s",
|
"%s",
|
||||||
@@ -376,4 +385,4 @@ int Render::RemoteClientInfoWindow() {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} // namespace crossdesk
|
} // namespace crossdesk
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace crossdesk {
|
|||||||
void Render::DrawConnectionStatusText(
|
void Render::DrawConnectionStatusText(
|
||||||
std::shared_ptr<SubStreamWindowProperties>& props) {
|
std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||||
std::string text;
|
std::string text;
|
||||||
switch (props->connection_status_) {
|
switch (props->connection_status_.load()) {
|
||||||
case ConnectionStatus::Disconnected:
|
case ConnectionStatus::Disconnected:
|
||||||
text = localization::p2p_disconnected[localization_language_index_];
|
text = localization::p2p_disconnected[localization_language_index_];
|
||||||
break;
|
break;
|
||||||
@@ -34,7 +34,7 @@ void Render::DrawConnectionStatusText(
|
|||||||
void Render::DrawReceivingScreenText(
|
void Render::DrawReceivingScreenText(
|
||||||
std::shared_ptr<SubStreamWindowProperties>& props) {
|
std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||||
if (!props->connection_established_ ||
|
if (!props->connection_established_ ||
|
||||||
props->connection_status_ != ConnectionStatus::Connected) {
|
props->connection_status_.load() != ConnectionStatus::Connected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user