mirror of
https://github.com/Eugeny/tabby.git
synced 2025-07-02 09:29:54 +00:00
moved menu zone handling into terminus-electron
This commit is contained in:
parent
cdf97f3b31
commit
96ce42461d
@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import { Injectable, NgZone } from '@angular/core'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { AppService } from './services/app.service'
|
||||
import { BaseTabComponent } from './components/baseTab.component'
|
||||
@ -15,7 +15,6 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
||||
|
||||
constructor (
|
||||
private app: AppService,
|
||||
private zone: NgZone,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@ -24,13 +23,13 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
||||
let items: MenuItemOptions[] = [
|
||||
{
|
||||
label: 'Close',
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
if (this.app.tabs.includes(tab)) {
|
||||
this.app.closeTab(tab, true)
|
||||
} else {
|
||||
tab.destroy()
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
]
|
||||
if (tabHeader) {
|
||||
@ -38,27 +37,27 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
||||
...items,
|
||||
{
|
||||
label: 'Close other tabs',
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
for (const t of this.app.tabs.filter(x => x !== tab)) {
|
||||
this.app.closeTab(t, true)
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Close tabs to the right',
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
|
||||
this.app.closeTab(t, true)
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Close tabs to the left',
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
|
||||
this.app.closeTab(t, true)
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
]
|
||||
} else {
|
||||
@ -73,9 +72,9 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
||||
l: 'Left',
|
||||
t: 'Up',
|
||||
}[dir],
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
(tab.parent as SplitTabComponent).splitTab(tab, dir)
|
||||
}),
|
||||
},
|
||||
})) as MenuItemOptions[],
|
||||
})
|
||||
}
|
||||
@ -100,7 +99,6 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
||||
weight = -1
|
||||
|
||||
constructor (
|
||||
private zone: NgZone,
|
||||
private app: AppService,
|
||||
) {
|
||||
super()
|
||||
@ -113,11 +111,11 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
||||
...items,
|
||||
{
|
||||
label: 'Rename',
|
||||
click: () => this.zone.run(() => tabHeader.showRenameTabModal()),
|
||||
click: () => tabHeader.showRenameTabModal(),
|
||||
},
|
||||
{
|
||||
label: 'Duplicate',
|
||||
click: () => this.zone.run(() => this.app.duplicateTab(tab)),
|
||||
click: () => this.app.duplicateTab(tab),
|
||||
},
|
||||
{
|
||||
label: 'Color',
|
||||
@ -126,9 +124,9 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
||||
label: color.name,
|
||||
type: 'radio',
|
||||
checked: tab.color === color.value,
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
tab.color = color.value
|
||||
}),
|
||||
},
|
||||
})) as MenuItemOptions[],
|
||||
},
|
||||
]
|
||||
@ -142,7 +140,6 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
||||
export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
||||
constructor (
|
||||
private app: AppService,
|
||||
private zone: NgZone,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@ -162,7 +159,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
||||
label: 'Notify when done',
|
||||
type: 'checkbox',
|
||||
checked: extTab.__completionNotificationEnabled,
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
extTab.__completionNotificationEnabled = !extTab.__completionNotificationEnabled
|
||||
|
||||
if (extTab.__completionNotificationEnabled) {
|
||||
@ -177,14 +174,14 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
||||
} else {
|
||||
this.app.stopObservingTabCompletion(tab)
|
||||
}
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
items.push({
|
||||
label: 'Notify on activity',
|
||||
type: 'checkbox',
|
||||
checked: !!extTab.__outputNotificationSubscription,
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
if (extTab.__outputNotificationSubscription) {
|
||||
extTab.__outputNotificationSubscription.unsubscribe()
|
||||
extTab.__outputNotificationSubscription = null
|
||||
@ -201,7 +198,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
||||
}
|
||||
})
|
||||
}
|
||||
}),
|
||||
},
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
@ -147,9 +147,19 @@ export class ElectronPlatformService extends PlatformService {
|
||||
}
|
||||
|
||||
popupContextMenu (menu: MenuItemOptions[], _event?: MouseEvent): void {
|
||||
this.electron.Menu.buildFromTemplate(menu.map(item => ({
|
||||
...item,
|
||||
}))).popup({})
|
||||
this.electron.Menu.buildFromTemplate(menu.map(item => this.rewrapMenuItemOptions(item))).popup({})
|
||||
}
|
||||
|
||||
rewrapMenuItemOptions (menu: MenuItemOptions): MenuItemOptions {
|
||||
return {
|
||||
...menu,
|
||||
click: () => {
|
||||
this.zone.run(() => {
|
||||
menu.click?.()
|
||||
})
|
||||
},
|
||||
submenu: menu.submenu ? menu.submenu.map(x => this.rewrapMenuItemOptions(x)) : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
async showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult> {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable, NgZone } from '@angular/core'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, SplitTabComponent, NotificationsService, MenuItemOptions } from 'terminus-core'
|
||||
import { TerminalTabComponent } from './components/terminalTab.component'
|
||||
import { UACService } from './services/uac.service'
|
||||
@ -9,7 +9,6 @@ import { TerminalService } from './services/terminal.service'
|
||||
export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
|
||||
constructor (
|
||||
private config: ConfigService,
|
||||
private zone: NgZone,
|
||||
private notifications: NotificationsService,
|
||||
) {
|
||||
super()
|
||||
@ -22,7 +21,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
|
||||
const items: MenuItemOptions[] = [
|
||||
{
|
||||
label: 'Save as profile',
|
||||
click: () => this.zone.run(async () => {
|
||||
click: async () => {
|
||||
const profile = {
|
||||
sessionOptions: {
|
||||
...tab.sessionOptions,
|
||||
@ -36,7 +35,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
|
||||
]
|
||||
this.config.save()
|
||||
this.notifications.info('Saved')
|
||||
}),
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@ -51,7 +50,6 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
|
||||
|
||||
constructor (
|
||||
public config: ConfigService,
|
||||
private zone: NgZone,
|
||||
private terminalService: TerminalService,
|
||||
private uac: UACService,
|
||||
) {
|
||||
@ -64,21 +62,21 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
|
||||
const items: MenuItemOptions[] = [
|
||||
{
|
||||
label: 'New terminal',
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
this.terminalService.openTabWithOptions((tab as any).sessionOptions)
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'New with profile',
|
||||
submenu: profiles.map(profile => ({
|
||||
label: profile.name,
|
||||
click: () => this.zone.run(async () => {
|
||||
click: async () => {
|
||||
let workingDirectory = this.config.store.terminal.workingDirectory
|
||||
if (this.config.store.terminal.alwaysUseWorkingDirectory !== true && tab instanceof TerminalTabComponent) {
|
||||
workingDirectory = await tab.session?.getWorkingDirectory()
|
||||
}
|
||||
await this.terminalService.openTab(profile, workingDirectory)
|
||||
}),
|
||||
},
|
||||
})),
|
||||
},
|
||||
]
|
||||
@ -88,12 +86,12 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
|
||||
label: 'New admin tab',
|
||||
submenu: profiles.map(profile => ({
|
||||
label: profile.name,
|
||||
click: () => this.zone.run(async () => {
|
||||
click: () => {
|
||||
this.terminalService.openTabWithOptions({
|
||||
...profile.sessionOptions,
|
||||
runAsAdministrator: true,
|
||||
})
|
||||
}),
|
||||
},
|
||||
})),
|
||||
})
|
||||
}
|
||||
@ -101,28 +99,28 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
|
||||
if (tab instanceof TerminalTabComponent && tabHeader && this.uac.isAvailable) {
|
||||
items.push({
|
||||
label: 'Duplicate as administrator',
|
||||
click: () => this.zone.run(async () => {
|
||||
click: () => {
|
||||
this.terminalService.openTabWithOptions({
|
||||
...tab.sessionOptions,
|
||||
runAsAdministrator: true,
|
||||
})
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (tab instanceof TerminalTabComponent && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
|
||||
items.push({
|
||||
label: 'Focus all panes',
|
||||
click: () => this.zone.run(() => {
|
||||
click: () => {
|
||||
tab.focusAllPanes()
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (tab instanceof TerminalTabComponent && tab.session?.supportsWorkingDirectory()) {
|
||||
items.push({
|
||||
label: 'Copy current path',
|
||||
click: () => this.zone.run(() => tab.copyCurrentPath()),
|
||||
click: () => tab.copyCurrentPath(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -20,16 +20,18 @@ export class WinSCPContextMenu extends TabContextMenuItemProvider {
|
||||
if (!(tab instanceof SSHTabComponent) || !tab.connection) {
|
||||
return []
|
||||
}
|
||||
if (this.hostApp.platform !== Platform.Windows || !this.ssh.getWinSCPPath()) {
|
||||
return []
|
||||
}
|
||||
return [
|
||||
{
|
||||
const items = [{
|
||||
label: 'Open SFTP panel',
|
||||
click: () => tab.openSFTP(),
|
||||
}]
|
||||
if (this.hostApp.platform === Platform.Windows && this.ssh.getWinSCPPath()) {
|
||||
items.push({
|
||||
label: 'Launch WinSCP',
|
||||
click: (): void => {
|
||||
this.ssh.launchWinSCP(tab.session!)
|
||||
},
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable, NgZone, Optional, Inject } from '@angular/core'
|
||||
import { Injectable, Optional, Inject } from '@angular/core'
|
||||
import { BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, NotificationsService, MenuItemOptions } from 'terminus-core'
|
||||
import { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
|
||||
import { TerminalContextMenuItemProvider } from './api/contextMenuProvider'
|
||||
@ -9,7 +9,6 @@ export class CopyPasteContextMenu extends TabContextMenuItemProvider {
|
||||
weight = -10
|
||||
|
||||
constructor (
|
||||
private zone: NgZone,
|
||||
private notifications: NotificationsService,
|
||||
) {
|
||||
super()
|
||||
@ -24,19 +23,15 @@ export class CopyPasteContextMenu extends TabContextMenuItemProvider {
|
||||
{
|
||||
label: 'Copy',
|
||||
click: (): void => {
|
||||
this.zone.run(() => {
|
||||
setTimeout(() => {
|
||||
tab.frontend?.copySelection()
|
||||
this.notifications.notice('Copied')
|
||||
})
|
||||
setTimeout(() => {
|
||||
tab.frontend?.copySelection()
|
||||
this.notifications.notice('Copied')
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
click: (): void => {
|
||||
this.zone.run(() => tab.paste())
|
||||
},
|
||||
click: () => tab.paste(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user