diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts index 89ff65ec499cb38cdb6d7cb3598fa97818de94b9..dee572ce8922b69964b8e06b698a90a207cc2140 100644 --- a/src/vs/base/browser/mouseEvent.ts +++ b/src/vs/base/browser/mouseEvent.ts @@ -115,6 +115,13 @@ export class DragMouseEvent extends StandardMouseEvent { export interface IMouseWheelEvent extends MouseEvent { readonly wheelDelta: number; + readonly wheelDeltaX: number; + readonly wheelDeltaY: number; + + readonly deltaX: number; + readonly deltaY: number; + readonly deltaZ: number; + readonly deltaMode: number; } interface IWebKitMouseWheelEvent { diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index b3b447201c627862b2e4a0a18d69a33d63901063..4a2dc7661c99b2bd8dc99f52a5f9cc29cfb24682 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -109,6 +109,8 @@ export class MouseHandler extends ViewEventHandler { this._register(mouseEvents.onMouseDown(this.viewHelper.viewDomNode, (e) => this._onMouseDown(e))); const onMouseWheel = (browserEvent: IMouseWheelEvent) => { + this.viewController.emitMouseWheel(browserEvent); + if (!this._context.configuration.editor.viewInfo.mouseWheelZoom) { return; } @@ -259,6 +261,10 @@ export class MouseHandler extends ViewEventHandler { target: t }); } + + public _onMouseWheel(e: IMouseWheelEvent): void { + this.viewController.emitMouseWheel(e); + } } class MouseDownOperation extends Disposable { diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 2cac1dc82d90343e1ed15b7d23883fdd65027497..496e9cae7ab454965c1f64782305ec2cb1059c05 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { IMouseEvent } from 'vs/base/browser/mouseEvent'; +import { IMouseEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { IDisposable } from 'vs/base/common/lifecycle'; import * as editorOptions from 'vs/editor/common/config/editorOptions'; import { ICursors } from 'vs/editor/common/controller/cursorCommon'; @@ -461,6 +461,12 @@ export interface ICodeEditor extends editorCommon.IEditor { * @event */ onMouseLeave(listener: (e: IPartialEditorMouseEvent) => void): IDisposable; + /** + * An event emitted on a "mousewheel" + * @event + * @internal + */ + onMouseWheel(listener: (e: IMouseWheelEvent) => void): IDisposable; /** * An event emitted on a "keyup". * @event diff --git a/src/vs/editor/browser/view/viewController.ts b/src/vs/editor/browser/view/viewController.ts index 7c7db40a3cf317d94f17498bd43dc1ed3a97f8ea..d238999505242ca3095d614b8c2c558445881555 100644 --- a/src/vs/editor/browser/view/viewController.ts +++ b/src/vs/editor/browser/view/viewController.ts @@ -11,6 +11,7 @@ import { Position } from 'vs/editor/common/core/position'; import { Selection } from 'vs/editor/common/core/selection'; import { IConfiguration } from 'vs/editor/common/editorCommon'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; +import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; export interface IMouseDispatchData { position: Position; @@ -316,4 +317,8 @@ export class ViewController { public emitMouseDrop(e: IPartialEditorMouseEvent): void { this.outgoingEvents.emitMouseDrop(e); } + + public emitMouseWheel(e: IMouseWheelEvent): void { + this.outgoingEvents.emitMouseWheel(e); + } } diff --git a/src/vs/editor/browser/view/viewOutgoingEvents.ts b/src/vs/editor/browser/view/viewOutgoingEvents.ts index ca110d888c8dbb918948dbc1f027e114e399114d..dce981872952d1af8e16f6c49b0b19c7d003314f 100644 --- a/src/vs/editor/browser/view/viewOutgoingEvents.ts +++ b/src/vs/editor/browser/view/viewOutgoingEvents.ts @@ -12,6 +12,7 @@ import { Range } from 'vs/editor/common/core/range'; import { IScrollEvent } from 'vs/editor/common/editorCommon'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; +import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; export interface EventCallback { (event: T): void; @@ -31,6 +32,7 @@ export class ViewOutgoingEvents extends Disposable { public onMouseDown: EventCallback | null = null; public onMouseDrag: EventCallback | null = null; public onMouseDrop: EventCallback | null = null; + public onMouseWheel: EventCallback | null = null; private readonly _viewModel: IViewModel; @@ -111,6 +113,12 @@ export class ViewOutgoingEvents extends Disposable { } } + public emitMouseWheel(e: IMouseWheelEvent): void { + if (this.onMouseWheel) { + this.onMouseWheel(e); + } + } + private _convertViewToModelMouseEvent(e: IEditorMouseEvent): IEditorMouseEvent; private _convertViewToModelMouseEvent(e: IPartialEditorMouseEvent): IPartialEditorMouseEvent; private _convertViewToModelMouseEvent(e: IEditorMouseEvent | IPartialEditorMouseEvent): IEditorMouseEvent | IPartialEditorMouseEvent { diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 4d63f087c89f36941ec50f77be2f6e61224c6794..8db9d0ab91cfe68cc75ce624bce5d4a5b55dd15b 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -8,7 +8,7 @@ import 'vs/css!./media/tokens'; import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { IMouseEvent } from 'vs/base/browser/mouseEvent'; +import { IMouseEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { Color } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -186,6 +186,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE private readonly _onMouseLeave: Emitter = this._register(new Emitter()); public readonly onMouseLeave: Event = this._onMouseLeave.event; + private readonly _onMouseWheel: Emitter = this._register(new Emitter()); + public readonly onMouseWheel: Event = this._onMouseWheel.event; + private readonly _onKeyUp: Emitter = this._register(new Emitter()); public readonly onKeyUp: Event = this._onKeyUp.event; @@ -1442,6 +1445,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE // In IE, the focus is not synchronous, so we give it a little help this._editorWidgetFocus.setValue(true); }; + viewOutgoingEvents.onDidScroll = (e) => this._onDidScrollChange.fire(e); viewOutgoingEvents.onDidLoseFocus = () => this._editorTextFocus.setValue(false); viewOutgoingEvents.onContextMenu = (e) => this._onContextMenu.fire(e); @@ -1452,6 +1456,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE viewOutgoingEvents.onKeyUp = (e) => this._onKeyUp.fire(e); viewOutgoingEvents.onMouseMove = (e) => this._onMouseMove.fire(e); viewOutgoingEvents.onMouseLeave = (e) => this._onMouseLeave.fire(e); + viewOutgoingEvents.onMouseWheel = (e) => this._onMouseWheel.fire(e); viewOutgoingEvents.onKeyDown = (e) => this._onKeyDown.fire(e); const view = new View( diff --git a/src/vs/editor/contrib/contextmenu/contextmenu.ts b/src/vs/editor/contrib/contextmenu/contextmenu.ts index dde109aa26f9cf139b111c0db78eb62cbef3d3e4..8fa07282fd8bbb20dbd8729526e8c3d4382427b3 100644 --- a/src/vs/editor/contrib/contextmenu/contextmenu.ts +++ b/src/vs/editor/contrib/contextmenu/contextmenu.ts @@ -13,7 +13,7 @@ import { KeyCode, KeyMod, ResolvedKeybinding } from 'vs/base/common/keyCodes'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { IEditorContribution, IScrollEvent, ScrollType } from 'vs/editor/common/editorCommon'; +import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -21,6 +21,7 @@ import { IContextMenuService, IContextViewService } from 'vs/platform/contextvie import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ITextModel } from 'vs/editor/common/model'; +import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; export class ContextMenuController implements IEditorContribution { @@ -45,8 +46,8 @@ export class ContextMenuController implements IEditorContribution { this._editor = editor; this._toDispose.push(this._editor.onContextMenu((e: IEditorMouseEvent) => this._onContextMenu(e))); - this._toDispose.push(this._editor.onDidScrollChange((e: IScrollEvent) => { - if (this._contextMenuIsBeingShownCount > 0 && e.scrollTopChanged) { + this._toDispose.push(this._editor.onMouseWheel((e: IMouseWheelEvent) => { + if (this._contextMenuIsBeingShownCount > 0) { this._contextViewService.hideContextView(); } })); diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 8290247bf8282c21e6dfa67bc737a1a91b5a2515..3b7a0c51d5b90b1686abeb435e6fd21813539b7f 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -17,6 +17,7 @@ import { IContextMenuDelegate } from 'vs/base/browser/contextmenu'; import { EventType, $, removeNode } from 'vs/base/browser/dom'; import { attachMenuStyler } from 'vs/platform/theme/common/styler'; import { domEvent } from 'vs/base/browser/event'; +import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; export interface IContextMenuHandlerOptions { blockMouse: boolean; @@ -83,6 +84,25 @@ export class ContextMenuHandler { menu.onDidCancel(() => this.contextViewService.hideContextView(true), null, menuDisposables); menu.onDidBlur(() => this.contextViewService.hideContextView(true), null, menuDisposables); domEvent(window, EventType.BLUR)(() => { this.contextViewService.hideContextView(true); }, null, menuDisposables); + domEvent(window, EventType.MOUSE_DOWN)((e: MouseEvent) => { + let event = new StandardMouseEvent(e); + let element: HTMLElement | null = event.target; + + // Don't do anything as we are likely creating a context menu + if (event.rightButton) { + return; + } + + while (element) { + if (element === container) { + return; + } + + element = element.parentElement; + } + + this.contextViewService.hideContextView(true); + }, null, menuDisposables); return combinedDisposable([...menuDisposables, menu]); },