diff --git a/README.md b/README.md index daf20ce0..06f65d16 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,6 @@ Tabby will run as a portable app on Windows, if you create a `data` folder in th Plugins and themes can be installed directly from the Settings view inside Tabby. -* [clickable-links](https://github.com/Eugeny/tabby-clickable-links) - makes paths and URLs in the terminal clickable * [docker](https://github.com/Eugeny/tabby-docker) - connect to Docker containers * [title-control](https://github.com/kbjr/terminus-title-control) - allows modifying the title of the terminal tabs by providing a prefix, suffix, and/or strings to be removed * [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - quickly send commands to one or all terminal tabs diff --git a/app/lib/app.ts b/app/lib/app.ts index 1fa9323e..0d20cb8a 100644 --- a/app/lib/app.ts +++ b/app/lib/app.ts @@ -130,7 +130,6 @@ export class Application { this.setupMenu() } await window.ready - window.present() return window } diff --git a/app/lib/window.ts b/app/lib/window.ts index b3b8db41..caf0a029 100644 --- a/app/lib/window.ts +++ b/app/lib/window.ts @@ -27,7 +27,7 @@ abstract class GlasstronWindow extends BrowserWindow { abstract setBlur (_: boolean) } -const macOSVibrancyType = process.platform === 'darwin' ? compareVersions(macOSRelease().version, '10.14', '>=') ? 'fullscreen-ui' : 'dark' : null +const macOSVibrancyType = process.platform === 'darwin' ? compareVersions(macOSRelease().version, '10.14', '>=') ? 'under-window' : 'dark' : null const activityIcon = nativeImage.createFromPath(`${app.getAppPath()}/assets/activity.png`) diff --git a/app/src/global.scss b/app/src/global.scss index 877c2f5b..c4c59854 100644 --- a/app/src/global.scss +++ b/app/src/global.scss @@ -1,7 +1,7 @@ body { min-height: 100vh; overflow: hidden; - background: #1D272D; + background: transparent !important; -webkit-font-smoothing: antialiased; } diff --git a/app/src/pluginBlacklist.ts b/app/src/pluginBlacklist.ts index 5b572449..86799c32 100644 --- a/app/src/pluginBlacklist.ts +++ b/app/src/pluginBlacklist.ts @@ -3,4 +3,5 @@ export const PLUGIN_BLACKLIST = [ 'terminus-scrollbar', // now useless 'terminus-clickable-links', // now bundled with Tabby 'tabby-clickable-links', // now bundled with Tabby + 'terminus-clickable-ips', // broken, functionality now bundled with Tabby ] diff --git a/app/src/preload.scss b/app/src/preload.scss index c86f7e21..7f72c897 100644 --- a/app/src/preload.scss +++ b/app/src/preload.scss @@ -1,3 +1,7 @@ +app-root { + background: #1D272D; +} + .preload-logo { -webkit-app-region: drag; position: fixed; diff --git a/electron-builder.yml b/electron-builder.yml index 9fe447d3..79daca38 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -40,7 +40,7 @@ publish: win: icon: "./build/windows/icon.ico" artifactName: tabby-${version}-portable.${ext} - rfc3161TimeStampServer: http://timestamp.comodoca.com/rfc3161 + rfc3161TimeStampServer: http://timestamp.sectigo.com nsis: oneClick: false artifactName: tabby-${version}-setup.${ext} diff --git a/locale/es-ES.po b/locale/es-ES.po index 3c8e1e97..0c43179b 100644 --- a/locale/es-ES.po +++ b/locale/es-ES.po @@ -12,7 +12,7 @@ msgstr "" "Project-Id-Version: tabby\n" "Language-Team: Spanish\n" "Language: es_ES\n" -"PO-Revision-Date: 2022-01-28 22:42\n" +"PO-Revision-Date: 2022-01-30 20:02\n" msgid "A second font family used to display characters missing in the main font" msgstr "Una familia tipográfica secundaria usada para mostrar los caracteres faltantes en la principal" @@ -20,6 +20,12 @@ msgstr "Una familia tipográfica secundaria usada para mostrar los caracteres fa msgid "Abort all" msgstr "Abortar todo" +msgid "Accept and remember key" +msgstr "" + +msgid "Accept just this once" +msgstr "" + msgid "Acrylic background" msgstr "Fondo acrílico" @@ -269,6 +275,9 @@ msgstr "Actual" msgid "Current color scheme" msgstr "Esquema de color actual" +msgid "Current host key fingerprint" +msgstr "" + msgid "Current process: {name}" msgstr "Proceso actual: {name}" @@ -341,6 +350,9 @@ msgstr "Deshabilitar el título de la pestaña dinámica" msgid "Disabled" msgstr "Deshabilitado" +msgid "Disconnect" +msgstr "" + msgid "Display on" msgstr "Mostrar en pantalla" @@ -566,6 +578,9 @@ msgstr "Anfitrión" msgid "Host key" msgstr "Clave de anfitrión" +msgid "Host key verification" +msgstr "" + msgid "Hotkeys" msgstr "Teclas de acceso rápido" @@ -632,6 +647,9 @@ msgstr "Autenticación interactiva con teclado" msgid "Language" msgstr "Idioma" +msgid "Last known host key fingerprint" +msgstr "" + msgid "Launch WinSCP" msgstr "Iniciar WinSCP" @@ -1017,7 +1035,7 @@ msgid "SSH connection" msgstr "Conexión SSH" msgid "SSH connection management is now done through the \"Profiles & connections\" tab" -msgstr "" +msgstr "La gestión de conexiones SSH ahora se realiza a través de la pestaña \"Perfiles y conexiones\"" msgid "SSH password for {user}@{host}:{port}" msgstr "Contraseña SSH para {user}@{host}:{port}" @@ -1170,7 +1188,7 @@ msgid "Source code" msgstr "Código fuente" msgid "Spanish" -msgstr "" +msgstr "Español" msgid "Split" msgstr "Dividir" @@ -1370,6 +1388,9 @@ msgstr "Vault no está configurado" msgid "Vault master passphrase needs to be set to allow storing secrets" msgstr "La contraseña maestra de Vault debe estar establecida para permitir secretos" +msgid "Verify host keys when connecting" +msgstr "" + msgid "Version" msgstr "Versión" @@ -1394,6 +1415,9 @@ msgstr "Advertir al pegar múltiples líneas" msgid "Warn when closing active connections" msgstr "Advertir al cerrar conexiones activas" +msgid "Warning: remote host's key has suddenly changed!" +msgstr "" + msgid "We're only tracking your Tabby and OS versions." msgstr "Solo estamos rastreando sus versiones de Tabby y SO." @@ -1448,6 +1472,9 @@ msgstr "Amarillo" msgid "You can change it later, but it's unrecoverable if forgotten." msgstr "Puedes cambiarlo más tarde, pero es irrecuperable si lo olvidas." +msgid "You could be under a man-in-the-middle attack right now, or the host key could have just been changed." +msgstr "" + msgid "Zoom in" msgstr "Ampliar" diff --git a/locale/fr-FR.po b/locale/fr-FR.po index a8cc82d0..419c8640 100644 --- a/locale/fr-FR.po +++ b/locale/fr-FR.po @@ -12,7 +12,7 @@ msgstr "" "Project-Id-Version: tabby\n" "Language-Team: French\n" "Language: fr_FR\n" -"PO-Revision-Date: 2022-01-28 22:42\n" +"PO-Revision-Date: 2022-01-30 20:02\n" msgid "A second font family used to display characters missing in the main font" msgstr "Une seconde famille de polices utilisable pour afficher les caractères absents de la police principale" @@ -20,6 +20,12 @@ msgstr "Une seconde famille de polices utilisable pour afficher les caractères msgid "Abort all" msgstr "Annuler tout" +msgid "Accept and remember key" +msgstr "" + +msgid "Accept just this once" +msgstr "" + msgid "Acrylic background" msgstr "Arrière-plan acrylique" @@ -269,6 +275,9 @@ msgstr "Actif" msgid "Current color scheme" msgstr "Schéma de couleurs actuel" +msgid "Current host key fingerprint" +msgstr "" + msgid "Current process: {name}" msgstr "Processus actuel : {name}" @@ -341,6 +350,9 @@ msgstr "Désactiver le titre dynamique des onglets" msgid "Disabled" msgstr "Désactivé" +msgid "Disconnect" +msgstr "" + msgid "Display on" msgstr "Afficher sur" @@ -566,6 +578,9 @@ msgstr "Hôte" msgid "Host key" msgstr "Clé de l'hôte" +msgid "Host key verification" +msgstr "" + msgid "Hotkeys" msgstr "Raccourcis clavier" @@ -632,6 +647,9 @@ msgstr "Authentification interactive au clavier" msgid "Language" msgstr "Langue" +msgid "Last known host key fingerprint" +msgstr "" + msgid "Launch WinSCP" msgstr "Lancer WinSCP" @@ -1017,7 +1035,7 @@ msgid "SSH connection" msgstr "Connexion SSH" msgid "SSH connection management is now done through the \"Profiles & connections\" tab" -msgstr "" +msgstr "La gestion des connexions SSH se fait maintenant via l'onglet \"Profils et connexions\"" msgid "SSH password for {user}@{host}:{port}" msgstr "Mot de passe SSH pour {user}@{host}:{port}" @@ -1155,7 +1173,7 @@ msgid "Show vault contents" msgstr "Afficher le contenu du coffre" msgid "Show {type} profile selector" -msgstr "" +msgstr "Afficher le sélecteur de profil {type}" msgid "Skip MoTD/banner" msgstr "Ne pas afficher le message du jour (MoTD) ni la bannière" @@ -1170,7 +1188,7 @@ msgid "Source code" msgstr "Code source" msgid "Spanish" -msgstr "" +msgstr "Espagnol" msgid "Split" msgstr "Diviser" @@ -1370,6 +1388,9 @@ msgstr "Le coffre n'est pas configuré" msgid "Vault master passphrase needs to be set to allow storing secrets" msgstr "Un mot de passe maître doit être défini pour permettre le stockage de secrets dans le coffre" +msgid "Verify host keys when connecting" +msgstr "" + msgid "Version" msgstr "Version" @@ -1394,6 +1415,9 @@ msgstr "Avertir en cas de collage de plusieurs lignes" msgid "Warn when closing active connections" msgstr "Avertir lors de la fermeture de connexions actives" +msgid "Warning: remote host's key has suddenly changed!" +msgstr "" + msgid "We're only tracking your Tabby and OS versions." msgstr "Nous ne collectons que la version de Tabby et celle de l'OS." @@ -1448,6 +1472,9 @@ msgstr "Jaune" msgid "You can change it later, but it's unrecoverable if forgotten." msgstr "Vous pouvez le changer plus tard, mais il n'est pas récupérable s'il est oublié." +msgid "You could be under a man-in-the-middle attack right now, or the host key could have just been changed." +msgstr "" + msgid "Zoom in" msgstr "Zoom avant" diff --git a/locale/zh-CN.po b/locale/zh-CN.po index 077983cd..bf652cb3 100644 --- a/locale/zh-CN.po +++ b/locale/zh-CN.po @@ -12,7 +12,7 @@ msgstr "" "Project-Id-Version: tabby\n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" -"PO-Revision-Date: 2022-01-28 22:42\n" +"PO-Revision-Date: 2022-01-30 20:02\n" msgid "A second font family used to display characters missing in the main font" msgstr "第二种字体,用于显示主字体中缺失的字符" @@ -20,6 +20,12 @@ msgstr "第二种字体,用于显示主字体中缺失的字符" msgid "Abort all" msgstr "中止全部" +msgid "Accept and remember key" +msgstr "接受并记住密钥" + +msgid "Accept just this once" +msgstr "只接受本次" + msgid "Acrylic background" msgstr "亚克力背景" @@ -269,6 +275,9 @@ msgstr "当前" msgid "Current color scheme" msgstr "当前配色方案" +msgid "Current host key fingerprint" +msgstr "当前主机密钥指纹" + msgid "Current process: {name}" msgstr "当前进程:{name}" @@ -341,6 +350,9 @@ msgstr "禁用动态标签页标题" msgid "Disabled" msgstr "已禁用" +msgid "Disconnect" +msgstr "断开连接" + msgid "Display on" msgstr "显示于" @@ -566,6 +578,9 @@ msgstr "主机" msgid "Host key" msgstr "主机密钥" +msgid "Host key verification" +msgstr "主机密钥校验" + msgid "Hotkeys" msgstr "快捷键" @@ -632,6 +647,9 @@ msgstr "键盘交互认证" msgid "Language" msgstr "语言" +msgid "Last known host key fingerprint" +msgstr "最后已知的主机密钥指纹" + msgid "Launch WinSCP" msgstr "启动 WinSCP" @@ -1017,7 +1035,7 @@ msgid "SSH connection" msgstr "SSH 连接" msgid "SSH connection management is now done through the \"Profiles & connections\" tab" -msgstr "" +msgstr "现在,SSH 连接管理通过“配置和连接“选项卡完成" msgid "SSH password for {user}@{host}:{port}" msgstr "{user}@{host}:{port} 的 SSH 密码" @@ -1170,7 +1188,7 @@ msgid "Source code" msgstr "源码" msgid "Spanish" -msgstr "" +msgstr "西班牙语" msgid "Split" msgstr "拆分" @@ -1370,6 +1388,9 @@ msgstr "保险库未配置" msgid "Vault master passphrase needs to be set to allow storing secrets" msgstr "为允许存储密钥,您必须设置保险库的主密码" +msgid "Verify host keys when connecting" +msgstr "连接时校验主机密钥" + msgid "Version" msgstr "版本" @@ -1394,6 +1415,9 @@ msgstr "多行粘贴时显示警告" msgid "Warn when closing active connections" msgstr "当关闭活动连接时,显示警告" +msgid "Warning: remote host's key has suddenly changed!" +msgstr "警告:远程主机密钥突然改变!" + msgid "We're only tracking your Tabby and OS versions." msgstr "我们只获取您的 Tabby 和操作系统版本信息。" @@ -1448,6 +1472,9 @@ msgstr "黄色" msgid "You can change it later, but it's unrecoverable if forgotten." msgstr "您可以稍后更改,但在忘记时无法恢复" +msgid "You could be under a man-in-the-middle attack right now, or the host key could have just been changed." +msgstr "您可能正在遭受中间人攻击,或您的主机密钥已经被更改。" + msgid "Zoom in" msgstr "放大" diff --git a/locale/zh-TW.po b/locale/zh-TW.po index 15617360..a82f48f0 100644 --- a/locale/zh-TW.po +++ b/locale/zh-TW.po @@ -12,7 +12,7 @@ msgstr "" "Project-Id-Version: tabby\n" "Language-Team: Chinese Traditional\n" "Language: zh_TW\n" -"PO-Revision-Date: 2022-01-28 22:42\n" +"PO-Revision-Date: 2022-01-30 20:02\n" msgid "A second font family used to display characters missing in the main font" msgstr "第二個字體系列,用於顯示主字體中缺少的字元" @@ -20,6 +20,12 @@ msgstr "第二個字體系列,用於顯示主字體中缺少的字元" msgid "Abort all" msgstr "中止所有" +msgid "Accept and remember key" +msgstr "" + +msgid "Accept just this once" +msgstr "" + msgid "Acrylic background" msgstr "壓克力背景" @@ -269,6 +275,9 @@ msgstr "現時" msgid "Current color scheme" msgstr "當前配色方案" +msgid "Current host key fingerprint" +msgstr "" + msgid "Current process: {name}" msgstr "當前行程:{name}" @@ -341,6 +350,9 @@ msgstr "停用動態分頁標題" msgid "Disabled" msgstr "已停用" +msgid "Disconnect" +msgstr "" + msgid "Display on" msgstr "顯示在" @@ -566,6 +578,9 @@ msgstr "主機" msgid "Host key" msgstr "快捷鍵" +msgid "Host key verification" +msgstr "" + msgid "Hotkeys" msgstr "快捷鍵" @@ -632,6 +647,9 @@ msgstr "" msgid "Language" msgstr "語言" +msgid "Last known host key fingerprint" +msgstr "" + msgid "Launch WinSCP" msgstr "啟動 WinSCP" @@ -1370,6 +1388,9 @@ msgstr "金鑰庫未設定" msgid "Vault master passphrase needs to be set to allow storing secrets" msgstr "" +msgid "Verify host keys when connecting" +msgstr "" + msgid "Version" msgstr "版本" @@ -1394,6 +1415,9 @@ msgstr "貼上多行時警告" msgid "Warn when closing active connections" msgstr "" +msgid "Warning: remote host's key has suddenly changed!" +msgstr "" + msgid "We're only tracking your Tabby and OS versions." msgstr "" @@ -1448,6 +1472,9 @@ msgstr "黃色" msgid "You can change it later, but it's unrecoverable if forgotten." msgstr "您可以稍後修改,但如果忘了就沒了" +msgid "You could be under a man-in-the-middle attack right now, or the host key could have just been changed." +msgstr "" + msgid "Zoom in" msgstr "放大" diff --git a/package.json b/package.json index e9e6c3fe..3c15f284 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "cross-env": "7.0.3", "css-loader": "^6.5.1", "deep-equal": "2.0.5", - "electron": "16.0.7", + "electron": "16.0.8", "electron-builder": "^22.14.5", "electron-download": "^4.1.1", "electron-installer-snap": "^5.1.0", diff --git a/tabby-core/src/components/appRoot.component.ts b/tabby-core/src/components/appRoot.component.ts index 1fb837cb..9f47890f 100644 --- a/tabby-core/src/components/appRoot.component.ts +++ b/tabby-core/src/components/appRoot.component.ts @@ -214,6 +214,10 @@ export class AppRootComponent { } } + @HostBinding('class.vibrant') get isVibrant () { + return this.config.store.appearance.vibrancy + } + private getToolbarButtons (aboveZero: boolean): ToolbarButton[] { let buttons: ToolbarButton[] = [] this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => { diff --git a/tabby-core/src/components/baseTab.component.ts b/tabby-core/src/components/baseTab.component.ts index 3f236fe6..2abc07c8 100644 --- a/tabby-core/src/components/baseTab.component.ts +++ b/tabby-core/src/components/baseTab.component.ts @@ -47,7 +47,9 @@ export abstract class BaseTabComponent extends BaseComponent { /** * CSS color override for the tab's header */ - color: string|null = null + get color (): string|null { return this._color } + set color (value: string|null) { this._color = value } + private _color: string|null = null hasFocus = false diff --git a/tabby-core/src/components/splitTab.component.ts b/tabby-core/src/components/splitTab.component.ts index 2c34ac6b..28bfe0e1 100644 --- a/tabby-core/src/components/splitTab.component.ts +++ b/tabby-core/src/components/splitTab.component.ts @@ -629,6 +629,16 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit super.clearActivity() } + get color (): string|null { + return this.getFocusedTab()?.color ?? null + } + + set color (color: string|null) { + for (const t of this.getAllTabs()) { + t.color = color + } + } + private updateTitle (): void { this.setTitle(this.getAllTabs().map(x => x.title).join(' | ')) } diff --git a/tabby-core/src/components/tabHeader.component.scss b/tabby-core/src/components/tabHeader.component.scss index a385ab31..81284646 100644 --- a/tabby-core/src/components/tabHeader.component.scss +++ b/tabby-core/src/components/tabHeader.component.scss @@ -37,6 +37,7 @@ $tabs-height: 38px; text-align: center; transition: 0.25s all; align-self: center; + margin-top: 1px; } .name { diff --git a/tabby-core/src/index.ts b/tabby-core/src/index.ts index 2218f5cf..b83f7c80 100644 --- a/tabby-core/src/index.ts +++ b/tabby-core/src/index.ts @@ -149,6 +149,7 @@ const PROVIDERS = [ SortablejsModule, DragDropModule, TranslateModule, + CdkAutoDropGroup, ], }) export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class diff --git a/tabby-core/src/services/hotkeys.service.ts b/tabby-core/src/services/hotkeys.service.ts index 7c4bcc5c..3e6b1559 100644 --- a/tabby-core/src/services/hotkeys.service.ts +++ b/tabby-core/src/services/hotkeys.service.ts @@ -130,9 +130,7 @@ export class HotkeysService { const keyName = getKeyName(eventData) if (eventName === 'keydown') { this.addPressedKey(keyName, eventData) - if (!nativeEvent.repeat) { - this.recognitionPhase = true - } + this.recognitionPhase = true this.updateModifiers(eventData) } if (eventName === 'keyup') { @@ -158,8 +156,10 @@ export class HotkeysService { const matched = this.matchActiveHotkey() this.zone.run(() => { - if (matched && this.recognitionPhase) { - this.emitHotkeyOn(matched) + if (matched) { + if (this.recognitionPhase) { + this.emitHotkeyOn(matched) + } } else if (this.pressedHotkey) { this.emitHotkeyOff(this.pressedHotkey) } @@ -288,10 +288,9 @@ export class HotkeysService { private emitHotkeyOn (hotkey: string) { if (this.pressedHotkey) { - if (this.pressedHotkey === hotkey) { - return + if (this.pressedHotkey !== hotkey) { + this.emitHotkeyOff(this.pressedHotkey) } - this.emitHotkeyOff(this.pressedHotkey) } if (document.querySelectorAll('input:focus').length === 0) { console.debug('Matched hotkey', hotkey) diff --git a/tabby-core/src/services/profiles.service.ts b/tabby-core/src/services/profiles.service.ts index b88bf3f0..607d8c09 100644 --- a/tabby-core/src/services/profiles.service.ts +++ b/tabby-core/src/services/profiles.service.ts @@ -37,9 +37,7 @@ export class ProfilesService { async openNewTabForProfile

(profile: PartialProfile

): Promise { const params = await this.newTabParametersForProfile(profile) if (params) { - const tab = this.app.openNewTab(params) - ;(this.app.getParentTab(tab) ?? tab).color = profile.color ?? null - return tab + return this.app.openNewTab(params) } return null } @@ -50,9 +48,12 @@ export class ProfilesService { if (params) { params.inputs ??= {} params.inputs['title'] = profile.name - if (profile.disableDynamicTitle) { + if (fullProfile.disableDynamicTitle) { params.inputs['disableDynamicTitle'] = true } + if (fullProfile.color) { + params.inputs['color'] = fullProfile.color + } } return params } diff --git a/tabby-core/src/theme.paper.scss b/tabby-core/src/theme.paper.scss index 7615007d..f83f23da 100644 --- a/tabby-core/src/theme.paper.scss +++ b/tabby-core/src/theme.paper.scss @@ -117,15 +117,13 @@ window-controls { $border-color: $base1; -body { +app-root { background: $body-bg; &.vibrant { background: rgba(255, 255, 255,.4) !important; } -} -app-root { &> .content { .tab-bar { .btn-tab-bar { diff --git a/tabby-core/src/theme.scss b/tabby-core/src/theme.scss index c31ee173..d360565d 100644 --- a/tabby-core/src/theme.scss +++ b/tabby-core/src/theme.scss @@ -25,15 +25,13 @@ window-controls { $border-color: #111; -body { +app-root { background: $body-bg; &.vibrant { background: rgba(0,0,0,.65); } -} -app-root { &.no-tabs { background: rgba(0,0,0,.5); } diff --git a/tabby-electron/src/index.ts b/tabby-electron/src/index.ts index 13874c8b..eda5431d 100644 --- a/tabby-electron/src/index.ts +++ b/tabby-electron/src/index.ts @@ -116,7 +116,6 @@ export default class ElectronModule { if (this.hostApp.platform === Platform.Windows && !isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) { vibrancyType = null } - document.body.classList.toggle('vibrant', this.config.store.appearance.vibrancy) this.electron.ipcRenderer.send('window-set-vibrancy', this.config.store.appearance.vibrancy, vibrancyType) this.hostWindow.setOpacity(this.config.store.appearance.opacity) diff --git a/tabby-terminal/src/api/baseTerminalTab.component.ts b/tabby-terminal/src/api/baseTerminalTab.component.ts index ffde073f..991b60db 100644 --- a/tabby-terminal/src/api/baseTerminalTab.component.ts +++ b/tabby-terminal/src/api/baseTerminalTab.component.ts @@ -1,4 +1,4 @@ -import { Observable, Subject, Subscription, first } from 'rxjs' +import { Observable, Subject, Subscription, first, auditTime } from 'rxjs' import { Spinner } from 'cli-spinner' import colors from 'ansi-colors' import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core' @@ -664,7 +664,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit this.sendInput(data) }) - this.termContainerSubscriptions.subscribe(this.frontend.resize$, ({ columns, rows }) => { + this.termContainerSubscriptions.subscribe(this.frontend.resize$.pipe(auditTime(100)), ({ columns, rows }) => { this.logger.debug(`Resizing to ${columns}x${rows}`) this.size = { columns, rows } this.zone.run(() => { diff --git a/tabby-terminal/src/components/terminalToolbar.component.pug b/tabby-terminal/src/components/terminalToolbar.component.pug index e4fc6fea..b7c62b2f 100644 --- a/tabby-terminal/src/components/terminalToolbar.component.pug +++ b/tabby-terminal/src/components/terminalToolbar.component.pug @@ -1,11 +1,23 @@ -ng-content - -button.btn.btn-sm.btn-link( - *ngIf='tab.enableToolbar', - (click)='tab.togglePinToolbar()', - (mouseenter)='tab.showToolbar()', - (mouseleave)='tab.hideToolbar()' +.content( + cdkDropList + cdkAutoDropGroup='app-tabs' ) - i.fas.fa-thumbtack - span(*ngIf='tab.pinToolbar', translate) Unpin - span(*ngIf='!tab.pinToolbar', translate) Pin + i.fas.fa-grip-vertical.drag-handle( + *ngIf='shouldShowDragHandle', + cdkDrag, + [cdkDragData]='tab', + (cdkDragStarted)='onTabDragStart()', + (cdkDragEnded)='onTabDragEnd()' + ) + + ng-content + + button.btn.btn-sm.btn-link( + *ngIf='tab.enableToolbar', + (click)='tab.togglePinToolbar()', + (mouseenter)='tab.showToolbar()', + (mouseleave)='tab.hideToolbar()' + ) + i.fas.fa-thumbtack + span(*ngIf='tab.pinToolbar', translate) Unpin + span(*ngIf='!tab.pinToolbar', translate) Pin diff --git a/tabby-terminal/src/components/terminalToolbar.component.scss b/tabby-terminal/src/components/terminalToolbar.component.scss index 1a13f070..65b352f3 100644 --- a/tabby-terminal/src/components/terminalToolbar.component.scss +++ b/tabby-terminal/src/components/terminalToolbar.component.scss @@ -1,10 +1,20 @@ :host { - background: rgba(0, 0, 0, .75); + background: #000000bf; padding: 5px 15px 5px 15px; + display: flex; + z-index: 3; +} +.content { + flex-grow: 1; display: flex; align-items: center; - z-index: 3; +} + +.drag-handle { + margin: 0 10px 0 0; + cursor: move; + opacity: .3; } ::ng-deep .btn { diff --git a/tabby-terminal/src/components/terminalToolbar.component.ts b/tabby-terminal/src/components/terminalToolbar.component.ts index a83a289f..559cba1a 100644 --- a/tabby-terminal/src/components/terminalToolbar.component.ts +++ b/tabby-terminal/src/components/terminalToolbar.component.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Component, HostListener, Input } from '@angular/core' +import { AppService, SplitTabComponent } from 'tabby-core' import { BaseTerminalTabComponent } from '../api/baseTerminalTab.component' /** @hidden */ @@ -11,6 +12,26 @@ import { BaseTerminalTabComponent } from '../api/baseTerminalTab.component' export class TerminalToolbarComponent { @Input() tab: BaseTerminalTabComponent + // eslint-disable-next-line @typescript-eslint/no-useless-constructor + constructor ( + private app: AppService, + ) { } + + onTabDragStart (): void { + this.app.emitTabDragStarted(this.tab) + } + + onTabDragEnd (): void { + setTimeout(() => { + this.app.emitTabDragEnded() + this.app.emitTabsChanged() + }) + } + + get shouldShowDragHandle (): boolean { + return this.tab.parent instanceof SplitTabComponent && this.tab.parent.getAllTabs().length > 1 + } + @HostListener('mouseenter') onMouseEnter () { this.tab.showToolbar() } diff --git a/yarn.lock b/yarn.lock index 068689b6..1336f135 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2763,10 +2763,10 @@ electron-to-chromium@^1.3.723: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.736.tgz#f632d900a1f788dab22fec9c62ec5c9c8f0c4052" integrity sha512-DY8dA7gR51MSo66DqitEQoUMQ0Z+A2DSXFi7tK304bdTVqczCAfUuyQw6Wdg8hIoo5zIxkU1L24RQtUce1Ioig== -electron@16.0.7: - version "16.0.7" - resolved "https://registry.yarnpkg.com/electron/-/electron-16.0.7.tgz#87eaccd05ab61563d3c17dfbad2949bba7ead162" - integrity sha512-/IMwpBf2svhA1X/7Q58RV+Nn0fvUJsHniG4TizaO7q4iKFYSQ6hBvsLz+cylcZ8hRMKmVy5G1XaMNJID2ah23w== +electron@16.0.8: + version "16.0.8" + resolved "https://registry.yarnpkg.com/electron/-/electron-16.0.8.tgz#7ebd3e23c4883c239f53d8b7af1100f455ac8a02" + integrity sha512-znTVkl8LaGcPNdfc6SRr+6LYg2GtSCKXln/nW/PC+urBfAFnOYIuDock8QyGVFfzr5PuAa+g8YQQAboHV77D7g== dependencies: "@electron/get" "^1.13.0" "@types/node" "^14.6.2" @@ -5538,9 +5538,11 @@ node-fetch-npm@^2.0.1: safe-buffer "^5.0.1" node-fetch@^2.6.0: - version "2.6.1" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" node-gyp-build@^4.2.1: version "4.2.3" @@ -8286,6 +8288,11 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz" @@ -8668,6 +8675,11 @@ wcwidth@^1.0.0, wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webpack-bundle-analyzer@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz#1b0eea2947e73528754a6f9af3e91b2b6e0f79d5" @@ -8744,6 +8756,14 @@ webpack@^5.67.0: watchpack "^2.3.1" webpack-sources "^3.2.3" +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"