cocoa - 使用命令 Alt NSKeyEquivalent 注册 NSService

标签 cocoa

我的应用程序提供全局服务。我想使用命令-alt-键组合来安装该服务。我现在做的事情不太容易出错,而且很难调试,因为我并没有真正看到发生了什么:

inside Info.plist:
 <key>NSServices</key>
 <array>
  <dict>
   <key>NSSendTypes</key>
   <array>
    <string></string>
   </array>
   <key>NSReturnTypes</key>
   <array>
    <string></string>
   </array>
   <key>NSMenuItem</key>
   <dict>
    <key>default</key>
    <string>Go To Window in ${PRODUCT_NAME}</string>
   </dict>
   <key>NSMessage</key>
   <string>bringZFToForegroundZoomOut</string>
   <key>NSPortName</key>
   <string>com.raskinformac.${PRODUCT_NAME:identifier}</string>
  </dict>
 </array>

并在代码中:

CFStringRef serviceStatusName = (CFStringRef)[NSString stringWithFormat:@"%@ - %@ - %@", appIdentifier, appName, 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", 
                               @"@~r", @"key_equivalent", nil];
[pbsAllServicesNew setObject:serviceStatus forKey:(NSString*)serviceStatusName];
CFPreferencesSetAppValue (
                          serviceStatusRoot,
                          (CFPropertyListRef) pbsAllServicesNew,
                          CFSTR("pbs"));
Boolean result = CFPreferencesAppSynchronize(CFSTR("pbs"));
if (result) {
    NSUpdateDynamicServices();
    JLog(@"successfully installed our alt-command-R service");
} else {
    ALog(@"couldn't install our alt-command-R service");
}

并更改服务:

// once installed, its's a bit tricky to set new ones (works only in RELEASE somehow?)
// quit finder
// open "~/Library/Preferences/pbs.plist" and remove ch.ana.Zoom - Reveal Window in Zoom - bringZFToForegroundZoomOut inside NSServicesStatus and save
// start app
// /System/Library/CoreServices/pbs -dump_pboard (to see if it hat actually done what we wanted, might be empty)
// /System/Library/CoreServices/pbs  (to add the new services)
// /System/Library/CoreServices/pbs -dump_pboard  (see new linking)
// and then /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder  -NSDebugServices MY.APP.IDENTIFIER  to restart finder

所以我的问题:是否有更简单的方法来使用 cmd-option-key 启用服务?如果是,我很乐意在我的软件中实现它。

最佳答案

您可以尝试仅将 key 等效字符串设置为“~”作为服务字典中 NSKeyEquivalent 的值。 Services Implementation Guide声称它必须是单个字符,但我认为值得尝试完整的 key 等效字符串。

请记住,与 NSMenuItem 一样,它必须包装在字典中:

<key>NSKeyEquivalent</key>
<dict>
    <key>default</key>
    <string>~r</string>
</dict>

(我省略了“@”;如果没有它不起作用,你可以尝试使用它。)

如果它确实有效,我建议 filing a bug反对文档。

Apple 可能希望所有服务都使用 ⌘-something 或 ⇧⌘-something 键等效键,为菜单项和全局热键保留其他修饰符。因此,虽然我会尝试上述方法,但如果它不起作用,我也不会感到太惊讶。

关于cocoa - 使用命令 Alt NSKeyEquivalent 注册 NSService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2845070/

相关文章:

ios - 如何在 cocoa 中获得图像的作者

objective-c - NSManagedObject子类和xcdatamodeld文件之间有什么关系?

objective-c - 如何选择要在我的 Cocoa 应用程序中使用的网络接口(interface)

objective-c - 如何在Cocoa中获取包含音乐(mp3)的所有文件夹路径?

swift 3 .all 已弃用 - 拖放 nstableview

objective-c - NSTextView 黄色突出显示像在 safari 搜索中

cocoa - 如何在 Cocoa 应用程序中获取删除的邮件消息数据?

objective-c - 如何使用 RXCollections 展平嵌套 NSArray

objective-c - NSArray 提取项目

ios - 如何让textureFromNode生成视网膜显示的纹理?