macOS:模拟鼠标事件仅在启动二进制文件而不是应用程序捆绑包时有效

问题描述 投票:2回答:1

我有以下代码在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,依此类推...

  • 如何在机器上修复它?
  • 我可以按照代码做些什么,以使我的软件用户永远不会遇到该问题,因为它破坏了我软件的核心UI交互?
macos accessibility core-graphics cursor-position
1个回答
1
投票

如何在计算机上修复它?

这实际上取决于您所做的事情。当我直接从Xcode运行应用程序时,通常会破坏这些东西,分发……所有这些都具有相同的包标识符(“系统偏好设置”中有一个条目,但周围有更多的二进制文件)。

要重新运行您的应用程序的可访问性,请执行以下操作:

sudo tccutil reset Accessibility com.your.bundle.Identifier

它将重置您所有二进制文件的可访问性设置,您可以重新开始。

我可以在代码方面做些什么,以使我的软件用户永远不会遇到该问题,因为它破坏了我软件的核心UI交互?

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
  • [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拖放到窗格中。

© www.soinside.com 2019 - 2024. All rights reserved.