summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/main/index.ts57
-rw-r--r--gui/src/main/window-controller.ts50
2 files changed, 67 insertions, 40 deletions
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index 29baab992a..5e3b28b342 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -1937,34 +1937,43 @@ class ApplicationMain {
}
private installTrayClickHandlers() {
- if (this.guiSettings.unpinnedWindow) {
- if (process.platform === 'win32' || process.platform === 'darwin') {
- this.tray?.on('right-click', () =>
+ switch (process.platform) {
+ case 'win32':
+ if (this.guiSettings.unpinnedWindow) {
// This needs to be executed on click since if it is added to the tray icon it will be
// displayed on left click as well.
- this.tray?.popUpContextMenu(this.createTrayContextMenu()),
- );
- }
- this.tray?.on('click', () => this.windowController?.show());
- } else {
- this.tray?.on('click', (event) => {
- // The app shouldn't become visible if the user is reordering the tray icons on macOS. The
- // tray icon becomes draggable when holding the command key (meta).
- if (process.platform !== 'darwin' || !event.metaKey) {
- const isMacOsBigSur = process.platform === 'darwin' && parseInt(os.release(), 10) >= 20;
- if (isMacOsBigSur && !this.windowController?.isVisible()) {
- // This is a workaround for this Electron issue, when it's resolved
- // `this.windowController?.toggle()` should do the trick on all platforms:
- // https://github.com/electron/electron/issues/28776
- const contextMenu = Menu.buildFromTemplate([]);
- contextMenu.on('menu-will-show', () => this.windowController?.show());
- this.tray?.popUpContextMenu(contextMenu);
+ this.tray?.on('right-click', () =>
+ this.tray?.popUpContextMenu(this.createTrayContextMenu()),
+ );
+ this.tray?.on('click', () => this.windowController?.show());
+ } else {
+ this.tray?.on('right-click', () => this.windowController?.hide());
+ this.tray?.on('click', () => this.windowController?.toggle());
+ }
+ break;
+ case 'darwin':
+ this.tray?.on('right-click', () => this.windowController?.hide());
+ this.tray?.on('click', (event) => {
+ if (event.metaKey) {
+ setImmediate(() => this.windowController?.updatePosition());
} else {
- this.windowController?.toggle();
+ const isBigSurOrNewer = parseInt(os.release(), 10) >= 20;
+ if (isBigSurOrNewer && !this.windowController?.isVisible()) {
+ // This is a workaround for this Electron issue, when it's resolved
+ // `this.windowController?.toggle()` should do the trick on all platforms:
+ // https://github.com/electron/electron/issues/28776
+ const contextMenu = Menu.buildFromTemplate([]);
+ contextMenu.on('menu-will-show', () => this.windowController?.show());
+ this.tray?.popUpContextMenu(contextMenu);
+ } else {
+ this.windowController?.toggle();
+ }
}
- }
- });
- this.tray?.on('right-click', () => this.windowController?.hide());
+ });
+ break;
+ case 'linux':
+ this.tray?.on('click', () => this.windowController?.show());
+ break;
}
}
diff --git a/gui/src/main/window-controller.ts b/gui/src/main/window-controller.ts
index 298f767fb5..c7ab18b5f7 100644
--- a/gui/src/main/window-controller.ts
+++ b/gui/src/main/window-controller.ts
@@ -1,6 +1,7 @@
import { BrowserWindow, Display, screen, Tray, WebContents } from 'electron';
import { IpcMainEventChannel } from './ipc-event-channel';
import { IWindowShapeParameters } from '../shared/ipc-types';
+import { Scheduler } from '../shared/scheduler';
interface IPosition {
x: number;
@@ -134,6 +135,8 @@ export default class WindowController {
private webContentsValue: WebContents;
private windowPositioning: IWindowPositioning;
+ private windowPositioningScheduler = new Scheduler();
+
get window(): BrowserWindow | undefined {
return this.windowValue.isDestroyed() ? undefined : this.windowValue;
}
@@ -153,21 +156,25 @@ export default class WindowController {
: new AttachedToTrayWindowPositioning(tray);
this.installDisplayMetricsHandler();
+ this.installHideHandler();
}
- public replaceWindow(window: BrowserWindow, unpinnedWindow: boolean) {
- this.window?.removeAllListeners();
+ public replaceWindow(windowValue: BrowserWindow, unpinnedWindow: boolean) {
this.window?.destroy();
- this.windowValue = window;
- this.webContentsValue = window.webContents;
+ const [width, height] = windowValue.getSize();
+ this.width = width;
+ this.height = height;
+ this.windowValue = windowValue;
+ this.webContentsValue = windowValue.webContents;
this.windowPositioning = unpinnedWindow
? new StandaloneWindowPositioning()
: new AttachedToTrayWindowPositioning(this.tray);
+ this.installDisplayMetricsHandler();
+ this.installHideHandler();
this.updatePosition();
- this.notifyUpdateWindowShape();
}
public show(whenReady = true) {
@@ -194,6 +201,20 @@ export default class WindowController {
return this.window?.isVisible() ?? false;
}
+ public updatePosition() {
+ if (this.window) {
+ const { x, y } = this.windowPositioning.getPosition(this.window);
+ this.window.setPosition(x, y, false);
+ }
+
+ this.notifyUpdateWindowShape();
+ }
+
+ private installHideHandler() {
+ this.window?.addListener('hide', () => this.windowPositioningScheduler.cancel());
+ this.window?.addListener('closed', () => this.windowPositioningScheduler.cancel());
+ }
+
private showImmediately() {
const window = this.window;
@@ -209,23 +230,14 @@ export default class WindowController {
window?.focus();
this.updatePosition();
- this.notifyUpdateWindowShape();
} else {
this.updatePosition();
- this.notifyUpdateWindowShape();
window?.show();
window?.focus();
}
}
- private updatePosition() {
- if (this.window) {
- const { x, y } = this.windowPositioning.getPosition(this.window);
- this.window.setPosition(x, y, false);
- }
- }
-
private notifyUpdateWindowShape() {
if (this.window) {
const shapeParameters = this.windowPositioning.getWindowShapeParameters(this.window);
@@ -251,8 +263,10 @@ export default class WindowController {
changedMetrics: string[],
) => {
if (changedMetrics.includes('workArea') && this.window?.isVisible()) {
- this.updatePosition();
- this.notifyUpdateWindowShape();
+ this.onWorkAreaSizeChange();
+ if (process.platform === 'win32') {
+ this.windowPositioningScheduler.schedule(() => this.onWorkAreaSizeChange(), 500);
+ }
}
// On linux, the window won't be properly rescaled back to it's original
@@ -263,6 +277,10 @@ export default class WindowController {
}
};
+ private onWorkAreaSizeChange() {
+ this.updatePosition();
+ }
+
private forceResizeWindow() {
this.window?.setSize(this.width, this.height);
}