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.
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 ... –