Сохранение NSStatusBarButton выделенным, пока отображается поповер
Практически все NSStatusItem
устарел для 10.10 и поведение базового NSStatusBarButton
кажется, сбивает с толку.
В настоящее время я работаю над приложением панели меню. Когда пользователь щелкает значок строки меню для приложения, метод в моем делегате приложения вызывается с помощью target-action, который отображает NSPopover (или закрывает его, если он уже виден) с некоторой информацией.
Обычно, если вы связали, скажем, NSMenu с NSStatusItem, когда пользователь нажимает на значок строки меню, этот значок остается подсвеченным синим до закрытия меню. Аналогичным образом, щелкнув значок системного тома, выскочит ползунок и выделит его синим цветом, пока вид, содержащий ползунок, не исчезнет.
Однако, поскольку я открываю NSPopover, система вместо этого подсвечивает значок синим цветом при нажатии мыши вниз, а затем возвращает его в нормальное состояние при нажатии мыши вверх после вызова моего метода. Это означает, что я ничего не могу сделать в этом цикле, чтобы сохранить основной момент. Я хочу, чтобы значок продолжал выделяться при наведении курсора мыши и возвращался к нормальному состоянию только тогда, когда я говорю об этом (т.е. когда я закрываю свой поповер).
Я понятия не имею, как это сделать. Я пытался использовать
[self.statusItem.button setHighlighted: YES];
//or [self.statusItem.button highlight: YES];
когда я получаю событие мыши в делегате приложения и открываю всплывающее окно. Проблема в том, что система все еще имеет его, по-видимому, подсвечивавший этот кадр / цикл от более ранней мыши вниз, и сразу же после того, как я установил его подсвеченным, он устанавливает его невыделенным из-за поднятия мыши. Я могу обойти это, инкапсулировав это в метод и запустив метод с использованием таймера или отложенного селектора через доли секунды. Это позволяет мне держать значок выделенным, но добавляет мерцание; значок подсвечивается автоматически, когда мышь опускается, когда мышь поднимается, она не выделяет ее для кадра, а затем мой метод снова выделяет ее.
Я также подумал, что я мог бы использовать устаревший setHighlightMode:
и установите его NO
для предотвращения автоматического выделения значка при нажатии, а затем с помощью setHighlighted: / highlighted:
установить его вручную, но это тоже не работает. Точно так же я подумал, может быть, это будет работать так же:
NSButtonCell* cell = (NSButtonCell*)self.statusItem.button.cell;
cell.highlightsBy = NSNoCellMask;
Но независимо от нажатия, он автоматически подсвечивает значок и выключает подсветку мыши сразу после вызова моего метода.
В принципе:
- Нежелательное автоматическое выделение
NSStatusBarButton
мешает ручной настройке состояния подсветки, если я не откладываю ручную настройку, что вызывает короткое мерцание.- Единственное, что, по-видимому, успешно отключает это автоматическое поведение, является устаревшим
setHighlightMode:
, но это, кажется, мешает подсветке, ручной или нет.- Похоже, единственное решение состоит в том, чтобы добавить подпредставление к NSButtonCell, добавить прослушиватель событий для мыши, а затем установить состояние подсветки суперпредставления, как показано здесь: NSStatusBarButton выделите, но я думаю, что был бы более простой способ просто... вообще отключить автоматическое выделение.
tl; dr: Есть ли способ для меня легко получить полный контроль над тем, когда и когда не выделен значок строки меню, чтобы я мог выделять ее естественным образом, пока отображается мой NSPopover?
1 ответ
Я решил это, не устанавливая NSStatusItem
свойство селектора действия. Вместо этого я использовал NSEvent
"s addLocalMonitorForEventsMatchingMask:handler:
, В блоке обработчика я проверяю event.locationInWindow
в моем статусе .bounds
, Если это так, я отправляю сообщение .action
придется вручную, а затем вернуть nil
чтобы предотвратить передачу события. Если это не в пределах значка статуса, я возвращаюсь event
так что это передается нормально. В моем методе обработки кликов я использую [self.statusItem.button highlight: YES/NO]
когда мой поповер отображается / закрывается.
TL; DR:
В applicationDidFinishLaunching:
__block AppDelegate* appDelegate = self;
[NSEvent addLocalMonitorForEventsMatchingMask: NSEventMaskFromType(NSLeftMouseDown) handler:^NSEvent* (NSEvent* event){
if (NSPointInRect(event.locationInWindow, appDelegate.statusItem.button.bounds)){
[appDelegate clickedMenuBarIcon: event];
return nil;
}
return event;
}];
В clickedMenuBarIcon:
Затем я могу установить состояние выделения. С тех пор как я вернулся nil
в моем блоке обработчика это предотвратило передачу события, поэтому автоматическое выделение никогда не происходит, и я могу сделать это вручную.
Если есть какие-либо ошибки, связанные с этим, я буду признателен за любой совет.