macOS: симулированное событие мыши работает только при запуске двоичного файла, а не пакета приложения

У меня есть следующий код, который перемещает курсор мыши на Mac:

void moveCursorPos()
{
  CGPoint ppos;
  ppos.x = 100;
  ppos.y = 100;

  CGEventRef e = CGEventCreateMouseEvent(nullptr, kCGEventMouseMoved, ppos, kCGMouseButtonLeft);
  CGEventPost(kCGHIDEventTap, e);
  CFRelease(e);
}

Он работает, когда я запускаю свое программное обеспечение непосредственно из его двоичного файла - например, ./foo.app/Contents/MacOS/foo. Не получается при запуске через open foo.app. Выполняю open ./foo.app/Contents/MacOS/foo работы.

В первый раз, когда я запустил его и вызвал эту функцию, macOS запросила у меня разрешение на использование API специальных возможностей (или что-то в этом роде), которое я предоставил - если я перейду на панель «Доступность> Конфиденциальность» в настройках безопасности macOS. , все флажки отмечены, все присваивается foo и т. д.

  • Как исправить это на моей машине?
  • Что я могу сделать с точки зрения кода, чтобы пользователи моего программного обеспечения никогда не сталкивались с этой проблемой, поскольку она нарушает базовое взаимодействие с пользовательским интерфейсом моего программного обеспечения?

person Jean-Michaël Celerier    schedule 16.05.2020    source источник


Ответы (1)


Как исправить это на моей машине?

Это действительно зависит от того, что вы сделали. Я обычно ломал эти вещи, когда запускаю приложение из Xcode напрямую, из дистрибутива ... и все они имеют одинаковый идентификатор пакета (одна запись в системных настройках, но больше двоичных файлов).

Чтобы сбросить доступность для вашего приложения, просто запустите:

sudo tccutil reset Accessibility com.your.bundle.Identifier

Он сбросит настройки специальных возможностей для всех экземпляров ваших двоичных файлов, и вы сможете начать заново.

Что я могу сделать с точки зрения кода, чтобы пользователи моего программного обеспечения никогда не сталкивались с этой проблемой, поскольку она нарушает базовое взаимодействие с пользовательским интерфейсом моего программного обеспечения?

Сделайте в своем AppDelegate.applicationDidFinishLaunching следующее:

acquireAccessibilityPrivileges(acquired: {
    self.moveCursorPos()
}, nope: {
    NSApp.terminate(self)
})

Прочие функции:

func acquireAccessibilityPrivileges(acquired: @escaping () -> Void, nope: @escaping () -> Void) {
    let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue(): true]
    let enabled = AXIsProcessTrustedWithOptions(options as CFDictionary)

    if enabled {
        acquired()
    } else {
        let alert = NSAlert()
        alert.messageText = "Enable XYZ"
        alert.informativeText = "Click OK once you enabled XYZ in System Preferences - ..."
        alert.beginSheetModal(for: self.window, completionHandler: { response in
            if AXIsProcessTrustedWithOptions(options as CFDictionary) {
                acquired()
            } else {
                nope()
            }
        })
    }
}

func moveCursorPos() {
    let event = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: CGPoint(x: 100, y: 100), mouseButton: .left)
    event?.post(tap: .cghidEventTap)
}

open foo.app vs ./foo

Также нужно знать одну вещь - разницу между open foo.app, ./foo.app/Contents/MacOS/foo, ...

open Foo.app:

  • Foo.app необходимы эти разрешения доступа
-+= 00001 root /sbin/launchd
 |--= 83677 zrzka /Users/zrzka/Desktop/Foo.app/Contents/MacOS/Foo

Foo.app/Contents/MacOS/Foo:

  • Iterm.app требуются эти разрешения доступа
-+= 00001 root /sbin/launchd
 |-+= 53984 zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2
 | |-+= 53986 zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --server /usr/bin/login -fpl zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
 | | \-+= 53987 root /usr/bin/login -fpl zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
 | |   \-+= 53988 zrzka -zsh
 | |     \--= 84461 zrzka Foo.app/Contents/MacOS/Foo

open Foo.app/Contents/MacOS/Foo:

  • Terminal.app запускается и Foo в нем
  • Это потому, что я использую iTerm, но по умолчанию это Терминал.
  • Terminal.app нужны эти разрешения доступа
-+= 00001 root /sbin/launchd
 |-+= 73320 zrzka /System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
 | \-+= 75674 root login -pf zrzka
 |   \-+= 75679 zrzka -zsh
 |     \--= 75717 zrzka /Users/zrzka/Desktop/Foo.app/Contents/MacOS/Foo

Больше советов

Время от времени случается, что мое приложение больше не отображается в Системных настройках - Безопасность и конфиденциальность - Доступность. Не знаю почему, но это как-то связано с моими tccutil сбросами. Откройте Finder и перетащите Foo.app на панель.

person zrzka    schedule 19.05.2020
comment
Спасибо, это очень исчерпывающий ответ. Перепроверка каждый раз действительно работает, хотя в моем приложении потребовалось три раза и снятие / повторная проверка в настройках, чтобы наконец зарегистрироваться ... это также убеждает меня в том, что macOS определенно представляет собой беспорядок с ошибками. - person Jean-Michaël Celerier; 23.05.2020