diff --git a/src/common/config/defaultPreferences.ts b/src/common/config/defaultPreferences.ts index 63f982d6..d38ef279 100644 --- a/src/common/config/defaultPreferences.ts +++ b/src/common/config/defaultPreferences.ts @@ -36,6 +36,7 @@ const defaultPreferences: ConfigV3 = { darkMode: false, lastActiveTeam: 0, downloadLocation: getDefaultDownloadLocation(), + startInFullscreen: false, }; export default defaultPreferences; diff --git a/src/common/config/index.ts b/src/common/config/index.ts index 6dc71603..f6d4ec96 100644 --- a/src/common/config/index.ts +++ b/src/common/config/index.ts @@ -252,6 +252,10 @@ export class Config extends EventEmitter { get enableHardwareAcceleration() { return this.combinedData?.enableHardwareAcceleration ?? defaultPreferences.enableHardwareAcceleration; } + + get startInFullscreen() { + return this.combinedData?.startInFullscreen ?? defaultPreferences.startInFullscreen; + } get enableServerManagement() { return this.combinedData?.enableServerManagement ?? buildConfig.enableServerManagement; } diff --git a/src/common/config/upgradePreferences.test.js b/src/common/config/upgradePreferences.test.js index d36aa7d2..3dc8d378 100644 --- a/src/common/config/upgradePreferences.test.js +++ b/src/common/config/upgradePreferences.test.js @@ -99,6 +99,7 @@ describe('common/config/upgradePreferences', () => { showUnreadBadge: false, useSpellChecker: false, enableHardwareAcceleration: false, + startInFullscreen: false, autostart: false, hideOnStart: false, spellCheckerLocale: 'en-CA', diff --git a/src/common/config/upgradePreferences.ts b/src/common/config/upgradePreferences.ts index 6ad1cd00..a51260c4 100644 --- a/src/common/config/upgradePreferences.ts +++ b/src/common/config/upgradePreferences.ts @@ -44,6 +44,7 @@ export function upgradeV2toV3(configV2: ConfigV2) { }); config.lastActiveTeam = 0; config.spellCheckerLocales = []; + config.startInFullscreen = false; return config; } diff --git a/src/main/ParseArgs.ts b/src/main/ParseArgs.ts index 03a70bee..8602f23b 100644 --- a/src/main/ParseArgs.ts +++ b/src/main/ParseArgs.ts @@ -29,6 +29,7 @@ function parseArgs(args: string[]) { alias('dataDir', 'd').string('dataDir').describe('dataDir', 'Set the path to where user data is stored.'). alias('disableDevMode', 'p').boolean('disableDevMode').describe('disableDevMode', 'Disable development mode. Allows for testing as if it was Production.'). alias('version', 'v').boolean('version').describe('version', 'Prints the application version.'). + alias('fullscreen', 'f').boolean('fullscreen').describe('fullscreen', 'Opens the application in fullscreen mode.'). help('help'). parse(args); } diff --git a/src/main/Validator.test.js b/src/main/Validator.test.js index 74f2ab21..665144f3 100644 --- a/src/main/Validator.test.js +++ b/src/main/Validator.test.js @@ -130,6 +130,7 @@ describe('main/Validator', () => { hideOnStart: false, darkMode: false, enableHardwareAcceleration: true, + startInFullscreen: false, lastActiveTeam: 0, minimizeToTray: false, showTrayIcon: false, diff --git a/src/main/Validator.ts b/src/main/Validator.ts index 7fbfd397..cb3275db 100644 --- a/src/main/Validator.ts +++ b/src/main/Validator.ts @@ -27,6 +27,7 @@ const argsSchema = Joi.object({ disableDevMode: Joi.boolean(), dataDir: Joi.string(), version: Joi.boolean(), + fullscreen: Joi.boolean(), }); const boundsInfoSchema = Joi.object({ @@ -118,6 +119,7 @@ const configDataSchemaV3 = Joi.object({ showUnreadBadge: Joi.boolean().default(true), useSpellChecker: Joi.boolean().default(true), enableHardwareAcceleration: Joi.boolean().default(true), + startInFullscreen: Joi.boolean().default(false), autostart: Joi.boolean().default(true), hideOnStart: Joi.boolean().default(false), spellCheckerLocales: Joi.array().items(Joi.string()).default([]), diff --git a/src/main/windows/mainWindow.test.js b/src/main/windows/mainWindow.test.js index 3b3d174e..3483768d 100644 --- a/src/main/windows/mainWindow.test.js +++ b/src/main/windows/mainWindow.test.js @@ -124,6 +124,13 @@ describe('main/windows/mainWindow', () => { })); }); + it('should open in fullscreen if fullscreen set to true', () => { + createMainWindow({fullscreen: true}); + expect(BrowserWindow).toHaveBeenCalledWith(expect.objectContaining({ + fullscreen: true, + })); + }); + it('should set default window size when failing to read bounds from file', () => { fs.readFileSync.mockImplementation(() => 'just a bunch of garbage'); createMainWindow({}); diff --git a/src/main/windows/mainWindow.ts b/src/main/windows/mainWindow.ts index aff159c9..3b82fe8a 100644 --- a/src/main/windows/mainWindow.ts +++ b/src/main/windows/mainWindow.ts @@ -43,10 +43,10 @@ function isFramelessWindow() { return os.platform() === 'darwin' || (os.platform() === 'win32' && Utils.isVersionGreaterThanOrEqualTo(os.release(), '6.2')); } -function createMainWindow(options: {linuxAppIcon: string}) { +function createMainWindow(options: {linuxAppIcon: string; fullscreen?: boolean}) { // Create the browser window. const preload = getLocalPreload('mainWindow.js'); - let savedWindowState; + let savedWindowState: any; try { savedWindowState = JSON.parse(fs.readFileSync(boundsInfoPath, 'utf-8')); savedWindowState = Validator.validateBoundsInfo(savedWindowState); @@ -65,6 +65,16 @@ function createMainWindow(options: {linuxAppIcon: string}) { const {maximized: windowIsMaximized} = savedWindowState; const spellcheck = (typeof Config.useSpellChecker === 'undefined' ? true : Config.useSpellChecker); + const isFullScreen = () => { + if (global?.args?.fullscreen !== undefined) { + return global.args.fullscreen; + } + + if (Config.startInFullscreen) { + return Config.startInFullscreen; + } + return options.fullscreen || savedWindowState.fullscreen || false; + }; const windowOptions: BrowserWindowConstructorOptions = Object.assign({}, savedWindowState, { title: app.name, @@ -74,7 +84,7 @@ function createMainWindow(options: {linuxAppIcon: string}) { minWidth: MINIMUM_WINDOW_WIDTH, minHeight: MINIMUM_WINDOW_HEIGHT, frame: !isFramelessWindow(), - fullscreen: savedWindowState.fullscreen, + fullscreen: isFullScreen(), titleBarStyle: 'hidden' as const, trafficLightPosition: {x: 12, y: 12}, backgroundColor: '#fff', // prevents blurry text: https://electronjs.org/docs/faq#the-font-looks-blurry-what-is-this-and-what-can-i-do diff --git a/src/renderer/components/SettingsPage.tsx b/src/renderer/components/SettingsPage.tsx index 3afc690c..86fb8940 100644 --- a/src/renderer/components/SettingsPage.tsx +++ b/src/renderer/components/SettingsPage.tsx @@ -68,8 +68,10 @@ export default class SettingsPage extends React.PureComponent; spellCheckerURLRef: React.RefObject; enableHardwareAccelerationRef: React.RefObject; + startInFullscreenRef: React.RefObject; autoCheckForUpdatesRef: React.RefObject; + saveQueue: SaveQueueItem[]; selectedSpellCheckerLocales: Array<{label: string; value: string}>; @@ -99,6 +101,7 @@ export default class SettingsPage extends React.PureComponent { + window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_APP_OPTIONS, {key: 'startInFullscreen', data: this.startInFullscreenRef.current?.checked}); + this.setState({ + startInFullscreen: this.startInFullscreenRef.current?.checked, + }); + } + saveDownloadLocation = (location: string) => { if (!location) { return; @@ -747,6 +757,24 @@ export default class SettingsPage extends React.PureComponent, ); + options.push( + + + {'Open app in fullscreen'} + + {'If enabled, the Mattermost application will always open in full screen'} + + , + ); + options.push(