You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Swift macOS开发:如何让窗口始终置顶并阻止后台应用获取焦点?

解决Mac Swift应用窗口始终置顶且阻止焦点窃取的问题

嘿,作为Mac开发新手碰到这个需求太正常了!你之前的代码确实能在窗口失去激活时把它拉回顶层,但还是会给后台应用短暂获取焦点的机会——这是因为applicationDidResignActive是在应用已经失去焦点后才触发的,中间会有个时间差。下面给你一套完整的解决方案:

1. 提升窗口层级,确保始终置顶

首先得让你的窗口稳稳站在所有普通窗口之上,我们可以设置它的level为浮动窗口层级(如果怕被其他浮动窗口盖住,还可以用更高层级):

applicationDidFinishLaunching里添加配置:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    guard let window = window else { return }
    
    // 设置窗口为浮动层级,确保在普通窗口上方
    window.level = .floatingWindowLevel
    // 可选:如果要压过其他浮动窗口,用更高层级
    // window.level = NSWindow.Level.mainMenuWindowLevel + 1
    
    // 让窗口成为主窗口并强制显示
    window.makeKeyAndOrderFront(nil)
    // 立即激活应用
    NSApp.activate(ignoringOtherApps: true)
}

2. 阻止应用被隐藏

默认情况下,用户按Command+H或者点击Dock里的其他应用,你的应用会被隐藏,我们直接禁用这个行为:

func applicationShouldHide(_ sender: NSApplication) -> Bool {
    // 返回false,禁止应用被隐藏
    return false
}

3. 提前拦截焦点丢失,不给后台应用机会

把之前的applicationDidResignActive换成applicationWillResignActive——在应用即将失去焦点时就立即重新激活,彻底堵死后台应用抢焦点的可能:

func applicationWillResignActive(_ notification: Notification) {
    DispatchQueue.main.async {
        // 重新激活应用
        NSApp.activate(ignoringOtherApps: true)
        // 确保窗口保持在最前面并成为主窗口
        self.window?.makeKeyAndOrderFront(nil)
    }
}

4. 可选:让窗口在所有桌面空间都显示

如果希望切换桌面空间时窗口也能保持置顶,给窗口加这个配置:

window.collectionBehavior = .canJoinAllSpaces

这样组合下来,你的窗口就会死死钉在最顶层,用户点击窗口外区域时,应用会瞬间重新激活,后台应用根本没机会拿到焦点,完美实现你的需求!

内容的提问来源于stack exchange,提问作者Julian Cimentarow

火山引擎 最新活动