diff --git a/src/WSRequestHandler.cpp b/src/WSRequestHandler.cpp index 56c4cdaa..b4ab8137 100644 --- a/src/WSRequestHandler.cpp +++ b/src/WSRequestHandler.cpp @@ -43,6 +43,9 @@ const QHash WSRequestHandler::messageMap { { "BroadcastCustomMessage", &WSRequestHandler::BroadcastCustomMessage }, + { "TriggerHotkeyByName", &WSRequestHandler::TriggerHotkeyByName }, + { "TriggerHotkeyBySequence", &WSRequestHandler::TriggerHotkeyBySequence }, + { "SetCurrentScene", &WSRequestHandler::SetCurrentScene }, { "GetCurrentScene", &WSRequestHandler::GetCurrentScene }, { "GetSceneList", &WSRequestHandler::GetSceneList }, diff --git a/src/WSRequestHandler.h b/src/WSRequestHandler.h index e409db50..c3190668 100644 --- a/src/WSRequestHandler.h +++ b/src/WSRequestHandler.h @@ -61,6 +61,9 @@ class WSRequestHandler { RpcResponse BroadcastCustomMessage(const RpcRequest&); + RpcResponse TriggerHotkeyByName(const RpcRequest&); + RpcResponse TriggerHotkeyBySequence(const RpcRequest&); + RpcResponse SetCurrentScene(const RpcRequest&); RpcResponse GetCurrentScene(const RpcRequest&); RpcResponse GetSceneList(const RpcRequest&); diff --git a/src/WSRequestHandler_General.cpp b/src/WSRequestHandler_General.cpp index ea1c6a63..a5f19143 100644 --- a/src/WSRequestHandler_General.cpp +++ b/src/WSRequestHandler_General.cpp @@ -345,3 +345,73 @@ RpcResponse WSRequestHandler::OpenProjector(const RpcRequest& request) { obs_frontend_open_projector(type, monitor, geometry, name); return request.success(); } + +/** +* Executes hotkey routine, identified by hotkey unique name +* +* @param {String} `hotkeyName` Unique name of the hotkey, as defined when registering the hotkey (e.g. "ReplayBuffer.Save") +* +* @api requests +* @name TriggerHotkeyByName +* @category general +* @since unreleased +*/ +RpcResponse WSRequestHandler::TriggerHotkeyByName(const RpcRequest& request) { + const char* name = obs_data_get_string(request.parameters(), "hotkeyName"); + + obs_hotkey_t* hk = Utils::FindHotkeyByName(name); + if (!hk) { + return request.failed("hotkey not found"); + } + obs_hotkey_trigger_routed_callback(obs_hotkey_get_id(hk), true); + return request.success(); +} + +/** +* Executes hotkey routine, identified by bound combination of keys. A single key combination might trigger multiple hotkey routines depending on user settings +* +* @param {String} `keyId` Main key identifier (e.g. `OBS_KEY_A` for key "A"). Available identifiers [here](https://github.com/obsproject/obs-studio/blob/master/libobs/obs-hotkeys.h) +* @param {Object (Optional)} `keyModifiers` Optional key modifiers object. False entries can be ommitted +* @param {boolean} `keyModifiers.shift` Trigger Shift Key +* @param {boolean} `keyModifiers.alt` Trigger Alt Key +* @param {boolean} `keyModifiers.control` Trigger Control (Ctrl) Key +* @param {boolean} `keyModifiers.command` Trigger Command Key (Mac) +* +* @api requests +* @name TriggerHotkeyByCombination +* @category general +* @since unreleased +*/ +RpcResponse WSRequestHandler::TriggerHotkeyBySequence(const RpcRequest& request) { + if (!request.hasField("keyId")) { + return request.failed("missing request keyId parameter"); + } + + OBSDataAutoRelease data = obs_data_get_obj(request.parameters(), "keyModifiers"); + + obs_key_combination_t combo = {0}; + uint32_t modifiers = 0; + if (obs_data_get_bool(data, "shift")) + modifiers |= INTERACT_SHIFT_KEY; + if (obs_data_get_bool(data, "control")) + modifiers |= INTERACT_CONTROL_KEY; + if (obs_data_get_bool(data, "alt")) + modifiers |= INTERACT_ALT_KEY; + if (obs_data_get_bool(data, "command")) + modifiers |= INTERACT_COMMAND_KEY; + + combo.modifiers = modifiers; + combo.key = obs_key_from_name(obs_data_get_string(request.parameters(), "keyId")); + + if (!modifiers + && (combo.key == OBS_KEY_NONE || combo.key >= OBS_KEY_LAST_VALUE)) { + return request.failed("invalid key-modifier combination"); + } + + // Inject hotkey press-release sequence + obs_hotkey_inject_event(combo, false); + obs_hotkey_inject_event(combo, true); + obs_hotkey_inject_event(combo, false); + + return request.success(); +}