我希望能够在我的程序中设置Mac上游标大小的系统首选项(如“辅助功能首选项”中所示),然后在程序退出后将其设置回来。
有没有办法通常从应用程序设置游标大小(具体)或系统首选项?
答案 0 :(得分:11)
首先,如果您只是在光标指向窗口/视图/窗口小部件时尝试获取更大的光标,那么您就错误地说了这个。以正确的方式阅读Introduction to Cursor Manager。
其次,即使您认为自己实际上想要在程序运行时设置系统范围的光标,在开始之前要更仔细地考虑它。即使您的应用程序在后台或隐藏,光标也会保持很大。如果你对透明的生命周期理念(用户通常不会注意或关心你的应用程序之间的差异,你的应用程序之间的差异和你的应用程序已经退出)做了任何动作,那么这将是甚至更多令人困惑。如果两个应用程序试图这样做,会发生什么?等等。 (不用说,Apple会拒绝任何来自App Store的应用程序。)
第三,设置系统偏好并不实际做任何事情,直到系统读取该偏好的新时间。并且不能保证何时会发生这种情况。因此,除非您的应用程序满足于更改在用户之前可能不会生效的首选项,例如,再次注销并重新登录(然后在您退出后将其更改回来),否则它并非完全有用。< / p>
但如果这真的是你想做的......
设置系统偏好非常容易。 “系统偏好设置”修改的大多数值都在默认存储中。 “辅助功能”窗格中的大多数值都位于com.apple.universalaccess
域中。光标大小的特定键是mouseDriverCursorSize
。
因此,要将光标从bash更改为max size:
defaults write com.apple.universalaccess mouseDriverCursorSize 4.0
ObjC有点单调乏味,但是这样(未经测试):
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *olddict = [defaults persistentDomainForName:@"com.apple.universalaccess"];
NSMutableDictionary *newdict = [olddict mutableCopy];
[newdict setObject:@4.0 forKey:@"mouseDriverCursorSize"];
[defaults setPersistentDomain:newdict forName:@"com.apple.universalaccess"];
[defaults synchronize]
那么,如果您想设置首选项,然后强制系统注意到更改,该怎么办?显然,系统偏好设置应用程序正在执行某些事情,您可以随时跟踪它确实看到它的功能。
通常,它所做的是调用一些没有记录或暴露的私人功能。并且它可能在不同的OS版本之间有所不同。无论如何,它的作用可能不是最好的。但是通过快速测试:
看起来调用CGSShowCursor
是有效的,只要隐藏光标可以接受它是可以接受的。连续两次调用CGSGetGlobalCursorData
似乎也有效,尽管我不知道它为什么要这样做。
当然这些CGSPrivate函数没有记录或暴露,但至少其他人已经对它们进行了逆向工程,所以你不必这样做。您所要做的就是从一些开源项目中借用代码(iTerm2拥有一套更完整的标题集),并在每次从Apple发布新的次要操作系统后进行测试,并调试不具备的黑魔法&# 39;为25%的用户工作,即使它适用于其他75%的用户(无法访问25%正在使用的机器,通常甚至无法获得体面的问题或答案)。
如果您想跟踪系统偏好设置,并且您在OS X中没有经验跟踪过程,最简单的方法是通过GUI工具仪器:
但是,请记住,系统偏好设置可能没有调用特殊的系统调用来执行它所需的操作;它可以是,例如,将特定的马赫消息发送到窗口服务器任务。幸运的是,你可以从任何看似可能的东西向后走。通过这样做,我发现它似乎在UniversalAccessCore中调用UACursorSetScale
,它在UAPreferencesSetValue
中调用/System/Library/PrivateFrameworks/UniversalAccess.framework/Versions/A/Libraries/libUAPreferences.dylib
,这个函数似乎执行CFPreferencesSetValue
并发送{ {1}}。也许只是通知很重要?你可以通过在Xcode / gdb / lldb中的相关函数上放置断点并查看参数是什么来测试它。或者你可以弄清楚如何自己调用CFNotificationCenterPostNotification
(我的第一个猜测是params与UAPreferencesSetValue
相同)。
快速检查:它发送的通知是&#34; UniversalAccessDomainMouseSettingsDidChangeNotification&#34;使用CFPreferencesSetValue
nil
和object
字典(如userInfo
到默认的分布式通知中心,并在更改@{@"mouseDriverCursorSize": @1.8327533, @"pid": @12345}
首选项后自己做同样的事情没有影响。此外,NSUserDefaults
显然采用与UAPreferencesSetValue
不同的参数,因为如果您传递明显的值,则会在CFPreferencesSetValue
内发生崩溃,因此您可能需要在系统中断开调用首选项以查看它发送的内容。
如果你从这个开始就很舒服,那很好。如果没有,在你考虑尝试做这项工作之前,你需要学习很多东西。
另一种解决方法是通过脚本编写。如果您可以让系统偏好设置应用程序执行与鼠标相同的操作,那么您可以设置,对吧?
只要启用了UI脚本(请参阅&#34;启用辅助设备的访问权限&#34;复选框,您已经在系统偏好设置中查看了同一个窗格,或谷歌如何启用它以编程方式关闭(如果您具有root访问权限),通过系统事件,这很乏味,但很容易。
事实上,虽然系统偏好设置没有公开足够的细节来实际更改任何内容,但它 显示足以让我们导航到右侧窗格,这节省了许多UI脚本步骤。所以,这里是AppleScript做你想做的事情:
CFNotificationCenterPostNotification
使用NSAppleScript
从ObjC运行 - 或者,如果您愿意,可以将其翻译为tell application "System Preferences"
reveal anchor "Seeing_Display" of pane id "com.apple.preference.universalaccess"
end tell
tell application "System Events"
set theSlider to slider "Cursor Size:" of group 1 of window 1 of application process "System Preferences"
set stash to value of theSlider
set value of theSlider to 4.0
stash
end tell
,ScriptingBridge
或其他您可以原生运行的内容 - 并且您可以完成。