terminalTab.component.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
  2. import { Component, Input, Injector } from '@angular/core'
  3. import { BaseTabProcess, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild, GetRecoveryTokenOptions } from 'tabby-core'
  4. import { BaseTerminalTabComponent } from 'tabby-terminal'
  5. import { LocalProfile, SessionOptions } from '../api'
  6. import { Session } from '../session'
  7. import { UACService } from '../services/uac.service'
  8. /** @hidden */
  9. @Component({
  10. selector: 'terminalTab',
  11. template: BaseTerminalTabComponent.template,
  12. styles: BaseTerminalTabComponent.styles,
  13. animations: BaseTerminalTabComponent.animations,
  14. })
  15. export class TerminalTabComponent extends BaseTerminalTabComponent<LocalProfile> {
  16. @Input() sessionOptions: SessionOptions // Deprecated
  17. session: Session|null = null
  18. // eslint-disable-next-line @typescript-eslint/no-useless-constructor
  19. constructor (
  20. injector: Injector,
  21. private uac: UACService,
  22. ) {
  23. super(injector)
  24. }
  25. ngOnInit (): void {
  26. this.sessionOptions = this.profile.options
  27. this.logger = this.log.create('terminalTab')
  28. this.session = new Session(this.injector)
  29. const isConPTY = isWindowsBuild(WIN_BUILD_CONPTY_SUPPORTED) && this.config.store.terminal.useConPTY
  30. this.subscribeUntilDestroyed(this.hotkeys.hotkey$, hotkey => {
  31. if (!this.hasFocus) {
  32. return
  33. }
  34. switch (hotkey) {
  35. case 'home':
  36. this.sendInput(isConPTY ? '\x1b[H' : '\x1bOH')
  37. break
  38. case 'end':
  39. this.sendInput(isConPTY ? '\x1b[F' : '\x1bOF')
  40. break
  41. }
  42. })
  43. super.ngOnInit()
  44. }
  45. protected onFrontendReady (): void {
  46. this.initializeSession(this.size.columns, this.size.rows)
  47. this.savedStateIsLive = this.profile.options.restoreFromPTYID === this.session?.getPTYID()
  48. super.onFrontendReady()
  49. }
  50. initializeSession (columns: number, rows: number): void {
  51. if (this.profile.options.runAsAdministrator && this.uac.isAvailable) {
  52. this.profile = {
  53. ...this.profile,
  54. options: this.uac.patchSessionOptionsForUAC(this.profile.options),
  55. }
  56. }
  57. this.session!.start({
  58. ...this.profile.options,
  59. width: columns,
  60. height: rows,
  61. })
  62. this.attachSessionHandlers(true)
  63. this.recoveryStateChangedHint.next()
  64. }
  65. async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise<any> {
  66. const cwd = this.session ? await this.session.getWorkingDirectory() : null
  67. return {
  68. type: 'app:local-tab',
  69. profile: {
  70. ...this.profile,
  71. options: {
  72. ...this.profile.options,
  73. cwd: cwd ?? this.profile.options.cwd,
  74. restoreFromPTYID: options?.includeState && this.session?.getPTYID(),
  75. },
  76. },
  77. savedState: options?.includeState && this.frontend?.saveState(),
  78. }
  79. }
  80. async getCurrentProcess (): Promise<BaseTabProcess|null> {
  81. const children = await this.session?.getChildProcesses()
  82. if (!children?.length) {
  83. return null
  84. }
  85. return {
  86. name: children[0].command,
  87. }
  88. }
  89. async canClose (): Promise<boolean> {
  90. const children = await this.session?.getChildProcesses()
  91. if (!children?.length) {
  92. return true
  93. }
  94. return (await this.platform.showMessageBox(
  95. {
  96. type: 'warning',
  97. message: this.translate.instant(
  98. _('"{command}" is still running. Close?'),
  99. children[0],
  100. ),
  101. buttons: [
  102. this.translate.instant(_('Kill')),
  103. this.translate.instant(_('Cancel')),
  104. ],
  105. defaultId: 0,
  106. cancelId: 1,
  107. },
  108. )).response === 0
  109. }
  110. ngOnDestroy (): void {
  111. super.ngOnDestroy()
  112. this.session?.destroy()
  113. }
  114. }