mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-12-17 04:26:47 +08:00
Compare commits
12 Commits
fix/macos-
...
v1.1.11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
feb9f2f460 | ||
|
|
9c1753c78c | ||
|
|
7370ff5b30 | ||
|
|
f6eda34dbd | ||
|
|
5d9a0a3ea5 | ||
|
|
3d8249bffa | ||
|
|
82f32cbe8f | ||
|
|
56da2f99f3 | ||
|
|
e6c72fe558 | ||
|
|
a964c6bbf5 | ||
|
|
239da373d0 | ||
|
|
217cfb091d |
35
.github/ISSUE_TEMPLATE/问题反馈.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/问题反馈.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: 问题反馈
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: kunkundi
|
||||
|
||||
---
|
||||
|
||||
**描述问题**
|
||||
清晰简洁地描述遇到的错误。
|
||||
|
||||
**复现步骤**
|
||||
复现该问题的步骤:
|
||||
1. 前往 '...'
|
||||
2. 点击 '....'
|
||||
3. 出现错误
|
||||
|
||||
**预期行为**
|
||||
清晰简洁地描述你期望发生的行为。
|
||||
|
||||
**截图**
|
||||
如果适用,请添加截图以帮助说明问题。
|
||||
|
||||
**桌面端信息(请填写以下内容):**
|
||||
- 操作系统: [例如 Windows 11]
|
||||
- 版本: [例如 v1.1.10]
|
||||
|
||||
**移动端信息(请填写以下内容):**
|
||||
- 设备: [例如 iPhone 17]
|
||||
- 操作系统: [例如 iOS 26.1]
|
||||
- 浏览器: [例如 系统浏览器、Safari]
|
||||
|
||||
**补充信息**
|
||||
在此添加与问题相关的其他上下文内容。
|
||||
@@ -1,5 +1,6 @@
|
||||
# CrossDesk
|
||||
|
||||
<a href="https://hellogithub.com/repository/kunkundi/crossdesk" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=55d41367570345f1838e02fd12be7961&claim_uid=cb0OpZRrBuGVAfL&theme=small" alt="Featured|HelloGitHub" /></a>
|
||||
[]()
|
||||
[](https://www.gnu.org/licenses/lgpl-3.0)
|
||||
[](https://github.com/kunkundi/crossdesk/commits/web-client)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# CrossDesk
|
||||
|
||||
<a href="https://hellogithub.com/repository/kunkundi/crossdesk" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=55d41367570345f1838e02fd12be7961&claim_uid=cb0OpZRrBuGVAfL&theme=small" alt="Featured|HelloGitHub" /></a>
|
||||
[]()
|
||||
[](https://www.gnu.org/licenses/lgpl-3.0)
|
||||
[](https://github.com/kunkundi/crossdesk/commits/web-client)
|
||||
|
||||
@@ -90,14 +90,51 @@ mkdir -p build_pkg_scripts
|
||||
|
||||
cat > build_pkg_scripts/postinstall <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
IDENTIFIER="cn.crossdesk.app"
|
||||
|
||||
# 获取当前登录用户
|
||||
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
||||
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
||||
|
||||
# 复制证书文件
|
||||
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
||||
|
||||
mkdir -p "$DEST"
|
||||
cp -R "/Library/Application Support/CrossDesk/certs/"* "$DEST/"
|
||||
|
||||
# 清除应用的权限授权,以便重新授权
|
||||
# 使用 tccutil 重置录屏权限和辅助功能权限
|
||||
if command -v tccutil >/dev/null 2>&1; then
|
||||
# 重置录屏权限
|
||||
tccutil reset ScreenCapture "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置辅助功能权限
|
||||
tccutil reset Accessibility "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置摄像头权限(如果需要)
|
||||
tccutil reset Camera "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置麦克风权限(如果需要)
|
||||
tccutil reset Microphone "$IDENTIFIER" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 为所有用户清除权限(可选,如果需要)
|
||||
# 遍历所有用户目录并清除权限
|
||||
for USER_DIR in /Users/*; do
|
||||
if [ -d "$USER_DIR" ] && [ "$USER_DIR" != "/Users/Shared" ]; then
|
||||
USER_NAME=$(basename "$USER_DIR")
|
||||
# 跳过系统用户
|
||||
if [ "$USER_NAME" != "Shared" ] && [ -d "$USER_DIR/Library" ]; then
|
||||
# 删除 TCC 数据库中的相关条目(需要管理员权限)
|
||||
TCC_DB="$USER_DIR/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
if [ -f "$TCC_DB" ]; then
|
||||
# 使用 sqlite3 删除相关权限记录(如果可用)
|
||||
if command -v sqlite3 >/dev/null 2>&1; then
|
||||
sqlite3 "$TCC_DB" "DELETE FROM access WHERE client='$IDENTIFIER' AND service IN ('kTCCServiceScreenCapture', 'kTCCServiceAccessibility');" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
|
||||
@@ -90,14 +90,51 @@ mkdir -p build_pkg_scripts
|
||||
|
||||
cat > build_pkg_scripts/postinstall <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
IDENTIFIER="cn.crossdesk.app"
|
||||
|
||||
# 获取当前登录用户
|
||||
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
||||
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
||||
|
||||
# 复制证书文件
|
||||
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
||||
|
||||
mkdir -p "$DEST"
|
||||
cp -R "/Library/Application Support/CrossDesk/certs/"* "$DEST/"
|
||||
|
||||
# 清除应用的权限授权,以便重新授权
|
||||
# 使用 tccutil 重置录屏权限和辅助功能权限
|
||||
if command -v tccutil >/dev/null 2>&1; then
|
||||
# 重置录屏权限
|
||||
tccutil reset ScreenCapture "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置辅助功能权限
|
||||
tccutil reset Accessibility "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置摄像头权限(如果需要)
|
||||
tccutil reset Camera "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置麦克风权限(如果需要)
|
||||
tccutil reset Microphone "$IDENTIFIER" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 为所有用户清除权限(可选,如果需要)
|
||||
# 遍历所有用户目录并清除权限
|
||||
for USER_DIR in /Users/*; do
|
||||
if [ -d "$USER_DIR" ] && [ "$USER_DIR" != "/Users/Shared" ]; then
|
||||
USER_NAME=$(basename "$USER_DIR")
|
||||
# 跳过系统用户
|
||||
if [ "$USER_NAME" != "Shared" ] && [ -d "$USER_DIR/Library" ]; then
|
||||
# 删除 TCC 数据库中的相关条目(需要管理员权限)
|
||||
TCC_DB="$USER_DIR/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
if [ -f "$TCC_DB" ]; then
|
||||
# 使用 sqlite3 删除相关权限记录(如果可用)
|
||||
if command -v sqlite3 >/dev/null 2>&1; then
|
||||
sqlite3 "$TCC_DB" "DELETE FROM access WHERE client='$IDENTIFIER' AND service IN ('kTCCServiceScreenCapture', 'kTCCServiceAccessibility');" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
|
||||
@@ -79,34 +79,59 @@ int Render::RemoteWindow() {
|
||||
enter_pressed) {
|
||||
connect_button_pressed_ = true;
|
||||
bool found = false;
|
||||
std::string target_remote_id;
|
||||
std::string target_password;
|
||||
bool should_connect = false;
|
||||
bool already_connected = false;
|
||||
|
||||
for (auto& [id, props] : recent_connections_) {
|
||||
if (id.find(remote_id) != std::string::npos) {
|
||||
found = true;
|
||||
if (client_properties_.find(remote_id) !=
|
||||
client_properties_.end()) {
|
||||
if (!client_properties_[remote_id]->connection_established_) {
|
||||
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||
target_remote_id = props.remote_id;
|
||||
target_password = props.password;
|
||||
{
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
if (client_properties_.find(remote_id) !=
|
||||
client_properties_.end()) {
|
||||
if (!client_properties_[remote_id]->connection_established_) {
|
||||
should_connect = true;
|
||||
} else {
|
||||
already_connected = true;
|
||||
}
|
||||
} else {
|
||||
// todo: show warning message
|
||||
LOG_INFO("Already connected to [{}]", remote_id);
|
||||
should_connect = true;
|
||||
}
|
||||
} else {
|
||||
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||
}
|
||||
|
||||
if (should_connect) {
|
||||
ConnectTo(target_remote_id, target_password.c_str(), false);
|
||||
} else if (already_connected) {
|
||||
LOG_INFO("Already connected to [{}]", remote_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ConnectTo(remote_id, "", false);
|
||||
}
|
||||
}
|
||||
|
||||
// check every 1 second for rejoin
|
||||
if (need_to_rejoin_) {
|
||||
need_to_rejoin_ = false;
|
||||
for (const auto& [_, props] : client_properties_) {
|
||||
if (props->rejoin_) {
|
||||
ConnectTo(props->remote_id_, props->remote_password_,
|
||||
props->remember_password_);
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now - last_rejoin_check_time_)
|
||||
.count();
|
||||
|
||||
if (elapsed >= 1000) {
|
||||
last_rejoin_check_time_ = now;
|
||||
need_to_rejoin_ = false;
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (const auto& [_, props] : client_properties_) {
|
||||
if (props->rejoin_) {
|
||||
ConnectTo(props->remote_id_, props->remote_password_,
|
||||
props->remember_password_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,33 +161,54 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
||||
LOG_INFO("Connect to [{}]", remote_id);
|
||||
focused_remote_id_ = remote_id;
|
||||
|
||||
if (client_properties_.find(remote_id) == client_properties_.end()) {
|
||||
client_properties_[remote_id] =
|
||||
std::make_shared<SubStreamWindowProperties>();
|
||||
auto props = client_properties_[remote_id];
|
||||
props->local_id_ = "C-" + std::string(client_id_);
|
||||
props->remote_id_ = remote_id;
|
||||
memcpy(&props->params_, ¶ms_, sizeof(Params));
|
||||
props->params_.user_id = props->local_id_.c_str();
|
||||
props->peer_ = CreatePeer(&props->params_);
|
||||
// std::shared_lock shared_lock(client_properties_mutex_);
|
||||
bool exists =
|
||||
(client_properties_.find(remote_id) != client_properties_.end());
|
||||
// shared_lock.unlock();
|
||||
|
||||
for (auto& display_info : display_info_list_) {
|
||||
AddVideoStream(peer_, display_info.name.c_str());
|
||||
}
|
||||
AddAudioStream(props->peer_, props->audio_label_.c_str());
|
||||
AddDataStream(props->peer_, props->data_label_.c_str());
|
||||
if (!exists) {
|
||||
PeerPtr* peer_to_init = nullptr;
|
||||
std::string local_id;
|
||||
|
||||
if (props->peer_) {
|
||||
LOG_INFO("[{}] Create peer instance successful", props->local_id_);
|
||||
Init(props->peer_);
|
||||
LOG_INFO("[{}] Peer init finish", props->local_id_);
|
||||
} else {
|
||||
LOG_INFO("Create peer [{}] instance failed", props->local_id_);
|
||||
{
|
||||
// std::unique_lock unique_lock(client_properties_mutex_);
|
||||
if (client_properties_.find(remote_id) == client_properties_.end()) {
|
||||
client_properties_[remote_id] =
|
||||
std::make_shared<SubStreamWindowProperties>();
|
||||
auto props = client_properties_[remote_id];
|
||||
props->local_id_ = "C-" + std::string(client_id_);
|
||||
props->remote_id_ = remote_id;
|
||||
memcpy(&props->params_, ¶ms_, sizeof(Params));
|
||||
props->params_.user_id = props->local_id_.c_str();
|
||||
props->peer_ = CreatePeer(&props->params_);
|
||||
|
||||
if (!props->peer_) {
|
||||
LOG_INFO("Create peer [{}] instance failed", props->local_id_);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (auto& display_info : display_info_list_) {
|
||||
AddVideoStream(props->peer_, display_info.name.c_str());
|
||||
}
|
||||
AddAudioStream(props->peer_, props->audio_label_.c_str());
|
||||
AddDataStream(props->peer_, props->data_label_.c_str());
|
||||
|
||||
props->connection_status_ = ConnectionStatus::Connecting;
|
||||
|
||||
peer_to_init = props->peer_;
|
||||
local_id = props->local_id_;
|
||||
}
|
||||
}
|
||||
|
||||
props->connection_status_ = ConnectionStatus::Connecting;
|
||||
if (peer_to_init) {
|
||||
LOG_INFO("[{}] Create peer instance successful", local_id);
|
||||
Init(peer_to_init);
|
||||
LOG_INFO("[{}] Peer init finish", local_id);
|
||||
}
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
// std::shared_lock read_lock(client_properties_mutex_);
|
||||
auto props = client_properties_[remote_id];
|
||||
if (!props->connection_established_) {
|
||||
props->remember_password_ = remember_password;
|
||||
@@ -174,14 +220,17 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
||||
}
|
||||
|
||||
std::string remote_id_with_pwd = remote_id + "@" + password;
|
||||
ret = JoinConnection(props->peer_, remote_id_with_pwd.c_str());
|
||||
if (0 == ret) {
|
||||
props->rejoin_ = false;
|
||||
} else {
|
||||
props->rejoin_ = true;
|
||||
need_to_rejoin_ = true;
|
||||
if (props->peer_) {
|
||||
ret = JoinConnection(props->peer_, remote_id_with_pwd.c_str());
|
||||
if (0 == ret) {
|
||||
props->rejoin_ = false;
|
||||
} else {
|
||||
props->rejoin_ = true;
|
||||
need_to_rejoin_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// read_lock.unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window,
|
||||
return SDL_HITTEST_NORMAL;
|
||||
}
|
||||
|
||||
Render::Render() {}
|
||||
Render::Render() : last_rejoin_check_time_(std::chrono::steady_clock::now()) {}
|
||||
|
||||
Render::~Render() {}
|
||||
|
||||
@@ -947,6 +947,7 @@ int Render::DrawStreamWindow() {
|
||||
ImGui::Render();
|
||||
SDL_RenderClear(stream_renderer_);
|
||||
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
if (props->tab_selected_) {
|
||||
@@ -1011,6 +1012,8 @@ int Render::Run() {
|
||||
}
|
||||
|
||||
InitializeLogger();
|
||||
LOG_INFO("CrossDesk version: {}", CROSSDESK_VERSION);
|
||||
|
||||
InitializeSettings();
|
||||
InitializeSDL();
|
||||
InitializeModules();
|
||||
@@ -1281,12 +1284,18 @@ void Render::CleanupPeers() {
|
||||
DestroyPeer(&peer_);
|
||||
}
|
||||
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
CleanupPeer(props);
|
||||
{
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
CleanupPeer(props);
|
||||
}
|
||||
}
|
||||
|
||||
client_properties_.clear();
|
||||
{
|
||||
// std::unique_lock lock(client_properties_mutex_);
|
||||
client_properties_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Render::CleanSubStreamWindowProperties(
|
||||
@@ -1303,6 +1312,7 @@ void Render::CleanSubStreamWindowProperties(
|
||||
}
|
||||
|
||||
void Render::UpdateRenderRect() {
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& [_, props] : client_properties_) {
|
||||
if (!props->reset_control_bar_pos_) {
|
||||
props->mouse_diff_control_bar_pos_x_ = 0;
|
||||
@@ -1377,34 +1387,41 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
|
||||
DestroyStreamWindow();
|
||||
DestroyStreamWindowContext();
|
||||
|
||||
for (auto& [host_name, props] : client_properties_) {
|
||||
thumbnail_->SaveToThumbnail(
|
||||
(char*)props->dst_buffer_, props->video_width_,
|
||||
props->video_height_, host_name, props->remote_host_name_,
|
||||
props->remember_password_ ? props->remote_password_ : "");
|
||||
{
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& [host_name, props] : client_properties_) {
|
||||
thumbnail_->SaveToThumbnail(
|
||||
(char*)props->dst_buffer_, props->video_width_,
|
||||
props->video_height_, host_name, props->remote_host_name_,
|
||||
props->remember_password_ ? props->remote_password_ : "");
|
||||
|
||||
if (props->peer_) {
|
||||
std::string client_id = (host_name == client_id_)
|
||||
? "C-" + std::string(client_id_)
|
||||
: client_id_;
|
||||
LOG_INFO("[{}] Leave connection [{}]", client_id, host_name);
|
||||
LeaveConnection(props->peer_, host_name.c_str());
|
||||
LOG_INFO("Destroy peer [{}]", client_id);
|
||||
DestroyPeer(&props->peer_);
|
||||
if (props->peer_) {
|
||||
std::string client_id = (host_name == client_id_)
|
||||
? "C-" + std::string(client_id_)
|
||||
: client_id_;
|
||||
LOG_INFO("[{}] Leave connection [{}]", client_id, host_name);
|
||||
LeaveConnection(props->peer_, host_name.c_str());
|
||||
LOG_INFO("Destroy peer [{}]", client_id);
|
||||
DestroyPeer(&props->peer_);
|
||||
}
|
||||
|
||||
props->streaming_ = false;
|
||||
props->remember_password_ = false;
|
||||
props->connection_established_ = false;
|
||||
props->audio_capture_button_pressed_ = false;
|
||||
|
||||
memset(&props->net_traffic_stats_, 0,
|
||||
sizeof(props->net_traffic_stats_));
|
||||
SDL_SetWindowFullscreen(main_window_, false);
|
||||
SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT);
|
||||
memset(audio_buffer_, 0, 720);
|
||||
}
|
||||
|
||||
props->streaming_ = false;
|
||||
props->remember_password_ = false;
|
||||
props->connection_established_ = false;
|
||||
props->audio_capture_button_pressed_ = false;
|
||||
|
||||
memset(&props->net_traffic_stats_, 0,
|
||||
sizeof(props->net_traffic_stats_));
|
||||
SDL_SetWindowFullscreen(main_window_, false);
|
||||
SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT);
|
||||
memset(audio_buffer_, 0, 720);
|
||||
}
|
||||
client_properties_.clear();
|
||||
|
||||
{
|
||||
// std::unique_lock lock(client_properties_mutex_);
|
||||
client_properties_.clear();
|
||||
}
|
||||
|
||||
rejoin_ = false;
|
||||
is_client_mode_ = false;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <mutex>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "screen_capturer_factory.h"
|
||||
#include "speaker_capturer_factory.h"
|
||||
#include "thumbnail.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "win_tray.h"
|
||||
#endif
|
||||
@@ -379,6 +381,7 @@ class Render {
|
||||
int audio_len_ = 0;
|
||||
bool audio_buffer_fresh_ = false;
|
||||
bool need_to_rejoin_ = false;
|
||||
std::chrono::steady_clock::time_point last_rejoin_check_time_;
|
||||
bool just_created_ = false;
|
||||
std::string controlled_remote_id_ = "";
|
||||
std::string focused_remote_id_ = "";
|
||||
@@ -503,6 +506,7 @@ class Render {
|
||||
/* ------ sub stream window property start ------ */
|
||||
std::unordered_map<std::string, std::shared_ptr<SubStreamWindowProperties>>
|
||||
client_properties_;
|
||||
std::shared_mutex client_properties_mutex_;
|
||||
void CloseTab(decltype(client_properties_)::iterator& it);
|
||||
/* ------ stream window property end ------ */
|
||||
|
||||
|
||||
@@ -21,13 +21,16 @@ int Render::SendKeyCommand(int key_code, bool is_down) {
|
||||
remote_action.k.key_value = key_code;
|
||||
|
||||
if (!controlled_remote_id_.empty()) {
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
if (client_properties_.find(controlled_remote_id_) !=
|
||||
client_properties_.end()) {
|
||||
auto props = client_properties_[controlled_remote_id_];
|
||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||
std::string msg = remote_action.to_json();
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +45,7 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||
float ratio_x, ratio_y = 0;
|
||||
RemoteAction remote_action;
|
||||
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
if (!props->control_mouse_) {
|
||||
@@ -94,8 +98,10 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||
}
|
||||
|
||||
std::string msg = remote_action.to_json();
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
}
|
||||
} else if (SDL_EVENT_MOUSE_WHEEL == event.type &&
|
||||
last_mouse_event.button.x >= props->stream_render_rect_.x &&
|
||||
last_mouse_event.button.x <= props->stream_render_rect_.x +
|
||||
@@ -139,8 +145,10 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||
render_height;
|
||||
|
||||
std::string msg = remote_action.to_json();
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,11 +162,14 @@ void Render::SdlCaptureAudioIn(void* userdata, Uint8* stream, int len) {
|
||||
}
|
||||
|
||||
if (1) {
|
||||
for (auto it : render->client_properties_) {
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
for (const auto& it : render->client_properties_) {
|
||||
auto props = it.second;
|
||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||
SendAudioFrame(props->peer_, (const char*)stream, len,
|
||||
render->audio_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendAudioFrame(props->peer_, (const char*)stream, len,
|
||||
render->audio_label_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,6 +218,7 @@ void Render::OnReceiveVideoBufferCb(const XVideoFrame* video_frame,
|
||||
}
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) ==
|
||||
render->client_properties_.end()) {
|
||||
return;
|
||||
@@ -302,6 +314,7 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
||||
}
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) !=
|
||||
render->client_properties_.end()) {
|
||||
// local
|
||||
@@ -373,6 +386,7 @@ void Render::OnSignalStatusCb(SignalStatus status, const char* user_id,
|
||||
}
|
||||
|
||||
std::string remote_id(client_id.begin() + 2, client_id.end());
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) ==
|
||||
render->client_properties_.end()) {
|
||||
return;
|
||||
@@ -402,6 +416,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
||||
if (!render) return;
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
auto it = render->client_properties_.find(remote_id);
|
||||
auto props = (it != render->client_properties_.end()) ? it->second : nullptr;
|
||||
|
||||
@@ -428,7 +443,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
||||
case ConnectionStatus::Closed: {
|
||||
props->connection_established_ = false;
|
||||
props->mouse_control_button_pressed_ = false;
|
||||
if (props->dst_buffer_) {
|
||||
if (props->dst_buffer_ && props->stream_texture_) {
|
||||
memset(props->dst_buffer_, 0, props->dst_buffer_capacity_);
|
||||
SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_,
|
||||
props->texture_width_);
|
||||
@@ -562,6 +577,7 @@ void Render::NetStatusReport(const char* client_id, size_t client_id_size,
|
||||
}
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) ==
|
||||
render->client_properties_.end()) {
|
||||
return;
|
||||
|
||||
@@ -32,6 +32,7 @@ int Render::MainWindow() {
|
||||
StatusBar();
|
||||
|
||||
if (show_connection_status_window_) {
|
||||
// std::unique_lock lock(client_properties_mutex_);
|
||||
for (auto it = client_properties_.begin();
|
||||
it != client_properties_.end();) {
|
||||
auto& props = it->second;
|
||||
|
||||
@@ -32,12 +32,15 @@ void Render::DrawConnectionStatusText(
|
||||
}
|
||||
|
||||
void Render::CloseTab(decltype(client_properties_)::iterator& it) {
|
||||
CleanupPeer(it->second);
|
||||
it = client_properties_.erase(it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
// std::unique_lock lock(client_properties_mutex_);
|
||||
if (it != client_properties_.end()) {
|
||||
CleanupPeer(it->second);
|
||||
it = client_properties_.erase(it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,11 +82,22 @@ int Render::StreamWindow() {
|
||||
ImGuiTabBarFlags_AutoSelectNewTabs)) {
|
||||
is_tab_bar_hovered_ = ImGui::IsWindowHovered();
|
||||
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto it = client_properties_.begin();
|
||||
it != client_properties_.end();) {
|
||||
auto& props = it->second;
|
||||
if (!props->tab_opened_) {
|
||||
CloseTab(it);
|
||||
std::string remote_id_to_close = props->remote_id_;
|
||||
// lock.unlock();
|
||||
{
|
||||
// std::unique_lock unique_lock(client_properties_mutex_);
|
||||
auto close_it = client_properties_.find(remote_id_to_close);
|
||||
if (close_it != client_properties_.end()) {
|
||||
CloseTab(close_it);
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = client_properties_.begin();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -122,12 +136,23 @@ int Render::StreamWindow() {
|
||||
focused_remote_id_ = props->remote_id_;
|
||||
|
||||
if (!props->peer_) {
|
||||
it = client_properties_.erase(it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
std::string remote_id_to_erase = props->remote_id_;
|
||||
// lock.unlock();
|
||||
{
|
||||
// std::unique_lock unique_lock(client_properties_mutex_);
|
||||
auto erase_it = client_properties_.find(remote_id_to_erase);
|
||||
if (erase_it != client_properties_.end()) {
|
||||
erase_it = client_properties_.erase(erase_it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = client_properties_.begin();
|
||||
continue;
|
||||
} else {
|
||||
DrawConnectionStatusText(props);
|
||||
++it;
|
||||
@@ -147,11 +172,22 @@ int Render::StreamWindow() {
|
||||
|
||||
ImGui::End(); // End TabBar
|
||||
} else {
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto it = client_properties_.begin();
|
||||
it != client_properties_.end();) {
|
||||
auto& props = it->second;
|
||||
if (!props->tab_opened_) {
|
||||
CloseTab(it);
|
||||
std::string remote_id_to_close = props->remote_id_;
|
||||
// lock.unlock();
|
||||
{
|
||||
// std::unique_lock unique_lock(client_properties_mutex_);
|
||||
auto close_it = client_properties_.find(remote_id_to_close);
|
||||
if (close_it != client_properties_.end()) {
|
||||
CloseTab(close_it);
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = client_properties_.begin();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -181,12 +217,23 @@ int Render::StreamWindow() {
|
||||
if (!props->peer_) {
|
||||
fullscreen_button_pressed_ = false;
|
||||
SDL_SetWindowFullscreen(stream_window_, false);
|
||||
it = client_properties_.erase(it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
std::string remote_id_to_erase = props->remote_id_;
|
||||
// lock.unlock();
|
||||
{
|
||||
// std::unique_lock unique_lock(client_properties_mutex_);
|
||||
auto erase_it = client_properties_.find(remote_id_to_erase);
|
||||
if (erase_it != client_properties_.end()) {
|
||||
client_properties_.erase(erase_it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = client_properties_.begin();
|
||||
continue;
|
||||
} else {
|
||||
DrawConnectionStatusText(props);
|
||||
++it;
|
||||
|
||||
@@ -36,7 +36,7 @@ std::filesystem::path PathManager::GetLogPath() {
|
||||
#elif __APPLE__
|
||||
return GetHome() + "/Library/Logs/" + app_name_;
|
||||
#else
|
||||
return GetCachePath() / app_name_ / "logs";
|
||||
return GetCachePath() / "logs";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user