mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-07 03:40:36 -07:00
paste transform followup (#17624)
Co-authored-by: Jack Wotherspoon <jackwoth@google.com>
This commit is contained in:
@@ -229,4 +229,88 @@ describe('MouseContext', () => {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should emit a double-click event when two left-presses occur quickly at the same position', () => {
|
||||
const handler = vi.fn();
|
||||
const { result } = renderHook(() => useMouseContext(), { wrapper });
|
||||
|
||||
act(() => {
|
||||
result.current.subscribe(handler);
|
||||
});
|
||||
|
||||
// First click
|
||||
act(() => {
|
||||
stdin.write('\x1b[<0;10;20M');
|
||||
});
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(1);
|
||||
expect(handler).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({ name: 'left-press', col: 10, row: 20 }),
|
||||
);
|
||||
|
||||
// Second click (within threshold)
|
||||
act(() => {
|
||||
stdin.write('\x1b[<0;10;20M');
|
||||
});
|
||||
|
||||
// Should have called for the second left-press AND the double-click
|
||||
expect(handler).toHaveBeenCalledTimes(3);
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 'double-click', col: 10, row: 20 }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should NOT emit a double-click event if clicks are too far apart', () => {
|
||||
const handler = vi.fn();
|
||||
const { result } = renderHook(() => useMouseContext(), { wrapper });
|
||||
|
||||
act(() => {
|
||||
result.current.subscribe(handler);
|
||||
});
|
||||
|
||||
// First click
|
||||
act(() => {
|
||||
stdin.write('\x1b[<0;10;20M');
|
||||
});
|
||||
|
||||
// Second click (too far)
|
||||
act(() => {
|
||||
stdin.write('\x1b[<0;15;25M');
|
||||
});
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(2);
|
||||
expect(handler).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 'double-click' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should NOT emit a double-click event if too much time passes', async () => {
|
||||
vi.useFakeTimers();
|
||||
const handler = vi.fn();
|
||||
const { result } = renderHook(() => useMouseContext(), { wrapper });
|
||||
|
||||
act(() => {
|
||||
result.current.subscribe(handler);
|
||||
});
|
||||
|
||||
// First click
|
||||
act(() => {
|
||||
stdin.write('\x1b[<0;10;20M');
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
vi.advanceTimersByTime(500); // Threshold is 400ms
|
||||
});
|
||||
|
||||
// Second click
|
||||
act(() => {
|
||||
stdin.write('\x1b[<0;10;20M');
|
||||
});
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(2);
|
||||
expect(handler).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 'double-click' }),
|
||||
);
|
||||
vi.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,6 +22,8 @@ import {
|
||||
type MouseEvent,
|
||||
type MouseEventName,
|
||||
type MouseHandler,
|
||||
DOUBLE_CLICK_THRESHOLD_MS,
|
||||
DOUBLE_CLICK_DISTANCE_TOLERANCE,
|
||||
} from '../utils/mouse.js';
|
||||
|
||||
export type { MouseEvent, MouseEventName, MouseHandler };
|
||||
@@ -67,6 +69,11 @@ export function MouseProvider({
|
||||
}) {
|
||||
const { stdin } = useStdin();
|
||||
const subscribers = useRef<Set<MouseHandler>>(new Set()).current;
|
||||
const lastClickRef = useRef<{
|
||||
time: number;
|
||||
col: number;
|
||||
row: number;
|
||||
} | null>(null);
|
||||
|
||||
const subscribe = useCallback(
|
||||
(handler: MouseHandler) => {
|
||||
@@ -96,6 +103,30 @@ export function MouseProvider({
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.name === 'left-press') {
|
||||
const now = Date.now();
|
||||
const lastClick = lastClickRef.current;
|
||||
if (
|
||||
lastClick &&
|
||||
now - lastClick.time < DOUBLE_CLICK_THRESHOLD_MS &&
|
||||
Math.abs(event.col - lastClick.col) <=
|
||||
DOUBLE_CLICK_DISTANCE_TOLERANCE &&
|
||||
Math.abs(event.row - lastClick.row) <= DOUBLE_CLICK_DISTANCE_TOLERANCE
|
||||
) {
|
||||
const doubleClickEvent: MouseEvent = {
|
||||
...event,
|
||||
name: 'double-click',
|
||||
};
|
||||
for (const handler of subscribers) {
|
||||
handler(doubleClickEvent);
|
||||
}
|
||||
lastClickRef.current = null;
|
||||
} else {
|
||||
lastClickRef.current = { time: now, col: event.col, row: event.row };
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!handled &&
|
||||
event.name === 'move' &&
|
||||
|
||||
Reference in New Issue
Block a user