2016-10-09 36 views
8

Jakiś czas temu napisałem prosty widget paska menu kalendarza o nazwie Day-O. Kalendarz używa zapasowego NSDatePicker zagnieżdżonego wewnątrz NSView wewnątrz NSMenuItem w NSMenu dodanym do NSStatusItem. Aplikacja ma aktywacjęPolicy z .accessory (pierwotnie ustawioną za pomocą bool'a "Application is agent" plista). W pewnym momencie (może przy aktualizacji El Capitan?) Kalendarz przestał odpowiadać na dane wejściowe. Po pierwszym uruchomieniu aplikacji możesz kliknąć element paska stanu, aby rozwinąć menu i wejść w interakcję z kalendarzem, a następnie odpowiedzieć zgodnie z oczekiwaniami. Ale gdy aplikacja straci początkowy fokus, kalendarz przestaje odpowiadać na dane wejściowe.NSDatePicker w NSStatusBar NSSMenuItem nie otrzymuje danych wejściowych

Wydaje mi się, że udało mi się zidentyfikować problem, ponieważ aplikacja nie aktywowała się po początkowej rezygnacji z aktywności. Problem polega na tym, że jeśli spróbuję ręcznie aktywować aplikację po kliknięciu elementu paska menu (za pomocą NSApp.activate(ignoringOtherApps:true)), menu (właśnie otworzyłeś) zostanie odrzucone.

Próbowałem także powiedzieć okno, aby NSDatePicker był pierwszym reagującym, ale to też nie ma żadnego efektu.

Jak uzyskać NSDatePicker w elemencie menu, aby akceptować dane wprowadzane przez użytkownika, gdy aplikacja paska stanu nie jest aktywną aplikacją?


Edit: Najprostszy kod do zilustrowania problemu (dodaj to do AppDelegate w nowym MacOS Cocoa aplikacji):

let statusItem = NSStatusBar.system().statusItem(withLength:NSVariableStatusItemLength) 
func applicationDidFinishLaunching(_ aNotification: Notification) { 
    NSApp.setActivationPolicy(.accessory) 

    statusItem.button?.title = "Calendar" 

    let menu = NSMenu() 
    let item = NSMenuItem() 
    let picker = NSDatePicker(frame: NSRect(x: 0, y: 0, width: 140, height: 148)) 
    picker.datePickerStyle = .clockAndCalendarDatePickerStyle 

    item.view = picker 
    menu.addItem(item) 

    statusItem.menu = menu 
} 

Uruchom aplikację, kliknij pozycję menu, a następnie kliknij ok kalendarz. Następnie kliknij inną aplikację, a następnie ponownie kliknij element menu. Kalendarz nie reaguje już na kliknięcia.

+0

Teraz zastanawiam się, czy niższy poziom API "kliknięć zdarzeń" pozwoli mi przechwycić wejście myszy zanim dotrze do elementu statusu, więc mogę aktywować aplikację, zanim otworzy menu ... –

Odpowiedz

5

Twój NSDatePicker musi zwrócić "acceptsFirstMouse" jako prawdziwy, który jest tylko do odczytu, więc będziesz to robić w podklasie.

Działa w projekcie testowym z uruchomionym kodem.