mirror of
https://github.com/Eugeny/tabby.git
synced 2025-09-12 19:34:34 +00:00
Merge branch 'master' into Add-dock-hide-on-blur-option
This commit is contained in:
@@ -199,8 +199,13 @@ export class Window {
|
|||||||
this.window.focus()
|
this.window.focus()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// docked, visible
|
if (this.configStore.appearance?.dockAlwaysOnTop) {
|
||||||
this.window.hide()
|
// docked, visible, on top
|
||||||
|
this.window.hide()
|
||||||
|
} else {
|
||||||
|
// docked, visible, not on top
|
||||||
|
this.window.focus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"@types/node": "12.7.12",
|
"@types/node": "12.7.12",
|
||||||
"@types/webpack-env": "1.15.0",
|
"@types/webpack-env": "1.15.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
||||||
"@typescript-eslint/parser": "^2.27.0",
|
"@typescript-eslint/parser": "^2.29.0",
|
||||||
"apply-loader": "2.0.0",
|
"apply-loader": "2.0.0",
|
||||||
"awesome-typescript-loader": "^5.0.0",
|
"awesome-typescript-loader": "^5.0.0",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
@@ -14,6 +14,11 @@ export interface BaseTabProcess {
|
|||||||
* Abstract base class for custom tab components
|
* Abstract base class for custom tab components
|
||||||
*/
|
*/
|
||||||
export abstract class BaseTabComponent {
|
export abstract class BaseTabComponent {
|
||||||
|
/**
|
||||||
|
* Parent tab (usually a SplitTabComponent)
|
||||||
|
*/
|
||||||
|
parent: BaseTabComponent|null = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current tab title
|
* Current tab title
|
||||||
*/
|
*/
|
||||||
|
@@ -358,6 +358,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
this.attachTabView(tab)
|
this.attachTabView(tab)
|
||||||
|
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
|
tab.parent = this
|
||||||
this.layout()
|
this.layout()
|
||||||
this.tabAdded.next(tab)
|
this.tabAdded.next(tab)
|
||||||
this.focus(tab)
|
this.focus(tab)
|
||||||
@@ -374,11 +375,11 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
parent.children.splice(index, 1)
|
parent.children.splice(index, 1)
|
||||||
|
|
||||||
this.detachTabView(tab)
|
this.detachTabView(tab)
|
||||||
|
tab.parent = null
|
||||||
|
|
||||||
this.layout()
|
this.layout()
|
||||||
|
|
||||||
this.tabRemoved.next(tab)
|
this.tabRemoved.next(tab)
|
||||||
|
|
||||||
if (this.root.children.length === 0) {
|
if (this.root.children.length === 0) {
|
||||||
this.destroy()
|
this.destroy()
|
||||||
} else {
|
} else {
|
||||||
@@ -569,6 +570,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
if (recovered) {
|
if (recovered) {
|
||||||
const tab = this.tabsService.create(recovered.type, recovered.options)
|
const tab = this.tabsService.create(recovered.type, recovered.options)
|
||||||
children.push(tab)
|
children.push(tab)
|
||||||
|
tab.parent = this
|
||||||
this.attachTabView(tab)
|
this.attachTabView(tab)
|
||||||
} else {
|
} else {
|
||||||
state.ratios.splice(state.children.indexOf(childState), 0)
|
state.ratios.splice(state.children.indexOf(childState), 0)
|
||||||
|
@@ -3,6 +3,7 @@ appearance:
|
|||||||
dockScreen: current
|
dockScreen: current
|
||||||
dockFill: 0.5
|
dockFill: 0.5
|
||||||
dockHideOnBlur: false
|
dockHideOnBlur: false
|
||||||
|
dockAlwaysOnTop: true
|
||||||
tabsLocation: top
|
tabsLocation: top
|
||||||
cycleTabs: true
|
cycleTabs: true
|
||||||
theme: Standard
|
theme: Standard
|
||||||
|
@@ -36,7 +36,7 @@ import { ConfigService } from './services/config.service'
|
|||||||
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
|
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
|
||||||
import { CoreConfigProvider } from './config'
|
import { CoreConfigProvider } from './config'
|
||||||
import { AppHotkeyProvider } from './hotkeys'
|
import { AppHotkeyProvider } from './hotkeys'
|
||||||
import { TaskCompletionContextMenu, CommonOptionsContextMenu, CloseContextMenu } from './tabContextMenu'
|
import { TaskCompletionContextMenu, CommonOptionsContextMenu, TabManagementContextMenu } from './tabContextMenu'
|
||||||
|
|
||||||
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
||||||
import 'ng2-dnd/bundles/style.css'
|
import 'ng2-dnd/bundles/style.css'
|
||||||
@@ -54,7 +54,7 @@ const PROVIDERS = [
|
|||||||
{ provide: Theme, useClass: PaperTheme, multi: true },
|
{ provide: Theme, useClass: PaperTheme, multi: true },
|
||||||
{ provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
|
{ provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
|
||||||
{ provide: TabContextMenuItemProvider, useClass: CommonOptionsContextMenu, multi: true },
|
{ provide: TabContextMenuItemProvider, useClass: CommonOptionsContextMenu, multi: true },
|
||||||
{ provide: TabContextMenuItemProvider, useClass: CloseContextMenu, multi: true },
|
{ provide: TabContextMenuItemProvider, useClass: TabManagementContextMenu, multi: true },
|
||||||
{ provide: TabContextMenuItemProvider, useClass: TaskCompletionContextMenu, multi: true },
|
{ provide: TabContextMenuItemProvider, useClass: TaskCompletionContextMenu, multi: true },
|
||||||
{ provide: TabRecoveryProvider, useClass: SplitTabRecoveryProvider, multi: true },
|
{ provide: TabRecoveryProvider, useClass: SplitTabRecoveryProvider, multi: true },
|
||||||
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
|
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
|
||||||
|
@@ -53,7 +53,9 @@ export class DockingService {
|
|||||||
newBounds.y = display.bounds.y
|
newBounds.y = display.bounds.y
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hostApp.setAlwaysOnTop(true)
|
const alwaysOnTop = this.config.store.appearance.dockAlwaysOnTop
|
||||||
|
|
||||||
|
this.hostApp.setAlwaysOnTop(alwaysOnTop)
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
this.hostApp.setBounds(newBounds)
|
this.hostApp.setBounds(newBounds)
|
||||||
})
|
})
|
||||||
|
@@ -4,11 +4,12 @@ import { Subscription } from 'rxjs'
|
|||||||
import { AppService } from './services/app.service'
|
import { AppService } from './services/app.service'
|
||||||
import { BaseTabComponent } from './components/baseTab.component'
|
import { BaseTabComponent } from './components/baseTab.component'
|
||||||
import { TabHeaderComponent } from './components/tabHeader.component'
|
import { TabHeaderComponent } from './components/tabHeader.component'
|
||||||
|
import { SplitTabComponent, SplitDirection } from './components/splitTab.component'
|
||||||
import { TabContextMenuItemProvider } from './api/tabContextMenuProvider'
|
import { TabContextMenuItemProvider } from './api/tabContextMenuProvider'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CloseContextMenu extends TabContextMenuItemProvider {
|
export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
||||||
weight = -5
|
weight = -5
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
@@ -19,7 +20,7 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
||||||
let items = [
|
let items: Electron.MenuItemConstructorOptions[] = [
|
||||||
{
|
{
|
||||||
label: 'Close',
|
label: 'Close',
|
||||||
click: () => this.zone.run(() => {
|
click: () => this.zone.run(() => {
|
||||||
@@ -59,6 +60,24 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
} else {
|
||||||
|
if (tab.parent instanceof SplitTabComponent) {
|
||||||
|
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
|
||||||
|
items.push({
|
||||||
|
label: 'Split',
|
||||||
|
submenu: directions.map(dir => ({
|
||||||
|
label: {
|
||||||
|
r: 'Right',
|
||||||
|
b: 'Down',
|
||||||
|
l: 'Left',
|
||||||
|
t: 'Up',
|
||||||
|
}[dir],
|
||||||
|
click: () => this.zone.run(() => {
|
||||||
|
(tab.parent as SplitTabComponent).splitTab(tab, dir)
|
||||||
|
}),
|
||||||
|
})) as Electron.MenuItemConstructorOptions[],
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
@@ -87,8 +106,10 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
||||||
|
let items: Electron.MenuItemConstructorOptions[] = []
|
||||||
if (tabHeader) {
|
if (tabHeader) {
|
||||||
return [
|
items = [
|
||||||
|
...items,
|
||||||
{
|
{
|
||||||
label: 'Rename',
|
label: 'Rename',
|
||||||
click: () => this.zone.run(() => tabHeader?.showRenameTabModal()),
|
click: () => this.zone.run(() => tabHeader?.showRenameTabModal()),
|
||||||
@@ -111,7 +132,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return []
|
return items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -207,6 +207,15 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
|
|||||||
)
|
)
|
||||||
| {{screen.name}}
|
| {{screen.name}}
|
||||||
|
|
||||||
|
.form-line(*ngIf='config.store.appearance.dock != "off"')
|
||||||
|
.header
|
||||||
|
.title Dock always on top
|
||||||
|
.description Keep docked terminal always on top
|
||||||
|
toggle(
|
||||||
|
[(ngModel)]='config.store.appearance.dockAlwaysOnTop',
|
||||||
|
(ngModelChange)='config.save(); docking.dock()',
|
||||||
|
)
|
||||||
|
|
||||||
.form-line(*ngIf='config.store.appearance.dock != "off"')
|
.form-line(*ngIf='config.store.appearance.dock != "off"')
|
||||||
.header
|
.header
|
||||||
.title Docked terminal size
|
.title Docked terminal size
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
"runes": "^0.4.2",
|
"runes": "^0.4.2",
|
||||||
"slugify": "^1.4.0",
|
"slugify": "^1.4.0",
|
||||||
"uuid": "^7.0.1",
|
"uuid": "^7.0.1",
|
||||||
"xterm": "^4.5.0-beta.9",
|
"xterm": "^4.6.0-beta.17",
|
||||||
"xterm-addon-fit": "^0.4.0-beta.8",
|
"xterm-addon-fit": "^0.4.0-beta.8",
|
||||||
"xterm-addon-ligatures": "^0.2.1",
|
"xterm-addon-ligatures": "^0.2.1",
|
||||||
"xterm-addon-search": "^0.7.0-beta.1",
|
"xterm-addon-search": "^0.7.0-beta.1",
|
||||||
|
@@ -257,10 +257,10 @@ xterm-addon-webgl@^0.7.0-beta.5:
|
|||||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.7.0-beta.5.tgz#20fbafcf2fb2c2438977c40fd41945d297ea0c25"
|
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.7.0-beta.5.tgz#20fbafcf2fb2c2438977c40fd41945d297ea0c25"
|
||||||
integrity sha512-Mf0PYiWe4GL8mcS4KnjVsosbvD2xSxUCappbTRNZ+5hQgmrayrr6UciKw7CasSLOsji8AHkoZJEl0MxMsTTEeg==
|
integrity sha512-Mf0PYiWe4GL8mcS4KnjVsosbvD2xSxUCappbTRNZ+5hQgmrayrr6UciKw7CasSLOsji8AHkoZJEl0MxMsTTEeg==
|
||||||
|
|
||||||
xterm@^4.5.0-beta.9:
|
xterm@^4.6.0-beta.17:
|
||||||
version "4.5.0"
|
version "4.6.0-beta.17"
|
||||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.5.0.tgz#c7fd145c6cf91c9f2ef07011a9b35026cf4bfecc"
|
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.6.0-beta.17.tgz#d3b448a7e09d65307f74ca862ce50847da891d89"
|
||||||
integrity sha512-4t12tsvtYnv13FBJwewddxdI/j4kSonmbQQv50j34R/rPIFbUNGtptbprmuUlTDAKvHLMDZ/Np2XcpNimga/HQ==
|
integrity sha512-/lG3pWSjejqPd58SSa1C24h3yarZkyVHefCt+3K2fqpV7EQTSnzl67RH3k/ojIflIX9d/JUQRqp/GGWnyyb2JQ==
|
||||||
|
|
||||||
yallist@^2.1.2:
|
yallist@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
|
30
yarn.lock
30
yarn.lock
@@ -283,24 +283,24 @@
|
|||||||
eslint-scope "^5.0.0"
|
eslint-scope "^5.0.0"
|
||||||
eslint-utils "^2.0.0"
|
eslint-utils "^2.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/experimental-utils@2.27.0":
|
"@typescript-eslint/experimental-utils@2.29.0":
|
||||||
version "2.27.0"
|
version "2.29.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.27.0.tgz#801a952c10b58e486c9a0b36cf21e2aab1e9e01a"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.29.0.tgz#3cb8060de9265ba131625a96bbfec31ba6d4a0fe"
|
||||||
integrity sha512-vOsYzjwJlY6E0NJRXPTeCGqjv5OHgRU1kzxHKWJVPjDYGbPgLudBXjIlc+OD1hDBZ4l1DLbOc5VjofKahsu9Jw==
|
integrity sha512-H/6VJr6eWYstyqjWXBP2Nn1hQJyvJoFdDtsHxGiD+lEP7piGnGpb/ZQd+z1ZSB1F7dN+WsxUDh8+S4LwI+f3jw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/json-schema" "^7.0.3"
|
"@types/json-schema" "^7.0.3"
|
||||||
"@typescript-eslint/typescript-estree" "2.27.0"
|
"@typescript-eslint/typescript-estree" "2.29.0"
|
||||||
eslint-scope "^5.0.0"
|
eslint-scope "^5.0.0"
|
||||||
eslint-utils "^2.0.0"
|
eslint-utils "^2.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@^2.27.0":
|
"@typescript-eslint/parser@^2.29.0":
|
||||||
version "2.27.0"
|
version "2.29.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.27.0.tgz#d91664335b2c46584294e42eb4ff35838c427287"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.29.0.tgz#6e3c4e21ed6393dc05b9d8b47f0b7e731ef21c9c"
|
||||||
integrity sha512-HFUXZY+EdwrJXZo31DW4IS1ujQW3krzlRjBrFRrJcMDh0zCu107/nRfhk/uBasO8m0NVDbBF5WZKcIUMRO7vPg==
|
integrity sha512-H78M+jcu5Tf6m/5N8iiFblUUv+HJDguMSdFfzwa6vSg9lKR8Mk9BsgeSjO8l2EshKnJKcbv0e8IDDOvSNjl0EA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/eslint-visitor-keys" "^1.0.0"
|
"@types/eslint-visitor-keys" "^1.0.0"
|
||||||
"@typescript-eslint/experimental-utils" "2.27.0"
|
"@typescript-eslint/experimental-utils" "2.29.0"
|
||||||
"@typescript-eslint/typescript-estree" "2.27.0"
|
"@typescript-eslint/typescript-estree" "2.29.0"
|
||||||
eslint-visitor-keys "^1.1.0"
|
eslint-visitor-keys "^1.1.0"
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@2.26.0":
|
"@typescript-eslint/typescript-estree@2.26.0":
|
||||||
@@ -316,10 +316,10 @@
|
|||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
tsutils "^3.17.1"
|
tsutils "^3.17.1"
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@2.27.0":
|
"@typescript-eslint/typescript-estree@2.29.0":
|
||||||
version "2.27.0"
|
version "2.29.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.27.0.tgz#a288e54605412da8b81f1660b56c8b2e42966ce8"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.29.0.tgz#1be6612bb02fc37ac9f466521c1459a4744e8d3a"
|
||||||
integrity sha512-t2miCCJIb/FU8yArjAvxllxbTiyNqaXJag7UOpB5DVoM3+xnjeOngtqlJkLRnMtzaRcJhe3CIR9RmL40omubhg==
|
integrity sha512-3YGbtnWy4az16Egy5Fj5CckkVlpIh0MADtAQza+jiMADRSKkjdpzZp/5WuvwK/Qib3Z0HtzrDFeWanS99dNhnA==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
eslint-visitor-keys "^1.1.0"
|
eslint-visitor-keys "^1.1.0"
|
||||||
|
Reference in New Issue
Block a user