From 5828eec9b00231a8402a99eca708614c27abc128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E7=86=B1?= Date: Wed, 22 Jul 2026 20:51:36 +0800 Subject: [PATCH] fix(sheets-ui): end selection when pointer is released (#7301) --- .../base-selection-render.service.spec.ts | 28 +++++++++++++++++++ .../base-selection-render.service.ts | 5 ++++ 2 files changed, 33 insertions(+) diff --git a/packages/sheets-ui/src/services/selection/__tests__/base-selection-render.service.spec.ts b/packages/sheets-ui/src/services/selection/__tests__/base-selection-render.service.spec.ts index dfd36f908c..47dcbb9ba0 100644 --- a/packages/sheets-ui/src/services/selection/__tests__/base-selection-render.service.spec.ts +++ b/packages/sheets-ui/src/services/selection/__tests__/base-selection-render.service.spec.ts @@ -441,6 +441,34 @@ describe('BaseSelectionRenderService', () => { expect(movingSelections.length).toBeGreaterThan(0); }); + it('ends a leaked drag before handling pointer movement with no pressed buttons', () => { + const { service } = createSelectionRenderService(); + const { scene } = service.changeRuntimeForTest(); + service.resetSelectionsByModelData([selections[0]]); + service.listenPointerMoveForTest(); + + (scene.onPointerMove$ as unknown as { emit: (evt: unknown) => void }).emit({ + offsetX: 350, + offsetY: 65, + buttons: 1, + }); + expect(service.selectionMoving).toBe(true); + + (scene.onPointerMove$ as unknown as { emit: (evt: unknown) => void }).emit({ + offsetX: 450, + offsetY: 85, + buttons: 0, + }); + + expect(service.getActiveRange()).toEqual({ + startRow: 1, + startColumn: 1, + endRow: 3, + endColumn: 3, + }); + expect(service.selectionMoving).toBe(false); + }); + it('cancels an in-progress selection when another scene receives a pointer event', () => { const { service } = createSelectionRenderService(); const { scene } = service.changeRuntimeForTest(); diff --git a/packages/sheets-ui/src/services/selection/base-selection-render.service.ts b/packages/sheets-ui/src/services/selection/base-selection-render.service.ts index dd1d42e2bb..4e336e795b 100644 --- a/packages/sheets-ui/src/services/selection/base-selection-render.service.ts +++ b/packages/sheets-ui/src/services/selection/base-selection-render.service.ts @@ -520,6 +520,11 @@ export class BaseSelectionRenderService extends Disposable implements ISheetSele // #region onPointerMove$ // eslint-disable-next-line max-lines-per-function, complexity this._scenePointerMoveSub = scene.onPointerMove$.subscribeEvent((moveEvt: IPointerEvent | IMouseEvent) => { + if (moveEvt.buttons === 0) { + this.endSelection(); + return; + } + const { offsetX: moveOffsetX, offsetY: moveOffsetY } = moveEvt; const { x: newMoveOffsetX, y: newMoveOffsetY } = scene.getCoordRelativeToViewport(Vector2.FromArray([moveOffsetX, moveOffsetY]));