Skip to content

Commit 9bd128b

Browse files
authored
Merge pull request #5594 from Tyriar/onSelectionChangeClear
Fire onSelectionChange on clear
2 parents 729a670 + bd8454d commit 9bd128b

2 files changed

Lines changed: 74 additions & 11 deletions

File tree

src/browser/services/SelectionService.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,9 @@ export class SelectionService extends Disposable implements ISelectionService {
532532
* @param event The mouse event.
533533
*/
534534
private _handleSingleClick(event: MouseEvent): void {
535+
// Track if there was a selection before clearing
536+
const hadSelection = this.hasSelection;
537+
535538
this._model.selectionStartLength = 0;
536539
this._model.isSelectAllActive = false;
537540
this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;
@@ -543,6 +546,11 @@ export class SelectionService extends Disposable implements ISelectionService {
543546
}
544547
this._model.selectionEnd = undefined;
545548

549+
// Fire selection change event if a selection was cleared
550+
if (hadSelection) {
551+
this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);
552+
}
553+
546554
// Ensure the line exists
547555
const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);
548556
if (!line) {

test/playwright/Terminal.test.ts

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -361,17 +361,72 @@ test.describe('API Integration Tests', () => {
361361
await pollFor(ctx.page, `window.calls`, [1, 2]);
362362
});
363363

364-
test('onSelectionChange', async () => {
365-
await openTerminal(ctx);
366-
await ctx.page.evaluate(`
367-
window.callCount = 0;
368-
window.term.onSelectionChange(() => window.callCount++);
369-
`);
370-
await pollFor(ctx.page, `window.callCount`, 0);
371-
await ctx.page.evaluate(`window.term.selectAll()`);
372-
await pollFor(ctx.page, `window.callCount`, 1);
373-
await ctx.page.evaluate(`window.term.clearSelection()`);
374-
await pollFor(ctx.page, `window.callCount`, 2);
364+
test.describe('onSelectionChange', () => {
365+
let callCount: number;
366+
367+
test.beforeEach(async () => {
368+
await openTerminal(ctx);
369+
callCount = 0;
370+
ctx.proxy.onSelectionChange(() => callCount++);
371+
});
372+
373+
test('should fire for programmatic selection changes', async () => {
374+
strictEqual(callCount, 0);
375+
await ctx.proxy.selectAll();
376+
strictEqual(callCount, 1);
377+
await ctx.proxy.clearSelection();
378+
strictEqual(callCount, 2);
379+
});
380+
381+
test('should fire on mousedown when clearing selection', async () => {
382+
await ctx.proxy.write('foo bar baz');
383+
await ctx.proxy.selectAll();
384+
strictEqual(callCount, 1);
385+
386+
const dims = (await ctx.proxy.dimensions)!;
387+
const termRect: any = await ctx.page.evaluate(`window.term.element.getBoundingClientRect()`);
388+
const x = termRect.left + dims.css.cell.width * 5;
389+
const y = termRect.top + dims.css.cell.height * 0.5;
390+
await ctx.page.mouse.click(x, y);
391+
392+
await pollFor(ctx.page, () => callCount, 2);
393+
});
394+
395+
test('should not fire on mousedown when no prior selection', async () => {
396+
await ctx.proxy.write('foo bar baz');
397+
strictEqual(callCount, 0);
398+
399+
const dims = (await ctx.proxy.dimensions)!;
400+
const termRect: any = await ctx.page.evaluate(`window.term.element.getBoundingClientRect()`);
401+
const x = termRect.left + dims.css.cell.width * 5;
402+
const y = termRect.top + dims.css.cell.height * 0.5;
403+
await ctx.page.mouse.click(x, y);
404+
await timeout(20);
405+
406+
strictEqual(callCount, 0);
407+
});
408+
409+
test('should fire once on mousedown to clear, and again on mouseup after drag', async () => {
410+
await ctx.proxy.write('foo bar baz');
411+
await ctx.proxy.selectAll();
412+
strictEqual(callCount, 1);
413+
414+
const dims = (await ctx.proxy.dimensions)!;
415+
const termRect: any = await ctx.page.evaluate(`window.term.element.getBoundingClientRect()`);
416+
const startX = termRect.left + dims.css.cell.width * 0.5;
417+
const endX = termRect.left + dims.css.cell.width * 5;
418+
const y = termRect.top + dims.css.cell.height * 0.5;
419+
420+
await ctx.page.mouse.move(startX, y);
421+
await ctx.page.mouse.down();
422+
await pollFor(ctx.page, () => callCount, 2);
423+
424+
await ctx.page.mouse.move(endX, y);
425+
strictEqual(callCount, 2);
426+
427+
await ctx.page.mouse.up();
428+
await pollFor(ctx.page, () => callCount, 3);
429+
});
375430
});
376431

377432
test('onRender', async () => {

0 commit comments

Comments
 (0)