mirror of
https://github.com/Eugeny/tabby.git
synced 2025-09-23 00:26:04 +00:00
added hotkey to focus all panes (fixes #722)
This commit is contained in:
@@ -157,6 +157,10 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
/** @hidden */
|
/** @hidden */
|
||||||
_spanners: SplitSpannerInfo[] = []
|
_spanners: SplitSpannerInfo[] = []
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
|
_allFocusMode = false
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
private focusedTab: BaseTabComponent
|
private focusedTab: BaseTabComponent
|
||||||
private maximizedTab: BaseTabComponent|null = null
|
private maximizedTab: BaseTabComponent|null = null
|
||||||
private hotkeysSubscription: Subscription
|
private hotkeysSubscription: Subscription
|
||||||
@@ -480,6 +484,12 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layout () {
|
||||||
|
this.root.normalize()
|
||||||
|
this._spanners = []
|
||||||
|
this.layoutInternal(this.root, 0, 0, 100, 100)
|
||||||
|
}
|
||||||
|
|
||||||
private attachTabView (tab: BaseTabComponent) {
|
private attachTabView (tab: BaseTabComponent) {
|
||||||
const ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any> // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
const ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any> // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
this.viewRefs.set(tab, ref)
|
this.viewRefs.set(tab, ref)
|
||||||
@@ -505,12 +515,6 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private layout () {
|
|
||||||
this.root.normalize()
|
|
||||||
this._spanners = []
|
|
||||||
this.layoutInternal(this.root, 0, 0, 100, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
|
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
|
||||||
const size = root.orientation === 'v' ? h : w
|
const size = root.orientation === 'v' ? h : w
|
||||||
const sizes = root.ratios.map(x => x * size)
|
const sizes = root.ratios.map(x => x * size)
|
||||||
@@ -535,7 +539,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
element.classList.toggle('child', true)
|
element.classList.toggle('child', true)
|
||||||
element.classList.toggle('maximized', child === this.maximizedTab)
|
element.classList.toggle('maximized', child === this.maximizedTab)
|
||||||
element.classList.toggle('minimized', this.maximizedTab && child !== this.maximizedTab)
|
element.classList.toggle('minimized', this.maximizedTab && child !== this.maximizedTab)
|
||||||
element.classList.toggle('focused', child === this.focusedTab)
|
element.classList.toggle('focused', this._allFocusMode || child === this.focusedTab)
|
||||||
element.style.left = `${childX}%`
|
element.style.left = `${childX}%`
|
||||||
element.style.top = `${childY}%`
|
element.style.top = `${childY}%`
|
||||||
element.style.width = `${childW}%`
|
element.style.width = `${childW}%`
|
||||||
|
@@ -4,7 +4,7 @@ import { ToastrService } from 'ngx-toastr'
|
|||||||
import colors from 'ansi-colors'
|
import colors from 'ansi-colors'
|
||||||
import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core'
|
import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core'
|
||||||
import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
|
import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
|
||||||
import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, Platform, LogService, Logger, TabContextMenuItemProvider } from 'terminus-core'
|
import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent } from 'terminus-core'
|
||||||
|
|
||||||
import { BaseSession, SessionsService } from '../services/sessions.service'
|
import { BaseSession, SessionsService } from '../services/sessions.service'
|
||||||
import { TerminalFrontendService } from '../services/terminalFrontend.service'
|
import { TerminalFrontendService } from '../services/terminalFrontend.service'
|
||||||
@@ -92,6 +92,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
private hotkeysSubscription: Subscription
|
private hotkeysSubscription: Subscription
|
||||||
private bellPlayer: HTMLAudioElement
|
private bellPlayer: HTMLAudioElement
|
||||||
private termContainerSubscriptions: Subscription[] = []
|
private termContainerSubscriptions: Subscription[] = []
|
||||||
|
private allFocusModeSubscription: Subscription|null = null
|
||||||
|
|
||||||
get input$ (): Observable<Buffer> { return this.frontend.input$ }
|
get input$ (): Observable<Buffer> { return this.frontend.input$ }
|
||||||
get output$ (): Observable<string> { return this.output }
|
get output$ (): Observable<string> { return this.output }
|
||||||
@@ -172,6 +173,9 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
this.element.nativeElement.querySelector('.search-input').focus()
|
this.element.nativeElement.querySelector('.search-input').focus()
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
|
case 'pane-focus-all':
|
||||||
|
this.focusAllPanes()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.bellPlayer = document.createElement('audio')
|
this.bellPlayer = document.createElement('audio')
|
||||||
@@ -255,6 +259,10 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.frontend.focus()
|
this.frontend.focus()
|
||||||
|
|
||||||
|
this.blurred$.subscribe(() => {
|
||||||
|
this.cancelFocusAllPanes()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildContextMenu (): Promise<Electron.MenuItemConstructorOptions[]> {
|
async buildContextMenu (): Promise<Electron.MenuItemConstructorOptions[]> {
|
||||||
@@ -366,6 +374,35 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
|||||||
this.frontend.setZoom(this.zoom)
|
this.frontend.setZoom(this.zoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
focusAllPanes (): void {
|
||||||
|
if (this.allFocusModeSubscription) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.parent instanceof SplitTabComponent) {
|
||||||
|
this.parent._allFocusMode = true
|
||||||
|
this.parent.layout()
|
||||||
|
this.allFocusModeSubscription = this.frontend.input$.subscribe(data => {
|
||||||
|
for (const tab of (this.parent as SplitTabComponent).getAllTabs()) {
|
||||||
|
if (tab !== this && tab instanceof BaseTerminalTabComponent) {
|
||||||
|
tab.sendInput(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelFocusAllPanes (): void {
|
||||||
|
if (!this.allFocusModeSubscription) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.parent instanceof SplitTabComponent) {
|
||||||
|
this.allFocusModeSubscription?.unsubscribe?.()
|
||||||
|
this.allFocusModeSubscription = null
|
||||||
|
this.parent._allFocusMode = false
|
||||||
|
this.parent.layout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
ngOnDestroy (): void {
|
ngOnDestroy (): void {
|
||||||
this.frontend.detach(this.content.nativeElement)
|
this.frontend.detach(this.content.nativeElement)
|
||||||
|
@@ -109,6 +109,9 @@ export class TerminalConfigProvider extends ConfigProvider {
|
|||||||
search: [
|
search: [
|
||||||
'⌘-F',
|
'⌘-F',
|
||||||
],
|
],
|
||||||
|
'pane-focus-all': [
|
||||||
|
'⌘-Shift-I',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[Platform.Windows]: {
|
[Platform.Windows]: {
|
||||||
@@ -152,6 +155,9 @@ export class TerminalConfigProvider extends ConfigProvider {
|
|||||||
search: [
|
search: [
|
||||||
'Ctrl-Shift-F',
|
'Ctrl-Shift-F',
|
||||||
],
|
],
|
||||||
|
'pane-focus-all': [
|
||||||
|
'Ctrl-Shift-I',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[Platform.Linux]: {
|
[Platform.Linux]: {
|
||||||
@@ -192,6 +198,9 @@ export class TerminalConfigProvider extends ConfigProvider {
|
|||||||
search: [
|
search: [
|
||||||
'Ctrl-Shift-F',
|
'Ctrl-Shift-F',
|
||||||
],
|
],
|
||||||
|
'pane-focus-all': [
|
||||||
|
'Ctrl-Shift-I',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -66,6 +66,10 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
|
|||||||
id: 'search',
|
id: 'search',
|
||||||
name: 'Search',
|
name: 'Search',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'pane-focus-all',
|
||||||
|
name: 'Focus all panes at once',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable, NgZone, Optional, Inject } from '@angular/core'
|
import { Injectable, NgZone, Optional, Inject } from '@angular/core'
|
||||||
import { ToastrService } from 'ngx-toastr'
|
import { ToastrService } from 'ngx-toastr'
|
||||||
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent } from 'terminus-core'
|
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, SplitTabComponent } from 'terminus-core'
|
||||||
import { TerminalTabComponent } from './components/terminalTab.component'
|
import { TerminalTabComponent } from './components/terminalTab.component'
|
||||||
import { UACService } from './services/uac.service'
|
import { UACService } from './services/uac.service'
|
||||||
import { TerminalService } from './services/terminal.service'
|
import { TerminalService } from './services/terminal.service'
|
||||||
@@ -113,6 +113,15 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tab instanceof BaseTerminalTabComponent && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
|
||||||
|
items.push({
|
||||||
|
label: 'Focus all panes',
|
||||||
|
click: () => this.zone.run(() => {
|
||||||
|
tab.focusAllPanes()
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user