Skip to content

Commit

Permalink
fix(macos): properly handle accessibility permission
Browse files Browse the repository at this point in the history
  • Loading branch information
Hazer committed Dec 5, 2024
1 parent af8ef23 commit 96505cc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/platform/macos/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <chrono>
#include <mach/mach.h>

#include "misc.h"

#include "src/logging.h"
#include "src/platform/common.h"
#include "src/utility.h"
Expand Down Expand Up @@ -226,6 +228,11 @@ const KeyCodeMap kKeyCodesMap[] = {
};
// clang-format on

/**
* Used to avoid spamming permission requests when the user receives an input event
*/
bool accessibility_permission_requested;

int
keysym(int keycode) {
KeyCodeMap key_map {};
Expand All @@ -242,12 +249,36 @@ const KeyCodeMap kKeyCodesMap[] = {
return temp_map->mac_keycode;
}

std::string
default_accessibility_log_msg() {
return "Accessibility permission is not enabled,"

Check warning on line 254 in src/platform/macos/input.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/macos/input.cpp#L253-L254

Added lines #L253 - L254 were not covered by tests
" please enable sunshine in "
"[System Settings > Privacy & Security > Privacy > Accessibility]"
", then please restart Sunshine for it to take effect";
}

void
print_accessibility_status(const bool is_keyboard_event, const bool release) {

Check warning on line 261 in src/platform/macos/input.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/macos/input.cpp#L261

Added line #L261 was not covered by tests
if (!release) return;

if (!has_accessibility_permission()) {
if (!accessibility_permission_requested) {
accessibility_permission_requested = true;
request_accessibility_permission();

Check warning on line 267 in src/platform/macos/input.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/macos/input.cpp#L266-L267

Added lines #L266 - L267 were not covered by tests
}
BOOST_LOG(info) << "Received " << (is_keyboard_event ? "keyboard" : "mouse") << " event but "
<< default_accessibility_log_msg();
}
}

void
keyboard_update(input_t &input, uint16_t modcode, bool release, uint8_t flags) {
auto key = keysym(modcode);

BOOST_LOG(debug) << "got keycode: 0x"sv << std::hex << modcode << ", translated to: 0x" << std::hex << key << ", release:" << release;

print_accessibility_status(true, release);

Check warning on line 280 in src/platform/macos/input.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/macos/input.cpp#L280

Added line #L280 was not covered by tests

if (key < 0) {
return;
}
Expand Down Expand Up @@ -437,6 +468,8 @@ const KeyCodeMap kKeyCodesMap[] = {
BOOST_LOG(warning) << "Unsupported mouse button for MacOS: "sv << button;
return;
}

print_accessibility_status(false, release);

Check warning on line 472 in src/platform/macos/input.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/macos/input.cpp#L472

Added line #L472 was not covered by tests

macos_input->mouse_down[mac_button] = !release;

Expand Down Expand Up @@ -538,6 +571,11 @@ const KeyCodeMap kKeyCodesMap[] = {

const auto macos_input = static_cast<macos_input_t *>(result.get());

accessibility_permission_requested = false;
if (request_accessibility_permission()) {
BOOST_LOG(info) << default_accessibility_log_msg() << ", to allow mouse clicks and keyboard inputs.";
}

// Default to main display
macos_input->display = CGMainDisplayID();

Expand Down
14 changes: 14 additions & 0 deletions src/platform/macos/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@
namespace platf {
bool
is_screen_capture_allowed();

/**
* Prompts the user for Accessibility permission
* @return returns true if requested permission, false if already has permission
*/
bool
request_accessibility_permission();

/**
* Checks for Accessibility permission
* @return returns true if sunshine has Accessibility permission enabled
*/
bool
has_accessibility_permission();
}

namespace dyn {
Expand Down
17 changes: 17 additions & 0 deletions src/platform/macos/misc.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#define __APPLE_USE_RFC_3542 1
#endif

#include <Carbon/Carbon.h>

#include <Foundation/Foundation.h>
#include <arpa/inet.h>
#include <dlfcn.h>
Expand Down Expand Up @@ -538,6 +540,21 @@

return std::make_unique<qos_t>(sockfd, reset_options);
}

bool
request_accessibility_permission() {
NSDictionary* options = @{static_cast<id>(kAXTrustedCheckOptionPrompt): @YES};
return !AXIsProcessTrustedWithOptions(static_cast<CFDictionaryRef>(options));
}

bool
has_accessibility_permission() {
NSDictionary* options = @{static_cast<id>(kAXTrustedCheckOptionPrompt): @NO};

Check warning on line 552 in src/platform/macos/misc.mm

View check run for this annotation

Codecov / codecov/patch

src/platform/macos/misc.mm#L551-L552

Added lines #L551 - L552 were not covered by tests
// We use kAXTrustedCheckOptionPrompt == NO here,
// instead of using XIsProcessTrusted(),
// because this will update the accessibility list with sunshine current path
return AXIsProcessTrustedWithOptions(static_cast<CFDictionaryRef>(options));

Check warning on line 556 in src/platform/macos/misc.mm

View check run for this annotation

Codecov / codecov/patch

src/platform/macos/misc.mm#L556

Added line #L556 was not covered by tests
}

std::string
get_host_name() {
Expand Down

0 comments on commit 96505cc

Please sign in to comment.