Handle mouseEventsRequireAlt option changes in mouse mode
Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
This commit is contained in:
co-authored by
Daniel Imms
parent
f8cef535c7
commit
7711d780c2
@@ -623,6 +623,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
this.element.classList.add('enable-mouse-events');
|
||||
} else {
|
||||
this._selectionService.enable();
|
||||
this.element.classList.remove('enable-mouse-events');
|
||||
}
|
||||
|
||||
if (this.options.screenReaderMode) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { MouseService } from 'browser/services/MouseService';
|
||||
import { MouseStateService } from 'common/services/MouseStateService';
|
||||
import { CoreMouseAction, CoreMouseButton } from 'common/Types';
|
||||
import { IBufferService, ICoreService, ILogService, IOptionsService } from 'common/services/Services';
|
||||
import { OptionsService } from 'common/services/OptionsService';
|
||||
import { MockCoreBrowserService, MockRenderService, MockSelectionService } from 'browser/TestUtils.test';
|
||||
|
||||
function toBytes(s: string | undefined): number[] {
|
||||
@@ -42,6 +43,36 @@ const logService: ILogService = {
|
||||
error: () => {}
|
||||
} as any;
|
||||
|
||||
class TestSelectionService extends MockSelectionService {
|
||||
public enableCount = 0;
|
||||
public disableCount = 0;
|
||||
|
||||
public override enable(): void {
|
||||
this.enableCount++;
|
||||
}
|
||||
|
||||
public override disable(): void {
|
||||
this.disableCount++;
|
||||
}
|
||||
|
||||
public override shouldForceSelection(): boolean {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createTestMouseTargetElement(): HTMLElement {
|
||||
const classes = new Set<string>();
|
||||
return {
|
||||
classList: {
|
||||
add: (className: string) => classes.add(className),
|
||||
remove: (className: string) => classes.delete(className),
|
||||
contains: (className: string) => classes.has(className)
|
||||
},
|
||||
addEventListener: () => {},
|
||||
removeEventListener: () => {}
|
||||
} as any;
|
||||
}
|
||||
|
||||
describe('MouseService _triggerMouseEvent', () => {
|
||||
let mouseService: MouseService;
|
||||
let mouseStateService: MouseStateService;
|
||||
@@ -211,3 +242,52 @@ describe('MouseService _triggerMouseEvent', () => {
|
||||
reports = [];
|
||||
});
|
||||
});
|
||||
|
||||
describe('MouseService mouseEventsRequireAlt', () => {
|
||||
it('should update selection state and cursor class when toggled while mouse events are active', () => {
|
||||
const mouseStateService = new MouseStateService();
|
||||
const optionsService = new OptionsService({});
|
||||
const selectionService = new TestSelectionService();
|
||||
const mouseService = new MouseService(
|
||||
new MockRenderService(),
|
||||
{
|
||||
getMouseReportCoords: (_ev: MouseEvent, _el: HTMLElement) => ({ col: 0, row: 0, x: 0, y: 0 })
|
||||
} as any,
|
||||
mouseStateService,
|
||||
{
|
||||
triggerDataEvent: () => {},
|
||||
triggerBinaryEvent: () => {},
|
||||
decPrivateModes: { applicationCursorKeys: false }
|
||||
} as any,
|
||||
bufferService,
|
||||
optionsService,
|
||||
selectionService,
|
||||
logService,
|
||||
new MockCoreBrowserService()
|
||||
);
|
||||
const element = createTestMouseTargetElement();
|
||||
const screenElement = createTestMouseTargetElement();
|
||||
const document = {
|
||||
addEventListener: () => {},
|
||||
removeEventListener: () => {}
|
||||
} as any;
|
||||
|
||||
mouseService.bindMouse({
|
||||
element,
|
||||
screenElement,
|
||||
document
|
||||
}, disposable => disposable, () => {});
|
||||
|
||||
mouseStateService.activeProtocol = 'ANY';
|
||||
assert.isTrue(element.classList.contains('enable-mouse-events'));
|
||||
assert.equal(selectionService.disableCount, 1);
|
||||
|
||||
optionsService.options.mouseEventsRequireAlt = true;
|
||||
assert.isFalse(element.classList.contains('enable-mouse-events'));
|
||||
assert.equal(selectionService.enableCount, 2);
|
||||
|
||||
optionsService.options.mouseEventsRequireAlt = false;
|
||||
assert.isTrue(element.classList.contains('enable-mouse-events'));
|
||||
assert.equal(selectionService.disableCount, 2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -66,6 +66,9 @@ export class MouseService implements IMouseService {
|
||||
register(this._mouseStateService.onProtocolChange(events => {
|
||||
this._handleProtocolChange(ctx, eventListeners, events);
|
||||
}));
|
||||
register(this._optionsService.onSpecificOptionChange('mouseEventsRequireAlt', () => {
|
||||
this._syncMouseModeState(element);
|
||||
}));
|
||||
// force initial onProtocolChange so we dont miss early mouse requests
|
||||
this._mouseStateService.activeProtocol = this._mouseStateService.activeProtocol;
|
||||
|
||||
@@ -360,6 +363,21 @@ export class MouseService implements IMouseService {
|
||||
this._touchScrollAccumulator = 0;
|
||||
}
|
||||
|
||||
private _syncMouseModeState(element: HTMLElement): void {
|
||||
if (this._mouseStateService.areMouseEventsActive) {
|
||||
if (this._optionsService.rawOptions.mouseEventsRequireAlt) {
|
||||
element.classList.remove('enable-mouse-events');
|
||||
this._selectionService.enable();
|
||||
} else {
|
||||
element.classList.add('enable-mouse-events');
|
||||
this._selectionService.disable();
|
||||
}
|
||||
} else {
|
||||
element.classList.remove('enable-mouse-events');
|
||||
this._selectionService.enable();
|
||||
}
|
||||
}
|
||||
|
||||
private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {
|
||||
const { element, document } = ctx.target;
|
||||
const { requestedEvents } = ctx;
|
||||
@@ -368,17 +386,10 @@ export class MouseService implements IMouseService {
|
||||
if (this._optionsService.rawOptions.logLevel === 'debug') {
|
||||
this._logService.debug('Binding to mouse events:', this._explainEvents(events));
|
||||
}
|
||||
if (this._optionsService.rawOptions.mouseEventsRequireAlt) {
|
||||
this._selectionService.enable();
|
||||
} else {
|
||||
element.classList.add('enable-mouse-events');
|
||||
this._selectionService.disable();
|
||||
}
|
||||
} else {
|
||||
this._logService.debug('Unbinding from mouse events.');
|
||||
element.classList.remove('enable-mouse-events');
|
||||
this._selectionService.enable();
|
||||
}
|
||||
this._syncMouseModeState(element);
|
||||
|
||||
// add/remove handlers from requestedEvents
|
||||
if (!(events & CoreMouseEventType.MOVE)) {
|
||||
|
||||
Reference in New Issue
Block a user