mirror of
https://github.com/Eugeny/tabby.git
synced 2025-09-14 12:24:34 +00:00
Compare commits
55 Commits
all-contri
...
all-contri
Author | SHA1 | Date | |
---|---|---|---|
![]() |
db916c922a | ||
![]() |
dfc438258d | ||
![]() |
6a714a746f | ||
![]() |
54284741e0 | ||
![]() |
e4b545f231 | ||
![]() |
c27566a561 | ||
![]() |
43121c33f2 | ||
![]() |
4b34f76997 | ||
![]() |
24db1cb99a | ||
![]() |
147d22f386 | ||
![]() |
c04b93c56c | ||
![]() |
ddab79d3ac | ||
![]() |
c501f541c8 | ||
![]() |
8af3c95212 | ||
![]() |
2fa612fe2c | ||
![]() |
725bc225f1 | ||
![]() |
8451848ba6 | ||
![]() |
186a4afa1c | ||
![]() |
1d1b149ea8 | ||
![]() |
b217aaf03b | ||
![]() |
c7471f737f | ||
![]() |
124d600bfd | ||
![]() |
a3f2405092 | ||
![]() |
a92f8956d4 | ||
![]() |
22fb2dbda2 | ||
![]() |
303eab2f0e | ||
![]() |
8a12e7c6d1 | ||
![]() |
821dcbff69 | ||
![]() |
44d8c3f04b | ||
![]() |
af515e01cf | ||
![]() |
fcac52a844 | ||
![]() |
4736b11c62 | ||
![]() |
a128a647d9 | ||
![]() |
9638be5349 | ||
![]() |
9c863762c3 | ||
![]() |
539c213ef6 | ||
![]() |
d2bdb55c6d | ||
![]() |
4edc0be280 | ||
![]() |
f10b8c0f35 | ||
![]() |
e38b826fd6 | ||
![]() |
2f1c388a8b | ||
![]() |
e7f7d9b024 | ||
![]() |
47a6e81998 | ||
![]() |
eea3ab9c74 | ||
![]() |
0313e872fd | ||
![]() |
84422d4453 | ||
![]() |
57da067727 | ||
![]() |
fa50c7d9fa | ||
![]() |
9a82c4c5c0 | ||
![]() |
a4136bec6e | ||
![]() |
82a262026f | ||
![]() |
6709217a86 | ||
![]() |
4bbf86a7a7 | ||
![]() |
d98fbe8b44 | ||
![]() |
3d9b15a82d |
@@ -1202,6 +1202,24 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "wljince007",
|
||||
"name": "wljince007",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/88243938?v=4",
|
||||
"profile": "https://github.com/wljince007",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "FeroTheFox",
|
||||
"name": "fero",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/52982404?v=4",
|
||||
"profile": "https://github.com/FeroTheFox",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
@@ -323,6 +323,8 @@ Dank geht an diese wunderbaren Menschen ([emoji key](https://allcontributors.org
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -325,6 +325,8 @@ Gracias a estas maravillosas personas ([emoji key](https://allcontributors.org/d
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -322,6 +322,8 @@ Terima kasih kepada mereka yang telah membantu ([emoji key](https://allcontribut
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -318,6 +318,8 @@ Grazie a queste persone meravigliose ([emoji key](https://allcontributors.org/do
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -333,6 +333,8 @@ Windows上では、`Tabby.exe`がある場所と同じ場所に`data`フォル
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -312,6 +312,8 @@ Pull requests and plugins are welcome!
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -334,6 +334,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -326,6 +326,8 @@ Obrigado vai para essas pessoas maravilhosas ([emoji key](https://allcontributor
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -318,6 +318,8 @@ Pull-запросы и плагины приветствуются!
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -317,6 +317,8 @@
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -92,8 +92,11 @@ export class Window {
|
||||
if (this.configStore.appearance?.frame === 'native') {
|
||||
bwOptions.frame = true
|
||||
} else {
|
||||
if (process.platform === 'darwin') {
|
||||
bwOptions.titleBarStyle = 'hidden'
|
||||
bwOptions.titleBarStyle = 'hidden'
|
||||
if (process.platform === 'win32') {
|
||||
bwOptions.titleBarOverlay = {
|
||||
color: '#00000000',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,6 +387,21 @@ export class Window {
|
||||
this.setVibrancy(enabled, type)
|
||||
})
|
||||
|
||||
ipcMain.on('window-set-window-controls-color', (event, theme) => {
|
||||
if (!this.window || event.sender !== this.window.webContents) {
|
||||
return
|
||||
}
|
||||
|
||||
const symbolColor: string = theme.foreground
|
||||
|
||||
this.window.setTitleBarOverlay(
|
||||
{
|
||||
symbolColor: symbolColor,
|
||||
height: 32,
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('window-set-title', (event, title) => {
|
||||
if (!this.window || event.sender !== this.window.webContents) {
|
||||
return
|
||||
|
@@ -16,7 +16,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/remote": "2.0.10",
|
||||
"node-pty": "^0.11.0-beta32",
|
||||
"node-pty": "^1.0",
|
||||
"any-promise": "^1.3.0",
|
||||
"electron-config": "2.0.0",
|
||||
"electron-debug": "^3.2.0",
|
||||
|
@@ -138,13 +138,6 @@
|
||||
dependencies:
|
||||
debug "^4.3.2"
|
||||
|
||||
"@tabby-gang/node-pty@^0.11.0-beta.203":
|
||||
version "0.11.0-beta.204"
|
||||
resolved "https://registry.yarnpkg.com/@tabby-gang/node-pty/-/node-pty-0.11.0-beta.204.tgz#80d4393c7a233d3298f47a4755467a246b0099f9"
|
||||
integrity sha512-sNT5Z2MEkEIhToAdVAdZ/lfeQ9UgFE3h2ENlOux+WHBrl1k0BiUEIOd/jh/K3mNAGEfcZ44gNQQ50g5KXTQEmA==
|
||||
dependencies:
|
||||
nan "^2.16.0"
|
||||
|
||||
"@tabby-gang/windows-blurbehind@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@tabby-gang/windows-blurbehind/-/windows-blurbehind-3.0.0.tgz#48d409c2eb14a12c867b70de5ee4d6769ef45e8f"
|
||||
@@ -2264,7 +2257,7 @@ mz@^2.7.0:
|
||||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
nan@^2.16.0, nan@^2.17.0, "nan@github:jkleinsc/nan#remove_accessor_signature":
|
||||
nan@^2.17.0, "nan@github:jkleinsc/nan#remove_accessor_signature":
|
||||
version "2.16.0"
|
||||
resolved "https://codeload.github.com/jkleinsc/nan/tar.gz/6a2f95a6a2209d8aa7542fb18099fd808a802059"
|
||||
|
||||
@@ -2352,6 +2345,13 @@ node-gyp@^5.0.2, node-gyp@^5.1.0:
|
||||
tar "^4.4.12"
|
||||
which "^1.3.1"
|
||||
|
||||
node-pty@^1.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-1.0.0.tgz#7daafc0aca1c4ca3de15c61330373af4af5861fd"
|
||||
integrity sha512-wtBMWWS7dFZm/VgqElrTvtfMq4GzJ6+edFI0Y0zyzygUSZMgZdraDUMUhCIvkjhJjme15qWmbyJbtAx4ot4uZA==
|
||||
dependencies:
|
||||
nan "^2.17.0"
|
||||
|
||||
nopt@^4.0.1, nopt@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
||||
|
@@ -39,7 +39,7 @@
|
||||
"cross-env": "7.0.3",
|
||||
"css-loader": "^6.7.3",
|
||||
"deep-equal": "2.0.5",
|
||||
"electron": "22.3.1",
|
||||
"electron": "^25.3.0",
|
||||
"electron-builder": "^24.0.0-alpha.1",
|
||||
"electron-download": "^4.1.1",
|
||||
"electron-installer-snap": "^5.1.0",
|
||||
|
@@ -1,16 +1,20 @@
|
||||
title-bar(
|
||||
*ngIf='ready && !hostWindow.isFullscreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
|
||||
(dblclick)='hostWindow.toggleMaximize()',
|
||||
[hideControls]='hostApp.platform !== Platform.Linux && !hostWindow.isFullscreen',
|
||||
[class.inset]='hostApp.platform == Platform.macOS && !hostWindow.isFullscreen'
|
||||
)
|
||||
|
||||
.content(
|
||||
*ngIf='ready',
|
||||
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left"',
|
||||
[class.tabs-on-side]='hasVerticalTabs()',
|
||||
[class.tabs-on-left]='hasVerticalTabs() && config.store.appearance.tabsLocation == "left"',
|
||||
[class.tabs-titlebar-enabled]='config.store.appearance.frame == "full"',
|
||||
[class.tabs-on-right]='hasVerticalTabs() && config.store.appearance.tabsLocation == "right"',
|
||||
)
|
||||
.tab-bar(
|
||||
*ngIf='!hostWindow.isFullscreen || config.store.appearance.tabsInFullscreen',
|
||||
[class.tab-bar-no-controls-overlay]='hostApp.platform == Platform.macOS',
|
||||
(dblclick)='hostWindow.toggleMaximize()'
|
||||
)
|
||||
.inset.background(*ngIf='hostApp.platform == Platform.macOS \
|
||||
@@ -81,9 +85,12 @@ title-bar(
|
||||
|
||||
window-controls.background(
|
||||
*ngIf='config.store.appearance.frame == "thin" \
|
||||
&& (hostApp.platform == Platform.Windows || hostApp.platform == Platform.Linux)',
|
||||
&& (hostApp.platform == Platform.Linux)',
|
||||
)
|
||||
|
||||
div.window-controls-spacer(
|
||||
*ngIf='config.store.appearance.frame == "thin" && (hostApp.platform == Platform.Windows) && (config.store.appearance.tabsLocation == "top")',
|
||||
)
|
||||
.content
|
||||
start-page.content-tab.content-tab-active(*ngIf='ready && app.tabs.length == 0')
|
||||
|
||||
|
@@ -35,17 +35,16 @@ $tab-border-radius: 4px;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&.tabs-on-side {
|
||||
&.tabs-on-right {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
&.tabs-on-top {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
&.tabs-on-left {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.content.tabs-on-side > .tab-bar {
|
||||
.content.tabs-on-left > .tab-bar, .content.tabs-on-right > .tab-bar {
|
||||
height: 100%;
|
||||
width: var(--side-tab-width);
|
||||
overflow-y: auto;
|
||||
@@ -76,6 +75,18 @@ $tab-border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.content.tabs-on-left > .tab-bar.tab-bar-no-controls-overlay, .content.tabs-titlebar-enabled {
|
||||
.tabs {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.content.tabs-on-right > .tab-bar {
|
||||
.tabs {
|
||||
// Account for WCO on Windows.
|
||||
padding-top: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-bar {
|
||||
flex: none;
|
||||
@@ -125,10 +136,17 @@ $tab-border-radius: 4px;
|
||||
}
|
||||
|
||||
&.persistent {
|
||||
min-width: 72px; // 2 x 36 px height, ie 2 squares
|
||||
// min-width: 72px; // 2 x 36 px height, ie 2 squares
|
||||
// Given WCO on Windows, the min-width of the window buttons is about 138px.
|
||||
min-width: 138px;
|
||||
}
|
||||
}
|
||||
|
||||
&>.window-controls-spacer {
|
||||
min-width: 138px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
& > .inset {
|
||||
width: calc(70px + 15px * var(--spaciness));
|
||||
height: var(--tabs-height);
|
||||
|
@@ -1,2 +1,2 @@
|
||||
.title((dblclick)='hostWindow.toggleMaximize()') Tabby
|
||||
window-controls
|
||||
window-controls(*ngIf="!hideControls")
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { Component, Input } from '@angular/core'
|
||||
import { HostWindowService } from '../api'
|
||||
|
||||
/** @hidden */
|
||||
@@ -8,5 +8,7 @@ import { HostWindowService } from '../api'
|
||||
styleUrls: ['./titleBar.component.scss'],
|
||||
})
|
||||
export class TitleBarComponent {
|
||||
@Input() hideControls: boolean
|
||||
|
||||
constructor (public hostWindow: HostWindowService) { }
|
||||
}
|
||||
|
@@ -15,6 +15,9 @@ const deepmerge = require('deepmerge')
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const configMerge = (a, b) => deepmerge(a, b, { arrayMerge: (_d, s) => s }) // eslint-disable-line @typescript-eslint/no-var-requires
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const configMergeByDefault = (a, b) => deepmerge(a, b) // eslint-disable-line @typescript-eslint/no-var-requires
|
||||
|
||||
const LATEST_VERSION = 1
|
||||
|
||||
function isStructuralMember (v) {
|
||||
@@ -162,7 +165,7 @@ export class ConfigService {
|
||||
defaults = configMerge(provider.defaults, defaults)
|
||||
}
|
||||
return defaults
|
||||
}).reduce(configMerge)
|
||||
}).reduce(configMergeByDefault)
|
||||
}
|
||||
|
||||
getDefaults (): Record<string, any> {
|
||||
@@ -213,7 +216,9 @@ export class ConfigService {
|
||||
* Reads config YAML as string
|
||||
*/
|
||||
readRaw (): string {
|
||||
return yaml.dump(this._store)
|
||||
// Scrub undefined values
|
||||
const cleanStore = JSON.parse(JSON.stringify(this._store))
|
||||
return yaml.dump(cleanStore)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,6 +356,14 @@ export class ConfigService {
|
||||
delete window.localStorage.lastSerialConnection
|
||||
config.version = 3
|
||||
}
|
||||
if (config.version < 4) {
|
||||
for (const p of config.profiles ?? []) {
|
||||
if (!p.id) {
|
||||
p.id = `${p.type}:custom:${uuidv4()}`
|
||||
}
|
||||
}
|
||||
config.version = 4
|
||||
}
|
||||
}
|
||||
|
||||
private async maybeDecryptConfig (store) {
|
||||
|
@@ -99,6 +99,7 @@ export default class ElectronModule {
|
||||
})
|
||||
this.registerGlobalHotkey()
|
||||
this.updateVibrancy()
|
||||
this.updateWindowControlsColor()
|
||||
})
|
||||
|
||||
config.changed$.subscribe(() => {
|
||||
@@ -131,6 +132,8 @@ export default class ElectronModule {
|
||||
|
||||
config.changed$.subscribe(() => this.updateVibrancy())
|
||||
|
||||
config.changed$.subscribe(() => this.updateWindowControlsColor())
|
||||
|
||||
config.ready$.toPromise().then(() => {
|
||||
dockMenu.update()
|
||||
})
|
||||
@@ -169,6 +172,15 @@ export default class ElectronModule {
|
||||
|
||||
this.hostWindow.setOpacity(this.config.store.appearance.opacity)
|
||||
}
|
||||
|
||||
private updateWindowControlsColor () {
|
||||
// if windows and not using native frame, WCO does not exist, return.
|
||||
if (this.hostApp.platform === Platform.Windows && this.config.store.appearance.frame === 'native') {
|
||||
return
|
||||
}
|
||||
|
||||
this.electron.ipcRenderer.send('window-set-window-controls-color', this.config.store.terminal.colorScheme)
|
||||
}
|
||||
}
|
||||
|
||||
export { ElectronHostWindow, ElectronHostAppService, ElectronService }
|
||||
|
@@ -21,7 +21,7 @@ import { RecoveryProvider } from './recoveryProvider'
|
||||
import { ShellSettingsTabProvider } from './settings'
|
||||
import { TerminalConfigProvider } from './config'
|
||||
import { LocalTerminalHotkeyProvider } from './hotkeys'
|
||||
import { NewTabContextMenu, SaveAsProfileContextMenu } from './tabContextMenu'
|
||||
import { NewTabContextMenu } from './tabContextMenu'
|
||||
|
||||
import { AutoOpenTabCLIHandler, OpenPathCLIHandler, TerminalCLIHandler } from './cli'
|
||||
import { LocalProfilesService } from './profiles'
|
||||
@@ -47,7 +47,6 @@ import { LocalProfilesService } from './profiles'
|
||||
{ provide: ProfileProvider, useClass: LocalProfilesService, multi: true },
|
||||
|
||||
{ provide: TabContextMenuItemProvider, useClass: NewTabContextMenu, multi: true },
|
||||
{ provide: TabContextMenuItemProvider, useClass: SaveAsProfileContextMenu, multi: true },
|
||||
|
||||
{ provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
|
||||
{ provide: CLIHandler, useClass: OpenPathCLIHandler, multi: true },
|
||||
|
@@ -1,59 +1,9 @@
|
||||
import { Inject, Injectable, Optional } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, NotificationsService, MenuItemOptions, ProfilesService, PromptModalComponent, TranslateService } from 'tabby-core'
|
||||
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, MenuItemOptions, ProfilesService, TranslateService } from 'tabby-core'
|
||||
import { TerminalTabComponent } from './components/terminalTab.component'
|
||||
import { TerminalService } from './services/terminal.service'
|
||||
import { LocalProfile, UACService } from './api'
|
||||
|
||||
/** @hidden */
|
||||
@Injectable()
|
||||
export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
|
||||
constructor (
|
||||
private config: ConfigService,
|
||||
private ngbModal: NgbModal,
|
||||
private notifications: NotificationsService,
|
||||
private translate: TranslateService,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
|
||||
if (!(tab instanceof TerminalTabComponent)) {
|
||||
return []
|
||||
}
|
||||
const terminalTab = tab
|
||||
const items: MenuItemOptions[] = [
|
||||
{
|
||||
label: this.translate.instant('Save as profile'),
|
||||
click: async () => {
|
||||
const modal = this.ngbModal.open(PromptModalComponent)
|
||||
modal.componentInstance.prompt = this.translate.instant('New profile name')
|
||||
const name = (await modal.result)?.value
|
||||
if (!name) {
|
||||
return
|
||||
}
|
||||
const profile = {
|
||||
options: {
|
||||
...terminalTab.profile.options,
|
||||
cwd: await terminalTab.session?.getWorkingDirectory() ?? terminalTab.profile.options.cwd,
|
||||
},
|
||||
name,
|
||||
type: 'local',
|
||||
}
|
||||
this.config.store.profiles = [
|
||||
...this.config.store.profiles,
|
||||
profile,
|
||||
]
|
||||
this.config.save()
|
||||
this.notifications.info(this.translate.instant('Saved'))
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
||||
/** @hidden */
|
||||
@Injectable()
|
||||
export class NewTabContextMenu extends TabContextMenuItemProvider {
|
||||
|
@@ -3,7 +3,7 @@ import { SerialPortStream } from '@serialport/stream'
|
||||
import { LogService, NotificationsService } from 'tabby-core'
|
||||
import { Subject, Observable } from 'rxjs'
|
||||
import { Injector, NgZone } from '@angular/core'
|
||||
import { BaseSession, BaseTerminalProfile, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor, UTF8SplitterMiddleware } from 'tabby-terminal'
|
||||
import { BaseSession, BaseTerminalProfile, InputProcessingOptions, InputProcessor, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor, UTF8SplitterMiddleware } from 'tabby-terminal'
|
||||
import { SerialService } from './services/serial.service'
|
||||
|
||||
export interface SerialProfile extends BaseTerminalProfile {
|
||||
@@ -21,6 +21,7 @@ export interface SerialProfileOptions extends StreamProcessingOptions, LoginScri
|
||||
xoff?: boolean
|
||||
xany?: boolean
|
||||
slowSend?: boolean
|
||||
input: InputProcessingOptions,
|
||||
}
|
||||
|
||||
export const BAUD_RATES = [
|
||||
@@ -65,6 +66,7 @@ export class SerialSession extends BaseSession {
|
||||
}
|
||||
|
||||
this.middleware.push(new UTF8SplitterMiddleware())
|
||||
this.middleware.push(new InputProcessor(profile.options.input))
|
||||
|
||||
this.setLoginScriptsOptions(profile.options)
|
||||
}
|
||||
|
@@ -92,4 +92,9 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
|
||||
ng-template(ngbNavContent)
|
||||
login-scripts-settings([options]='profile.options')
|
||||
|
||||
li(ngbNavItem)
|
||||
a(ngbNavLink, translate) Input
|
||||
ng-template(ngbNavContent)
|
||||
input-processing-settings([options]='profile.options.input')
|
||||
|
||||
div([ngbNavOutlet]='nav')
|
||||
|
@@ -30,6 +30,7 @@ export class SerialProfilesService extends ProfileProvider<SerialProfile> {
|
||||
outputNewlines: null,
|
||||
scripts: [],
|
||||
slowSend: false,
|
||||
input: { backspace: 'backspace' },
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { BaseTerminalProfile, LoginScriptsOptions } from 'tabby-terminal'
|
||||
import { BaseTerminalProfile, InputProcessingOptions, LoginScriptsOptions } from 'tabby-terminal'
|
||||
|
||||
export enum SSHAlgorithmType {
|
||||
HMAC = 'hmac',
|
||||
@@ -34,6 +34,7 @@ export interface SSHProfileOptions extends LoginScriptsOptions {
|
||||
httpProxyHost?: string
|
||||
httpProxyPort?: number
|
||||
reuseSession?: boolean
|
||||
input: InputProcessingOptions,
|
||||
}
|
||||
|
||||
export enum PortForwardType {
|
||||
|
@@ -294,4 +294,9 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
|
||||
ng-template(ngbNavContent)
|
||||
login-scripts-settings([options]='profile.options', #loginScriptsSettings)
|
||||
|
||||
li(ngbNavItem)
|
||||
a(ngbNavLink, translate) Input
|
||||
ng-template(ngbNavContent)
|
||||
input-processing-settings([options]='profile.options.input')
|
||||
|
||||
div([ngbNavOutlet]='nav')
|
||||
|
@@ -43,6 +43,7 @@ export class SSHProfilesService extends ProfileProvider<SSHProfile> {
|
||||
httpProxyHost: null,
|
||||
httpProxyPort: null,
|
||||
reuseSession: true,
|
||||
input: { backspace: 'backspace' },
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@ import stripAnsi from 'strip-ansi'
|
||||
import { ClientChannel } from 'ssh2'
|
||||
import { Injector } from '@angular/core'
|
||||
import { LogService } from 'tabby-core'
|
||||
import { BaseSession, UTF8SplitterMiddleware } from 'tabby-terminal'
|
||||
import { BaseSession, UTF8SplitterMiddleware, InputProcessor } from 'tabby-terminal'
|
||||
import { SSHSession } from './ssh'
|
||||
import { SSHProfile } from '../api'
|
||||
|
||||
@@ -24,6 +24,7 @@ export class SSHShellSession extends BaseSession {
|
||||
this.setLoginScriptsOptions(this.profile.options)
|
||||
this.ssh.serviceMessage$.subscribe(m => this.serviceMessage.next(m))
|
||||
this.middleware.push(new UTF8SplitterMiddleware())
|
||||
this.middleware.push(new InputProcessor(profile.options.input))
|
||||
}
|
||||
|
||||
async start (): Promise<void> {
|
||||
|
@@ -24,4 +24,9 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
|
||||
ng-template(ngbNavContent)
|
||||
login-scripts-settings([options]='profile.options')
|
||||
|
||||
li(ngbNavItem)
|
||||
a(ngbNavLink, translate) Input
|
||||
ng-template(ngbNavContent)
|
||||
input-processing-settings([options]='profile.options.input')
|
||||
|
||||
div([ngbNavOutlet]='nav')
|
||||
|
@@ -19,6 +19,7 @@ export class TelnetProfilesService extends ProfileProvider<TelnetProfile> {
|
||||
inputNewlines: null,
|
||||
outputNewlines: 'crlf',
|
||||
scripts: [],
|
||||
input: { backspace: 'backspace' },
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@ import colors from 'ansi-colors'
|
||||
import stripAnsi from 'strip-ansi'
|
||||
import { Injector } from '@angular/core'
|
||||
import { LogService } from 'tabby-core'
|
||||
import { BaseSession, BaseTerminalProfile, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal'
|
||||
import { BaseSession, BaseTerminalProfile, InputProcessingOptions, InputProcessor, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal'
|
||||
import { Subject, Observable } from 'rxjs'
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ export interface TelnetProfile extends BaseTerminalProfile {
|
||||
export interface TelnetProfileOptions extends StreamProcessingOptions, LoginScriptsOptions {
|
||||
host: string
|
||||
port?: number
|
||||
input: InputProcessingOptions,
|
||||
}
|
||||
|
||||
enum TelnetCommands {
|
||||
@@ -66,6 +67,7 @@ export class TelnetSession extends BaseSession {
|
||||
private lastWidth = 0
|
||||
private lastHeight = 0
|
||||
private requestedOptions = new Set<number>()
|
||||
private telnetRemoteEcho = false
|
||||
|
||||
constructor (
|
||||
injector: Injector,
|
||||
@@ -74,6 +76,7 @@ export class TelnetSession extends BaseSession {
|
||||
super(injector.get(LogService).create(`telnet-${profile.options.host}-${profile.options.port}`))
|
||||
this.streamProcessor = new TerminalStreamProcessor(profile.options)
|
||||
this.middleware.push(this.streamProcessor)
|
||||
this.middleware.push(new InputProcessor(profile.options.input))
|
||||
this.setLoginScriptsOptions(profile.options)
|
||||
}
|
||||
|
||||
@@ -159,7 +162,7 @@ export class TelnetSession extends BaseSession {
|
||||
data = data.slice(3)
|
||||
this.logger.debug('<', commandName || command, optionName || option)
|
||||
|
||||
if (command === TelnetCommands.WILL || command === TelnetCommands.WONT) {
|
||||
if (command === TelnetCommands.WILL || command === TelnetCommands.WONT || command === TelnetCommands.DONT) {
|
||||
if (this.requestedOptions.has(option)) {
|
||||
this.requestedOptions.delete(option)
|
||||
continue
|
||||
@@ -172,6 +175,11 @@ export class TelnetSession extends BaseSession {
|
||||
TelnetOptions.ECHO,
|
||||
].includes(option)) {
|
||||
this.emitTelnet(TelnetCommands.DO, option)
|
||||
if (option === TelnetOptions.ECHO && this.streamProcessor.forceEcho) {
|
||||
this.telnetRemoteEcho = true
|
||||
this.streamProcessor.forceEcho = false
|
||||
this.requestOption(TelnetCommands.WONT, option)
|
||||
}
|
||||
} else {
|
||||
this.logger.debug('(!) Unhandled option')
|
||||
this.emitTelnet(TelnetCommands.DONT, option)
|
||||
@@ -182,8 +190,13 @@ export class TelnetSession extends BaseSession {
|
||||
this.emitTelnet(TelnetCommands.WILL, option)
|
||||
this.emitSize()
|
||||
} else if (option === TelnetOptions.ECHO) {
|
||||
this.streamProcessor.forceEcho = true
|
||||
this.emitTelnet(TelnetCommands.WILL, option)
|
||||
if (this.telnetRemoteEcho) {
|
||||
this.streamProcessor.forceEcho = false
|
||||
this.emitTelnet(TelnetCommands.WONT, option)
|
||||
} else {
|
||||
this.streamProcessor.forceEcho = true
|
||||
this.emitTelnet(TelnetCommands.WILL, option)
|
||||
}
|
||||
} else if (option === TelnetOptions.TERMINAL_TYPE) {
|
||||
this.emitTelnet(TelnetCommands.WILL, option)
|
||||
} else {
|
||||
@@ -197,7 +210,16 @@ export class TelnetSession extends BaseSession {
|
||||
this.emitTelnet(TelnetCommands.WONT, option)
|
||||
} else {
|
||||
this.logger.debug('(!) Unhandled option')
|
||||
this.emitTelnet(TelnetCommands.WILL, option)
|
||||
this.emitTelnet(TelnetCommands.WONT, option)
|
||||
}
|
||||
}
|
||||
if (command === TelnetCommands.WONT) {
|
||||
if (option === TelnetOptions.ECHO) {
|
||||
this.telnetRemoteEcho = false
|
||||
this.emitTelnet(TelnetCommands.DONT, option)
|
||||
} else {
|
||||
this.logger.debug('(!) Unhandled option')
|
||||
this.emitTelnet(TelnetCommands.DONT, option)
|
||||
}
|
||||
}
|
||||
if (command === TelnetCommands.SUBOPTION) {
|
||||
|
@@ -0,0 +1,9 @@
|
||||
.form-line
|
||||
.header
|
||||
.title(translate) Backspace key mode
|
||||
|
||||
select.form-control([(ngModel)]='options.backspace')
|
||||
option(
|
||||
*ngFor='let mode of backspaceModes',
|
||||
[value]='mode.key',
|
||||
) {{mode.name|translate}}
|
@@ -0,0 +1,40 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
|
||||
import { Component, Input } from '@angular/core'
|
||||
import { InputProcessingOptions } from '../middleware/inputProcessing'
|
||||
|
||||
/** @hidden */
|
||||
@Component({
|
||||
selector: 'input-processing-settings',
|
||||
templateUrl: './inputProcessingSettings.component.pug',
|
||||
})
|
||||
export class InputProcessingSettingsComponent {
|
||||
@Input() options: InputProcessingOptions
|
||||
|
||||
backspaceModes = [
|
||||
{
|
||||
key: 'backspace',
|
||||
name: _('Pass-through'),
|
||||
},
|
||||
{
|
||||
key: 'ctrl-h',
|
||||
name: 'Ctrl-H',
|
||||
},
|
||||
{
|
||||
key: 'ctrl-?',
|
||||
name: 'Ctrl-?',
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
name: 'Delete (CSI 3~)',
|
||||
},
|
||||
]
|
||||
|
||||
getBackspaceModeName (key) {
|
||||
return this.backspaceModes.find(x => x.key === key)?.name
|
||||
}
|
||||
|
||||
setBackspaceMode (mode) {
|
||||
this.options.backspace = mode
|
||||
}
|
||||
}
|
@@ -18,6 +18,7 @@ import { StreamProcessingSettingsComponent } from './components/streamProcessing
|
||||
import { LoginScriptsSettingsComponent } from './components/loginScriptsSettings.component'
|
||||
import { TerminalToolbarComponent } from './components/terminalToolbar.component'
|
||||
import { ColorSchemeSelectorComponent } from './components/colorSchemeSelector.component'
|
||||
import { InputProcessingSettingsComponent } from './components/inputProcessingSettings.component'
|
||||
|
||||
import { TerminalDecorator } from './api/decorator'
|
||||
import { TerminalContextMenuItemProvider } from './api/contextMenuProvider'
|
||||
@@ -28,7 +29,7 @@ import { PathDropDecorator } from './features/pathDrop'
|
||||
import { ZModemDecorator } from './features/zmodem'
|
||||
import { TerminalConfigProvider } from './config'
|
||||
import { TerminalHotkeyProvider } from './hotkeys'
|
||||
import { CopyPasteContextMenu, MiscContextMenu, LegacyContextMenu, ReconnectContextMenu } from './tabContextMenu'
|
||||
import { CopyPasteContextMenu, MiscContextMenu, LegacyContextMenu, ReconnectContextMenu, SaveAsProfileContextMenu } from './tabContextMenu'
|
||||
|
||||
import { Frontend } from './frontends/frontend'
|
||||
import { XTermFrontend, XTermWebGLFrontend } from './frontends/xtermFrontend'
|
||||
@@ -60,6 +61,7 @@ import { DefaultColorSchemes } from './colorSchemes'
|
||||
{ provide: TabContextMenuItemProvider, useClass: MiscContextMenu, multi: true },
|
||||
{ provide: TabContextMenuItemProvider, useClass: LegacyContextMenu, multi: true },
|
||||
{ provide: TabContextMenuItemProvider, useClass: ReconnectContextMenu, multi: true },
|
||||
{ provide: TabContextMenuItemProvider, useClass: SaveAsProfileContextMenu, multi: true },
|
||||
|
||||
{ provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
|
||||
{ provide: TerminalColorSchemeProvider, useClass: DefaultColorSchemes, multi: true },
|
||||
@@ -75,6 +77,7 @@ import { DefaultColorSchemes } from './colorSchemes'
|
||||
StreamProcessingSettingsComponent,
|
||||
LoginScriptsSettingsComponent,
|
||||
TerminalToolbarComponent,
|
||||
InputProcessingSettingsComponent,
|
||||
],
|
||||
exports: [
|
||||
ColorPickerComponent,
|
||||
@@ -83,6 +86,7 @@ import { DefaultColorSchemes } from './colorSchemes'
|
||||
StreamProcessingSettingsComponent,
|
||||
LoginScriptsSettingsComponent,
|
||||
TerminalToolbarComponent,
|
||||
InputProcessingSettingsComponent,
|
||||
],
|
||||
})
|
||||
export default class TerminalModule { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||
@@ -96,6 +100,7 @@ export * from './middleware/streamProcessing'
|
||||
export * from './middleware/loginScriptProcessing'
|
||||
export * from './middleware/oscProcessing'
|
||||
export * from './middleware/utf8Splitter'
|
||||
export * from './middleware/inputProcessing'
|
||||
export * from './api/middleware'
|
||||
export * from './session'
|
||||
export { LoginScriptsSettingsComponent, StreamProcessingSettingsComponent }
|
||||
|
28
tabby-terminal/src/middleware/inputProcessing.ts
Normal file
28
tabby-terminal/src/middleware/inputProcessing.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { SessionMiddleware } from '../api/middleware'
|
||||
|
||||
export interface InputProcessingOptions {
|
||||
backspace: 'ctrl-h'|'ctrl-?'|'delete'|'backspace'
|
||||
}
|
||||
|
||||
export class InputProcessor extends SessionMiddleware {
|
||||
constructor (
|
||||
private options: InputProcessingOptions,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
feedFromTerminal (data: Buffer): void {
|
||||
if (data.length === 1 && data[0] === 0x7f) {
|
||||
if (this.options.backspace === 'ctrl-h') {
|
||||
data = Buffer.from('\x08')
|
||||
} else if (this.options.backspace === 'ctrl-?') {
|
||||
data = Buffer.from('\x7f')
|
||||
} else if (this.options.backspace === 'delete') {
|
||||
data = Buffer.from('\x1b[3~')
|
||||
} else {
|
||||
data = Buffer.from('\x7f')
|
||||
}
|
||||
}
|
||||
this.outputToSession.next(data)
|
||||
}
|
||||
}
|
@@ -73,11 +73,6 @@ export class LoginScriptProcessor extends SessionMiddleware {
|
||||
super.feedFromSession(data)
|
||||
}
|
||||
|
||||
close (): void {
|
||||
this.outputToSession.complete()
|
||||
super.close()
|
||||
}
|
||||
|
||||
executeUnconditionalScripts (): void {
|
||||
for (const script of this.remainingScripts) {
|
||||
if (!script.expect) {
|
||||
|
@@ -1,9 +1,12 @@
|
||||
import { Injectable, Optional, Inject } from '@angular/core'
|
||||
import { BaseTabComponent, TabContextMenuItemProvider, NotificationsService, MenuItemOptions, TranslateService, SplitTabComponent } from 'tabby-core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { BaseTabComponent, TabContextMenuItemProvider, NotificationsService, MenuItemOptions, TranslateService, SplitTabComponent, PromptModalComponent, ConfigService, PartialProfile, Profile } from 'tabby-core'
|
||||
import { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
|
||||
import { TerminalContextMenuItemProvider } from './api/contextMenuProvider'
|
||||
import { MultifocusService } from './services/multifocus.service'
|
||||
import { ConnectableTerminalTabComponent } from './api/connectableTerminalTab.component'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import slugify from 'slugify'
|
||||
|
||||
/** @hidden */
|
||||
@Injectable()
|
||||
@@ -150,3 +153,66 @@ export class LegacyContextMenu extends TabContextMenuItemProvider {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @hidden */
|
||||
@Injectable()
|
||||
export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
|
||||
constructor (
|
||||
private config: ConfigService,
|
||||
private ngbModal: NgbModal,
|
||||
private notifications: NotificationsService,
|
||||
private translate: TranslateService,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
|
||||
if (tab instanceof BaseTerminalTabComponent) {
|
||||
return [
|
||||
{
|
||||
label: this.translate.instant('Save as profile'),
|
||||
click: async () => {
|
||||
const modal = this.ngbModal.open(PromptModalComponent)
|
||||
modal.componentInstance.prompt = this.translate.instant('New profile name')
|
||||
modal.componentInstance.value = tab.profile.name
|
||||
const name = (await modal.result)?.value
|
||||
if (!name) {
|
||||
return
|
||||
}
|
||||
|
||||
const options = {
|
||||
...tab.profile.options,
|
||||
}
|
||||
|
||||
const cwd = await tab.session?.getWorkingDirectory() ?? tab.profile.options.cwd
|
||||
if (cwd) {
|
||||
options.cwd = cwd
|
||||
}
|
||||
|
||||
const profile: PartialProfile<Profile> = {
|
||||
type: tab.profile.type,
|
||||
name,
|
||||
options,
|
||||
}
|
||||
|
||||
profile.id = `${profile.type}:custom:${slugify(name)}:${uuidv4()}`
|
||||
profile.group = tab.profile.group
|
||||
profile.icon = tab.profile.icon
|
||||
profile.color = tab.profile.color
|
||||
profile.disableDynamicTitle = tab.profile.disableDynamicTitle
|
||||
profile.behaviorOnSessionEnd = tab.profile.behaviorOnSessionEnd
|
||||
|
||||
this.config.store.profiles = [
|
||||
...this.config.store.profiles,
|
||||
profile,
|
||||
]
|
||||
this.config.save()
|
||||
this.notifications.info(this.translate.instant('Saved'))
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
18
yarn.lock
18
yarn.lock
@@ -829,10 +829,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe"
|
||||
integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==
|
||||
|
||||
"@types/node@^16.11.26":
|
||||
version "16.11.26"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47"
|
||||
integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==
|
||||
"@types/node@^18.11.18":
|
||||
version "18.16.19"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.19.tgz#cb03fca8910fdeb7595b755126a8a78144714eea"
|
||||
integrity sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==
|
||||
|
||||
"@types/parse5@^5":
|
||||
version "5.0.3"
|
||||
@@ -3066,13 +3066,13 @@ electron-to-chromium@^1.4.284:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.286.tgz#0e039de59135f44ab9a8ec9025e53a9135eba11f"
|
||||
integrity sha512-Vp3CVhmYpgf4iXNKAucoQUDcCrBQX3XLBtwgFqP9BUXuucgvAV9zWp1kYU7LL9j4++s9O+12cb3wMtN4SJy6UQ==
|
||||
|
||||
electron@22.3.1:
|
||||
version "22.3.1"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-22.3.1.tgz#a09769e6592cadbf45d7629c9143ffa2ef8a3842"
|
||||
integrity sha512-iDltL9j12bINK3aOp8ZoGq4NFBFjJhw1AYHelbWj93XUCAIT4fdA+PRsq0aaTHg3bthLLlLRvIZVgNsZPqWcqg==
|
||||
electron@^25.3.0:
|
||||
version "25.3.0"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-25.3.0.tgz#e818ab3ebd3e7a45f8fca0f47e607c9af2dc92c7"
|
||||
integrity sha512-cyqotxN+AroP5h2IxUsJsmehYwP5LrFAOO7O7k9tILME3Sa1/POAg3shrhx4XEnaAMyMqMLxzGvkzCVxzEErnA==
|
||||
dependencies:
|
||||
"@electron/get" "^2.0.0"
|
||||
"@types/node" "^16.11.26"
|
||||
"@types/node" "^18.11.18"
|
||||
extract-zip "^2.0.1"
|
||||
|
||||
elliptic@^6.5.3:
|
||||
|
Reference in New Issue
Block a user