区分NSWindow close和Multiple-Tab-NSWindow关闭?

时间:2017-05-06 01:09:22

标签: cocoa nswindow macos-sierra appkit

当用户尝试通过红色按钮关闭最后一个窗口时,我试图让我的应用程序调用隐藏。

注意:下面提到的标签是sierra自动标签功能的一部分。

我知道我可以使用analyze -v隐藏应用程序,但是,我只想在用户尝试关闭最后一个打开的窗口(意味着关闭的红色按钮)时执行此操作该窗口的所有选项卡)。但是,我想允许选项卡上的关闭按钮正常执行,并关闭选项卡。

到目前为止,标签封闭和窗口关闭在API中看起来相同,我很难实现我想要的行为。有没有办法通过红色关闭按钮或其标签关闭按钮确定是否正在关闭?

1 个答案:

答案 0 :(得分:0)

声明:

  • 我只与Swift / Cocoa合作了几个星期。
  • 这可能是一种更好的方法。

所以我找不到一个简单的方法来做到这一点。我的实现背后的想法是在窗口关闭时调用去抖动函数。由于单击角落中的“X”会关闭所有窗口,因此在完成所有操作后,去抖动将允许您调用一次函数。

还有一些其他的东西:你必须在选项卡中缓存窗口数量。你必须保持一个关闭的窗口列表。

但最后,您可以区分:

  • 关闭窗口中的多个标签(“关闭其他标签”)
  • 关闭窗口中的单个标签
  • 关闭整个标签窗口
  • 关闭不带标签的窗口

无论如何,这是我的实施。您需要debounce from here

// Stands for TabbedWindowCloseDebouncer
class TWCDebouncer {
    private static var Debouncers = [NSWindowTabGroup: () -> Void]()
    private static var TabStartCounts = [NSWindowTabGroup: Int]()
    private static var Windows = [NSWindowTabGroup: [NSWindow]]()
    private static var LastTabGroup: NSWindowTabGroup?

    func handleClose(window: NSWindow) {
        // This handles a window without tabs.
        // Check presence in Debouncers, otherwise it will also catch the last
        // window of a tabbed window closing.
        if window.tabbedWindows == nil && TWCDebouncer.Debouncers[window.tabGroup!] == nil {
            // You can consider this to be the same as closing a whole window.
            return
        }

        // This could probably lead to problems.
        TWCDebouncer.LastTabGroup = window.tabGroup

        // Store the initial tab count.
        if TWCDebouncer.TabStartCounts[TWCDebouncer.LastTabGroup!] == nil {
            TWCDebouncer.TabStartCounts[TWCDebouncer.LastTabGroup!] = window.tabbedWindows?.count
        }

        // Initialize the list of windows closing.
        if TWCDebouncer.Windows[TWCDebouncer.LastTabGroup!] == nil {
            TWCDebouncer.Windows[TWCDebouncer.LastTabGroup!] = []
        }

        // Set up the debounced function.
        if TWCDebouncer.Debouncers[TWCDebouncer.LastTabGroup!] == nil {
            TWCDebouncer.Debouncers[TWCDebouncer.LastTabGroup!] = debounce(delay: .milliseconds(20), action: {
                let countAfter = TWCDebouncer.LastTabGroup?.windows.count ?? 0

                print(TWCDebouncer.Windows[TWCDebouncer.LastTabGroup!])
                if countAfter == 0 {
                    // All windows were closed.
                } else {
                    // One or more windows were closed in the tab group
                }

                // Reset.
                TWCDebouncer.Debouncers[TWCDebouncer.LastTabGroup!] = nil
                TWCDebouncer.TabStartCounts[TWCDebouncer.LastTabGroup!] = nil
                TWCDebouncer.Windows[TWCDebouncer.LastTabGroup!] = nil
                TWCDebouncer.LastTabGroup = nil
            })
        }

        // Store the window.
        TWCDebouncer.Windows[TWCDebouncer.LastTabGroup!]?.append(window)
        // Call the debounced function.
        TWCDebouncer.Debouncers[window.tabGroup!]!()
    }
}

要使用它,我已将它放在我的WindowController上。我必须将其放入windowShouldClose,当windowWillClose被调用时,window.tabbedWindowsnil

class WindowController: NSWindowController {
    var closeDebouncer = TWCDebouncer()

    func windowShouldClose(_ sender: NSWindow) -> Bool {
        self.closeDebouncer.handleClose(window: self.window!)
        return true
    }
}
相关问题