Skip to content

Commit

Permalink
Preserve focus during query execution (#18503) (#18505)
Browse files Browse the repository at this point in the history
* preserve focus during query execution

* fix focus at more places

* doc

* fix test
  • Loading branch information
caohai authored Dec 12, 2024
1 parent 91f0deb commit 8281bca
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 12 deletions.
4 changes: 3 additions & 1 deletion src/controllers/mainController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,9 @@ export default class MainController implements vscode.Disposable {
vscode.commands.registerCommand(
Constants.cmdrevealQueryResultPanel,
() => {
vscode.commands.executeCommand("queryResult.focus");
vscode.commands.executeCommand("queryResult.focus", {
preserveFocus: true,
});
},
),
);
Expand Down
5 changes: 4 additions & 1 deletion src/controllers/reactWebviewPanelController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ export class ReactWebviewPanelController<
this._panel = vscode.window.createWebviewPanel(
"mssql-react-webview",
this._options.title,
this._options.viewColumn,
{
viewColumn: this._options.viewColumn,
preserveFocus: this._options.preserveFocus,
},
{
enableScripts: true,
retainContextWhenHidden: true,
Expand Down
10 changes: 10 additions & 0 deletions src/controllers/reactWebviewViewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ export class ReactWebviewViewController<State, Reducers>
* Creates a new ReactWebviewViewController
* @param _context Extension context
* @param _sourceFile Source file that the webview will use
* @param _viewId The id of the view, this should be the same id defined in the package.json
* @param initialData Initial state object that the webview will use
*/
constructor(
_context: vscode.ExtensionContext,
_sourceFile: string,
private _viewId: string,
initialData: State,
) {
super(_context, _sourceFile, initialData);
Expand All @@ -47,6 +49,14 @@ export class ReactWebviewViewController<State, Reducers>
* Displays the webview in the foreground
*/
public revealToForeground(): void {
if (!this._webviewView?.webview) {
// If the webview is not yet created, focus will force it to be created and shown.
// The preserveFocus arg is not documented
// https://github.com/microsoft/vscode/issues/205766#issuecomment-1994961088
void vscode.commands.executeCommand(`${this._viewId}.focus`, {
preserveFocus: true,
});
}
this._webviewView.show(true);
}

Expand Down
10 changes: 4 additions & 6 deletions src/models/sqlOutputContentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,7 @@ export class SqlOutputContentProvider {
}
this._queryResultWebviewController.updatePanelState(uri);
if (!this._queryResultWebviewController.hasPanel(uri)) {
await vscode.commands.executeCommand(
"queryResult.focus",
);
this._queryResultWebviewController.revealToForeground();
}
sendActionEvent(
TelemetryViews.QueryResult,
Expand Down Expand Up @@ -520,7 +518,7 @@ export class SqlOutputContentProvider {
);
this._queryResultWebviewController.updatePanelState(uri);
if (!this._queryResultWebviewController.hasPanel(uri)) {
vscode.commands.executeCommand("queryResult.focus");
this._queryResultWebviewController.revealToForeground();
}
}
});
Expand Down Expand Up @@ -549,7 +547,7 @@ export class SqlOutputContentProvider {
uri,
);
if (!this._queryResultWebviewController.hasPanel(uri)) {
vscode.commands.executeCommand("queryResult.focus");
this._queryResultWebviewController.revealToForeground();
}
this._lastSendMessageTime = Date.now();
}
Expand Down Expand Up @@ -599,7 +597,7 @@ export class SqlOutputContentProvider {
uri,
);
if (!this._queryResultWebviewController.hasPanel(uri)) {
vscode.commands.executeCommand("queryResult.focus");
this._queryResultWebviewController.revealToForeground();
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/queryResult/queryResultWebViewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class QueryResultWebviewController extends ReactWebviewViewController<
private untitledSqlDocumentService: UntitledSqlDocumentService,
private _vscodeWrapper: VscodeWrapper,
) {
super(context, "queryResult", {
super(context, "queryResult", "queryResult", {
resultSetSummaries: {},
messages: [],
tabStates: {
Expand Down
3 changes: 2 additions & 1 deletion src/queryResult/queryResultWebviewPanelController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class QueryResultWebviewPanelController extends ReactWebviewPanelControll
comment: "{0} is the editor title",
}),
viewColumn: _viewColumn,
preserveFocus: true,
iconPath: {
dark: vscode.Uri.joinPath(
context.extensionUri,
Expand Down Expand Up @@ -83,7 +84,7 @@ export class QueryResultWebviewPanelController extends ReactWebviewPanelControll
}

public revealToForeground() {
this.panel.reveal(this._viewColumn);
this.panel.reveal(this._viewColumn, true);
}

public getQueryResultWebviewViewController(): QueryResultWebviewController {
Expand Down
2 changes: 1 addition & 1 deletion src/reactviews/pages/QueryResult/queryResultPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ export const QueryResultPane = () => {
className={classes.hidePanelLink}
onClick={async () => {
await webViewState.extensionRpc.call("executeCommand", {
command: "workbench.action.togglePanel",
command: "workbench.action.closePanel",
});
}}
>
Expand Down
4 changes: 4 additions & 0 deletions src/sharedInterfaces/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export interface MssqlWebviewPanelOptions {
* The view column in which the webview panel should be displayed.
*/
viewColumn: vscode.ViewColumn;
/**
* Whether the focus should be preserved when the webview is revealed.
*/
preserveFocus?: boolean;
/**
* The icon path for the webview panel tab icon.
*/
Expand Down
7 changes: 6 additions & 1 deletion test/unit/reactWebviewPanelController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ suite("ReactWebviewPanelController", () => {
const defaultOptions: MssqlWebviewPanelOptions = {
title: "Test Panel",
viewColumn: vscode.ViewColumn.One,
preserveFocus: true,
iconPath: vscode.Uri.file("path"),
showRestorePromptAfterClose: true,
};
Expand All @@ -95,6 +96,7 @@ suite("ReactWebviewPanelController", () => {
const options = {
title: "My Test Panel",
viewColumn: vscode.ViewColumn.Two,
preserveFocus: true,
iconPath: vscode.Uri.file("/path/to/test-icon.png"),
showRestorePromptAfterClose: true,
};
Expand All @@ -104,7 +106,10 @@ suite("ReactWebviewPanelController", () => {
createWebviewPanelStub.calledWith(
"mssql-react-webview",
options.title,
options.viewColumn,
{
viewColumn: options.viewColumn,
preserveFocus: options.preserveFocus,
},
{
enableScripts: true,
retainContextWhenHidden: true,
Expand Down

0 comments on commit 8281bca

Please sign in to comment.