From b2817d0adc9209e6a3c72d542364d69b8d0c98f6 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Wed, 11 Nov 2026 16:27:27 +0800 Subject: [PATCH] [fix] enable web file browsing across control transports, refs #135 --- apps/desktop/src/gui/runtime/peer_data_callbacks.cpp | 5 +++-- apps/desktop/src/gui/runtime/peer_event_handler.cpp | 12 ++++++------ .../gui/application/local_host_application.cpp | 7 +++++-- deps/submodules/minirtc | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp b/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp index c4969ae6..a3cb311c 100644 --- a/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp +++ b/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp @@ -151,7 +151,8 @@ void PeerEventHandler::OnReceiveDataBuffer( source_id == runtime->clipboard_label_ || source_id == web_clipboard::kStream)) return; - if (source_id == runtime->control_data_label_ && + // MiniRTC reports the browser's reliable control channel as data-stream. + if ((source_id == runtime->control_data_label_ || source_id == kWebControlStream) && runtime->transfers_.HandleBrowser(data, size, handler, remote_id)) return; if (source_id == web_clipboard::kStream) { runtime->clipboard_.ReceiveWeb( @@ -463,7 +464,7 @@ void PeerEventHandler::OnReceiveDataBuffer( } if (remote_action.type == ControlType::host_infomation) { - if (source_id == runtime->control_data_label_) { + if (source_id == runtime->control_data_label_ || source_id == kWebControlStream) { runtime->transfers_.SetBrowserSupport(handler, remote_id, remote_action.i.supports_file_browser); } diff --git a/apps/desktop/src/gui/runtime/peer_event_handler.cpp b/apps/desktop/src/gui/runtime/peer_event_handler.cpp index 662e6066..1cc2552f 100644 --- a/apps/desktop/src/gui/runtime/peer_event_handler.cpp +++ b/apps/desktop/src/gui/runtime/peer_event_handler.cpp @@ -685,12 +685,12 @@ std::string GuiRuntime::BuildHostInformation(bool advertise_trust, LOG_INFO("Local display [{}:{}]", i + 1, action.i.display_list[i]); auto message = action.to_json(); FreeRemoteAction(action); - if (advertise_trust) { - auto information = nlohmann::json::parse(message); - information["device_trust_version"] = 1; - message = information.dump(); - } - return message; + auto information = nlohmann::json::parse(message); + // Older desktop builds advertise native directory RPC, but their Web + // control router cannot carry it. Negotiate the Web route independently. + information["host_info"]["supports_web_file_browser"] = UserSessionFeaturesAvailable(); + if (advertise_trust) information["device_trust_version"] = 1; + return information.dump(); } void GuiRuntime::AnnounceHostCapabilities(const std::string& id) { diff --git a/apps/desktop/src/platform/windows/gui/application/local_host_application.cpp b/apps/desktop/src/platform/windows/gui/application/local_host_application.cpp index 4c64d584..9987ecd2 100644 --- a/apps/desktop/src/platform/windows/gui/application/local_host_application.cpp +++ b/apps/desktop/src/platform/windows/gui/application/local_host_application.cpp @@ -1,6 +1,7 @@ #include "application/gui_application.h" #include +#include #include #include #include @@ -35,7 +36,7 @@ bool GuiRuntime::ForwardUserSessionData(const std::string& id, const bool user_stream = stream == file_label_ || stream == file_feedback_label_ || stream == clipboard_label_ || stream == web_clipboard::kStream; Json action; - if (stream == control_data_label_ && size <= 65536) + if ((stream == control_data_label_ || stream == kWebControlStream) && size <= 65536) action = Json::parse(data, data + size, nullptr, false); const auto type = action.is_object() ? action.value("type", Json{}) : Json{}; const bool host_info = type == static_cast(ControlType::host_infomation); @@ -54,7 +55,9 @@ bool GuiRuntime::ForwardUserSessionData(const std::string& id, } if (local_gui_ready_ && local_host_ && (user_stream || user_control || host_info || preview || audio)) { - if (!local_host_->Send({{"op", "data"}, {"id", id}, {"epoch", epoch}, {"stream", stream}, + // IPC uses the native label; the Web alias belongs to the SCTP boundary. + const auto& forwarded_stream = stream == kWebControlStream ? control_data_label_ : stream; + if (!local_host_->Send({{"op", "data"}, {"id", id}, {"epoch", epoch}, {"stream", forwarded_stream}, {"bytes", Json::binary(std::vector(data, data + size))}})) { LOG_WARN( "Cannot forward user-session data on {}; reconnecting local frontend", diff --git a/deps/submodules/minirtc b/deps/submodules/minirtc index 810dd0b0..b18575b4 160000 --- a/deps/submodules/minirtc +++ b/deps/submodules/minirtc @@ -1 +1 @@ -Subproject commit 810dd0b0999ba8422a40c2f84c72ed5f3c9aac83 +Subproject commit b18575b4d9b57feb466d930f85696cce1e1cc5b2