diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 499049aa182..32d343568b0 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -1087,7 +1087,7 @@ export class List implements ISpliceable, IDisposable { if (this.length === 0) { return; } const focus = this.focus.get(); let index = focus.length > 0 ? focus[0] + n : 0; - this.setFocus(loop ? [index % this.length] : [Math.min(index, this.length - 1)]); + this.setFocus(loop ? [index % this.length] : [Math.min(index, this.length - 1)], browserEvent); } focusPrevious(n = 1, loop = false, browserEvent?: UIEvent): void { @@ -1095,7 +1095,7 @@ export class List implements ISpliceable, IDisposable { const focus = this.focus.get(); let index = focus.length > 0 ? focus[0] - n : 0; if (loop && index < 0) { index = (this.length + (index % this.length)) % this.length; } - this.setFocus([Math.max(index, 0)]); + this.setFocus([Math.max(index, 0)], browserEvent); } focusNextPage(browserEvent?: UIEvent): void { @@ -1105,14 +1105,14 @@ export class List implements ISpliceable, IDisposable { const currentlyFocusedElement = this.getFocusedElements()[0]; if (currentlyFocusedElement !== lastPageElement) { - this.setFocus([lastPageIndex]); + this.setFocus([lastPageIndex], browserEvent); } else { const previousScrollTop = this.view.getScrollTop(); this.view.setScrollTop(previousScrollTop + this.view.renderHeight - this.view.elementHeight(lastPageIndex)); if (this.view.getScrollTop() !== previousScrollTop) { // Let the scroll event listener run - setTimeout(() => this.focusNextPage(), 0); + setTimeout(() => this.focusNextPage(browserEvent), 0); } } } @@ -1131,26 +1131,26 @@ export class List implements ISpliceable, IDisposable { const currentlyFocusedElement = this.getFocusedElements()[0]; if (currentlyFocusedElement !== firstPageElement) { - this.setFocus([firstPageIndex]); + this.setFocus([firstPageIndex], browserEvent); } else { const previousScrollTop = scrollTop; this.view.setScrollTop(scrollTop - this.view.renderHeight); if (this.view.getScrollTop() !== previousScrollTop) { // Let the scroll event listener run - setTimeout(() => this.focusPreviousPage(), 0); + setTimeout(() => this.focusPreviousPage(browserEvent), 0); } } } focusLast(browserEvent?: UIEvent): void { if (this.length === 0) { return; } - this.setFocus([this.length - 1]); + this.setFocus([this.length - 1], browserEvent); } focusFirst(browserEvent?: UIEvent): void { if (this.length === 0) { return; } - this.setFocus([0]); + this.setFocus([0], browserEvent); } getFocus(): number[] { diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 807cead7989..16d9f2d0ae6 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -302,33 +302,33 @@ export abstract class AbstractTree implements IDisposable return nodes.map(n => n.element); } - setFocus(elements: TRef[]): void { + setFocus(elements: TRef[], browserEvent?: UIEvent): void { const indexes = elements.map(e => this.model.getListIndex(e)); - this.view.setFocus(indexes); + this.view.setFocus(indexes, browserEvent); } - focusNext(n = 1, loop = false): void { - this.view.focusNext(n, loop); + focusNext(n = 1, loop = false, browserEvent?: UIEvent): void { + this.view.focusNext(n, loop, browserEvent); } - focusPrevious(n = 1, loop = false): void { - this.view.focusPrevious(n, loop); + focusPrevious(n = 1, loop = false, browserEvent?: UIEvent): void { + this.view.focusPrevious(n, loop, browserEvent); } - focusNextPage(): void { - this.view.focusNextPage(); + focusNextPage(browserEvent?: UIEvent): void { + this.view.focusNextPage(browserEvent); } - focusPreviousPage(): void { - this.view.focusPreviousPage(); + focusPreviousPage(browserEvent?: UIEvent): void { + this.view.focusPreviousPage(browserEvent); } - focusLast(): void { - this.view.focusLast(); + focusLast(browserEvent?: UIEvent): void { + this.view.focusLast(browserEvent); } - focusFirst(): void { - this.view.focusFirst(); + focusFirst(browserEvent?: UIEvent): void { + this.view.focusFirst(browserEvent); } getFocus(): T[] { diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index abb88e40e0f..29615cd9eb9 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -598,6 +598,10 @@ export class ObjectTreeResourceNavigator extends Disposable { const focus = this.tree.getFocus(); this.tree.setSelection(focus, e.browserEvent); + if (!e.browserEvent) { + return; + } + const isMouseEvent = e.browserEvent && e.browserEvent instanceof MouseEvent; if (!isMouseEvent) { diff --git a/src/vs/workbench/electron-browser/commands.ts b/src/vs/workbench/electron-browser/commands.ts index aa0364cd935..880dbe5f55b 100644 --- a/src/vs/workbench/electron-browser/commands.ts +++ b/src/vs/workbench/electron-browser/commands.ts @@ -61,7 +61,9 @@ export function registerCommands(): void { else if (focused instanceof ObjectTree) { const list = focused; - list.focusNext(count); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + list.focusNext(count, false, fakeKeyboardEvent); + const listFocus = list.getFocus(); if (listFocus.length) { list.reveal(listFocus[0]); @@ -110,10 +112,12 @@ export function registerCommands(): void { const focus = list.getFocus() ? list.getFocus()[0] : void 0; const selection = list.getSelection(); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + if (selection && selection.indexOf(focus) >= 0) { - list.setSelection(selection.filter(s => s !== previousFocus)); + list.setSelection(selection.filter(s => s !== previousFocus), fakeKeyboardEvent); } else { - list.setSelection(selection.concat(focus)); + list.setSelection(selection.concat(focus), fakeKeyboardEvent); } } @@ -140,19 +144,7 @@ export function registerCommands(): void { const focused = accessor.get(IListService).lastFocusedList; // List - if (focused instanceof List || focused instanceof PagedList) { - const list = focused; - - // Focus down first - const previousFocus = list.getFocus() ? list.getFocus()[0] : void 0; - focusDown(accessor, arg2); - - // Then adjust selection - expandMultiSelection(focused, previousFocus); - } - - // ObjectTree - else if (focused instanceof ObjectTree) { + if (focused instanceof List || focused instanceof PagedList || focused instanceof ObjectTree) { const list = focused; // Focus down first @@ -199,7 +191,9 @@ export function registerCommands(): void { else if (focused instanceof ObjectTree) { const list = focused; - list.focusPrevious(count); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + list.focusPrevious(count, false, fakeKeyboardEvent); + const listFocus = list.getFocus(); if (listFocus.length) { list.reveal(listFocus[0]); @@ -289,7 +283,8 @@ export function registerCommands(): void { const parent = tree.getParentElement(focus); if (parent) { - tree.setFocus([parent]); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + tree.setFocus([parent], fakeKeyboardEvent); tree.reveal(parent); } } @@ -335,7 +330,8 @@ export function registerCommands(): void { const child = tree.getFirstElementChild(focus); if (child) { - tree.setFocus([child]); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + tree.setFocus([child], fakeKeyboardEvent); tree.reveal(child); } } @@ -380,7 +376,8 @@ export function registerCommands(): void { else if (focused instanceof ObjectTree) { const list = focused; - list.focusPreviousPage(); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + list.focusPreviousPage(fakeKeyboardEvent); list.reveal(list.getFocus()[0]); } @@ -417,7 +414,8 @@ export function registerCommands(): void { else if (focused instanceof ObjectTree) { const list = focused; - list.focusNextPage(); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + list.focusNextPage(fakeKeyboardEvent); list.reveal(list.getFocus()[0]); } @@ -470,7 +468,8 @@ export function registerCommands(): void { return; } - list.setFocus([first]); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + list.setFocus([first], fakeKeyboardEvent); list.reveal(first); } @@ -522,7 +521,8 @@ export function registerCommands(): void { return; } - list.setFocus([last]); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + list.setFocus([last], fakeKeyboardEvent); list.reveal(last); } @@ -557,7 +557,8 @@ export function registerCommands(): void { // ObjectTree else if (focused instanceof ObjectTree) { const list = focused; - list.setSelection(list.getFocus()); + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + list.setSelection(list.getFocus(), fakeKeyboardEvent); list.open(list.getFocus()); } @@ -642,11 +643,12 @@ export function registerCommands(): void { // ObjectTree else if (focused instanceof ObjectTree) { const list = focused; + const fakeKeyboardEvent = new KeyboardEvent('keydown'); if (list.getSelection().length > 0) { - list.setSelection([]); + list.setSelection([], fakeKeyboardEvent); } else if (list.getFocus().length > 0) { - list.setFocus([]); + list.setFocus([], fakeKeyboardEvent); } }