Сохранение 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;

Но независимо от нажатия, он автоматически подсвечивает значок и выключает подсветку мыши сразу после вызова моего метода.

В принципе:

  1. Нежелательное автоматическое выделение NSStatusBarButton мешает ручной настройке состояния подсветки, если я не откладываю ручную настройку, что вызывает короткое мерцание.
  2. Единственное, что, по-видимому, успешно отключает это автоматическое поведение, является устаревшим setHighlightMode:, но это, кажется, мешает подсветке, ручной или нет.
  3. Похоже, единственное решение состоит в том, чтобы добавить подпредставление к 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 в моем блоке обработчика это предотвратило передачу события, поэтому автоматическое выделение никогда не происходит, и я могу сделать это вручную.


Если есть какие-либо ошибки, связанные с этим, я буду признателен за любой совет.

Другие вопросы по тегам