mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-12-17 20:47:01 +08:00
Compare commits
5 Commits
v1.1.6
...
v1.1.8-202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d8249bffa | ||
|
|
82f32cbe8f | ||
|
|
56da2f99f3 | ||
|
|
e6c72fe558 | ||
|
|
a964c6bbf5 |
@@ -90,14 +90,51 @@ mkdir -p build_pkg_scripts
|
|||||||
|
|
||||||
cat > build_pkg_scripts/postinstall <<'EOF'
|
cat > build_pkg_scripts/postinstall <<'EOF'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
IDENTIFIER="cn.crossdesk.app"
|
||||||
|
|
||||||
|
# 获取当前登录用户
|
||||||
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
||||||
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
||||||
|
|
||||||
|
# 复制证书文件
|
||||||
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
||||||
|
|
||||||
mkdir -p "$DEST"
|
mkdir -p "$DEST"
|
||||||
cp -R "/Library/Application Support/CrossDesk/certs/"* "$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
|
exit 0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,51 @@ mkdir -p build_pkg_scripts
|
|||||||
|
|
||||||
cat > build_pkg_scripts/postinstall <<'EOF'
|
cat > build_pkg_scripts/postinstall <<'EOF'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
IDENTIFIER="cn.crossdesk.app"
|
||||||
|
|
||||||
|
# 获取当前登录用户
|
||||||
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
||||||
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
||||||
|
|
||||||
|
# 复制证书文件
|
||||||
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
||||||
|
|
||||||
mkdir -p "$DEST"
|
mkdir -p "$DEST"
|
||||||
cp -R "/Library/Application Support/CrossDesk/certs/"* "$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
|
exit 0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ int Render::RemoteWindow() {
|
|||||||
for (auto& [id, props] : recent_connections_) {
|
for (auto& [id, props] : recent_connections_) {
|
||||||
if (id.find(remote_id) != std::string::npos) {
|
if (id.find(remote_id) != std::string::npos) {
|
||||||
found = true;
|
found = true;
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
if (client_properties_.find(remote_id) !=
|
if (client_properties_.find(remote_id) !=
|
||||||
client_properties_.end()) {
|
client_properties_.end()) {
|
||||||
if (!client_properties_[remote_id]->connection_established_) {
|
if (!client_properties_[remote_id]->connection_established_) {
|
||||||
@@ -111,6 +112,7 @@ int Render::RemoteWindow() {
|
|||||||
if (elapsed >= 1000) {
|
if (elapsed >= 1000) {
|
||||||
last_rejoin_check_time_ = now;
|
last_rejoin_check_time_ = now;
|
||||||
need_to_rejoin_ = false;
|
need_to_rejoin_ = false;
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
for (const auto& [_, props] : client_properties_) {
|
for (const auto& [_, props] : client_properties_) {
|
||||||
if (props->rejoin_) {
|
if (props->rejoin_) {
|
||||||
ConnectTo(props->remote_id_, props->remote_password_,
|
ConnectTo(props->remote_id_, props->remote_password_,
|
||||||
@@ -145,33 +147,49 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
|||||||
LOG_INFO("Connect to [{}]", remote_id);
|
LOG_INFO("Connect to [{}]", remote_id);
|
||||||
focused_remote_id_ = remote_id;
|
focused_remote_id_ = remote_id;
|
||||||
|
|
||||||
if (client_properties_.find(remote_id) == client_properties_.end()) {
|
std::shared_lock shared_lock(client_properties_mutex_);
|
||||||
client_properties_[remote_id] =
|
bool exists =
|
||||||
std::make_shared<SubStreamWindowProperties>();
|
(client_properties_.find(remote_id) != client_properties_.end());
|
||||||
auto props = client_properties_[remote_id];
|
shared_lock.unlock();
|
||||||
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_);
|
|
||||||
|
|
||||||
for (auto& display_info : display_info_list_) {
|
if (!exists) {
|
||||||
AddVideoStream(peer_, display_info.name.c_str());
|
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());
|
||||||
|
|
||||||
|
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_);
|
||||||
|
}
|
||||||
|
|
||||||
|
props->connection_status_ = ConnectionStatus::Connecting;
|
||||||
}
|
}
|
||||||
AddAudioStream(props->peer_, props->audio_label_.c_str());
|
unique_lock.unlock();
|
||||||
AddDataStream(props->peer_, props->data_label_.c_str());
|
|
||||||
|
|
||||||
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_);
|
|
||||||
}
|
|
||||||
|
|
||||||
props->connection_status_ = ConnectionStatus::Connecting;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
std::shared_lock read_lock(client_properties_mutex_);
|
||||||
auto props = client_properties_[remote_id];
|
auto props = client_properties_[remote_id];
|
||||||
if (!props->connection_established_) {
|
if (!props->connection_established_) {
|
||||||
props->remember_password_ = remember_password;
|
props->remember_password_ = remember_password;
|
||||||
@@ -183,14 +201,17 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string remote_id_with_pwd = remote_id + "@" + password;
|
std::string remote_id_with_pwd = remote_id + "@" + password;
|
||||||
ret = JoinConnection(props->peer_, remote_id_with_pwd.c_str());
|
if (props->peer_) {
|
||||||
if (0 == ret) {
|
ret = JoinConnection(props->peer_, remote_id_with_pwd.c_str());
|
||||||
props->rejoin_ = false;
|
if (0 == ret) {
|
||||||
} else {
|
props->rejoin_ = false;
|
||||||
props->rejoin_ = true;
|
} else {
|
||||||
need_to_rejoin_ = true;
|
props->rejoin_ = true;
|
||||||
|
need_to_rejoin_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
read_lock.unlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -947,6 +947,7 @@ int Render::DrawStreamWindow() {
|
|||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
SDL_RenderClear(stream_renderer_);
|
SDL_RenderClear(stream_renderer_);
|
||||||
|
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
for (auto& it : client_properties_) {
|
for (auto& it : client_properties_) {
|
||||||
auto props = it.second;
|
auto props = it.second;
|
||||||
if (props->tab_selected_) {
|
if (props->tab_selected_) {
|
||||||
@@ -966,7 +967,6 @@ int Render::DrawStreamWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Render::Run() {
|
int Render::Run() {
|
||||||
LOG_INFO("CrossDesk version: {}", CROSSDESK_VERSION);
|
|
||||||
latest_version_info_ = CheckUpdate();
|
latest_version_info_ = CheckUpdate();
|
||||||
if (!latest_version_info_.empty() &&
|
if (!latest_version_info_.empty() &&
|
||||||
latest_version_info_.contains("version") &&
|
latest_version_info_.contains("version") &&
|
||||||
@@ -1012,6 +1012,8 @@ int Render::Run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InitializeLogger();
|
InitializeLogger();
|
||||||
|
LOG_INFO("CrossDesk version: {}", CROSSDESK_VERSION);
|
||||||
|
|
||||||
InitializeSettings();
|
InitializeSettings();
|
||||||
InitializeSDL();
|
InitializeSDL();
|
||||||
InitializeModules();
|
InitializeModules();
|
||||||
@@ -1282,12 +1284,18 @@ void Render::CleanupPeers() {
|
|||||||
DestroyPeer(&peer_);
|
DestroyPeer(&peer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& it : client_properties_) {
|
{
|
||||||
auto props = it.second;
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
CleanupPeer(props);
|
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(
|
void Render::CleanSubStreamWindowProperties(
|
||||||
@@ -1304,6 +1312,7 @@ void Render::CleanSubStreamWindowProperties(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Render::UpdateRenderRect() {
|
void Render::UpdateRenderRect() {
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
for (auto& [_, props] : client_properties_) {
|
for (auto& [_, props] : client_properties_) {
|
||||||
if (!props->reset_control_bar_pos_) {
|
if (!props->reset_control_bar_pos_) {
|
||||||
props->mouse_diff_control_bar_pos_x_ = 0;
|
props->mouse_diff_control_bar_pos_x_ = 0;
|
||||||
@@ -1378,34 +1387,41 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
|
|||||||
DestroyStreamWindow();
|
DestroyStreamWindow();
|
||||||
DestroyStreamWindowContext();
|
DestroyStreamWindowContext();
|
||||||
|
|
||||||
for (auto& [host_name, props] : client_properties_) {
|
{
|
||||||
thumbnail_->SaveToThumbnail(
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
(char*)props->dst_buffer_, props->video_width_,
|
for (auto& [host_name, props] : client_properties_) {
|
||||||
props->video_height_, host_name, props->remote_host_name_,
|
thumbnail_->SaveToThumbnail(
|
||||||
props->remember_password_ ? props->remote_password_ : "");
|
(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_) {
|
if (props->peer_) {
|
||||||
std::string client_id = (host_name == client_id_)
|
std::string client_id = (host_name == client_id_)
|
||||||
? "C-" + std::string(client_id_)
|
? "C-" + std::string(client_id_)
|
||||||
: client_id_;
|
: client_id_;
|
||||||
LOG_INFO("[{}] Leave connection [{}]", client_id, host_name);
|
LOG_INFO("[{}] Leave connection [{}]", client_id, host_name);
|
||||||
LeaveConnection(props->peer_, host_name.c_str());
|
LeaveConnection(props->peer_, host_name.c_str());
|
||||||
LOG_INFO("Destroy peer [{}]", client_id);
|
LOG_INFO("Destroy peer [{}]", client_id);
|
||||||
DestroyPeer(&props->peer_);
|
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;
|
rejoin_ = false;
|
||||||
is_client_mode_ = false;
|
is_client_mode_ = false;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
#include "screen_capturer_factory.h"
|
#include "screen_capturer_factory.h"
|
||||||
#include "speaker_capturer_factory.h"
|
#include "speaker_capturer_factory.h"
|
||||||
#include "thumbnail.h"
|
#include "thumbnail.h"
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#include "win_tray.h"
|
#include "win_tray.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -504,6 +506,7 @@ class Render {
|
|||||||
/* ------ sub stream window property start ------ */
|
/* ------ sub stream window property start ------ */
|
||||||
std::unordered_map<std::string, std::shared_ptr<SubStreamWindowProperties>>
|
std::unordered_map<std::string, std::shared_ptr<SubStreamWindowProperties>>
|
||||||
client_properties_;
|
client_properties_;
|
||||||
|
std::shared_mutex client_properties_mutex_;
|
||||||
void CloseTab(decltype(client_properties_)::iterator& it);
|
void CloseTab(decltype(client_properties_)::iterator& it);
|
||||||
/* ------ stream window property end ------ */
|
/* ------ stream window property end ------ */
|
||||||
|
|
||||||
|
|||||||
@@ -21,13 +21,16 @@ int Render::SendKeyCommand(int key_code, bool is_down) {
|
|||||||
remote_action.k.key_value = key_code;
|
remote_action.k.key_value = key_code;
|
||||||
|
|
||||||
if (!controlled_remote_id_.empty()) {
|
if (!controlled_remote_id_.empty()) {
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
if (client_properties_.find(controlled_remote_id_) !=
|
if (client_properties_.find(controlled_remote_id_) !=
|
||||||
client_properties_.end()) {
|
client_properties_.end()) {
|
||||||
auto props = client_properties_[controlled_remote_id_];
|
auto props = client_properties_[controlled_remote_id_];
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||||
std::string msg = remote_action.to_json();
|
std::string msg = remote_action.to_json();
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
if (props->peer_) {
|
||||||
props->data_label_.c_str());
|
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;
|
float ratio_x, ratio_y = 0;
|
||||||
RemoteAction remote_action;
|
RemoteAction remote_action;
|
||||||
|
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
for (auto& it : client_properties_) {
|
for (auto& it : client_properties_) {
|
||||||
auto props = it.second;
|
auto props = it.second;
|
||||||
if (!props->control_mouse_) {
|
if (!props->control_mouse_) {
|
||||||
@@ -94,8 +98,10 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string msg = remote_action.to_json();
|
std::string msg = remote_action.to_json();
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
if (props->peer_) {
|
||||||
props->data_label_.c_str());
|
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||||
|
props->data_label_.c_str());
|
||||||
|
}
|
||||||
} else if (SDL_EVENT_MOUSE_WHEEL == event.type &&
|
} 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 &&
|
||||||
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;
|
render_height;
|
||||||
|
|
||||||
std::string msg = remote_action.to_json();
|
std::string msg = remote_action.to_json();
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
if (props->peer_) {
|
||||||
props->data_label_.c_str());
|
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) {
|
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;
|
auto props = it.second;
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||||
SendAudioFrame(props->peer_, (const char*)stream, len,
|
if (props->peer_) {
|
||||||
render->audio_label_.c_str());
|
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::string remote_id(user_id, user_id_size);
|
||||||
|
std::shared_lock lock(render->client_properties_mutex_);
|
||||||
if (render->client_properties_.find(remote_id) ==
|
if (render->client_properties_.find(remote_id) ==
|
||||||
render->client_properties_.end()) {
|
render->client_properties_.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -302,6 +314,7 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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_);
|
||||||
if (render->client_properties_.find(remote_id) !=
|
if (render->client_properties_.find(remote_id) !=
|
||||||
render->client_properties_.end()) {
|
render->client_properties_.end()) {
|
||||||
// local
|
// 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::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) ==
|
if (render->client_properties_.find(remote_id) ==
|
||||||
render->client_properties_.end()) {
|
render->client_properties_.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -402,6 +416,7 @@ 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_);
|
||||||
auto it = render->client_properties_.find(remote_id);
|
auto it = render->client_properties_.find(remote_id);
|
||||||
auto props = (it != render->client_properties_.end()) ? it->second : nullptr;
|
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: {
|
case ConnectionStatus::Closed: {
|
||||||
props->connection_established_ = false;
|
props->connection_established_ = false;
|
||||||
props->mouse_control_button_pressed_ = 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_);
|
memset(props->dst_buffer_, 0, props->dst_buffer_capacity_);
|
||||||
SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_,
|
SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_,
|
||||||
props->texture_width_);
|
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::string remote_id(user_id, user_id_size);
|
||||||
|
std::shared_lock lock(render->client_properties_mutex_);
|
||||||
if (render->client_properties_.find(remote_id) ==
|
if (render->client_properties_.find(remote_id) ==
|
||||||
render->client_properties_.end()) {
|
render->client_properties_.end()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ int Render::MainWindow() {
|
|||||||
StatusBar();
|
StatusBar();
|
||||||
|
|
||||||
if (show_connection_status_window_) {
|
if (show_connection_status_window_) {
|
||||||
|
std::unique_lock lock(client_properties_mutex_);
|
||||||
for (auto it = client_properties_.begin();
|
for (auto it = client_properties_.begin();
|
||||||
it != client_properties_.end();) {
|
it != client_properties_.end();) {
|
||||||
auto& props = it->second;
|
auto& props = it->second;
|
||||||
|
|||||||
@@ -32,12 +32,15 @@ void Render::DrawConnectionStatusText(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Render::CloseTab(decltype(client_properties_)::iterator& it) {
|
void Render::CloseTab(decltype(client_properties_)::iterator& it) {
|
||||||
CleanupPeer(it->second);
|
std::unique_lock lock(client_properties_mutex_);
|
||||||
it = client_properties_.erase(it);
|
if (it != client_properties_.end()) {
|
||||||
if (client_properties_.empty()) {
|
CleanupPeer(it->second);
|
||||||
SDL_Event event;
|
it = client_properties_.erase(it);
|
||||||
event.type = SDL_EVENT_QUIT;
|
if (client_properties_.empty()) {
|
||||||
SDL_PushEvent(&event);
|
SDL_Event event;
|
||||||
|
event.type = SDL_EVENT_QUIT;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,11 +82,22 @@ int Render::StreamWindow() {
|
|||||||
ImGuiTabBarFlags_AutoSelectNewTabs)) {
|
ImGuiTabBarFlags_AutoSelectNewTabs)) {
|
||||||
is_tab_bar_hovered_ = ImGui::IsWindowHovered();
|
is_tab_bar_hovered_ = ImGui::IsWindowHovered();
|
||||||
|
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
for (auto it = client_properties_.begin();
|
for (auto it = client_properties_.begin();
|
||||||
it != client_properties_.end();) {
|
it != client_properties_.end();) {
|
||||||
auto& props = it->second;
|
auto& props = it->second;
|
||||||
if (!props->tab_opened_) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,12 +136,23 @@ int Render::StreamWindow() {
|
|||||||
focused_remote_id_ = props->remote_id_;
|
focused_remote_id_ = props->remote_id_;
|
||||||
|
|
||||||
if (!props->peer_) {
|
if (!props->peer_) {
|
||||||
it = client_properties_.erase(it);
|
std::string remote_id_to_erase = props->remote_id_;
|
||||||
if (client_properties_.empty()) {
|
lock.unlock();
|
||||||
SDL_Event event;
|
{
|
||||||
event.type = SDL_EVENT_QUIT;
|
std::unique_lock unique_lock(client_properties_mutex_);
|
||||||
SDL_PushEvent(&event);
|
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 {
|
} else {
|
||||||
DrawConnectionStatusText(props);
|
DrawConnectionStatusText(props);
|
||||||
++it;
|
++it;
|
||||||
@@ -147,11 +172,22 @@ int Render::StreamWindow() {
|
|||||||
|
|
||||||
ImGui::End(); // End TabBar
|
ImGui::End(); // End TabBar
|
||||||
} else {
|
} else {
|
||||||
|
std::shared_lock lock(client_properties_mutex_);
|
||||||
for (auto it = client_properties_.begin();
|
for (auto it = client_properties_.begin();
|
||||||
it != client_properties_.end();) {
|
it != client_properties_.end();) {
|
||||||
auto& props = it->second;
|
auto& props = it->second;
|
||||||
if (!props->tab_opened_) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,12 +217,23 @@ int Render::StreamWindow() {
|
|||||||
if (!props->peer_) {
|
if (!props->peer_) {
|
||||||
fullscreen_button_pressed_ = false;
|
fullscreen_button_pressed_ = false;
|
||||||
SDL_SetWindowFullscreen(stream_window_, false);
|
SDL_SetWindowFullscreen(stream_window_, false);
|
||||||
it = client_properties_.erase(it);
|
std::string remote_id_to_erase = props->remote_id_;
|
||||||
if (client_properties_.empty()) {
|
lock.unlock();
|
||||||
SDL_Event event;
|
{
|
||||||
event.type = SDL_EVENT_QUIT;
|
std::unique_lock unique_lock(client_properties_mutex_);
|
||||||
SDL_PushEvent(&event);
|
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 {
|
} else {
|
||||||
DrawConnectionStatusText(props);
|
DrawConnectionStatusText(props);
|
||||||
++it;
|
++it;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ std::filesystem::path PathManager::GetLogPath() {
|
|||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
return GetHome() + "/Library/Logs/" + app_name_;
|
return GetHome() + "/Library/Logs/" + app_name_;
|
||||||
#else
|
#else
|
||||||
return GetCachePath() / app_name_ / "logs";
|
return GetCachePath() / "logs";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user