Enable minimize to tray on linux in production

This commit is contained in:
trevor-signal 2024-03-14 13:01:40 -04:00 committed by GitHub
parent 2ce23c20ee
commit beee8414a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 81 additions and 48 deletions

View file

@ -21,8 +21,7 @@ export class SystemTraySettingCache {
constructor( constructor(
private readonly ephemeralConfig: Pick<ConfigType, 'get' | 'set'>, private readonly ephemeralConfig: Pick<ConfigType, 'get' | 'set'>,
private readonly argv: Array<string>, private readonly argv: Array<string>
private readonly appVersion: string
) {} ) {}
async get(): Promise<SystemTraySetting> { async get(): Promise<SystemTraySetting> {
@ -53,7 +52,7 @@ export class SystemTraySettingCache {
log.info( log.info(
`getSystemTraySetting saw --use-tray-icon flag. Returning ${result}` `getSystemTraySetting saw --use-tray-icon flag. Returning ${result}`
); );
} else if (isSystemTraySupported(OS, this.appVersion)) { } else if (isSystemTraySupported(OS)) {
const value = this.ephemeralConfig.get('system-tray-setting'); const value = this.ephemeralConfig.get('system-tray-setting');
if (value !== undefined) { if (value !== undefined) {
log.info('getSystemTraySetting got value', value); log.info('getSystemTraySetting got value', value);

View file

@ -84,7 +84,10 @@ import {
shouldMinimizeToSystemTray, shouldMinimizeToSystemTray,
parseSystemTraySetting, parseSystemTraySetting,
} from '../ts/types/SystemTraySetting'; } from '../ts/types/SystemTraySetting';
import { isSystemTraySupported } from '../ts/types/Settings'; import {
getDefaultSystemTraySetting,
isSystemTraySupported,
} from '../ts/types/Settings';
import * as ephemeralConfig from './ephemeral_config'; import * as ephemeralConfig from './ephemeral_config';
import * as logging from '../ts/logging/main_process_logging'; import * as logging from '../ts/logging/main_process_logging';
import { MainSQL } from '../ts/sql/main'; import { MainSQL } from '../ts/sql/main';
@ -396,8 +399,7 @@ const zoomFactorService = new ZoomFactorService({
let systemTrayService: SystemTrayService | undefined; let systemTrayService: SystemTrayService | undefined;
const systemTraySettingCache = new SystemTraySettingCache( const systemTraySettingCache = new SystemTraySettingCache(
ephemeralConfig, ephemeralConfig,
process.argv, process.argv
app.getVersion()
); );
const windowFromUserConfig = userConfig.get('window'); const windowFromUserConfig = userConfig.get('window');
@ -1789,10 +1791,10 @@ app.on('ready', async () => {
// would still show the window. // would still show the window.
// (User can change these settings later) // (User can change these settings later)
if ( if (
isSystemTraySupported(OS, app.getVersion()) && isSystemTraySupported(OS) &&
(await systemTraySettingCache.get()) === SystemTraySetting.Uninitialized (await systemTraySettingCache.get()) === SystemTraySetting.Uninitialized
) { ) {
const newValue = SystemTraySetting.MinimizeToSystemTray; const newValue = getDefaultSystemTraySetting(OS, app.getVersion());
getLogger().info(`app.ready: setting system-tray-setting to ${newValue}`); getLogger().info(`app.ready: setting system-tray-setting to ${newValue}`);
systemTraySettingCache.set(newValue); systemTraySettingCache.set(newValue);

View file

@ -28,21 +28,16 @@ describe('SystemTraySettingCache', () => {
}); });
it('returns MinimizeToAndStartInSystemTray if passed the --start-in-tray argument', async () => { it('returns MinimizeToAndStartInSystemTray if passed the --start-in-tray argument', async () => {
const justOneArg = new SystemTraySettingCache( const justOneArg = new SystemTraySettingCache(config, ['--start-in-tray']);
config,
['--start-in-tray'],
'1.2.3'
);
assert.strictEqual( assert.strictEqual(
await justOneArg.get(), await justOneArg.get(),
SystemTraySetting.MinimizeToAndStartInSystemTray SystemTraySetting.MinimizeToAndStartInSystemTray
); );
const bothArgs = new SystemTraySettingCache( const bothArgs = new SystemTraySettingCache(config, [
config, '--start-in-tray',
['--start-in-tray', '--use-tray-icon'], '--use-tray-icon',
'1.2.3' ]);
);
assert.strictEqual( assert.strictEqual(
await bothArgs.get(), await bothArgs.get(),
SystemTraySetting.MinimizeToAndStartInSystemTray SystemTraySetting.MinimizeToAndStartInSystemTray
@ -53,11 +48,7 @@ describe('SystemTraySettingCache', () => {
}); });
it('returns MinimizeToSystemTray if passed the --use-tray-icon argument', async () => { it('returns MinimizeToSystemTray if passed the --use-tray-icon argument', async () => {
const cache = new SystemTraySettingCache( const cache = new SystemTraySettingCache(config, ['--use-tray-icon']);
config,
['--use-tray-icon'],
'1.2.3'
);
assert.strictEqual( assert.strictEqual(
await cache.get(), await cache.get(),
SystemTraySetting.MinimizeToSystemTray SystemTraySetting.MinimizeToSystemTray
@ -70,7 +61,7 @@ describe('SystemTraySettingCache', () => {
it('returns Uninitialized if system tray is supported but no preference is stored', async () => { it('returns Uninitialized if system tray is supported but no preference is stored', async () => {
sandbox.stub(process, 'platform').value('win32'); sandbox.stub(process, 'platform').value('win32');
const cache = new SystemTraySettingCache(config, [], '1.2.3'); const cache = new SystemTraySettingCache(config, []);
assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized); assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized);
assert(configGetStub.calledOnceWith('system-tray-setting')); assert(configGetStub.calledOnceWith('system-tray-setting'));
assert( assert(
@ -86,7 +77,7 @@ describe('SystemTraySettingCache', () => {
configGetStub.returns('garbage'); configGetStub.returns('garbage');
const cache = new SystemTraySettingCache(config, [], '1.2.3'); const cache = new SystemTraySettingCache(config, []);
assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized); assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized);
assert(configGetStub.calledOnceWith('system-tray-setting')); assert(configGetStub.calledOnceWith('system-tray-setting'));
assert( assert(
@ -102,7 +93,7 @@ describe('SystemTraySettingCache', () => {
configGetStub.returns('MinimizeToSystemTray'); configGetStub.returns('MinimizeToSystemTray');
const cache = new SystemTraySettingCache(config, [], '1.2.3'); const cache = new SystemTraySettingCache(config, []);
assert.strictEqual( assert.strictEqual(
await cache.get(), await cache.get(),
SystemTraySetting.MinimizeToSystemTray SystemTraySetting.MinimizeToSystemTray
@ -113,7 +104,7 @@ describe('SystemTraySettingCache', () => {
it('returns DoNotUseSystemTray if system tray is unsupported and there are no CLI flags', async () => { it('returns DoNotUseSystemTray if system tray is unsupported and there are no CLI flags', async () => {
sandbox.stub(process, 'platform').value('darwin'); sandbox.stub(process, 'platform').value('darwin');
const cache = new SystemTraySettingCache(config, [], '1.2.3'); const cache = new SystemTraySettingCache(config, []);
assert.strictEqual(await cache.get(), SystemTraySetting.DoNotUseSystemTray); assert.strictEqual(await cache.get(), SystemTraySetting.DoNotUseSystemTray);
sinon.assert.notCalled(configGetStub); sinon.assert.notCalled(configGetStub);

View file

@ -7,6 +7,7 @@ import { assert } from 'chai';
import { getOSFunctions } from '../../util/os/shared'; import { getOSFunctions } from '../../util/os/shared';
import * as Settings from '../../types/Settings'; import * as Settings from '../../types/Settings';
import { SystemTraySetting } from '../../types/SystemTraySetting';
describe('Settings', () => { describe('Settings', () => {
let sandbox: Sinon.SinonSandbox; let sandbox: Sinon.SinonSandbox;
@ -128,26 +129,59 @@ describe('Settings', () => {
it('returns false on macOS', () => { it('returns false on macOS', () => {
sandbox.stub(process, 'platform').value('darwin'); sandbox.stub(process, 'platform').value('darwin');
const OS = getOSFunctions(os.release()); const OS = getOSFunctions(os.release());
assert.isFalse(Settings.isSystemTraySupported(OS, '1.2.3')); assert.isFalse(Settings.isSystemTraySupported(OS));
}); });
it('returns true on Windows 8', () => { it('returns true on Windows 8', () => {
sandbox.stub(process, 'platform').value('win32'); sandbox.stub(process, 'platform').value('win32');
sandbox.stub(os, 'release').returns('8.0.0'); sandbox.stub(os, 'release').returns('8.0.0');
const OS = getOSFunctions(os.release()); const OS = getOSFunctions(os.release());
assert.isTrue(Settings.isSystemTraySupported(OS, '1.2.3')); assert.isTrue(Settings.isSystemTraySupported(OS));
}); });
it('returns false on Linux production', () => { it('returns true on Linux', () => {
sandbox.stub(process, 'platform').value('linux'); sandbox.stub(process, 'platform').value('linux');
const OS = getOSFunctions(os.release()); const OS = getOSFunctions(os.release());
assert.isFalse(Settings.isSystemTraySupported(OS, '1.2.3')); assert.isTrue(Settings.isSystemTraySupported(OS));
});
});
describe('getDefaultSystemTraySetting', () => {
it('returns DoNotUseSystemTray is unsupported OS', () => {
sandbox.stub(process, 'platform').value('darwin');
const OS = getOSFunctions(os.release());
assert.strictEqual(
Settings.getDefaultSystemTraySetting(OS, '1.2.3'),
SystemTraySetting.DoNotUseSystemTray
);
}); });
it('returns true on Linux beta', () => { it('returns MinimizeToSystemTray on Windows 8', () => {
sandbox.stub(process, 'platform').value('win32');
sandbox.stub(os, 'release').returns('8.0.0');
const OS = getOSFunctions(os.release());
assert.strictEqual(
Settings.getDefaultSystemTraySetting(OS, '1.2.3'),
SystemTraySetting.MinimizeToSystemTray
);
});
it('returns MinimizeToSystemTray on Linux Beta', () => {
sandbox.stub(process, 'platform').value('linux'); sandbox.stub(process, 'platform').value('linux');
const OS = getOSFunctions(os.release()); const OS = getOSFunctions(os.release());
assert.isTrue(Settings.isSystemTraySupported(OS, '1.2.3-beta.4')); assert.strictEqual(
Settings.getDefaultSystemTraySetting(OS, '1.2.3-beta.1'),
SystemTraySetting.MinimizeToSystemTray
);
});
it('returns DoNotUseSystemTray on Linux Prod', () => {
sandbox.stub(process, 'platform').value('linux');
const OS = getOSFunctions(os.release());
assert.strictEqual(
Settings.getDefaultSystemTraySetting(OS, '1.2.3'),
SystemTraySetting.DoNotUseSystemTray
);
}); });
}); });
}); });

View file

@ -4,6 +4,7 @@
import semver from 'semver'; import semver from 'semver';
import type { OSType } from '../util/os/shared'; import type { OSType } from '../util/os/shared';
import { SystemTraySetting } from './SystemTraySetting';
import { isProduction } from '../util/version'; import { isProduction } from '../util/version';
const MIN_WINDOWS_VERSION = '8.0.0'; const MIN_WINDOWS_VERSION = '8.0.0';
@ -29,19 +30,31 @@ export const isDrawAttentionSupported = (OS: OSType): boolean => !OS.isMacOS();
* Returns `true` if you can minimize the app to the system tray. Users can override this * Returns `true` if you can minimize the app to the system tray. Users can override this
* option with a command line flag, but that is not officially supported. * option with a command line flag, but that is not officially supported.
*/ */
export const isSystemTraySupported = ( export const isSystemTraySupported = (OS: OSType): boolean =>
OS.isWindows() || OS.isLinux();
export const getDefaultSystemTraySetting = (
OS: OSType, OS: OSType,
appVersion: string appVersion: string
): boolean => ): SystemTraySetting => {
// We eventually want to support Linux in production. if (!isSystemTraySupported(OS)) {
OS.isWindows() || (OS.isLinux() && !isProduction(appVersion)); return SystemTraySetting.DoNotUseSystemTray;
}
// System tray on linux may not be well supported, so we default to it being off in
// production
if (OS.isLinux() && isProduction(appVersion)) {
return SystemTraySetting.DoNotUseSystemTray;
}
return SystemTraySetting.MinimizeToSystemTray;
};
// On Windows minimize and start in system tray is default when app is selected // On Windows minimize and start in system tray is default when app is selected
// to launch at login, because we can provide `['--start-in-tray']` args. // to launch at login, because we can provide `['--start-in-tray']` args.
export const isMinimizeToAndStartInSystemTraySupported = ( export const isMinimizeToAndStartInSystemTraySupported = (
OS: OSType, OS: OSType
appVersion: string ): boolean => !OS.isWindows() && isSystemTraySupported(OS);
): boolean => !OS.isWindows() && isSystemTraySupported(OS, appVersion);
export const isAutoDownloadUpdatesSupported = (OS: OSType): boolean => export const isAutoDownloadUpdatesSupported = (OS: OSType): boolean =>
OS.isWindows() || OS.isMacOS(); OS.isWindows() || OS.isMacOS();

View file

@ -310,15 +310,9 @@ async function renderPreferences() {
isHideMenuBarSupported: Settings.isHideMenuBarSupported(OS), isHideMenuBarSupported: Settings.isHideMenuBarSupported(OS),
isNotificationAttentionSupported: Settings.isDrawAttentionSupported(OS), isNotificationAttentionSupported: Settings.isDrawAttentionSupported(OS),
isSyncSupported: !isSyncNotSupported, isSyncSupported: !isSyncNotSupported,
isSystemTraySupported: Settings.isSystemTraySupported( isSystemTraySupported: Settings.isSystemTraySupported(OS),
OS,
MinimalSignalContext.getVersion()
),
isMinimizeToAndStartInSystemTraySupported: isMinimizeToAndStartInSystemTraySupported:
Settings.isMinimizeToAndStartInSystemTraySupported( Settings.isMinimizeToAndStartInSystemTraySupported(OS),
OS,
MinimalSignalContext.getVersion()
),
// Change handlers // Change handlers
onAudioNotificationsChange: attachRenderCallback( onAudioNotificationsChange: attachRenderCallback(