Avoid calling tray.destroy() when quitting

This commit is contained in:
Fedor Indutny 2022-01-24 16:18:53 -08:00 committed by GitHub
parent dff941adc7
commit 3aa488c3d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 3 deletions

View file

@ -7,6 +7,13 @@ import { Menu, Tray, app, nativeImage } from 'electron';
import * as log from '../ts/logging/log';
import type { LocaleMessagesType } from '../ts/types/I18N';
export type SystemTrayServiceOptionsType = Readonly<{
messages: LocaleMessagesType;
// For testing
createTrayInstance?: (icon: NativeImage) => Tray;
}>;
/**
* A class that manages an [Electron `Tray` instance][0]. It's responsible for creating
* and destroying a `Tray`, and listening to the associated `BrowserWindow`'s visibility
@ -23,14 +30,19 @@ export class SystemTrayService {
private isEnabled = false;
private isQuitting = false;
private unreadCount = 0;
private boundRender: typeof SystemTrayService.prototype.render;
constructor({ messages }: Readonly<{ messages: LocaleMessagesType }>) {
private createTrayInstance: (icon: NativeImage) => Tray;
constructor({ messages, createTrayInstance }: SystemTrayServiceOptionsType) {
log.info('System tray service: created');
this.messages = messages;
this.boundRender = this.render.bind(this);
this.createTrayInstance = createTrayInstance || (icon => new Tray(icon));
}
/**
@ -92,6 +104,19 @@ export class SystemTrayService {
this.render();
}
/**
* Workaround for: https://github.com/electron/electron/issues/32581#issuecomment-1020359931
*
* Tray is automatically destroyed when app quits so we shouldn't destroy it
* twice when all windows will close.
*/
markShouldQuit(): void {
log.info('System tray service: markShouldQuit');
this.tray = undefined;
this.isQuitting = true;
}
private render(): void {
if (this.isEnabled && this.browserWindow) {
this.renderEnabled();
@ -101,6 +126,11 @@ export class SystemTrayService {
}
private renderEnabled() {
if (this.isQuitting) {
log.info('System tray service: not rendering the tray, quitting');
return;
}
log.info('System tray service: rendering the tray');
this.tray = this.tray || this.createTray();
@ -177,7 +207,7 @@ export class SystemTrayService {
log.info('System tray service: creating the tray');
// This icon may be swiftly overwritten.
const result = new Tray(getDefaultIcon());
const result = this.createTrayInstance(getDefaultIcon());
// Note: "When app indicator is used on Linux, the click event is ignored." This
// doesn't mean that the click event is always ignored on Linux; it depends on how