From 3a70cdfd8f84136e858b3d39e5a709e637fc35e7 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sun, 18 Mar 2018 19:17:42 +0100 Subject: [PATCH] Workaround smooth scroll issues on Windows (#46063) * update to electron 1.7.12 * restore smooth scrolling after restore/maximize * add smoothScrollingWorkaround setting * update relauncher contribution --- src/vs/code/electron-main/window.ts | 66 +++++++++++++++---- src/vs/platform/windows/common/windows.ts | 1 + .../electron-browser/main.contribution.ts | 6 ++ .../relauncher.contribution.ts | 7 ++ 4 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 7ba536117de..dbd4821bea1 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -414,6 +414,34 @@ export class CodeWindow implements ICodeWindow { // Handle Workspace events this.toDispose.push(this.workspacesMainService.onUntitledWorkspaceDeleted(e => this.onUntitledWorkspaceDeleted(e))); + + // TODO@Ben workaround for https://github.com/Microsoft/vscode/issues/13612 + // It looks like smooth scrolling disappears as soon as the window is minimized + // and maximized again. Touching some window properties "fixes" it, like toggling + // the visibility of the menu. + if (isWindows) { + const windowConfig = this.configurationService.getValue('window'); + if (windowConfig && windowConfig.smoothScrollingWorkaround === true) { + let minimized = false; + + const restoreSmoothScrolling = () => { + if (minimized) { + const visibility = this.getMenuBarVisibility(); + const temporaryVisibility: MenuBarVisibility = (visibility === 'hidden' || visibility === 'toggle') ? 'default' : 'hidden'; + setTimeout(() => { + this.doSetMenuBarVisibility(temporaryVisibility); + this.doSetMenuBarVisibility(visibility); + }, 0); + } + + minimized = false; + }; + + this._win.on('minimize', () => minimized = true); + this._win.on('restore', () => restoreSmoothScrolling()); + this._win.on('maximize', () => restoreSmoothScrolling()); + } + } } private onUntitledWorkspaceDeleted(workspace: IWorkspaceIdentifier): void { @@ -797,11 +825,32 @@ export class CodeWindow implements ICodeWindow { return menuBarVisibility; } - public setMenuBarVisibility(visibility: MenuBarVisibility, notify: boolean = true): void { + private setMenuBarVisibility(visibility: MenuBarVisibility, notify: boolean = true): void { if (isMacintosh) { return; // ignore for macOS platform } + if (visibility === 'toggle') { + if (notify) { + this.send('vscode:showInfoMessage', nls.localize('hiddenMenuBar', "You can still access the menu bar by pressing the Alt-key.")); + } + } + + if (visibility === 'hidden') { + // for some weird reason that I have no explanation for, the menu bar is not hiding when calling + // this without timeout (see https://github.com/Microsoft/vscode/issues/19777). there seems to be + // a timing issue with us opening the first window and the menu bar getting created. somehow the + // fact that we want to hide the menu without being able to bring it back via Alt key makes Electron + // still show the menu. Unable to reproduce from a simple Hello World application though... + setTimeout(() => { + this.doSetMenuBarVisibility(visibility); + }); + } else { + this.doSetMenuBarVisibility(visibility); + } + } + + private doSetMenuBarVisibility(visibility: MenuBarVisibility): void { const isFullscreen = this._win.isFullScreen(); switch (visibility) { @@ -818,22 +867,11 @@ export class CodeWindow implements ICodeWindow { case ('toggle'): this._win.setMenuBarVisibility(false); this._win.setAutoHideMenuBar(true); - - if (notify) { - this.send('vscode:showInfoMessage', nls.localize('hiddenMenuBar', "You can still access the menu bar by pressing the Alt-key.")); - } break; case ('hidden'): - // for some weird reason that I have no explanation for, the menu bar is not hiding when calling - // this without timeout (see https://github.com/Microsoft/vscode/issues/19777). there seems to be - // a timing issue with us opening the first window and the menu bar getting created. somehow the - // fact that we want to hide the menu without being able to bring it back via Alt key makes Electron - // still show the menu. Unable to reproduce from a simple Hello World application though... - setTimeout(() => { - this._win.setMenuBarVisibility(false); - this._win.setAutoHideMenuBar(false); - }); + this._win.setMenuBarVisibility(false); + this._win.setAutoHideMenuBar(false); break; } } diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 96616e8f181..909b45d6551 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -224,6 +224,7 @@ export interface IWindowSettings { nativeTabs: boolean; enableMenuBarMnemonics: boolean; closeWhenEmpty: boolean; + smoothScrollingWorkaround: boolean; } export enum OpenContext { diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 6846791700a..87d47096eef 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -406,6 +406,12 @@ configurationRegistry.registerConfiguration({ 'default': false, 'description': nls.localize('window.nativeTabs', "Enables macOS Sierra window tabs. Note that changes require a full restart to apply and that native tabs will disable a custom title bar style if configured."), 'included': isMacintosh && parseFloat(os.release()) >= 16 // Minimum: macOS Sierra (10.12.x = darwin 16.x) + }, + 'window.smoothScrollingWorkaround': { + 'type': 'boolean', + 'default': false, + 'description': nls.localize('window.smoothScrollingWorkaround', "Enable this workaround if scrolling is no longer smooth after restoring a minimized VS Code window. This is a workaround for an issue (https://github.com/Microsoft/vscode/issues/13612) where scrolling starts to lag on devices with precision trackpads like the Surface devices from Microsoft. Enabling this workaround can result in a little bit of layout flickering after restoring the window from minimized state but is otherwise harmless."), + 'included': isWindows } } }); diff --git a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts index cb3d1191eaa..0b63e5adb18 100644 --- a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts @@ -38,6 +38,7 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution { private enableCrashReporter: boolean; private touchbarEnabled: boolean; private treeHorizontalScrolling: boolean; + private windowsSmoothScrollingWorkaround: boolean; private firstFolderResource: URI; private extensionHostRestarter: RunOnceScheduler; @@ -107,6 +108,12 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution { changed = true; } + // Windows: smooth scrolling workaround + if (config.window && typeof config.window.smoothScrollingWorkaround === 'boolean' && config.window.smoothScrollingWorkaround !== this.windowsSmoothScrollingWorkaround) { + this.windowsSmoothScrollingWorkaround = config.window.smoothScrollingWorkaround; + changed = true; + } + // Notify only when changed and we are the focused window (avoids notification spam across windows) if (notify && changed) { this.doConfirm(