macOS Cocoa应用调用NSApp.activate()后无法激活并获取焦点的问题求助
macOS Cocoa应用调用NSApp.activate()后无法激活并获取焦点的问题求助
我最近做了个简单的Cocoa小应用,需求是通过键盘快捷键把应用窗口调到前台并让它获取焦点,但折腾了好久都没搞定,想请教下大家怎么解决。
先贴下我的代码:
import Cocoa import HotKey class ViewController: NSViewController { let hotKey = HotKey(key: .s, modifiers: .option) override func viewDidLoad() { super.viewDidLoad() hotKey.keyUpHandler = { self.show() } } @objc func show(){ NSApp.activate() view.window?.orderFrontRegardless() DispatchQueue.main.async { self.view.window?.makeKey() } } } class CustomWindow: NSWindow { override var canBecomeKey: Bool { true } override var canBecomeMain: Bool { true } }
我用Option + S这个快捷键测试,现在的问题是:按快捷键确实能把应用窗口带到前台,但窗口并没有真正获取焦点——标题栏不是激活状态的高亮样式,macOS顶部菜单栏还停留在之前活跃的应用上,只有我手动点击窗口标题栏或者窗口内容区域,应用才会真正激活,菜单栏也切换过来。
我本来以为下面这段代码能同时激活应用并让窗口获取焦点,但完全没用:
NSApp.activate() view.window?.orderFrontRegardless() DispatchQueue.main.async { self.view.window?.makeKey() }
后来我还尝试了这些办法,都没解决:
- 子类化NSWindow(就是上面的CustomWindow),把
canBecomeKey和canBecomeMain都设为true,并且在Storyboard里把窗口指定为这个子类,结果没有任何变化 - 修改
show()方法成下面这样,结果连窗口都调不到前台了:
@objc func show(){ print("show: \(view.window)") NSApp.activate(ignoringOtherApps: true) view.window?.makeKeyAndOrderFront(nil) }
- 加了300ms的延迟再调用窗口激活方法,打印
window.isKeyWindow始终返回false:
@objc func show(){ print("show") NSApp.activate(ignoringOtherApps: true) DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) { guard let window = self.view.window else { return } window.makeKeyAndOrderFront(window) print("window: \(window.isKeyWindow)") // 这里一直打印false } }
我的系统是macOS Sequoia 15.5,有没有遇到过类似问题的朋友,能告诉我怎么才能让快捷键触发后,应用窗口自动获取焦点、菜单栏也切换过来吗?
内容来源于stack exchange
相关产品推荐
相关产品推荐

