mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Create IKeyboardService
This commit is contained in:
@@ -39,8 +39,9 @@ import { LinkProviderService } from 'browser/services/LinkProviderService';
|
||||
import { MouseService } from 'browser/services/MouseService';
|
||||
import { RenderService } from 'browser/services/RenderService';
|
||||
import { SelectionService } from 'browser/services/SelectionService';
|
||||
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, ILinkProviderService, IMouseService, IRenderService, ISelectionService, IThemeService } from 'browser/services/Services';
|
||||
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseService, IRenderService, ISelectionService, IThemeService } from 'browser/services/Services';
|
||||
import { ThemeService } from 'browser/services/ThemeService';
|
||||
import { KeyboardService } from 'browser/services/KeyboardService';
|
||||
import { channels, color } from 'common/Color';
|
||||
import { CoreTerminal } from 'common/CoreTerminal';
|
||||
import * as Browser from 'common/Platform';
|
||||
@@ -48,8 +49,6 @@ import { ColorRequestType, CoreMouseAction, CoreMouseButton, CoreMouseEventType,
|
||||
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
||||
import { IBuffer } from 'common/buffer/Types';
|
||||
import { C0, C1_ESCAPED } from 'common/data/EscapeSequences';
|
||||
import { evaluateKeyboardEvent } from 'common/input/Keyboard';
|
||||
import { evaluateKeyboardEventKitty, KittyKeyboardEventType, shouldUseKittyProtocol } from 'common/input/KittyKeyboard';
|
||||
import { toRgbString } from 'common/input/XParseColor';
|
||||
import { DecorationService } from 'common/services/DecorationService';
|
||||
import { IDecorationService } from 'common/services/Services';
|
||||
@@ -82,6 +81,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
|
||||
// Browser services
|
||||
private _decorationService: DecorationService;
|
||||
private _keyboardService: IKeyboardService;
|
||||
private _linkProviderService: ILinkProviderService;
|
||||
|
||||
// Optional browser services
|
||||
@@ -174,6 +174,8 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
|
||||
this._decorationService = this._instantiationService.createInstance(DecorationService);
|
||||
this._instantiationService.setService(IDecorationService, this._decorationService);
|
||||
this._keyboardService = this._instantiationService.createInstance(KeyboardService);
|
||||
this._instantiationService.setService(IKeyboardService, this._keyboardService);
|
||||
this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);
|
||||
this._instantiationService.setService(ILinkProviderService, this._linkProviderService);
|
||||
this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));
|
||||
@@ -1082,12 +1084,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
this._unprocessedDeadKey = true;
|
||||
}
|
||||
|
||||
// Use Kitty keyboard protocol if enabled, otherwise use legacy encoding
|
||||
const kittyFlags = this.coreService.kittyKeyboard.flags;
|
||||
const useKitty = this.options.vtExtensions?.kittyKeyboard && shouldUseKittyProtocol(kittyFlags);
|
||||
const result = useKitty
|
||||
? evaluateKeyboardEventKitty(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS)
|
||||
: evaluateKeyboardEvent(event, this.coreService.decPrivateModes.applicationCursorKeys, this.browser.isMac, this.options.macOptionIsMeta);
|
||||
const result = this._keyboardService.evaluateKeyDown(event);
|
||||
|
||||
this.updateCursorStyle(event);
|
||||
|
||||
@@ -1117,7 +1114,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
// HACK: Process A-Z in the keypress event to fix an issue with macOS IMEs where lower case
|
||||
// letters cannot be input while caps lock is on. Skip this hack when using kitty protocol
|
||||
// as it needs to send proper CSI u sequences for all key events.
|
||||
if (!useKitty && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {
|
||||
if (!this._keyboardService.useKitty && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {
|
||||
if (event.key.charCodeAt(0) >= 65 && event.key.charCodeAt(0) <= 90) {
|
||||
return true;
|
||||
}
|
||||
@@ -1176,13 +1173,9 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
}
|
||||
|
||||
// Handle key release for Kitty keyboard protocol
|
||||
const kittyFlags = this.coreService.kittyKeyboard.flags;
|
||||
const useKitty = this.options.vtExtensions?.kittyKeyboard && shouldUseKittyProtocol(kittyFlags);
|
||||
if (useKitty && (kittyFlags & 0b10)) { // REPORT_EVENT_TYPES flag
|
||||
const result = evaluateKeyboardEventKitty(ev, kittyFlags, KittyKeyboardEventType.RELEASE);
|
||||
if (result.key) {
|
||||
this.coreService.triggerDataEvent(result.key, true);
|
||||
}
|
||||
const result = this._keyboardService.evaluateKeyUp(ev);
|
||||
if (result?.key) {
|
||||
this.coreService.triggerDataEvent(result.key, true);
|
||||
}
|
||||
|
||||
this.updateCursorStyle(ev);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2025 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IKeyboardService } from 'browser/services/Services';
|
||||
import { evaluateKeyboardEvent } from 'common/input/Keyboard';
|
||||
import { evaluateKeyboardEventKitty, KittyKeyboardEventType, shouldUseKittyProtocol } from 'common/input/KittyKeyboard';
|
||||
import { isMac } from 'common/Platform';
|
||||
import { ICoreService, IOptionsService } from 'common/services/Services';
|
||||
import { IKeyboardResult } from 'common/Types';
|
||||
|
||||
export class KeyboardService implements IKeyboardService {
|
||||
public serviceBrand: undefined;
|
||||
|
||||
constructor(
|
||||
@ICoreService private readonly _coreService: ICoreService,
|
||||
@IOptionsService private readonly _optionsService: IOptionsService
|
||||
) {
|
||||
}
|
||||
|
||||
public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {
|
||||
const kittyFlags = this._coreService.kittyKeyboard.flags;
|
||||
return this.useKitty
|
||||
? evaluateKeyboardEventKitty(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS)
|
||||
: evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);
|
||||
}
|
||||
|
||||
public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {
|
||||
const kittyFlags = this._coreService.kittyKeyboard.flags;
|
||||
if (this.useKitty && (kittyFlags & 0b10)) { // REPORT_EVENT_TYPES flag
|
||||
return evaluateKeyboardEventKitty(event, kittyFlags, KittyKeyboardEventType.RELEASE);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public get useKitty(): boolean {
|
||||
const kittyFlags = this._coreService.kittyKeyboard.flags;
|
||||
return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && shouldUseKittyProtocol(kittyFlags));
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/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 } from 'common/Types';
|
||||
import { AllColorIndex, IDisposable, IKeyboardResult } from 'common/Types';
|
||||
import type { Event } from 'vs/base/common/event';
|
||||
|
||||
export const ICharSizeService = createDecorator<ICharSizeService>('CharSizeService');
|
||||
@@ -156,3 +156,11 @@ export interface ILinkProviderService extends IDisposable {
|
||||
export interface ILinkProvider {
|
||||
provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;
|
||||
}
|
||||
|
||||
export const IKeyboardService = createDecorator<IKeyboardService>('KeyboardService');
|
||||
export interface IKeyboardService {
|
||||
serviceBrand: undefined;
|
||||
evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;
|
||||
evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;
|
||||
readonly useKitty: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user