Skip to content

Commit 0ab9506

Browse files
committed
Fix sticky tabs option
This fixes two issues: 1. Occasionally the mouse hit test will find a gap between characters and `request.target` will be `div.overflow-guard`. This causes a different code path to be followed and the snapping code is not called. I fixed that by moving the snapping code to the outermost function so it is always called. 2. `request.mouseContentHorizontalOffset` is a float but `createMouseTargetFromHitTestPosition` treats it as an int. I initially thought this was the cause of the broken sticky tabs. I don't think it actually was but it seems like a good idea to fix anyway. I also slightly simplified the control flow in `mouseContentHorizontalOffset`. Fixes microsoft#155299
1 parent 5b0bca8 commit 0ab9506

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

src/vs/editor/browser/controller/mouseTarget.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,14 @@ export class MouseTargetFactory {
496496
try {
497497
const r = MouseTargetFactory._createMouseTarget(ctx, request, false);
498498
// console.log(MouseTarget.toString(r));
499+
500+
if (r.type === MouseTargetType.CONTENT_TEXT) {
501+
// Snap to the nearest soft tab boundary if atomic soft tabs are enabled.
502+
if (ctx.stickyTabStops && r.position !== null) {
503+
const position = MouseTargetFactory._snapToSoftTabBoundary(r.position, ctx.viewModel);
504+
return request.fulfillContentText(position, r.range, r.detail);
505+
}
506+
}
499507
return r;
500508
} catch (err) {
501509
// console.log(err);
@@ -774,10 +782,12 @@ export class MouseTargetFactory {
774782
const lineNumber = pos.lineNumber;
775783
const column = pos.column;
776784

785+
const mouseContentHorizontalOffset = Math.floor(request.mouseContentHorizontalOffset);
786+
777787
const lineWidth = ctx.getLineWidth(lineNumber);
778788

779-
if (request.mouseContentHorizontalOffset > lineWidth) {
780-
const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth);
789+
if (mouseContentHorizontalOffset > lineWidth) {
790+
const detail = createEmptyContentDataInLines(mouseContentHorizontalOffset - lineWidth);
781791
return request.fulfillContentEmpty(pos, detail);
782792
}
783793

@@ -789,7 +799,7 @@ export class MouseTargetFactory {
789799

790800
const columnHorizontalOffset = visibleRange.left;
791801

792-
if (request.mouseContentHorizontalOffset === columnHorizontalOffset) {
802+
if (mouseContentHorizontalOffset === columnHorizontalOffset) {
793803
return request.fulfillContentText(pos, null, { mightBeForeignElement: !!injectedText, injectedText });
794804
}
795805

@@ -818,29 +828,32 @@ export class MouseTargetFactory {
818828
const spanNodeClientRect = spanNode.getBoundingClientRect();
819829
const mouseIsOverSpanNode = (spanNodeClientRect.left <= mouseCoordinates.clientX && mouseCoordinates.clientX <= spanNodeClientRect.right);
820830

831+
let rng: EditorRange | null = null;
832+
821833
for (let i = 1; i < points.length; i++) {
822834
const prev = points[i - 1];
823835
const curr = points[i];
824-
if (prev.offset <= request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset <= curr.offset) {
825-
const rng = new EditorRange(lineNumber, prev.column, lineNumber, curr.column);
836+
if (prev.offset <= mouseContentHorizontalOffset && mouseContentHorizontalOffset <= curr.offset) {
837+
rng = new EditorRange(lineNumber, prev.column, lineNumber, curr.column);
826838

827839
// See https://github.com/microsoft/vscode/issues/152819
828840
// Due to the use of zwj, the browser's hit test result is skewed towards the left
829841
// Here we try to correct that if the mouse horizontal offset is closer to the right than the left
830842

831-
const prevDelta = Math.abs(prev.offset - request.mouseContentHorizontalOffset);
832-
const nextDelta = Math.abs(curr.offset - request.mouseContentHorizontalOffset);
843+
const prevDelta = Math.abs(prev.offset - mouseContentHorizontalOffset);
844+
const nextDelta = Math.abs(curr.offset - mouseContentHorizontalOffset);
833845

834-
const resultPos = (
846+
pos = (
835847
prevDelta < nextDelta
836848
? new Position(lineNumber, prev.column)
837849
: new Position(lineNumber, curr.column)
838850
);
839851

840-
return request.fulfillContentText(resultPos, rng, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText });
852+
break;
841853
}
842854
}
843-
return request.fulfillContentText(pos, null, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText });
855+
856+
return request.fulfillContentText(pos, rng, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText });
844857
}
845858

846859
/**
@@ -990,10 +1003,6 @@ export class MouseTargetFactory {
9901003
result = new ContentHitTestResult(normalizedPosition, result.spanNode, injectedText);
9911004
}
9921005
}
993-
// Snap to the nearest soft tab boundary if atomic soft tabs are enabled.
994-
if (result.type === HitTestResultType.Content && ctx.stickyTabStops) {
995-
result = new ContentHitTestResult(this._snapToSoftTabBoundary(result.position, ctx.viewModel), result.spanNode, result.injectedText);
996-
}
9971006
return result;
9981007
}
9991008
}

0 commit comments

Comments
 (0)