2017-05-06 99 views
0

我試圖讓我的應用程序調用隱藏,當用戶試圖通過紅色按鈕關閉最後一個窗口。區分NSWindow close和Multiple-Tab-NSWindow關閉嗎?

注意:下面提到的選項卡是sierra自動切換功能的一部分。

我知道我可以用NSApplication.shared().hide()來隱藏應用程序,但是我只想在用戶試圖關閉最後一個打開的窗口(也就是說關閉所有窗口的紅色按鈕的時候這樣做) )。但是,我想允許選項卡上的關閉按鈕正常執行,並關閉選項卡。

到目前爲止,API關閉和窗口關閉在API中看起來完全相同,我很難實現我想要的行爲。有沒有辦法通過它的紅色關閉按鈕或其關閉按鈕確定是否關閉?

+0

當用戶試圖關閉最後一個窗口時不要調用隱藏。關閉按鈕應該關閉,而不是隱藏。關閉最後一個窗口後關閉,或者關閉最後一個窗口,或在應用程序不是最前面的應用程序時隱藏窗口。 – Willeke

+0

Finder的行爲讓我受到了一點啓發。如果在最後一個查找器窗口中有多個選項卡,關閉並重新打開該窗口似乎不會影響重新打開的選項卡。但是,在頁面和Safari中,所有標籤在關閉時都會丟失....唉! – orion

+0

當我關閉窗口時,Finder不會隱藏自己。它保持活躍和最前端的應用程序。 Finder在激活時會恢復一個窗口。你如何在Finder中重新打開一個窗口? – Willeke

回答

0

免責聲明:

  • 我只用斯威夫特/可可工作了幾個星期。
  • 這可能是一個更好的方法。

所以我找不到一個簡單的方法來做到這一點。我的實現背後的想法是在窗口關閉時調用一個去抖動函數。由於單擊角落中的「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 
    } 
}