在创建 main window 后添加 NSTouchBar 支持

Adding NSTouchBar support after main window has been created

我正在尝试添加对通过插件向我无法修改的应用程序公开 NSTouchBar 按钮的支持。该插件是一个共享库,在主 window 创建后在运行时加载。我创建了一个 AppDelegate 如下:

@interface AppDelegate : NSResponder <NSTouchBarDelegate>
@end

使用实现 makeTouchBartouchBar 函数的 @implmentation

- (NSTouchBar *) makeTouchBar
- (nullable NSTouchBarItem *) touchBar:(NSTouchBar *)touchBar
                       makeItemForIdentifier: (NSTouchBarItemIdentifier)identifier

我终于尝试将它注入到应用程序中,我在 onload 函数中有以下内容,当它加载到应用程序中时,动态库中会调用该函数。

NSWindow *w = [NSApp mainWindow];

AppDelegate *a = [[AppDelegate alloc] init];
a.nextResponder = w.nextResponder;
w.nextResponder = a;

// Re-setting FirstResponder will trigger AppDelegate::makeTouchBar
// that was attached above.
NSResponder *n = w.firstResponder;
[w makeFirstResponder: nil];
[w makeFirstResponder: n];

但是...AppDelegate::touchBar 永远不会被调用,因此触摸栏永远不会填充我的测试按钮。

如果我在 Xcode 中创建一个新项目,并使用完全相同的 AppDelegate 实现(复制粘贴相同的 @interface@implementation),我获取既显示又响应按下事件的功能按钮,因此似乎是注入部分坏了。 (在 Xcode 中,我猜一切都是通过 MainMenu.xib 连接起来的)

更新: 主要问题是应用程序的编译方式阻止了 TouchBar 的工作。也许建立在 Mac OS.

的旧版本之上

如果这个对象真的应该充当应用程序委托(顾名思义)——而不是将它插入主 window 的响应者链中,最好将它实际设置为NSApp 的 delegate。 set delegate 的 touchBar 在构建 touch bar 时也会用到(见NSTouchBar Discovery and the Responder Chain)。

如果这对你的插件不起作用(也许应用程序已经有它需要的特定应用委托),你可以将它插入 NSApp 的响应链而不是 mainWindow

这两者还具有使触摸条在应用程序级别而不是 window 关联的好处。因此,如果 main/key window 更改,将始终使用提供的触摸栏。