Skip to content

Commit

Permalink
Preferences: Support window.zoomLevel Preference
Browse files Browse the repository at this point in the history
Fixes eclipse-theia#8751

What it does

- Adds support to specify window zoom level as a preference

How to test

1. Open `Preferences` view and locate the `window.zoomLevel` preference
2. Enter in a custom value or change the zoom level using ctrl + / - / 0
3. Observe that the zoom level preference is updated
4. Reload the window and observe that the preferred zoom level is
   preserved

Signed-off-by: seantan22 <[email protected]>
  • Loading branch information
seantan22 committed Feb 18, 2021
1 parent 4e1c1d4 commit cade160
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .theia/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"editor.tabSize": 2
},
"typescript.tsdk": "node_modules/typescript/lib",
"clang-format.language.typescript.enable": false
"clang-format.language.typescript.enable": false,
"window.zoomLevel": -1
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import {
Command, CommandContribution, CommandRegistry,
isOSX, isWindows, MenuModelRegistry, MenuContribution, Disposable
} from '../../common';
import { KeybindingContribution, KeybindingRegistry } from '../../browser';
import { KeybindingContribution, KeybindingRegistry, PreferenceScope, PreferenceService } from '../../browser';
import { FrontendApplication, FrontendApplicationContribution, CommonMenus } from '../../browser';
import { ElectronMainMenuFactory } from './electron-main-menu-factory';
import { FrontendApplicationStateService, FrontendApplicationState } from '../../browser/frontend-application-state';
import { WindowPreferences } from '../window/window-preferences';

