addCustomWheelEventHandler API

I opted for consistency with the key event handler over our more modern
approach, we can migrate them at the same time if we end up returning
a disposable.

See microsoft/vscode#76381
This commit is contained in:
Daniel Imms
2023-12-12 05:17:24 -08:00
parent fb2c39cb57
commit 88ba66d00b
6 changed files with 43 additions and 10 deletions
+13 -10
View File
@@ -26,7 +26,7 @@ import { addDisposableDomListener } from 'browser/Lifecycle';
import { Linkifier2 } from 'browser/Linkifier2';
import * as Strings from 'browser/LocalizableStrings';
import { OscLinkProvider } from 'browser/OscLinkProvider';
import { CharacterJoinerHandler, CustomKeyEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal, IViewport } from 'browser/Types';
import { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal, IViewport } from 'browser/Types';
import { Viewport } from 'browser/Viewport';
import { BufferDecorationRenderer } from 'browser/decorations/BufferDecorationRenderer';
import { OverviewRulerRenderer } from 'browser/decorations/OverviewRulerRenderer';
@@ -74,6 +74,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
public browser: IBrowser = Browser as any;
private _customKeyEventHandler: CustomKeyEventHandler | undefined;
private _customWheelEventHandler: CustomWheelEventHandler | undefined;
// browser services
private _decorationService: DecorationService;
@@ -633,6 +634,9 @@ export class Terminal extends CoreTerminal implements ITerminal {
but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;
break;
case 'wheel':
if (self._customWheelEventHandler && self._customWheelEventHandler(ev as WheelEvent) === false) {
return false;
}
const amount = self.viewport!.getLinesScrolled(ev as WheelEvent);
if (amount === 0) {
@@ -792,6 +796,10 @@ export class Terminal extends CoreTerminal implements ITerminal {
// do nothing, if app side handles wheel itself
if (requestedEvents.wheel) return;
if (this._customWheelEventHandler && this._customWheelEventHandler(ev) === false) {
return false;
}
if (!this.buffer.hasScrollback) {
// Convert wheel events into up/down events when the buffer does not have scrollback, this
// enables scrolling in apps hosted in the alt buffer such as vim or tmux.
@@ -878,19 +886,14 @@ export class Terminal extends CoreTerminal implements ITerminal {
paste(data, this.textarea!, this.coreService, this.optionsService);
}
/**
* Attaches a custom key event handler which is run before keys are processed,
* giving consumers of xterm.js ultimate control as to what keys should be
* processed by the terminal and what keys should not.
* @param customKeyEventHandler The custom KeyboardEvent handler to attach.
* This is a function that takes a KeyboardEvent, allowing consumers to stop
* propagation and/or prevent the default action. The function returns whether
* the event should be processed by xterm.js.
*/
public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {
this._customKeyEventHandler = customKeyEventHandler;
}
public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void {
this._customWheelEventHandler = customWheelEventHandler;
}
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
return this.linkifier2.registerLinkProvider(linkProvider);
}
+3
View File
@@ -86,6 +86,9 @@ export class MockTerminal implements ITerminal {
public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {
throw new Error('Method not implemented.');
}
public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {
throw new Error('Method not implemented.');
}
public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise<boolean>): IDisposable {
throw new Error('Method not implemented.');
}
+1
View File
@@ -32,6 +32,7 @@ export interface ITerminal extends InternalPassthroughApis, ICoreTerminal {
}
export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
export type CustomWheelEventHandler = (event: WheelEvent) => boolean;
export type LineData = CharData[];
+3
View File
@@ -148,6 +148,9 @@ export class Terminal extends Disposable implements ITerminalApi {
public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {
this._core.attachCustomKeyEventHandler(customKeyEventHandler);
}
public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {
this._core.attachCustomWheelEventHandler(customWheelEventHandler);
}
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
return this._core.registerLinkProvider(linkProvider);
}
+1
View File
@@ -75,6 +75,7 @@ type TerminalProxyCustomOverrides = 'buffer' | (
'options' |
'open' |
'attachCustomKeyEventHandler' |
'attachCustomWheelEventHandler' |
'registerLinkProvider' |
'registerCharacterJoiner' |
'deregisterCharacterJoiner' |
+22
View File
@@ -1010,6 +1010,28 @@ declare module '@xterm/xterm' {
*/
attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void;
/**
* Attaches a custom wheel event handler which is run before keys are
* processed, giving consumers of xterm.js control over whether to proceed
* or cancel terminal wheel events.
* @param customMouseEventHandler The custom WheelEvent handler to attach.
* This is a function that takes a WheelEvent, allowing consumers to stop
* propagation and/or prevent the default action. The function returns
* whether the event should be processed by xterm.js.
*
* @example A handler that prevents all wheel events while ctrl is held from
* being processed.
* ```ts
* term.attachCustomKeyEventHandler(ev => {
* if (ev.ctrlKey) {
* return false;
* }
* return true;
* });
* ```
*/
attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void;
/**
* Registers a link provider, allowing a custom parser to be used to match
* and handle links. Multiple link providers can be used, they will be asked