1

OmniFocus 有一个 Cocoa 服务,允许您根据所选项目创建任务。

它有一个首选项,允许您设置触发服务的键盘快捷键。这不仅仅是一个全局热键,它是显示在菜单中的真正服务。

您可以使用键盘快捷键进行几乎任何组合,包括与 ⌥ 和 ^ 的组合。此功能未记录 -文档似乎说 KeyEquivalents 必须是⌘+[⇧]+someKey.

一旦设置好,我观察到三件事:

  1. OmniFocus Info.plist 文件不包含列出的 KeyEquivalent。这并不奇怪,因为该文件是只读的。
  2. pbs -dump_pboard 实用程序列出NSKeyEquivalent = {};该服务。
  3. 使用 NSDebugServices 列出了这个有趣的行,它不会出现在大多数调试会话中(显然,对于键盘快捷键⌃⌥⌘M):OmniFocus: Send to Inbox (com.omnigroup.OmniFocus) has a custom key equivalent: <NSKeyboardShortcut: 0x7fb18a0d18f0 (⌃⌥⌘M)>.

所以我的问题是双重的,我怀疑它们是相关的:

  1. 如何动态更改服务的 KeyEquivalent?
  2. 如何将 KeyEquivalent 设置为包含 ⌃ 和 ⌥</li> 的组合

谢谢!

4

1 回答 1

2

弄清楚了。这里描述了基本过程:Register NSService with Command Alt NSKeyEquivalent

代码是这样的:

//Bundle identifier from Info.plist
NSString* bundleIdentifier = @"com.whatever.MyApp";
//Services -> Menu -> Menu item title from Info.plist
NSString* appServiceName = @"Launch My Service";
//Services -> Instance method name from Info.plist
NSString* methodNameForService = @"myServiceMethod";

//The key equivalent
NSString* keyEquivalent = @"@~r";

CFStringRef serviceStatusName = (CFStringRef)[NSString stringWithFormat:@"%@ - %@ - %@", bundleIdentifier, appServiceName, methodNameForService];
CFStringRef serviceStatusRoot =  CFSTR("NSServicesStatus");
CFPropertyListRef pbsAllServices = (CFPropertyListRef) CFMakeCollectable ( CFPreferencesCopyAppValue(serviceStatusRoot, CFSTR("pbs")) );
// the user did not configure any custom services
BOOL otherServicesDefined = pbsAllServices != NULL;
BOOL ourServiceDefined = NO;
if ( otherServicesDefined ) {
    ourServiceDefined = NULL != CFDictionaryGetValue((CFDictionaryRef)pbsAllServices, serviceStatusName);
}

NSUpdateDynamicServices();
NSMutableDictionary *pbsAllServicesNew = nil;
if (otherServicesDefined) {
    pbsAllServicesNew = [NSMutableDictionary dictionaryWithDictionary:(NSDictionary*)pbsAllServices];
} else {
   pbsAllServicesNew = [NSMutableDictionary dictionaryWithCapacity:1];
}

NSDictionary *serviceStatus = [NSDictionary dictionaryWithObjectsAndKeys:
                               (id)kCFBooleanTrue, @"enabled_context_menu", 
                               (id)kCFBooleanTrue, @"enabled_services_menu", 
                               keyEquivalent, @"key_equivalent", nil];
[pbsAllServicesNew setObject:serviceStatus forKey:(NSString*)serviceStatusName];
CFPreferencesSetAppValue (
                          serviceStatusRoot,
                          (CFPropertyListRef) pbsAllServicesNew,
                          CFSTR("pbs"));
Boolean result = CFPreferencesAppSynchronize(CFSTR("pbs"));
if (result) {
    NSUpdateDynamicServices();
    NSLog(@"successfully installed our alt-command-r service");
} else {
    NSLog(@"couldn't install our alt-command-r service");
}

如果代码成功,您可以在~/Library/Preferences/pbs.plist

您应该会看到如下内容:

NSServicesStatus = {
    "com.whatever.MyApp - Launch My Service - myServiceMethod" = {
        enabled_context_menu = :true;
        enabled_services_menu = :true;
        key_equivalent = "@~r";
    };
于 2013-09-13T16:04:30.437 回答