diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index bab014e28eb03ace358a601d37250e4fd34eec7e..018b2686b7363909d18be4655f7b402b53a584b4 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -35,6 +35,7 @@ export interface IMarginData { export interface IEmptyContentData { isAfterLines: boolean; + horizontalDistanceToText?: number; } interface IETextRange { @@ -415,7 +416,13 @@ class HitTestRequest extends BareHitTestRequest { } const EMPTY_CONTENT_AFTER_LINES: IEmptyContentData = { isAfterLines: true }; -const EMPTY_CONTENT_IN_LINES: IEmptyContentData = { isAfterLines: false }; + +function createEmptyContentDataInLines(horizontalDistanceToText: number): IEmptyContentData { + return { + isAfterLines: false, + horizontalDistanceToText: horizontalDistanceToText + }; +} export class MouseTargetFactory { @@ -639,7 +646,9 @@ export class MouseTargetFactory { if (ElementPath.isStrictChildOfViewLines(request.targetPath)) { const lineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset); if (ctx.model.getLineLength(lineNumber) === 0) { - return request.fulfill(MouseTargetType.CONTENT_EMPTY, new Position(lineNumber, 1), void 0, EMPTY_CONTENT_IN_LINES); + const lineWidth = ctx.getLineWidth(lineNumber); + const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth); + return request.fulfill(MouseTargetType.CONTENT_EMPTY, new Position(lineNumber, 1), void 0, detail); } } @@ -713,9 +722,11 @@ export class MouseTargetFactory { if (request.mouseContentHorizontalOffset > lineWidth) { if (browser.isEdge && pos.column === 1) { // See https://github.com/Microsoft/vscode/issues/10875 - return request.fulfill(MouseTargetType.CONTENT_EMPTY, new Position(lineNumber, ctx.model.getLineMaxColumn(lineNumber)), void 0, EMPTY_CONTENT_IN_LINES); + const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth); + return request.fulfill(MouseTargetType.CONTENT_EMPTY, new Position(lineNumber, ctx.model.getLineMaxColumn(lineNumber)), void 0, detail); } - return request.fulfill(MouseTargetType.CONTENT_EMPTY, pos, void 0, EMPTY_CONTENT_IN_LINES); + const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth); + return request.fulfill(MouseTargetType.CONTENT_EMPTY, pos, void 0, detail); } const visibleRange = ctx.visibleRangeForPosition2(lineNumber, column); diff --git a/src/vs/editor/contrib/hover/hover.ts b/src/vs/editor/contrib/hover/hover.ts index a48e61cb54f0380583b53d398559271f87d1bbd1..23eb1cdf5afea824d5e4edfcfe73d460b110553c 100644 --- a/src/vs/editor/contrib/hover/hover.ts +++ b/src/vs/editor/contrib/hover/hover.ts @@ -23,6 +23,7 @@ import { registerThemingParticipant, IThemeService } from 'vs/platform/theme/com import { editorHoverHighlight, editorHoverBackground, editorHoverBorder, textLinkForeground, textCodeBlockBackground } from 'vs/platform/theme/common/colorRegistry'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer'; +import { IEmptyContentData } from 'vs/editor/browser/controller/mouseTarget'; export class ModesHoverController implements editorCommon.IEditorContribution { @@ -114,8 +115,8 @@ export class ModesHoverController implements editorCommon.IEditorContribution { } private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { - var targetType = mouseEvent.target.type; - var stopKey = platform.isMacintosh ? 'metaKey' : 'ctrlKey'; + let targetType = mouseEvent.target.type; + let stopKey = platform.isMacintosh ? 'metaKey' : 'ctrlKey'; if (this._isMouseDown && this._hoverClicked && this.contentWidget.isColorPickerVisible()) { return; @@ -131,6 +132,15 @@ export class ModesHoverController implements editorCommon.IEditorContribution { return; } + if (targetType === MouseTargetType.CONTENT_EMPTY) { + const epsilon = this._editor.getConfiguration().fontInfo.typicalHalfwidthCharacterWidth / 2; + const data = mouseEvent.target.detail; + if (data && !data.isAfterLines && typeof data.horizontalDistanceToText === 'number' && data.horizontalDistanceToText < epsilon) { + // Let hover kick in even when the mouse is technically in the empty area after a line, given the distance is small enough + targetType = MouseTargetType.CONTENT_TEXT; + } + } + if (this._editor.getConfiguration().contribInfo.hover && targetType === MouseTargetType.CONTENT_TEXT) { this.glyphWidget.hide(); this.contentWidget.startShowingAt(mouseEvent.target.range, false);