Подтвердить что ты не робот

Как сделать события кликов на электронном лотке надежными?

В моем приложении OSX Electron у меня есть значок в трее, который я бы хотел переключить между открытием и закрытием окна приложения Electron. Подобно тому, как щелчок по значку в окне Dropbox OSX откроет и закроет меню Dropbox, независимо от того, как быстро вы нажимаете значок в трее.

Вот код, который я использую:

  tray.on('click', function(e){
    if (mainWindow.isVisible()) {
      mainWindow.hide()
    } else {
      mainWindow.show()
    }
  });

Это работает, если вы щелкаете медленно (подождите секунду между щелчками), однако, если вы нажимаете повторно, более 1 раза в секунду, клик не выполняется, и ничего не происходит. Я не мог найти каких-либо задержек в документах. Любые идеи о том, что происходит и как сделать событие click надежно?

4b9b3361

Ответ 1

Проблема, которую вы описываете, легко воспроизвести. Результат, который вы получаете, не является ошибкой или неправильной реализацией на вашей стороне, но это ожидаемый результат относительно текущего способа, которым Electron обрабатывает эти события щелчка в элементе лотка.

Класс Tray предоставляет 3 события относительно щелчка: click, double-click и right-click.

Если вы используете событие right-click, у вас не будет этой проблемы, вы можете щелкнуть так быстро, как хотите, вы будете каждый раз вызывать обратный вызов.

Электронный код для macOS, например для обработки этого события, следующий:

- (void)rightMouseUp:(NSEvent*)event {
  trayIcon_->NotifyRightClicked(
    [self getBoundsFromEvent:event],
    ui::EventFlagsFromModifiers([event modifierFlags]));
}

Для каждого щелчка правой кнопкой мыши они запускают событие right-click и его.

Теперь, если мы посмотрим, как обрабатывается левый клик, код немного отличается:

- (void)mouseUp:(NSEvent*)event {

  // ...
  // Truncated to only show the relevant part...
  // ...

  // Single click event.
  if (event.clickCount == 1)
    trayIcon_->NotifyClicked(
        [self getBoundsFromEvent:event],
        ui::EventFlagsFromModifiers([event modifierFlags]));

  // Double click event.
  if (event.clickCount == 2)
    trayIcon_->NotifyDoubleClicked(
        [self getBoundsFromEvent:event],
        ui::EventFlagsFromModifiers([event modifierFlags]));

  [self setNeedsDisplay:YES];
}

При многократном нажатии значка в трее, event.clickCount не всегда возвращает 1. Вместо этого он возвращает значение, которое подсчитывает время щелчка.

Итак, когда вы щелкаете значок в трее очень быстро, event.clickCount будет иметь значение больше, чем 2, и они будут излучать только событие, когда значение 1 или 2, и если оно не в случае, они не имеют никакого резерва, они просто не излучают никакого события. Это результат, который вы видите в своих тестах при достаточно быстром нажатии.

Поэтому, не изменяя сама реализация Electron, отправляя проблему или запрос на pull, вы не можете в данный момент избежать этого поведения.

Ответ 2

Electron 3.0 представил API, который предотвращает ожидание двойного щелчка.

// Ignore double click events for the tray icon
tray.setIgnoreDoubleClickEvents(true)

"Устанавливает опцию игнорирования событий двойного щелчка. Игнорирование этих событий позволяет обнаруживать каждый отдельный щелчок значка в трее. Это значение по умолчанию установлено в false".

Связанные документы | Замечания к выпуску Electron 3.0