From 11c0cbfb9ba643714f5d6b1269fbaaa6faf8220e Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Thu, 7 May 2020 22:54:35 -0700 Subject: [PATCH] Port scrolling fix to release (#11688) * Fix scrolling (#11681) * Fix scrolling * Review feedback - fix scrolling on expand/collapse * Update changelog * Update package.json Co-authored-by: Jim Griesmer --- CHANGELOG.md | 2 ++ package.json | 6 ++++++ src/client/common/types.ts | 1 + .../history-react/interactivePanel.tsx | 4 +++- .../interactive-common/contentPanel.tsx | 17 +++++++++++++++-- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab8c4a0e0d83..ec36802066db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,8 @@ ([#11579](https://github.com/Microsoft/vscode-python/issues/11579)) 1. When VS quits, make sure to save contents of notebook for next reopen. ([#11557](https://github.com/Microsoft/vscode-python/issues/11557)) +1. Fix scrolling when clicking in the interactive window to not jump around. + ([#11554](https://github.com/Microsoft/vscode-python/issues/11554)) ### Code Health diff --git a/package.json b/package.json index e2d8413913ee..1c8bbf58fb27 100644 --- a/package.json +++ b/package.json @@ -1761,6 +1761,12 @@ "description": "Maximum size (in pixels) of text output in the Python Interactive window and Notebook Editor before a scrollbar appears. First enable scrolling for cell outputs in settings.", "scope": "resource" }, + "python.dataScience.alwaysScrollOnNewCell": { + "type": "boolean", + "default": false, + "description": "Automatically scroll the interactive window to show the output of the last statement executed. If false, the interactive window will only automatically scroll if the bottom of the prior cell is visible.", + "scope": "resource" + }, "python.dataScience.enableScrollingForCellOutputs": { "type": "boolean", "default": true, diff --git a/src/client/common/types.ts b/src/client/common/types.ts index 656af6d5ff22..ff33f32e19f0 100644 --- a/src/client/common/types.ts +++ b/src/client/common/types.ts @@ -389,6 +389,7 @@ export interface IDataScienceSettings { disableJupyterAutoStart?: boolean; jupyterCommandLineArguments: string[]; widgetScriptSources: WidgetCDNs[]; + alwaysScrollOnNewCell?: boolean; } export type WidgetCDNs = 'unpkg.com' | 'jsdelivr.com'; diff --git a/src/datascience-ui/history-react/interactivePanel.tsx b/src/datascience-ui/history-react/interactivePanel.tsx index 66a06e711a9e..0cbec0042ce3 100644 --- a/src/datascience-ui/history-react/interactivePanel.tsx +++ b/src/datascience-ui/history-react/interactivePanel.tsx @@ -373,7 +373,9 @@ ${buildSettingsCss(this.props.settings)}`} if (this.internalScrollCount > 0) { this.internalScrollCount -= 1; } else if (this.contentPanelRef.current) { - const isAtBottom = this.contentPanelRef.current.computeIsAtBottom(e.currentTarget); + const isAtBottom = this.props.settings?.alwaysScrollOnNewCell + ? true + : this.contentPanelRef.current.computeIsAtBottom(e.currentTarget); this.props.scroll(isAtBottom); } }; diff --git a/src/datascience-ui/interactive-common/contentPanel.tsx b/src/datascience-ui/interactive-common/contentPanel.tsx index fba2e3ad5be3..f8653aa48fa4 100644 --- a/src/datascience-ui/interactive-common/contentPanel.tsx +++ b/src/datascience-ui/interactive-common/contentPanel.tsx @@ -3,6 +3,7 @@ 'use strict'; import * as React from 'react'; +import * as fastDeepEqual from 'fast-deep-equal'; import { IDataScienceExtraSettings } from '../../client/datascience/types'; import { InputHistory } from './inputHistory'; import { ICellViewModel } from './mainState'; @@ -37,8 +38,12 @@ export class ContentPanel extends React.Component { public componentDidMount() { this.scrollToBottom(); } - public componentWillReceiveProps() { - this.scrollToBottom(); + public componentWillReceiveProps(prevProps: IContentPanelProps) { + // Scroll if we suddenly finished or updated a cell. This should happen on + // finish, updating output, etc. + if (!fastDeepEqual(prevProps.cellVMs.map(this.outputCheckable), this.props.cellVMs.map(this.outputCheckable))) { + this.scrollToBottom(); + } } public computeIsAtBottom(parent: HTMLDivElement): boolean { @@ -61,6 +66,14 @@ export class ContentPanel extends React.Component { ); } + private outputCheckable = (cellVM: ICellViewModel) => { + // Return the properties that if they change means a cell updated something + return { + outputs: cellVM.cell.data.outputs, + state: cellVM.cell.state + }; + }; + private renderCells = () => { return this.props.cellVMs.map((cellVM: ICellViewModel, index: number) => { return this.props.renderCell(cellVM, index);