2017-05-06 3 views
0

ユーザーが最後のウィンドウを赤いボタンで閉じようとしたときにアプリケーション呼び出しを非表示にしようとしています。NSWindow closeとMultiple-Tab-NSWindow closeを区別しますか?

注:下記のタブは、sierra自動タブ機能の一部です。

私はNSApplication.shared().hide()でアプリケーションを非表示にすることができますが、ユーザーが最後に開いているウィンドウを閉じることを試みた場合のみ(このウィンドウのすべてのタブを閉じる赤いボタンを意味します)。しかし、私は、タブ上のクローズボタンが正常に実行され、タブを閉じることを許可します。

これまでのところ、タブクロージャとウィンドウクロージャはAPIで同じように見えますが、私が望む動作を達成するのは苦労しています。赤い閉じるボタンまたはタブの閉じるボタンで閉じているかどうかを判断する方法はありますか?

+0

最後のウィンドウを閉じるときにhideを呼び出さないでください。閉じるボタンは非表示にする必要があります。最後のウィンドウを閉じた後に終了するか、最後のウィンドウを閉じることを無効にするか、またはアプリケーションが最前面のアプリケーションでないときにウィンドウを非表示にします。 – 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に入れなければなりませんでした。window.tabbedWindowsnilです。

    class WindowController: NSWindowController { 
        var closeDebouncer = TWCDebouncer() 
    
        func windowShouldClose(_ sender: NSWindow) -> Bool { 
         self.closeDebouncer.handleClose(window: self.window!) 
         return true 
        } 
    }