diff --git a/src/browser/CoreBrowserTerminal.ts b/src/browser/CoreBrowserTerminal.ts index fe74f3d80..de2d76a36 100644 --- a/src/browser/CoreBrowserTerminal.ts +++ b/src/browser/CoreBrowserTerminal.ts @@ -78,7 +78,6 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { public browser: IBrowser = Browser as any; private _customKeyEventHandler: CustomKeyEventHandler | undefined; - private _customWheelEventHandler: CustomWheelEventHandler | undefined; // Browser services private readonly _decorationService: DecorationService; @@ -582,7 +581,6 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { )); this._instantiationService.setService(ISelectionService, this._selectionService); this._mouseService = this._instantiationService.createInstance(MouseService); - this._mouseService.setCustomWheelEventHandler(this._customWheelEventHandler); this._instantiationService.setService(IMouseService, this._mouseService); this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent))); this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire())); @@ -727,8 +725,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { } public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void { - this._customWheelEventHandler = customWheelEventHandler; - this._mouseService?.setCustomWheelEventHandler(customWheelEventHandler); + this.mouseStateService.setCustomWheelEventHandler(customWheelEventHandler); } public registerLinkProvider(linkProvider: ILinkProvider): IDisposable { diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index fc62b4c4b..4f38faa2e 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -393,10 +393,6 @@ export class MockMouseService implements IMouseService { throw new Error('Not implemented'); } - public setCustomWheelEventHandler(): void { - throw new Error('Not implemented'); - } - public bindMouse(): void { throw new Error('Not implemented'); } diff --git a/src/browser/services/MouseService.ts b/src/browser/services/MouseService.ts index b75ee15b8..d21b3debf 100644 --- a/src/browser/services/MouseService.ts +++ b/src/browser/services/MouseService.ts @@ -8,7 +8,6 @@ import { IBufferService, IMouseStateService, ICoreService, ILogService, IOptions import { CoreMouseAction, CoreMouseButton, CoreMouseEventType, IDisposable } from 'common/Types'; import { C0 } from 'common/data/EscapeSequences'; import { toDisposable } from 'common/Lifecycle'; -import { CustomWheelEventHandler } from 'browser/Types'; import { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services'; type RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>; @@ -22,8 +21,6 @@ interface IMouseBindContext { export class MouseService implements IMouseService { public serviceBrand: undefined; - private _customWheelEventHandler: CustomWheelEventHandler | undefined; - constructor( @IRenderService private readonly _renderService: IRenderService, @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService, @@ -119,7 +116,7 @@ export class MouseService implements IMouseService { but = ev.button < 3 ? ev.button : CoreMouseButton.NONE; break; case 'wheel': - if (this._customWheelEventHandler && this._customWheelEventHandler(ev as WheelEvent) === false) { + if (!this._mouseStateService.allowCustomWheelEvent(ev as WheelEvent)) { return false; } const deltaY = (ev as WheelEvent).deltaY; @@ -226,7 +223,7 @@ export class MouseService implements IMouseService { return; } - if (this._customWheelEventHandler && this._customWheelEventHandler(ev) === false) { + if (!this._mouseStateService.allowCustomWheelEvent(ev)) { return false; } @@ -320,7 +317,4 @@ export class MouseService implements IMouseService { } } - public setCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler | undefined): void { - this._customWheelEventHandler = customWheelEventHandler; - } } diff --git a/src/browser/services/Services.ts b/src/browser/services/Services.ts index 7f1c10576..2471d5718 100644 --- a/src/browser/services/Services.ts +++ b/src/browser/services/Services.ts @@ -4,7 +4,7 @@ */ import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types'; -import { CustomWheelEventHandler, IColorSet, ILink, ReadonlyColorSet } from 'browser/Types'; +import { IColorSet, ILink, ReadonlyColorSet } from 'browser/Types'; import { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types'; import { createDecorator } from 'common/services/ServiceRegistry'; import { AllColorIndex, IDisposable, IKeyboardResult } from 'common/Types'; @@ -61,7 +61,6 @@ export const IMouseService = createDecorator('MouseService'); export interface IMouseService { serviceBrand: undefined; - setCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler | undefined): void; bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void; } export interface IMouseServiceTarget { diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index cd09be569..cd5798d4f 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -82,6 +82,8 @@ export class MockMouseStateService implements IMouseStateService { public consumeWheelEvent(ev: WheelEvent, cellHeight: number, dpr: number): number { return 1; } + public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void { } + public allowCustomWheelEvent(ev: WheelEvent): boolean { return true; } } export class MockCharsetService implements ICharsetService { diff --git a/src/common/services/MouseStateService.ts b/src/common/services/MouseStateService.ts index 7a52d97ed..8a2629482 100644 --- a/src/common/services/MouseStateService.ts +++ b/src/common/services/MouseStateService.ts @@ -175,6 +175,7 @@ export class MouseStateService extends Disposable implements IMouseStateService private _activeEncoding: string = ''; private _lastEvent: ICoreMouseEvent | null = null; private _wheelPartialScroll: number = 0; + private _customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined; private readonly _onProtocolChange = this._register(new Emitter()); public readonly onProtocolChange = this._onProtocolChange.event; @@ -268,6 +269,14 @@ export class MouseStateService extends Disposable implements IMouseStateService return amount; } + public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void { + this._customWheelEventHandler = customWheelEventHandler; + } + + public allowCustomWheelEvent(ev: WheelEvent): boolean { + return this._customWheelEventHandler ? this._customWheelEventHandler(ev) !== false : true; + } + private _applyScrollModifier(amount: number, ev: WheelEvent): number { // Multiply the scroll speed when the modifier key is pressed if (ev.altKey || ev.ctrlKey || ev.shiftKey) { diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index 9a7561be0..5b298d720 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -70,6 +70,16 @@ export interface IMouseStateService { * Process wheel event taking partial scroll into account. */ consumeWheelEvent(ev: WheelEvent, cellHeight?: number, dpr?: number): number; + + /** + * Sets a custom wheel event handler that can veto wheel processing. + */ + setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void; + + /** + * Checks whether a wheel event should be processed. + */ + allowCustomWheelEvent(ev: WheelEvent): boolean; } export const ICoreService = createDecorator('CoreService');