[feat] support concurrent MCP sessions and multi-display operations

This commit is contained in:
dijunkun
2026-11-06 21:15:31 +08:00
parent 12afcce690
commit 0c1aa1339d
8 changed files with 266 additions and 56 deletions
+18 -2
View File
@@ -943,14 +943,30 @@ private:
session_.Disconnect();
} else
throw std::invalid_argument("INVALID_REQUEST");
} else if (method == "video_settings") {
Fields(j, {"id", "method", "fps", "width", "height", "quality", "max_bitrate_bps"});
if (action_) throw std::invalid_argument("BUSY");
if (session_.HasPressedInput()) throw std::invalid_argument("INPUT_HELD");
const auto status = session_.Status();
if (!session_.Connected() || !status.value("preview_supported", false))
throw std::invalid_argument("VIDEO_SETTINGS_UNSUPPORTED");
if (((j.contains("width") || j.contains("height")) && !status.value("preview_resolution_supported", false)) ||
(j.contains("max_bitrate_bps") && !status.value("preview_bitrate_supported", false)) ||
(j.value("fps", json{}) == 15 && !status.value("preview_fps15_supported", false)))
throw std::invalid_argument("VIDEO_SETTINGS_UNSUPPORTED");
session_.SetPreview(Number(j, "fps", 1, 60, status.value("preview_fps", 30)),
Number(j, "width", 2, 3840, status.value("preview_width", 1920)),
Number(j, "height", 2, 2160, status.value("preview_height", 1080)),
Number(j, "quality", 0, 2, status.value("preview_quality", 2)),
Number(j, "max_bitrate_bps", 128000, 100000000, status.value("preview_bitrate_bps", 6000000)));
} else if (method == "display") {
Fields(j, {"id", "method", "index"});
Fields(j, {"id", "method", "index", "preserve_input"});
const int index = Number(j, "index", 0, 63, -1);
if (!session_.Connected() || index < 0 ||
size_t(index) >= session_.Status()["displays"].size())
throw std::invalid_argument("DISPLAY_UNAVAILABLE");
Stop("SESSION_CHANGED");
if (!session_.SelectDisplay(index))
if (!session_.SelectDisplay(index, Flag(j, "preserve_input")))
throw std::invalid_argument("DISPLAY_UNAVAILABLE");
frame_.reset();
++epoch_;
+6
View File
@@ -163,3 +163,9 @@ The desktop and CLI share `FileBrowser` and the existing file transfer engine. P
`key_down`, `key_up`, `mouse_down`, and `mouse_up` extend the action union. Each successful action renews a fifteen-second lease for held input. Existing held modifiers survive subsequent clicks, movement and hotkeys. `release_inputs` releases the controller's tracked keys/buttons and cancels current input without requiring an observation. Errors, human pause, display changes and disconnection release held input.
`key_press` and `hotkey` accept `duration_ms` from 10 to 30000. Drags accept durations up to 30000 milliseconds. Extended key names include F13–F24, NUMPAD0–NUMPAD9, arithmetic keypad keys, lock/menu/print keys and media controls. Target platform key mapping determines availability. Text input requires held keys/buttons to be released first.
## Display management
`video_settings` accepts optional `fps`, even `width`/`height`, `quality`, and `max_bitrate_bps`. The controller checks negotiated preview capabilities and publishes the requested cadence and acceptance state. Supported MCP frame-rate tiers are 1, 8, 15, 30 and 60.
The trusted adapter may use `display` with `preserve_input: true` during a cross-display drag. It captures a fresh observation after each switch, maps the requested point from its source display image, and releases input in a final cleanup step. Ordinary display selection releases input. Multi-display capture returns sequential observations and restores the previous display.