Adding NSTouchBar support after main window has been created

安稳与你 提交于 2019-12-24 01:12:31

问题


I'm trying to add support for exposing NSTouchBar buttons via a plugin to an application that I cannot otherwise modify. The plugin, a shared library, is loaded at runtime after the main window has been created. I've created an AppDelegate as follows:

@interface AppDelegate : NSResponder <NSTouchBarDelegate>
@end

With an @implmentation that implements the makeTouchBar and touchBar functions:

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

I finally try to inject it into the application, I have the following in the onload function that's called in the dynamic library when it's loaded into the application.

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];

however... AppDelegate::touchBar will never be called, thus the touchbar will never be populated with my test buttons.

If I create a new project in Xcode, and use the exact same AppDelegate implementation (copy-paste of the same @interface and @implementation), I get functional buttons that are both shown and responds to press events, so it's the injection part that seems to be broken. (In Xcode everything is hooked up via MainMenu.xib I guess)

Update: The main problem was that the application was compiled in a way that prevented TouchBar to work. Perhaps built on an older version of Mac OS.


回答1:


If this object really should act as the application delegate (as the name suggests) -- rather than inserting it in the main window's responder chain, it would be better to actually set it as the NSApp's delegate. The set delegate's touchBar is also used when building the touch bar (see NSTouchBar Discovery and the Responder Chain).

If that doesn't work for your plugin (maybe the application already has a specific app delegate it needs), you could insert it into NSApp's responder chain instead of the mainWindow's.

Both of these also have the benefit of making the touch bar be associated at the application level rather than window. So if the main/key window changes, the provided touch bar will always be used.



来源:https://stackoverflow.com/questions/41383194/adding-nstouchbar-support-after-main-window-has-been-created

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!