Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat #6518: add disconnect current tab hotkey and context menu item #8589

Merged
merged 4 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tabby-core/src/configDefaults.linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ hotkeys:
duplicate-tab: []
restart-tab: []
reconnect-tab: []
disconnect-tab: []
explode-tab:
- 'Ctrl-Shift-.'
combine-tabs:
Expand Down
1 change: 1 addition & 0 deletions tabby-core/src/configDefaults.macos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ hotkeys:
duplicate-tab: []
restart-tab: []
reconnect-tab: []
disconnect-tab: []
explode-tab:
- '⌘-Shift-.'
combine-tabs:
Expand Down
1 change: 1 addition & 0 deletions tabby-core/src/configDefaults.windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ hotkeys:
duplicate-tab: []
restart-tab: []
reconnect-tab: []
disconnect-tab: []
explode-tab:
- 'Ctrl-Shift-.'
combine-tabs:
Expand Down
22 changes: 18 additions & 4 deletions tabby-terminal/src/api/baseTerminalTab.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,10 +772,7 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
})

this.attachSessionHandler(this.session.closed$, () => {
const behavior = this.profile.behaviorOnSessionEnd
if (destroyOnSessionClose || behavior === 'close' || behavior === 'auto' && this.isSessionExplicitlyTerminated()) {
this.destroy()
}
this.onSessionClosed(destroyOnSessionClose)
})

this.attachSessionHandler(this.session.destroyed$, () => {
Expand All @@ -788,6 +785,23 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
})
}

/**
* Method called when session is closed.
*/
protected onSessionClosed (destroyOnSessionClose = false): void {
if (destroyOnSessionClose || this.shouldTabBeDestroyedOnSessionClose()) {
this.destroy()
}
}

/**
* Return true if tab should be destroyed on session closed.
*/
protected shouldTabBeDestroyedOnSessionClose (): boolean {
const behavior = this.profile.behaviorOnSessionEnd
return behavior === 'close' || behavior === 'auto' && this.isSessionExplicitlyTerminated()
}

/**
* Method called when session is destroyed. Set the session to null
*/
Expand Down
36 changes: 32 additions & 4 deletions tabby-terminal/src/api/connectableTerminalTab.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,25 @@ import { GetRecoveryTokenOptions, RecoveryToken } from 'tabby-core'
export abstract class ConnectableTerminalTabComponent<P extends BaseTerminalProfile> extends BaseTerminalTabComponent<P> {

protected reconnectOffered = false
protected isDisconnectedByHand = false

constructor (protected injector: Injector) {
super(injector)

this.subscribeUntilDestroyed(this.hotkeys.hotkey$, hotkey => {
if (this.hasFocus && hotkey === 'reconnect-tab') {
this.reconnect()
if (!this.hasFocus) {
return
}

switch (hotkey) {
case 'reconnect-tab':
this.reconnect()
this.notifications.notice(this.translate.instant('Reconnect'))
break
case 'disconnect-tab':
this.disconnect()
this.notifications.notice(this.translate.instant('Disconnect'))
break
}
})
}
Expand All @@ -44,6 +56,7 @@ export abstract class ConnectableTerminalTabComponent<P extends BaseTerminalProf
*/
async initializeSession (): Promise<void> {
this.reconnectOffered = false
this.isDisconnectedByHand = false
}

/**
Expand All @@ -53,9 +66,9 @@ export abstract class ConnectableTerminalTabComponent<P extends BaseTerminalProf
super.onSessionDestroyed()

if (this.frontend) {
if (this.profile.behaviorOnSessionEnd === 'reconnect') {
if (this.profile.behaviorOnSessionEnd === 'reconnect' && !this.isDisconnectedByHand) {
this.reconnect()
} else if (this.profile.behaviorOnSessionEnd === 'keep' || this.profile.behaviorOnSessionEnd === 'auto' && !this.isSessionExplicitlyTerminated()) {
} else if (this.profile.behaviorOnSessionEnd === 'keep' || !this.shouldTabBeDestroyedOnSessionClose()) {
this.offerReconnection()
}
}
Expand All @@ -77,6 +90,16 @@ export abstract class ConnectableTerminalTabComponent<P extends BaseTerminalProf
}
}

/**
* Return true if tab should be destroyed on session closed.
*/
protected shouldTabBeDestroyedOnSessionClose (): boolean {
if (this.isDisconnectedByHand) {
return false
}
return super.shouldTabBeDestroyedOnSessionClose()
}

async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise<RecoveryToken> {
return {
type: `app:${this.profile.type}-tab`,
Expand All @@ -85,6 +108,11 @@ export abstract class ConnectableTerminalTabComponent<P extends BaseTerminalProf
}
}

async disconnect (): Promise<void> {
this.isDisconnectedByHand = true
await this.session?.destroy()
}

async reconnect (): Promise<void> {
this.session?.destroy()
await this.initializeSession()
Expand Down
4 changes: 4 additions & 0 deletions tabby-terminal/src/hotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
id: 'reconnect-tab',
name: this.translate.instant('Reconnect current tab (Serial/Telnet/SSH)'),
},
{
id: 'disconnect-tab',
name: this.translate.instant('Disconnect current tab (Serial/Telnet/SSH)'),
},
]

constructor (private translate: TranslateService) { super() }
Expand Down
9 changes: 9 additions & 0 deletions tabby-terminal/src/tabContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ export class ReconnectContextMenu extends TabContextMenuItemProvider {
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
if (tab instanceof ConnectableTerminalTabComponent) {
return [
{
label: this.translate.instant('Disconnect'),
click: (): void => {
setTimeout(() => {
tab.disconnect()
this.notifications.notice(this.translate.instant('Disconnect'))
})
},
},
{
label: this.translate.instant('Reconnect'),
click: (): void => {
Expand Down
Loading