diff --git a/src/vs/base/parts/tree/browser/treeDefaults.ts b/src/vs/base/parts/tree/browser/treeDefaults.ts index 845ec66aa4cdf..116c4c017e2b7 100644 --- a/src/vs/base/parts/tree/browser/treeDefaults.ts +++ b/src/vs/base/parts/tree/browser/treeDefaults.ts @@ -159,13 +159,14 @@ export class DefaultController implements _.IController { protected onLeftClick(tree: _.ITree, element: any, eventish: ICancelableEvent, origin: string = 'mouse'): boolean { const payload = { origin: origin, originalEvent: eventish }; - const isDoubleClick = (origin === 'mouse' && (eventish).detail === 2); + const event = eventish; + const isDoubleClick = (origin === 'mouse' && event.detail === 2); if (tree.getInput() === element) { tree.clearFocus(payload); tree.clearSelection(payload); } else { - const isMouseDown = eventish && (eventish).browserEvent && (eventish).browserEvent.type === 'mousedown'; + const isMouseDown = eventish && event.browserEvent && event.browserEvent.type === 'mousedown'; if (!isMouseDown) { eventish.preventDefault(); // we cannot preventDefault onMouseDown because this would break DND otherwise } @@ -175,7 +176,7 @@ export class DefaultController implements _.IController { tree.setSelection([element], payload); tree.setFocus(element, payload); - if (this.openOnSingleClick || isDoubleClick) { + if (this.openOnSingleClick || isDoubleClick || this.isClickOnTwistie(event)) { if (tree.isExpanded(element)) { tree.collapse(element).done(null, errors.onUnexpectedError); } else { @@ -195,6 +196,16 @@ export class DefaultController implements _.IController { return this.options.openMode === OpenMode.SINGLE_CLICK; } + protected isClickOnTwistie(event: mouse.IMouseEvent): boolean { + const target = event.target as HTMLElement; + + // There is no way to find out if the ::before element is clicked where + // the twistie is drawn, but the
element in the + // tree item is the only thing we get back as target when the user clicks + // on the twistie. + return target && target.className === 'content' && dom.hasClass(target.parentElement, 'monaco-tree-row'); + } + public onContextMenu(tree: _.ITree, element: any, event: _.ContextMenuEvent): boolean { if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') { return false; // allow context menu on input fields diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index 47ea71b6a66cb..c91628d3b0b36 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -245,7 +245,7 @@ class Controller extends WorkbenchTreeController { var isDoubleClick = event.detail === 2; if (event.leftButton) { if (element instanceof FileReferences) { - if (this.openOnSingleClick || isDoubleClick) { + if (this.openOnSingleClick || isDoubleClick || this.isClickOnTwistie(event)) { event.preventDefault(); event.stopPropagation(); return this._expandCollapse(tree, element); diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index eaf035bc91e3a..9d2271aa8ca04 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -409,7 +409,7 @@ export class FileController extends WorkbenchTreeController implements IDisposab else { // Expand / Collapse - if (isDoubleClick || this.openOnSingleClick) { + if (isDoubleClick || this.openOnSingleClick || this.isClickOnTwistie(event)) { tree.toggleExpansion(stat, event.altKey); this.previousSelectionRangeStop = undefined; } @@ -715,6 +715,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { public onDragStart(tree: ITree, data: IDragAndDropData, originalEvent: DragMouseEvent): void { const sources: FileStat[] = data.getData(); if (sources && sources.length) { + // When dragging folders, make sure to collapse them to free up some space sources.forEach(s => { if (s.isDirectory && tree.isExpanded(s)) {