Skip to content

Commit 3a70cdf

Browse files
authored
Workaround smooth scroll issues on Windows (microsoft#46063)
* update to electron 1.7.12 * restore smooth scrolling after restore/maximize * add smoothScrollingWorkaround setting * update relauncher contribution
1 parent 24ae207 commit 3a70cdf

4 files changed

Lines changed: 66 additions & 14 deletions

File tree

src/vs/code/electron-main/window.ts

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,34 @@ export class CodeWindow implements ICodeWindow {
414414

415415
// Handle Workspace events
416416
this.toDispose.push(this.workspacesMainService.onUntitledWorkspaceDeleted(e => this.onUntitledWorkspaceDeleted(e)));
417+
418+
// TODO@Ben workaround for https://github.com/Microsoft/vscode/issues/13612
419+
// It looks like smooth scrolling disappears as soon as the window is minimized
420+
// and maximized again. Touching some window properties "fixes" it, like toggling
421+
// the visibility of the menu.
422+
if (isWindows) {
423+
const windowConfig = this.configurationService.getValue<IWindowSettings>('window');
424+
if (windowConfig && windowConfig.smoothScrollingWorkaround === true) {
425+
let minimized = false;
426+
427+
const restoreSmoothScrolling = () => {
428+
if (minimized) {
429+
const visibility = this.getMenuBarVisibility();
430+
const temporaryVisibility: MenuBarVisibility = (visibility === 'hidden' || visibility === 'toggle') ? 'default' : 'hidden';
431+
setTimeout(() => {
432+
this.doSetMenuBarVisibility(temporaryVisibility);
433+
this.doSetMenuBarVisibility(visibility);
434+
}, 0);
435+
}
436+
437+
minimized = false;
438+
};
439+
440+
this._win.on('minimize', () => minimized = true);
441+
this._win.on('restore', () => restoreSmoothScrolling());
442+
this._win.on('maximize', () => restoreSmoothScrolling());
443+
}
444+
}
417445
}
418446

419447
private onUntitledWorkspaceDeleted(workspace: IWorkspaceIdentifier): void {
@@ -797,11 +825,32 @@ export class CodeWindow implements ICodeWindow {
797825
return menuBarVisibility;
798826
}
799827

800-
public setMenuBarVisibility(visibility: MenuBarVisibility, notify: boolean = true): void {
828+
private setMenuBarVisibility(visibility: MenuBarVisibility, notify: boolean = true): void {
801829
if (isMacintosh) {
802830
return; // ignore for macOS platform
803831
}
804832

833+
if (visibility === 'toggle') {
834+
if (notify) {
835+
this.send('vscode:showInfoMessage', nls.localize('hiddenMenuBar', "You can still access the menu bar by pressing the Alt-key."));
836+
}
837+
}
838+
839+
if (visibility === 'hidden') {
840+
// for some weird reason that I have no explanation for, the menu bar is not hiding when calling
841+
// this without timeout (see https://github.com/Microsoft/vscode/issues/19777). there seems to be
842+
// a timing issue with us opening the first window and the menu bar getting created. somehow the
843+
// fact that we want to hide the menu without being able to bring it back via Alt key makes Electron
844+
// still show the menu. Unable to reproduce from a simple Hello World application though...
845+
setTimeout(() => {
846+
this.doSetMenuBarVisibility(visibility);
847+
});
848+
} else {
849+
this.doSetMenuBarVisibility(visibility);
850+
}
851+
}
852+
853+
private doSetMenuBarVisibility(visibility: MenuBarVisibility): void {
805854
const isFullscreen = this._win.isFullScreen();
806855

807856
switch (visibility) {
@@ -818,22 +867,11 @@ export class CodeWindow implements ICodeWindow {
818867
case ('toggle'):
819868
this._win.setMenuBarVisibility(false);
820869
this._win.setAutoHideMenuBar(true);
821-
822-
if (notify) {
823-
this.send('vscode:showInfoMessage', nls.localize('hiddenMenuBar', "You can still access the menu bar by pressing the Alt-key."));
824-
}
825870
break;
826871

827872
case ('hidden'):
828-
// for some weird reason that I have no explanation for, the menu bar is not hiding when calling
829-
// this without timeout (see https://github.com/Microsoft/vscode/issues/19777). there seems to be
830-
// a timing issue with us opening the first window and the menu bar getting created. somehow the
831-
// fact that we want to hide the menu without being able to bring it back via Alt key makes Electron
832-
// still show the menu. Unable to reproduce from a simple Hello World application though...
833-
setTimeout(() => {
834-
this._win.setMenuBarVisibility(false);
835-
this._win.setAutoHideMenuBar(false);
836-
});
873+
this._win.setMenuBarVisibility(false);
874+
this._win.setAutoHideMenuBar(false);
837875
break;
838876
}
839877
}

src/vs/platform/windows/common/windows.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ export interface IWindowSettings {
224224
nativeTabs: boolean;
225225
enableMenuBarMnemonics: boolean;
226226
closeWhenEmpty: boolean;
227+
smoothScrollingWorkaround: boolean;
227228
}
228229

229230
export enum OpenContext {

src/vs/workbench/electron-browser/main.contribution.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ configurationRegistry.registerConfiguration({
406406
'default': false,
407407
'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."),
408408
'included': isMacintosh && parseFloat(os.release()) >= 16 // Minimum: macOS Sierra (10.12.x = darwin 16.x)
409+
},
410+
'window.smoothScrollingWorkaround': {
411+
'type': 'boolean',
412+
'default': false,
413+
'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."),
414+
'included': isWindows
409415
}
410416
}
411417
});

src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
3838
private enableCrashReporter: boolean;
3939
private touchbarEnabled: boolean;
4040
private treeHorizontalScrolling: boolean;
41+
private windowsSmoothScrollingWorkaround: boolean;
4142

4243
private firstFolderResource: URI;
4344
private extensionHostRestarter: RunOnceScheduler;
@@ -107,6 +108,12 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
107108
changed = true;
108109
}
109110

111+
// Windows: smooth scrolling workaround
112+
if (config.window && typeof config.window.smoothScrollingWorkaround === 'boolean' && config.window.smoothScrollingWorkaround !== this.windowsSmoothScrollingWorkaround) {
113+
this.windowsSmoothScrollingWorkaround = config.window.smoothScrollingWorkaround;
114+
changed = true;
115+
}
116+
110117
// Notify only when changed and we are the focused window (avoids notification spam across windows)
111118
if (notify && changed) {
112119
this.doConfirm(

0 commit comments

Comments
 (0)