diff --git a/cli/main.cpp b/cli/main.cpp index 72559802..007cff80 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -37,8 +37,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -420,7 +420,7 @@ class HIDEnumeration { if (devices_) hid_free_enumeration(devices_); } - HIDEnumeration(const HIDEnumeration&) = delete; + HIDEnumeration(const HIDEnumeration&) = delete; HIDEnumeration& operator=(const HIDEnumeration&) = delete; hid_device_info* get() const { return devices_; } @@ -1003,7 +1003,7 @@ void setupSignalHandler() #ifdef _WIN32 signal(SIGINT, signalHandler); #else - struct sigaction act {}; + struct sigaction act { }; act.sa_handler = signalHandler; sigaction(SIGINT, &act, nullptr); #endif @@ -1031,13 +1031,32 @@ std::vector toLegacyDeviceList(std::vector& device return legacy; } +// Whether this device was asked to set something. Only counts requests that are +// still live, so it has to run after handleMultiDeviceActions has had its say. +bool hasRequestedAction(const DiscoveredDevice& device) +{ + for (const auto& req : device.feature_requests) { + if (req.type == CAPABILITYTYPE_ACTION && req.should_process) { + return true; + } + } + + return false; +} + // Enable info requests for extended output formats (JSON, YAML, ENV) +// Only for a pure query: the extra reads can cost far more than the action +// itself (Maxwell 2: -s 20 is 0.07 s, -s 20 -o json is 2.90 s). Per device, so +// an action on one headset does not silence the info reads of another. void enableExtendedInfoRequests(std::vector& devices, bool extended) { if (!extended) return; for (auto& dev : devices) { + if (hasRequestedAction(dev)) + continue; + for (auto& req : dev.feature_requests) { if (req.type == CAPABILITYTYPE_INFO && !req.should_process && dev.hasCapability(req.cap)) { req.should_process = true; @@ -1201,8 +1220,11 @@ int main(int argc, char* argv[]) // Initialize and configure feature requests initializeFeatureRequests(devices, opts); bool extended = opts.output_format == OUTPUT_YAML || opts.output_format == OUTPUT_JSON || opts.output_format == OUTPUT_ENV; - enableExtendedInfoRequests(devices, extended); + // Order matters: handleMultiDeviceActions neutralizes action requests, and + // enableExtendedInfoRequests has to see the result of that, not the requests + // as they were parsed. handleMultiDeviceActions(devices, opts); + enableExtendedInfoRequests(devices, extended); // Main loop do { diff --git a/cli/output/output.cpp b/cli/output/output.cpp index d193cf06..68b2d569 100644 --- a/cli/output/output.cpp +++ b/cli/output/output.cpp @@ -23,7 +23,9 @@ using namespace headsetcontrol::serializers; // Constants // ============================================================================ -constexpr std::string_view API_VERSION = "1.4"; +// 1.5: an invocation that performs an action no longer reports info it was not +// explicitly asked for. +constexpr std::string_view API_VERSION = "1.5"; constexpr std::string_view APP_NAME = "HeadsetControl"; // ============================================================================ @@ -179,8 +181,7 @@ void processFeatureRequest(const FeatureRequest& req, DeviceData& dev, std::stri for (const auto& preset : presets->presets) { preset_data.push_back(EqualizerPresetData { .name = preset.name, - .values = preset.values - }); + .values = preset.values }); } dev.equalizer_presets = std::move(preset_data); } diff --git a/docs/LIBRARY_USAGE.md b/docs/LIBRARY_USAGE.md index cf8afc07..419dd808 100644 --- a/docs/LIBRARY_USAGE.md +++ b/docs/LIBRARY_USAGE.md @@ -28,7 +28,7 @@ headsetcontrol -o env { "name": "HeadsetControl", "version": "3.0.0", - "api_version": "1.4", + "api_version": "1.5", "device_count": 1, "devices": [ {