Skip to content

Commit d95f2e0

Browse files
authored
undo general focus/selection preservation from lists and trees (microsoft#201309)
fixes microsoft#174768 fixes microsoft#127622
1 parent 199216c commit d95f2e0

File tree

5 files changed

+33
-13
lines changed

5 files changed

+33
-13
lines changed

src/vs/base/browser/ui/list/listWidget.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,8 @@ class TraitRenderer<T> implements IListRenderer<T, ITraitTemplateData>
109109

110110
class Trait<T> implements ISpliceable<boolean>, IDisposable {
111111

112-
private length = 0;
113-
private indexes: number[] = [];
114-
private sortedIndexes: number[] = [];
112+
protected indexes: number[] = [];
113+
protected sortedIndexes: number[] = [];
115114

116115
private readonly _onChange = new Emitter<ITraitChangeEvent>();
117116
readonly onChange: Event<ITraitChangeEvent> = this._onChange.event;
@@ -126,8 +125,6 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
126125
constructor(private _trait: string) { }
127126

128127
splice(start: number, deleteCount: number, elements: boolean[]): void {
129-
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
130-
131128
const diff = elements.length - deleteCount;
132129
const end = start + deleteCount;
133130
const sortedIndexes: number[] = [];
@@ -147,16 +144,8 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
147144
sortedIndexes.push(this.sortedIndexes[i++] + diff);
148145
}
149146

150-
const length = this.length + diff;
151-
152-
if (this.sortedIndexes.length > 0 && sortedIndexes.length === 0 && length > 0) {
153-
const first = this.sortedIndexes.find(index => index >= start) ?? length - 1;
154-
sortedIndexes.push(Math.min(first, length - 1));
155-
}
156-
157147
this.renderer.splice(start, deleteCount, elements.length);
158148
this._set(sortedIndexes, sortedIndexes);
159-
this.length = length;
160149
}
161150

162151
renderIndex(index: number, container: HTMLElement): void {

src/vs/workbench/contrib/files/browser/explorerService.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ export class ExplorerService implements IExplorerService {
448448
// Remove Element from Parent (Model)
449449
const parent = modelElement.parent;
450450
parent.removeChild(modelElement);
451+
this.view?.focusNext();
451452

452453
const oldNestedParent = modelElement.nestedParent;
453454
if (oldNestedParent) {
@@ -456,6 +457,10 @@ export class ExplorerService implements IExplorerService {
456457
}
457458
// Refresh Parent (View)
458459
await this.view?.refresh(shouldDeepRefresh, parent);
460+
461+
if (this.view?.getFocus().length === 0) {
462+
this.view?.focusLast();
463+
}
459464
}
460465
}));
461466
}

src/vs/workbench/contrib/files/browser/files.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ export interface IExplorerView {
6060
isItemVisible(item: ExplorerItem): boolean;
6161
isItemCollapsed(item: ExplorerItem): boolean;
6262
hasFocus(): boolean;
63+
getFocus(): ExplorerItem[];
64+
focusNext(): void;
65+
focusLast(): void;
6366
}
6467

6568
function getFocus(listService: IListService): unknown | undefined {

src/vs/workbench/contrib/files/browser/views/explorerView.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,18 @@ export class ExplorerView extends ViewPane implements IExplorerView {
348348
return DOM.isAncestorOfActiveElement(this.container);
349349
}
350350

351+
getFocus(): ExplorerItem[] {
352+
return this.tree.getFocus();
353+
}
354+
355+
focusNext(): void {
356+
this.tree.focusNext();
357+
}
358+
359+
focusLast(): void {
360+
this.tree.focusLast();
361+
}
362+
351363
getContext(respectMultiSelection: boolean): ExplorerItem[] {
352364
return getContext(this.tree.getFocus(), this.tree.getSelection(), respectMultiSelection, this.renderer);
353365
}

src/vs/workbench/contrib/workspace/browser/workspaceTrustEditor.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ class WorkspaceTrustedUrisTable extends Disposable {
155155
return localize('trustedFolderWithHostAriaLabel', "{0} on {1}, trusted", this.labelService.getUriLabel(item.uri), hostLabel);
156156
},
157157
getWidgetAriaLabel: () => localize('trustedFoldersAndWorkspaces', "Trusted Folders & Workspaces")
158+
},
159+
identityProvider: {
160+
getId(element: ITrustedUriItem) {
161+
return element.uri.toString();
162+
},
158163
}
159164
}
160165
) as WorkbenchTable<ITrustedUriItem>;
@@ -336,8 +341,14 @@ class WorkspaceTrustedUrisTable extends Disposable {
336341
}
337342

338343
async delete(item: ITrustedUriItem) {
344+
this.table.focusNext();
339345
await this.workspaceTrustManagementService.setUrisTrust([item.uri], false);
346+
347+
if (this.table.getFocus().length === 0) {
348+
this.table.focusLast();
349+
}
340350
this._onDelete.fire(item);
351+
this.table.domFocus();
341352
}
342353

343354
async edit(item: ITrustedUriItem, usePickerIfPossible?: boolean) {

0 commit comments

Comments
 (0)