Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/macos-gamepad.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ root-owned broker. The broker alone calls Apple's `IOHIDUserDevice` API and hold
the virtual HID entitlement. The ordinary C++ library has no Apple entitlement
and uses CoreGraphics for keyboard and mouse input.

The broker's gamepad report thread and `IOHIDUserDevice` callback queue request
user-interactive QoS to reduce scheduling delay in the input path. License
validation and other broker work keep their normal scheduling. This is a
best-effort priority hint, not a real-time latency guarantee. The virtual HID
device is provided by macOS, so there is no separate libvirtualhid driver
process to prioritize.

The client checks root ownership of the broker directory, socket, and
connected peer before exchanging versioned messages. Socket transfers handle
partial reads and writes so truncated messages are not treated as complete.
Expand Down
5 changes: 4 additions & 1 deletion src/platform/macos/broker/libvirtualhid_macos_broker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <memory>
#include <mutex>
#include <poll.h>
#include <pthread/qos.h>
#include <span>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -263,7 +264,7 @@ namespace lvh::detail::macos_broker {
*size = static_cast<CFIndex>(report.size());
return kIOReturnSuccess;
});
IOHIDUserDeviceSetDispatchQueue(device, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0));
IOHIDUserDeviceSetDispatchQueue(device, dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0));
IOHIDUserDeviceSetCancelHandler(device, ^{
dispatch_semaphore_signal(cancelled);
});
Expand All @@ -276,6 +277,8 @@ namespace lvh::detail::macos_broker {
}

void receive_reports(DeviceSession &session, LicenseManager &licenses, bool evaluation, std::uint32_t expected_input_size) {
// Only the HID input path needs interactive scheduling; licensing stays at its normal QoS.
static_cast<void>(::pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0));
Message request;
for (;;) {
pollfd descriptor {.fd = session.fd, .events = POLLIN, .revents = 0};
Expand Down
Loading