export namespace ElectronCommands {
export const TOGGLE_DEVELOPER_TOOLS: Command = {
Expand Down Expand Up @@ -65,12 +66,21 @@ export namespace ElectronMenus {
export const FILE_CLOSE = [...CommonMenus.FILE_CLOSE, 'window-close'];
}

export const MINIMUM_ZOOM_LEVEL = -8;
export const MAXIMUM_ZOOM_LEVEL = 9;

@injectable()
export class ElectronMenuContribution implements FrontendApplicationContribution, CommandContribution, MenuContribution, KeybindingContribution {

@inject(FrontendApplicationStateService)
protected readonly stateService: FrontendApplicationStateService;

@inject(PreferenceService)
protected readonly preferenceService: PreferenceService;

@inject(WindowPreferences)
protected readonly windowPreferences: WindowPreferences;

constructor(
@inject(ElectronMainMenuFactory) protected readonly factory: ElectronMainMenuFactory
) { }
Expand Down Expand Up @@ -152,19 +162,32 @@ export class ElectronMenuContribution implements FrontendApplicationContribution
});

registry.registerCommand(ElectronCommands.ZOOM_IN, {
execute: () => {
execute: async () => {
const webContents = currentWindow.webContents;
webContents.setZoomLevel(webContents.zoomLevel + 0.5);
let zoomLevel = webContents.zoomLevel + 0.5;
if (zoomLevel > MAXIMUM_ZOOM_LEVEL) {
zoomLevel = MAXIMUM_ZOOM_LEVEL;
return;
};
this.preferenceService.set('window.zoomLevel', zoomLevel, PreferenceScope.User);
}
});
registry.registerCommand(ElectronCommands.ZOOM_OUT, {
execute: () => {
execute: async () => {
const webContents = currentWindow.webContents;
webContents.setZoomLevel(webContents.zoomLevel - 0.5);
let zoomLevel = webContents.zoomLevel - 0.5;
if (zoomLevel < MINIMUM_ZOOM_LEVEL) {
zoomLevel = MINIMUM_ZOOM_LEVEL;
return;
};
this.preferenceService.set('window.zoomLevel', zoomLevel, PreferenceScope.User);
}
});
registry.registerCommand(ElectronCommands.RESET_ZOOM, {
execute: () => currentWindow.webContents.setZoomLevel(0)
execute: async () => {
const zoomLevel = 0;
this.preferenceService.set('window.zoomLevel', zoomLevel, PreferenceScope.User);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import { ElectronClipboardService } from '../electron-clipboard-service';
import { ClipboardService } from '../../browser/clipboard-service';
import { ElectronMainWindowService, electronMainWindowServicePath } from '../../electron-common/electron-main-window-service';
import { ElectronIpcConnectionProvider } from '../messaging/electron-ipc-connection-provider';
import { bindWindowPreferences } from './window-preferences';

export default new ContainerModule(bind => {
bind(ElectronMainWindowService).toDynamicValue(context =>
ElectronIpcConnectionProvider.createProxy(context.container, electronMainWindowServicePath)
).inSingletonScope();
bindWindowPreferences(bind);
bind(WindowService).to(ElectronWindowService).inSingletonScope();
bind(FrontendApplicationContribution).toService(WindowService);
bind(ClipboardService).to(ElectronClipboardService).inSingletonScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import * as electron from 'electron';
import { injectable, inject } from 'inversify';
import { remote } from 'electron';
import { NewWindowOptions } from '../../browser/window/window-service';
import { DefaultWindowService } from '../../browser/window/default-window-service';
import { ElectronMainWindowService } from '../../electron-common/electron-main-window-service';
import { WindowConfiguration, WindowPreferences } from './window-preferences';
import { PreferenceChangeEvent } from '../../browser';

@injectable()
export class ElectronWindowService extends DefaultWindowService {
Expand All @@ -33,9 +36,17 @@ export class ElectronWindowService extends DefaultWindowService {
*/
protected closeOnUnload: boolean = false;

/**
* Do not update window zoom level if preference is unchanged.
*/
protected prevPreferredZoomLevel: number | undefined;

@inject(ElectronMainWindowService)
protected readonly delegate: ElectronMainWindowService;

@inject(WindowPreferences)
protected readonly windowPreferences: WindowPreferences;

openNewWindow(url: string, { external }: NewWindowOptions = {}): undefined {
this.delegate.openNewWindow(url, { external });
return undefined;
Expand Down Expand Up @@ -67,6 +78,14 @@ export class ElectronWindowService extends DefaultWindowService {
return this.preventUnload(event);
}
});

// Update changes to zoom level.
this.updateWindowZoomLevel();
this.windowPreferences.onPreferenceChanged((e: PreferenceChangeEvent<WindowConfiguration>) => {
if (e.preferenceName === 'window.zoomLevel') {
this.updateWindowZoomLevel();
}
});
}

/**
Expand All @@ -85,4 +104,22 @@ export class ElectronWindowService extends DefaultWindowService {
});
return response === 0; // 'Yes', close the window.
}

/**
* Updates the window zoom level based on the amount set in `Preferences`.
*/
protected updateWindowZoomLevel(): void {
const preferredZoomLevel = this.windowPreferences['window.zoomLevel'];
if (this.prevPreferredZoomLevel === preferredZoomLevel) {
return;
}
this.prevPreferredZoomLevel = preferredZoomLevel;

const currentWindow = electron.remote.getCurrentWindow();
const webContents = currentWindow.webContents;

if (webContents.getZoomLevel() !== preferredZoomLevel) {
webContents.setZoomLevel(preferredZoomLevel);
}
}
}
51 changes: 51 additions & 0 deletions packages/core/src/electron-browser/window/window-preferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/********************************************************************************
* Copyright (C) 2021 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { interfaces } from 'inversify';
import { createPreferenceProxy, PreferenceContribution, PreferenceProxy, PreferenceSchema, PreferenceService } from '../../browser/preferences';

export const windowPreferencesSchema: PreferenceSchema = {
type: 'object',
scope: 'application',
properties: {
'window.zoomLevel': {
'type': 'number',
'default': 0,
'minimum': -8,
'maximum': 9,
'description': 'Adjust the zoom level of the window. The original size is 0. Each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller.'
},
}
};

export class WindowConfiguration {
'window.zoomLevel': number;
}

export const WindowPreferences = Symbol('WindowPreferences');
export type WindowPreferences = PreferenceProxy<WindowConfiguration>;

export function createWindowPreferences(preferences: PreferenceService): WindowPreferences {
return createPreferenceProxy(preferences, windowPreferencesSchema);
}

export function bindWindowPreferences(bind: interfaces.Bind): void {
bind(WindowPreferences).toDynamicValue(ctx => {
const preferences = ctx.container.get<PreferenceService>(PreferenceService);
return createWindowPreferences(preferences);
}).inSingletonScope();

bind(PreferenceContribution).toConstantValue({ schema: windowPreferencesSchema });
}
7 changes: 7 additions & 0 deletions packages/vsx-registry/src/browser/workspace.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"folders": [
{
"path": "..\\..\\..\\.."
}
]
}

0 comments on commit cade160

Please sign in to comment.