From cbfb36b566b8637c9bdb81917ede3a08a6b05ab9 Mon Sep 17 00:00:00 2001 From: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:04:53 -0700 Subject: [PATCH] fix(tabs): activate clicks when pointer release has no button (#6386) Co-authored-by: Orca --- .../tab-bar/tab-strip-pointer-activation.test.tsx | 14 ++++++++++++-- .../tab-bar/tab-strip-pointer-activation.ts | 7 +++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.test.tsx b/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.test.tsx index 1dacc025d7b..1f7eae92b1d 100644 --- a/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.test.tsx +++ b/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.test.tsx @@ -65,8 +65,8 @@ function renderProbe(onActivate = vi.fn()): { } } -function dispatchPointer(target: EventTarget, type: string): void { - target.dispatchEvent(new MouseEvent(type, { bubbles: true, button: 0 })) +function dispatchPointer(target: EventTarget, type: string, button = 0): void { + target.dispatchEvent(new MouseEvent(type, { bubbles: true, button })) } afterEach(() => { @@ -89,6 +89,16 @@ describe('useTabStripPointerActivation', () => { expect(onActivate).toHaveBeenCalledTimes(1) }) + it('activates when the release event reports no changed button', () => { + const { onActivate, tabButton } = renderProbe() + + act(() => dispatchPointer(tabButton, 'pointerdown')) + act(() => dispatchPointer(window, 'pointerup', -1)) + + expect(tabButton.dataset.pressed).toBe('false') + expect(onActivate).toHaveBeenCalledTimes(1) + }) + it('cancels pending activation on pointercancel', () => { const { onActivate, tabButton } = renderProbe() diff --git a/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.ts b/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.ts index e4ce56597ca..a61748038c4 100644 --- a/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.ts +++ b/src/renderer/src/components/tab-bar/tab-strip-pointer-activation.ts @@ -33,10 +33,9 @@ export function useTabStripPointerActivation({ if (!isPressed) { return } - const finishPointerPress = (event: PointerEvent): void => { - if (event.button !== 0) { - return - } + const finishPointerPress = (): void => { + // Why: pointerup often reports button -1/no changed button; the left-button + // gate is on pointerdown, so release must always clear the pending click. const shouldActivate = pendingActivationRef.current && !isTabDragActiveRef.current pendingActivationRef.current = false setIsPressed(false)