diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/assets/images/taskbar/win32/display.ico | bin | 0 -> 101249 bytes | |||
-rw-r--r-- | src/config.js | 7 | ||||
-rw-r--r-- | src/electron/windowUtils.js | 11 | ||||
-rw-r--r-- | src/index.js | 47 |
4 files changed, 59 insertions, 6 deletions
diff --git a/src/assets/images/taskbar/win32/display.ico b/src/assets/images/taskbar/win32/display.ico new file mode 100644 index 000000000..4f4670a85 --- /dev/null +++ b/src/assets/images/taskbar/win32/display.ico | |||
Binary files differ | |||
diff --git a/src/config.js b/src/config.js index ba3af14b9..d981f9c6a 100644 --- a/src/config.js +++ b/src/config.js | |||
@@ -39,6 +39,13 @@ export const DEFAULT_FEATURES_CONFIG = { | |||
39 | isServiceProxyPremiumFeature: true, | 39 | isServiceProxyPremiumFeature: true, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | export const DEFAULT_WINDOW_OPTIONS = { | ||
43 | width: 800, | ||
44 | height: 600, | ||
45 | x: 0, | ||
46 | y: 0, | ||
47 | }; | ||
48 | |||
42 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-plugin-docs'; | 49 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-plugin-docs'; |
43 | export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate'; | 50 | export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate'; |
44 | 51 | ||
diff --git a/src/electron/windowUtils.js b/src/electron/windowUtils.js new file mode 100644 index 000000000..23b946ac4 --- /dev/null +++ b/src/electron/windowUtils.js | |||
@@ -0,0 +1,11 @@ | |||
1 | /* eslint import/prefer-default-export: 0 */ | ||
2 | |||
3 | import { screen } from 'electron'; | ||
4 | |||
5 | export function isPositionValid(position) { | ||
6 | const displays = screen.getAllDisplays(); | ||
7 | const { x, y } = position; | ||
8 | return displays.some(({ | ||
9 | workArea, | ||
10 | }) => x >= workArea.x && x <= workArea.x + workArea.width && y >= workArea.y && y <= workArea.y + workArea.height); | ||
11 | } | ||
diff --git a/src/index.js b/src/index.js index 37c553840..7f3fe5b44 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -15,10 +15,14 @@ import ipcApi from './electron/ipc-api'; | |||
15 | import Tray from './lib/Tray'; | 15 | import Tray from './lib/Tray'; |
16 | import Settings from './electron/Settings'; | 16 | import Settings from './electron/Settings'; |
17 | import handleDeepLink from './electron/deepLinking'; | 17 | import handleDeepLink from './electron/deepLinking'; |
18 | import { isPositionValid } from './electron/windowUtils'; | ||
18 | import { appId } from './package.json'; // eslint-disable-line import/no-unresolved | 19 | import { appId } from './package.json'; // eslint-disable-line import/no-unresolved |
19 | import './electron/exception'; | 20 | import './electron/exception'; |
20 | 21 | ||
21 | import { DEFAULT_APP_SETTINGS } from './config'; | 22 | import { |
23 | DEFAULT_APP_SETTINGS, | ||
24 | DEFAULT_WINDOW_OPTIONS, | ||
25 | } from './config'; | ||
22 | /* eslint-enable import/first */ | 26 | /* eslint-enable import/first */ |
23 | 27 | ||
24 | const debug = require('debug')('Franz:App'); | 28 | const debug = require('debug')('Franz:App'); |
@@ -52,6 +56,15 @@ const isSecondInstance = app.makeSingleInstance((argv) => { | |||
52 | } | 56 | } |
53 | } | 57 | } |
54 | } | 58 | } |
59 | |||
60 | if (argv.includes('--reset-window')) { | ||
61 | // Needs to be delayed to not interfere with mainWindow.restore(); | ||
62 | setTimeout(() => { | ||
63 | debug('Resetting windows via Task'); | ||
64 | mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100); | ||
65 | mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height); | ||
66 | }, 1); | ||
67 | } | ||
55 | }); | 68 | }); |
56 | 69 | ||
57 | if (isSecondInstance) { | 70 | if (isSecondInstance) { |
@@ -78,14 +91,23 @@ if (!settings.get('enableGPUAcceleration')) { | |||
78 | const createWindow = () => { | 91 | const createWindow = () => { |
79 | // Remember window size | 92 | // Remember window size |
80 | const mainWindowState = windowStateKeeper({ | 93 | const mainWindowState = windowStateKeeper({ |
81 | defaultWidth: 800, | 94 | defaultWidth: DEFAULT_WINDOW_OPTIONS.width, |
82 | defaultHeight: 600, | 95 | defaultHeight: DEFAULT_WINDOW_OPTIONS.height, |
83 | }); | 96 | }); |
84 | 97 | ||
98 | let posX = mainWindowState.x || DEFAULT_WINDOW_OPTIONS.x; | ||
99 | let posY = mainWindowState.y || DEFAULT_WINDOW_OPTIONS.y; | ||
100 | |||
101 | if (!isPositionValid({ x: posX, y: posY })) { | ||
102 | debug('Window is out of screen bounds, resetting window'); | ||
103 | posX = DEFAULT_WINDOW_OPTIONS.x; | ||
104 | posY = DEFAULT_WINDOW_OPTIONS.y; | ||
105 | } | ||
106 | |||
85 | // Create the browser window. | 107 | // Create the browser window. |
86 | mainWindow = new BrowserWindow({ | 108 | mainWindow = new BrowserWindow({ |
87 | x: mainWindowState.x, | 109 | x: posX, |
88 | y: mainWindowState.y, | 110 | y: posY, |
89 | width: mainWindowState.width, | 111 | width: mainWindowState.width, |
90 | height: mainWindowState.height, | 112 | height: mainWindowState.height, |
91 | minWidth: 600, | 113 | minWidth: 600, |
@@ -187,7 +209,20 @@ const createWindow = () => { | |||
187 | // This method will be called when Electron has finished | 209 | // This method will be called when Electron has finished |
188 | // initialization and is ready to create browser windows. | 210 | // initialization and is ready to create browser windows. |
189 | // Some APIs can only be used after this event occurs. | 211 | // Some APIs can only be used after this event occurs. |
190 | app.on('ready', createWindow); | 212 | app.on('ready', () => { |
213 | if (process.platform === 'win32') { | ||
214 | app.setUserTasks([{ | ||
215 | program: process.execPath, | ||
216 | arguments: `${isDevMode ? `${__dirname} ` : ''}--reset-window`, | ||
217 | iconPath: path.join(`${__dirname}`, '../src/assets/images/taskbar/win32/display.ico'), | ||
218 | iconIndex: 0, | ||
219 | title: 'Move Franz to Current Display', | ||
220 | description: 'Restore the position and size of Franz', | ||
221 | }]); | ||
222 | } | ||
223 | |||
224 | createWindow(); | ||
225 | }); | ||
191 | 226 | ||
192 | // This is the worst possible implementation as the webview.webContents based callback doesn't work 🖕 | 227 | // This is the worst possible implementation as the webview.webContents based callback doesn't work 🖕 |
193 | app.on('login', (event, webContents, request, authInfo, callback) => { | 228 | app.on('login', (event, webContents, request, authInfo, callback) => { |