[feat] acknowledge remote input and wait for visual changes

This commit is contained in:
dijunkun
2026-11-06 20:12:41 +08:00
parent a49eb7ad5b
commit 0eab020c38
15 changed files with 285 additions and 11 deletions
@@ -0,0 +1,47 @@
#include "runtime/gui_runtime.h"
#include <stream_names.h>
namespace crossdesk {
void GuiRuntime::HandleAutomation(const std::string& remote_id,
const nlohmann::json& request) {
using nlohmann::json;
if (request.value("version", json{}) != 1 || !request.contains("id") ||
!request["id"].is_number_unsigned() || request["id"].get<uint64_t>() == 0)
return;
const auto source = ControllerEvents(remote_id);
if (!source || !source->DataAllowed()) return;
const auto id = request["id"].get<uint64_t>();
const auto reply = [this, remote_id, id, source](bool ok, json result) {
const auto current = ControllerEvents(remote_id);
if (current != source || !current->DataAllowed()) return;
const auto message = json{{"type", "automation_result"}, {"version", 1},
{"id", id}, {"ok", ok}, {ok ? "result" : "error", std::move(result)}}.dump();
SendControllerData(remote_id, message.data(), message.size(), kControlStream);
};
try {
const auto method = request.value("method", std::string{});
if (method == "capabilities") {
reply(true, {{"input_ack", true}});
} else if (method == "input") {
RemoteAction action{};
if (!request.contains("arguments") ||
!action.from_json(request["arguments"].dump())) {
reply(false, "INVALID_ARGUMENT");
return;
}
const auto result = remote_input_.Push(remote_id, action,
[reply](InputOutcome outcome) {
reply(true, {{"state", InputOutcomeName(outcome)}});
});
FreeRemoteAction(action);
if (result == RemoteInputDispatcher::Result::rejected ||
result == RemoteInputDispatcher::Result::overflow)
reply(false, "INPUT_REJECTED");
} else {
reply(false, "UNSUPPORTED_OPERATION");
}
} catch (...) {
reply(false, "INVALID_ARGUMENT");
}
}
} // namespace crossdesk
@@ -152,6 +152,7 @@ class GuiRuntime : protected gui_detail::GuiState {
// or every connected session while that target leads DeskHub group control.
void SendRemoteInput(const RemoteAction& action);
InputOutcome ApplyRemoteInput(const std::string& remote_id, const RemoteAction& action);
void HandleAutomation(const std::string& remote_id, const nlohmann::json& request);
InputOutcome InjectRemoteMouse(const RemoteAction& action, int display);
std::string gallery_group_control_id_;
@@ -179,6 +179,14 @@ void PeerEventHandler::OnReceiveDataBuffer(
PeerPtr* bound_peer =
handler->IsDirect() ? handler->DirectPeer() : runtime->peer_;
std::string json_str(data, size);
if (json_str.find("\"automation\"") != std::string::npos) {
const auto request = nlohmann::json::parse(json_str, nullptr, false);
if (request.is_object() && request.value("type", nlohmann::json{}) == "automation") {
if (source_id == runtime->control_data_label_ && runtime->IsAuthorizedController(remote_id))
runtime->HandleAutomation(remote_id, request);
return;
}
}
const auto preview_json =
json_str.find("\"deskhub_preview") != std::string::npos
? nlohmann::json::parse(json_str, nullptr, false)