mirror of
https://github.com/Eugeny/tabby.git
synced 2025-09-21 07:36:05 +00:00
Compare commits
37 Commits
mica2
...
all-contri
Author | SHA1 | Date | |
---|---|---|---|
![]() |
eae3114fff | ||
![]() |
d7ce585ffe | ||
![]() |
dc418aee21 | ||
![]() |
4da0dd463a | ||
![]() |
e922ac4011 | ||
![]() |
af2f278b05 | ||
![]() |
af0e25ea09 | ||
![]() |
f0d228bb60 | ||
![]() |
0241623d27 | ||
![]() |
f4992c3f70 | ||
![]() |
5fca7ccf7b | ||
![]() |
3740166ace | ||
![]() |
82013e3139 | ||
![]() |
4d60ae2e90 | ||
![]() |
d6c2c5de31 | ||
![]() |
ccb59c3eae | ||
![]() |
2966c1fdad | ||
![]() |
42eefe8ef0 | ||
![]() |
1c62438f9d | ||
![]() |
e9f17ea597 | ||
![]() |
838d4afb94 | ||
![]() |
09194a964e | ||
![]() |
a5188f4cf5 | ||
![]() |
d7b7e6bcfd | ||
![]() |
37b1c1c750 | ||
![]() |
09b261e265 | ||
![]() |
df75f2bdb7 | ||
![]() |
ccee879b16 | ||
![]() |
5587e10dc8 | ||
![]() |
856a800cb2 | ||
![]() |
3c5f2ba28c | ||
![]() |
aa105bdf4d | ||
![]() |
b0dcc5f9df | ||
![]() |
fdda602a76 | ||
![]() |
f630b53e0a | ||
![]() |
89dd0773ee | ||
![]() |
deaa529c07 |
@@ -1310,6 +1310,15 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "fireblue",
|
||||||
|
"name": "fireblue",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1034929?v=4",
|
||||||
|
"profile": "https://github.com/fireblue",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
@@ -340,6 +340,8 @@ Dank geht an diese wunderbaren Menschen ([emoji key](https://allcontributors.org
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marko1616"><img src="https://avatars.githubusercontent.com/u/45327989?v=4?s=100" width="100px;" alt="marko1616"/><br /><sub><b>marko1616</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=marko1616" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -342,6 +342,7 @@ Gracias a estas maravillosas personas ([emoji key](https://allcontributors.org/d
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -339,6 +339,7 @@ Terima kasih kepada mereka yang telah membantu ([emoji key](https://allcontribut
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -335,6 +335,8 @@ Grazie a queste persone meravigliose ([emoji key](https://allcontributors.org/do
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marko1616"><img src="https://avatars.githubusercontent.com/u/45327989?v=4?s=100" width="100px;" alt="marko1616"/><br /><sub><b>marko1616</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=marko1616" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -350,6 +350,7 @@ Windows上では、`Tabby.exe`がある場所と同じ場所に`data`フォル
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -334,6 +334,8 @@ Pull requests and plugins are welcome!
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marko1616"><img src="https://avatars.githubusercontent.com/u/45327989?v=4?s=100" width="100px;" alt="marko1616"/><br /><sub><b>marko1616</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=marko1616" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -356,6 +356,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marko1616"><img src="https://avatars.githubusercontent.com/u/45327989?v=4?s=100" width="100px;" alt="marko1616"/><br /><sub><b>marko1616</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=marko1616" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -343,6 +343,7 @@ Obrigado vai para essas pessoas maravilhosas ([emoji key](https://allcontributor
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -335,6 +335,8 @@ Pull-запросы и плагины приветствуются!
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marko1616"><img src="https://avatars.githubusercontent.com/u/45327989?v=4?s=100" width="100px;" alt="marko1616"/><br /><sub><b>marko1616</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=marko1616" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -334,6 +334,8 @@
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://5k.work/"><img src="https://avatars.githubusercontent.com/u/82694310?v=4?s=100" width="100px;" alt="Mxmilu"/><br /><sub><b>Mxmilu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Mxmilu666" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://cbuff.dev"><img src="https://avatars.githubusercontent.com/u/29805363?v=4?s=100" width="100px;" alt="Charles Buffington"/><br /><sub><b>Charles Buffington</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=C41M50N" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GeminiLn"><img src="https://avatars.githubusercontent.com/u/12425057?v=4?s=100" width="100px;" alt="Yu Qin"/><br /><sub><b>Yu Qin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=GeminiLn" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fireblue"><img src="https://avatars.githubusercontent.com/u/1034929?v=4?s=100" width="100px;" alt="fireblue"/><br /><sub><b>fireblue</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=fireblue" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marko1616"><img src="https://avatars.githubusercontent.com/u/45327989?v=4?s=100" width="100px;" alt="marko1616"/><br /><sub><b>marko1616</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=marko1616" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
|
import * as glasstron from 'glasstron'
|
||||||
import { autoUpdater } from 'electron-updater'
|
import { autoUpdater } from 'electron-updater'
|
||||||
import { Subject, Observable, debounceTime } from 'rxjs'
|
import { Subject, Observable, debounceTime } from 'rxjs'
|
||||||
import { BrowserWindow, app, ipcMain, Rectangle, Menu, screen, BrowserWindowConstructorOptions, TouchBar, nativeImage, WebContents } from 'electron'
|
import { BrowserWindow, app, ipcMain, Rectangle, Menu, screen, BrowserWindowConstructorOptions, TouchBar, nativeImage, WebContents } from 'electron'
|
||||||
import ElectronConfig = require('electron-config')
|
import ElectronConfig = require('electron-config')
|
||||||
import { enable as enableRemote } from '@electron/remote/main'
|
import { enable as enableRemote } from '@electron/remote/main'
|
||||||
|
import * as os from 'os'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import macOSRelease from 'macos-release'
|
import macOSRelease from 'macos-release'
|
||||||
import { compare as compareVersions } from 'compare-versions'
|
import { compare as compareVersions } from 'compare-versions'
|
||||||
@@ -10,11 +12,21 @@ import { compare as compareVersions } from 'compare-versions'
|
|||||||
import type { Application } from './app'
|
import type { Application } from './app'
|
||||||
import { parseArgs } from './cli'
|
import { parseArgs } from './cli'
|
||||||
|
|
||||||
|
let DwmEnableBlurBehindWindow: any = null
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
DwmEnableBlurBehindWindow = require('@tabby-gang/windows-blurbehind').DwmEnableBlurBehindWindow
|
||||||
|
}
|
||||||
|
|
||||||
export interface WindowOptions {
|
export interface WindowOptions {
|
||||||
hidden?: boolean
|
hidden?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const macOSVibrancyType: any = process.platform === 'darwin' ? compareVersions(macOSRelease().version || '0.0', '10.14', '>=') ? 'under-window' : 'dark' : null
|
abstract class GlasstronWindow extends BrowserWindow {
|
||||||
|
blurType: string
|
||||||
|
abstract setBlur (_: boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
const macOSVibrancyType: any = process.platform === 'darwin' ? compareVersions(macOSRelease().version || '0.0', '10.14', '>=') ? 'fullscreen-ui' : 'dark' : null
|
||||||
|
|
||||||
const activityIcon = nativeImage.createFromPath(`${app.getAppPath()}/assets/activity.png`)
|
const activityIcon = nativeImage.createFromPath(`${app.getAppPath()}/assets/activity.png`)
|
||||||
|
|
||||||
@@ -24,11 +36,14 @@ export class Window {
|
|||||||
webContents: WebContents
|
webContents: WebContents
|
||||||
private visible = new Subject<boolean>()
|
private visible = new Subject<boolean>()
|
||||||
private closed = new Subject<void>()
|
private closed = new Subject<void>()
|
||||||
private window?: BrowserWindow
|
private window?: GlasstronWindow
|
||||||
private windowConfig: ElectronConfig
|
private windowConfig: ElectronConfig
|
||||||
private windowBounds?: Rectangle
|
private windowBounds?: Rectangle
|
||||||
private closing = false
|
private closing = false
|
||||||
|
private lastVibrancy: { enabled: boolean, type?: string } | null = null
|
||||||
|
private disableVibrancyWhileDragging = false
|
||||||
private touchBarControl: any
|
private touchBarControl: any
|
||||||
|
private isFluentVibrancy = false
|
||||||
private dockHidden = false
|
private dockHidden = false
|
||||||
|
|
||||||
get visible$ (): Observable<boolean> { return this.visible }
|
get visible$ (): Observable<boolean> { return this.visible }
|
||||||
@@ -56,7 +71,6 @@ export class Window {
|
|||||||
},
|
},
|
||||||
maximizable: true,
|
maximizable: true,
|
||||||
frame: false,
|
frame: false,
|
||||||
transparent: true,
|
|
||||||
show: false,
|
show: false,
|
||||||
backgroundColor: '#00000000',
|
backgroundColor: '#00000000',
|
||||||
acceptFirstMouse: true,
|
acceptFirstMouse: true,
|
||||||
@@ -86,15 +100,11 @@ export class Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.window = new BrowserWindow(bwOptions)
|
if (process.platform === 'darwin') {
|
||||||
|
this.window = new BrowserWindow(bwOptions) as GlasstronWindow
|
||||||
// https://github.com/electron/electron/issues/39959#issuecomment-1758736966
|
} else {
|
||||||
this.window.on('blur', () => {
|
this.window = new glasstron.BrowserWindow(bwOptions)
|
||||||
this.window.setBackgroundColor('#00000000')
|
}
|
||||||
})
|
|
||||||
this.window.on('focus', () => {
|
|
||||||
this.window.setBackgroundColor('#00000000')
|
|
||||||
})
|
|
||||||
|
|
||||||
this.webContents = this.window.webContents
|
this.webContents = this.window.webContents
|
||||||
|
|
||||||
@@ -167,12 +177,26 @@ export class Window {
|
|||||||
this.window.webContents.send('host:became-main-window')
|
this.window.webContents.send('host:became-main-window')
|
||||||
}
|
}
|
||||||
|
|
||||||
setMaterial (material: 'mica'|'acrylic'|'auto'): void {
|
setVibrancy (enabled: boolean, type?: string, userRequested?: boolean): void {
|
||||||
this.window.setBackgroundMaterial(material)
|
if (userRequested ?? true) {
|
||||||
|
this.lastVibrancy = { enabled, type }
|
||||||
}
|
}
|
||||||
|
if (process.platform === 'win32') {
|
||||||
setVibrancy (enabled: boolean): void {
|
if (parseFloat(os.release()) >= 10) {
|
||||||
if (process.platform === 'darwin') {
|
this.window.blurType = enabled ? type === 'fluent' ? 'acrylic' : 'blurbehind' : null
|
||||||
|
try {
|
||||||
|
this.window.setBlur(enabled)
|
||||||
|
this.isFluentVibrancy = enabled && type === 'fluent'
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to set window blur', error)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DwmEnableBlurBehindWindow(this.window.getNativeWindowHandle(), enabled)
|
||||||
|
}
|
||||||
|
} else if (process.platform === 'linux') {
|
||||||
|
this.window.setBackgroundColor(enabled ? '#00000000' : '#131d27')
|
||||||
|
this.window.setBlur(enabled)
|
||||||
|
} else {
|
||||||
this.window.setVibrancy(enabled ? macOSVibrancyType : null)
|
this.window.setVibrancy(enabled ? macOSVibrancyType : null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,12 +369,8 @@ export class Window {
|
|||||||
this.window?.setAlwaysOnTop(flag)
|
this.window?.setAlwaysOnTop(flag)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.on('window-set-vibrancy', (_, enabled) => {
|
this.on('window-set-vibrancy', (_, enabled, type) => {
|
||||||
this.setVibrancy(enabled)
|
this.setVibrancy(enabled, type)
|
||||||
})
|
|
||||||
|
|
||||||
this.on('window-set-material', (_, material) => {
|
|
||||||
this.setMaterial(material)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.on('window-set-window-controls-color', (_, theme) => {
|
this.on('window-set-window-controls-color', (_, theme) => {
|
||||||
@@ -393,6 +413,26 @@ export class Window {
|
|||||||
return { action: 'deny' }
|
return { action: 'deny' }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.on('window-set-disable-vibrancy-while-dragging', (_event, value) => {
|
||||||
|
this.disableVibrancyWhileDragging = value && this.configStore.hacks?.disableVibrancyWhileDragging
|
||||||
|
})
|
||||||
|
|
||||||
|
let moveEndedTimeout: any = null
|
||||||
|
const onBoundsChange = () => {
|
||||||
|
if (!this.lastVibrancy?.enabled || !this.disableVibrancyWhileDragging || !this.isFluentVibrancy) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.setVibrancy(false, undefined, false)
|
||||||
|
if (moveEndedTimeout) {
|
||||||
|
clearTimeout(moveEndedTimeout)
|
||||||
|
}
|
||||||
|
moveEndedTimeout = setTimeout(() => {
|
||||||
|
this.setVibrancy(this.lastVibrancy.enabled, this.lastVibrancy.type)
|
||||||
|
}, 50)
|
||||||
|
}
|
||||||
|
this.window.on('move', onBoundsChange)
|
||||||
|
this.window.on('resize', onBoundsChange)
|
||||||
|
|
||||||
ipcMain.on('window-set-traffic-light-position', (_event, x, y) => {
|
ipcMain.on('window-set-traffic-light-position', (_event, x, y) => {
|
||||||
this.window.setWindowButtonPosition({ x, y })
|
this.window.setWindowButtonPosition({ x, y })
|
||||||
})
|
})
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
"electron-promise-ipc": "^2.2.4",
|
"electron-promise-ipc": "^2.2.4",
|
||||||
"electron-updater": "^5.2.1",
|
"electron-updater": "^5.2.1",
|
||||||
"fontmanager-redux": "1.1.0",
|
"fontmanager-redux": "1.1.0",
|
||||||
|
"glasstron": "0.1.1",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"keytar": "^7.9.0",
|
"keytar": "^7.9.0",
|
||||||
"mz": "^2.7.0",
|
"mz": "^2.7.0",
|
||||||
@@ -34,6 +35,7 @@
|
|||||||
"yargs": "^17.7.2"
|
"yargs": "^17.7.2"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
"@tabby-gang/windows-blurbehind": "^3.0.0",
|
||||||
"macos-native-processlist": "^2.1.0",
|
"macos-native-processlist": "^2.1.0",
|
||||||
"patch-package": "^6.5.0",
|
"patch-package": "^6.5.0",
|
||||||
"serialport": "11.0.1",
|
"serialport": "11.0.1",
|
||||||
|
@@ -44,6 +44,7 @@ const config = {
|
|||||||
'electron-promise-ipc': 'commonjs electron-promise-ipc',
|
'electron-promise-ipc': 'commonjs electron-promise-ipc',
|
||||||
'electron-updater': 'commonjs electron-updater',
|
'electron-updater': 'commonjs electron-updater',
|
||||||
fs: 'commonjs fs',
|
fs: 'commonjs fs',
|
||||||
|
glasstron: 'commonjs glasstron',
|
||||||
mz: 'commonjs mz',
|
mz: 'commonjs mz',
|
||||||
npm: 'commonjs npm',
|
npm: 'commonjs npm',
|
||||||
'node:os': 'commonjs os',
|
'node:os': 'commonjs os',
|
||||||
@@ -53,6 +54,7 @@ const config = {
|
|||||||
'source-map-support': 'commonjs source-map-support',
|
'source-map-support': 'commonjs source-map-support',
|
||||||
'windows-swca': 'commonjs windows-swca',
|
'windows-swca': 'commonjs windows-swca',
|
||||||
'windows-native-registry': 'commonjs windows-native-registry',
|
'windows-native-registry': 'commonjs windows-native-registry',
|
||||||
|
'@tabby-gang/windows-blurbehind': 'commonjs @tabby-gang/windows-blurbehind',
|
||||||
'yargs/yargs': 'commonjs yargs/yargs',
|
'yargs/yargs': 'commonjs yargs/yargs',
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@@ -173,6 +173,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
|
"@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"
|
||||||
|
integrity sha512-ah6eJcoQZWOZfu9sd2pWlOJmfl1v+2EZQMeIp7MWvg+/16WS16UFNdnOtlV6AUiABHfZo2QKfCNUEuorCM+Q2A==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "^10.12.18"
|
||||||
|
|
||||||
"@types/mz@2.7.4":
|
"@types/mz@2.7.4":
|
||||||
version "2.7.4"
|
version "2.7.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-2.7.4.tgz#f9d1535cb5171199b28ae6abd6ec29e856551401"
|
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-2.7.4.tgz#f9d1535cb5171199b28ae6abd6ec29e856551401"
|
||||||
@@ -185,6 +192,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe"
|
||||||
integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==
|
integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==
|
||||||
|
|
||||||
|
"@types/node@^10.12.18":
|
||||||
|
version "10.17.60"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
|
||||||
|
integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==
|
||||||
|
|
||||||
"@types/semver@^7.3.6":
|
"@types/semver@^7.3.6":
|
||||||
version "7.3.9"
|
version "7.3.9"
|
||||||
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
|
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
|
||||||
@@ -1469,6 +1481,14 @@ github-from-package@0.0.0:
|
|||||||
resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz"
|
resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz"
|
||||||
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
|
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
|
||||||
|
|
||||||
|
glasstron@0.1.1:
|
||||||
|
version "0.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/glasstron/-/glasstron-0.1.1.tgz#491a2e6f7e7b285c3776c5f7af7aaba2269833b2"
|
||||||
|
integrity sha512-oLEMQM5wwdAQ44NrXD3wjk+b3dsfQG1XtkLn5pCxQNa3ri1AtWvvzpnhFUd88ZTmguHvkY4c3JKzcPSYaJAKKA==
|
||||||
|
dependencies:
|
||||||
|
node-addon-api "^4.0.0"
|
||||||
|
x11 "^2.3.0"
|
||||||
|
|
||||||
glob@^10.2.2, glob@^10.3.10:
|
glob@^10.2.2, glob@^10.3.10:
|
||||||
version "10.3.10"
|
version "10.3.10"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b"
|
||||||
|
@@ -53,7 +53,7 @@
|
|||||||
"html-loader": "4.2.0",
|
"html-loader": "4.2.0",
|
||||||
"json-loader": "^0.5.7",
|
"json-loader": "^0.5.7",
|
||||||
"lru-cache": "^6.0.0",
|
"lru-cache": "^6.0.0",
|
||||||
"macos-release": "^3.1.0",
|
"macos-release": "^3.3.0",
|
||||||
"ngx-toastr": "^16.0.2",
|
"ngx-toastr": "^16.0.2",
|
||||||
"node-abi": "^3.65.0",
|
"node-abi": "^3.65.0",
|
||||||
"npmlog": "6.0.2",
|
"npmlog": "6.0.2",
|
||||||
|
@@ -10,7 +10,7 @@ export { Theme } from './theme'
|
|||||||
export { TabContextMenuItemProvider } from './tabContextMenuProvider'
|
export { TabContextMenuItemProvider } from './tabContextMenuProvider'
|
||||||
export { SelectorOption } from './selector'
|
export { SelectorOption } from './selector'
|
||||||
export { CLIHandler, CLIEvent } from './cli'
|
export { CLIHandler, CLIEvent } from './cli'
|
||||||
export { PlatformService, ClipboardContent, MessageBoxResult, MessageBoxOptions, FileDownload, FileUpload, FileTransfer, HTMLFileUpload, FileUploadOptions } from './platform'
|
export { PlatformService, ClipboardContent, MessageBoxResult, MessageBoxOptions, FileDownload, FileUpload, FileTransfer, HTMLFileUpload, FileUploadOptions, DirectoryUpload } from './platform'
|
||||||
export { MenuItemOptions } from './menu'
|
export { MenuItemOptions } from './menu'
|
||||||
export { BootstrapData, PluginInfo, BOOTSTRAP_DATA } from './mainProcess'
|
export { BootstrapData, PluginInfo, BOOTSTRAP_DATA } from './mainProcess'
|
||||||
export { HostWindowService } from './hostWindow'
|
export { HostWindowService } from './hostWindow'
|
||||||
|
@@ -86,6 +86,26 @@ export interface FileUploadOptions {
|
|||||||
multiple: boolean
|
multiple: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DirectoryUpload {
|
||||||
|
private childrens: (FileUpload|DirectoryUpload)[] = []
|
||||||
|
|
||||||
|
constructor (private name = '') {
|
||||||
|
// Just set name for now.
|
||||||
|
}
|
||||||
|
|
||||||
|
getName (): string {
|
||||||
|
return this.name
|
||||||
|
}
|
||||||
|
|
||||||
|
getChildrens (): (FileUpload|DirectoryUpload)[] {
|
||||||
|
return this.childrens
|
||||||
|
}
|
||||||
|
|
||||||
|
pushChildren (item: FileUpload|DirectoryUpload): void {
|
||||||
|
this.childrens.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type PlatformTheme = 'light'|'dark'
|
export type PlatformTheme = 'light'|'dark'
|
||||||
|
|
||||||
export abstract class PlatformService {
|
export abstract class PlatformService {
|
||||||
@@ -106,23 +126,54 @@ export abstract class PlatformService {
|
|||||||
|
|
||||||
abstract startDownload (name: string, mode: number, size: number): Promise<FileDownload|null>
|
abstract startDownload (name: string, mode: number, size: number): Promise<FileDownload|null>
|
||||||
abstract startUpload (options?: FileUploadOptions): Promise<FileUpload[]>
|
abstract startUpload (options?: FileUploadOptions): Promise<FileUpload[]>
|
||||||
|
abstract startUploadDirectory (paths?: string[]): Promise<DirectoryUpload>
|
||||||
|
|
||||||
|
async startUploadFromDragEvent (event: DragEvent, multiple = false): Promise<DirectoryUpload> {
|
||||||
|
const result = new DirectoryUpload()
|
||||||
|
|
||||||
startUploadFromDragEvent (event: DragEvent, multiple = false): FileUpload[] {
|
|
||||||
const result: FileUpload[] = []
|
|
||||||
if (!event.dataTransfer) {
|
if (!event.dataTransfer) {
|
||||||
return []
|
return Promise.resolve(result)
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
||||||
for (let i = 0; i < event.dataTransfer.files.length; i++) {
|
const traverseFileTree = (item: any, root: DirectoryUpload = result): Promise<void> => {
|
||||||
const file = event.dataTransfer.files[i]
|
return new Promise((resolve) => {
|
||||||
|
if (item.isFile) {
|
||||||
|
item.file((file: File) => {
|
||||||
const transfer = new HTMLFileUpload(file)
|
const transfer = new HTMLFileUpload(file)
|
||||||
this.fileTransferStarted.next(transfer)
|
this.fileTransferStarted.next(transfer)
|
||||||
result.push(transfer)
|
root.pushChildren(transfer)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
} else if (item.isDirectory) {
|
||||||
|
const dirReader = item.createReader()
|
||||||
|
const childrenFolder = new DirectoryUpload(item.name)
|
||||||
|
dirReader.readEntries(async (entries: any[]) => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
await traverseFileTree(entry, childrenFolder)
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
root.pushChildren(childrenFolder)
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises: Promise<void>[] = []
|
||||||
|
|
||||||
|
const items = event.dataTransfer.items
|
||||||
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const item = items[i].webkitGetAsEntry()
|
||||||
|
if (item) {
|
||||||
|
promises.push(traverseFileTree(item))
|
||||||
if (!multiple) {
|
if (!multiple) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
}
|
||||||
|
return Promise.all(promises).then(() => result)
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfigPath (): string|null {
|
getConfigPath (): string|null {
|
||||||
|
@@ -821,7 +821,13 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
if (this.disableDynamicTitle) {
|
if (this.disableDynamicTitle) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.setTitle([...new Set(this.getAllTabs().map(x => x.title))].join(' | '))
|
const titles = [
|
||||||
|
this.getFocusedTab()?.title,
|
||||||
|
...this.getAllTabs()
|
||||||
|
.filter(x => x !== this.getFocusedTab())
|
||||||
|
.map(x => x.title),
|
||||||
|
]
|
||||||
|
this.setTitle([...new Set(titles)].join(' | '))
|
||||||
}
|
}
|
||||||
|
|
||||||
private attachTabView (tab: BaseTabComponent) {
|
private attachTabView (tab: BaseTabComponent) {
|
||||||
@@ -837,6 +843,10 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tab.subscribeUntilDestroyed(
|
||||||
|
this.observeUntilChildDetached(tab, tab.focused$),
|
||||||
|
() => this.updateTitle(),
|
||||||
|
)
|
||||||
tab.subscribeUntilDestroyed(
|
tab.subscribeUntilDestroyed(
|
||||||
this.observeUntilChildDetached(tab, tab.titleChange$),
|
this.observeUntilChildDetached(tab, tab.titleChange$),
|
||||||
() => this.updateTitle(),
|
() => this.updateTitle(),
|
||||||
|
@@ -54,5 +54,7 @@ providerBlacklist: []
|
|||||||
profileBlacklist: []
|
profileBlacklist: []
|
||||||
hacks:
|
hacks:
|
||||||
disableGPU: false
|
disableGPU: false
|
||||||
|
disableVibrancyWhileDragging: false
|
||||||
|
enableFluentBackground: false
|
||||||
language: null
|
language: null
|
||||||
defaultQuickConnectProvider: "ssh"
|
defaultQuickConnectProvider: "ssh"
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Directive, Output, ElementRef, EventEmitter, AfterViewInit } from '@angular/core'
|
import { Directive, Output, ElementRef, EventEmitter, AfterViewInit } from '@angular/core'
|
||||||
import { FileUpload, PlatformService } from '../api/platform'
|
import { DirectoryUpload, PlatformService } from '../api/platform'
|
||||||
import './dropZone.directive.scss'
|
import './dropZone.directive.scss'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -7,7 +7,7 @@ import './dropZone.directive.scss'
|
|||||||
selector: '[dropZone]',
|
selector: '[dropZone]',
|
||||||
})
|
})
|
||||||
export class DropZoneDirective implements AfterViewInit {
|
export class DropZoneDirective implements AfterViewInit {
|
||||||
@Output() transfer = new EventEmitter<FileUpload>()
|
@Output() transfer = new EventEmitter<DirectoryUpload>()
|
||||||
private dropHint?: HTMLElement
|
private dropHint?: HTMLElement
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
@@ -27,11 +27,9 @@ export class DropZoneDirective implements AfterViewInit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.el.nativeElement.addEventListener('drop', (event: DragEvent) => {
|
this.el.nativeElement.addEventListener('drop', async (event: DragEvent) => {
|
||||||
this.removeHint()
|
this.removeHint()
|
||||||
for (const transfer of this.platform.startUploadFromDragEvent(event, true)) {
|
this.transfer.emit(await this.platform.startUploadFromDragEvent(event, true))
|
||||||
this.transfer.emit(transfer)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
this.el.nativeElement.addEventListener('dragleave', () => {
|
this.el.nativeElement.addEventListener('dragleave', () => {
|
||||||
this.removeHint()
|
this.removeHint()
|
||||||
|
@@ -5,7 +5,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
|
|||||||
export const WIN_BUILD_CONPTY_SUPPORTED = 17692
|
export const WIN_BUILD_CONPTY_SUPPORTED = 17692
|
||||||
export const WIN_BUILD_CONPTY_STABLE = 18309
|
export const WIN_BUILD_CONPTY_STABLE = 18309
|
||||||
export const WIN_BUILD_WSL_EXE_DISTRO_FLAG = 17763
|
export const WIN_BUILD_WSL_EXE_DISTRO_FLAG = 17763
|
||||||
export const WIN_BUILD_WINDOW_MATERIAL_SUPPORTED = 22621
|
export const WIN_BUILD_FLUENT_BG_SUPPORTED = 17063
|
||||||
|
|
||||||
export function getWindows10Build (): number|undefined {
|
export function getWindows10Build (): number|undefined {
|
||||||
return process.platform === 'win32' && parseFloat(os.release()) >= 10 ? parseInt(os.release().split('.')[2]) : undefined
|
return process.platform === 'win32' && parseFloat(os.release()) >= 10 ? parseInt(os.release().split('.')[2]) : undefined
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, isWindowsBuild, HostWindowService, HotkeyProvider, ConfigProvider, FileProvider, WIN_BUILD_WINDOW_MATERIAL_SUPPORTED } from 'tabby-core'
|
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild, HostWindowService, HotkeyProvider, ConfigProvider, FileProvider } from 'tabby-core'
|
||||||
import { TerminalColorSchemeProvider } from 'tabby-terminal'
|
import { TerminalColorSchemeProvider } from 'tabby-terminal'
|
||||||
import { SFTPContextMenuItemProvider, SSHProfileImporter, AutoPrivateKeyLocator } from 'tabby-ssh'
|
import { SFTPContextMenuItemProvider, SSHProfileImporter, AutoPrivateKeyLocator } from 'tabby-ssh'
|
||||||
import { PTYInterface, ShellProvider, UACService } from 'tabby-local'
|
import { PTYInterface, ShellProvider, UACService } from 'tabby-local'
|
||||||
@@ -164,23 +164,13 @@ export default class ElectronModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateVibrancy () {
|
private updateVibrancy () {
|
||||||
|
let vibrancyType = this.config.store.appearance.vibrancyType
|
||||||
|
if (this.hostApp.platform === Platform.Windows && !isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
|
||||||
|
vibrancyType = null
|
||||||
|
}
|
||||||
|
this.electron.ipcRenderer.send('window-set-vibrancy', this.config.store.appearance.vibrancy, vibrancyType)
|
||||||
|
|
||||||
this.hostWindow.setOpacity(this.config.store.appearance.opacity)
|
this.hostWindow.setOpacity(this.config.store.appearance.opacity)
|
||||||
|
|
||||||
if (isWindowsBuild(WIN_BUILD_WINDOW_MATERIAL_SUPPORTED)) {
|
|
||||||
this.electron.ipcRenderer.send(
|
|
||||||
'window-set-material',
|
|
||||||
this.config.store.appearance.vibrancy
|
|
||||||
? this.config.store.appearance.vibrancyType === 'fluent'
|
|
||||||
? 'mica'
|
|
||||||
: 'acrylic'
|
|
||||||
: 'none',
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.hostApp.platform === Platform.macOS) {
|
|
||||||
this.electron.ipcRenderer.send('window-set-vibrancy', this.config.store.appearance.vibrancy)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateWindowControlsColor () {
|
private updateWindowControlsColor () {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable, NgZone, Injector } from '@angular/core'
|
import { Injectable, NgZone, Injector } from '@angular/core'
|
||||||
import { HostAppService, Platform, CLIHandler } from 'tabby-core'
|
import { isWindowsBuild, WIN_BUILD_FLUENT_BG_SUPPORTED, HostAppService, Platform, CLIHandler } from 'tabby-core'
|
||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
|
|
||||||
|
|
||||||
@@ -48,6 +48,10 @@ export class ElectronHostAppService extends HostAppService {
|
|||||||
electron.ipcRenderer.on('host:config-change', () => this.zone.run(() => {
|
electron.ipcRenderer.on('host:config-change', () => this.zone.run(() => {
|
||||||
this.configChangeBroadcast.next()
|
this.configChangeBroadcast.next()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
if (isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
|
||||||
|
electron.ipcRenderer.send('window-set-disable-vibrancy-while-dragging', true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newWindow (): void {
|
newWindow (): void {
|
||||||
|
@@ -5,7 +5,7 @@ import * as os from 'os'
|
|||||||
import promiseIpc, { RendererProcessType } from 'electron-promise-ipc'
|
import promiseIpc, { RendererProcessType } from 'electron-promise-ipc'
|
||||||
import { execFile } from 'mz/child_process'
|
import { execFile } from 'mz/child_process'
|
||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
import { PlatformService, ClipboardContent, Platform, MenuItemOptions, MessageBoxOptions, MessageBoxResult, FileUpload, FileDownload, FileUploadOptions, wrapPromise, TranslateService } from 'tabby-core'
|
import { PlatformService, ClipboardContent, Platform, MenuItemOptions, MessageBoxOptions, MessageBoxResult, DirectoryUpload, FileUpload, FileDownload, FileUploadOptions, wrapPromise, TranslateService } from 'tabby-core'
|
||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
import { ElectronHostWindow } from './hostWindow.service'
|
import { ElectronHostWindow } from './hostWindow.service'
|
||||||
import { ShellIntegrationService } from './shellIntegration.service'
|
import { ShellIntegrationService } from './shellIntegration.service'
|
||||||
@@ -48,6 +48,21 @@ export class ElectronPlatformService extends PlatformService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAllFiles (dir: string, root: DirectoryUpload): Promise<DirectoryUpload> {
|
||||||
|
const items = await fs.readdir(dir, { withFileTypes: true })
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.isDirectory()) {
|
||||||
|
root.pushChildren(await this.getAllFiles(path.join(dir, item.name), new DirectoryUpload(item.name)))
|
||||||
|
} else {
|
||||||
|
const file = new ElectronFileUpload(path.join(dir, item.name), this.electron)
|
||||||
|
root.pushChildren(file)
|
||||||
|
await wrapPromise(this.zone, file.open())
|
||||||
|
this.fileTransferStarted.next(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
readClipboard (): string {
|
readClipboard (): string {
|
||||||
return this.electron.clipboard.readText()
|
return this.electron.clipboard.readText()
|
||||||
}
|
}
|
||||||
@@ -216,6 +231,28 @@ export class ElectronPlatformService extends PlatformService {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async startUploadDirectory (paths?: string[]): Promise<DirectoryUpload> {
|
||||||
|
const properties: any[] = ['openFile', 'treatPackageAsDirectory', 'openDirectory']
|
||||||
|
|
||||||
|
if (!paths) {
|
||||||
|
const result = await this.electron.dialog.showOpenDialog(
|
||||||
|
this.hostWindow.getWindow(),
|
||||||
|
{
|
||||||
|
buttonLabel: this.translate.instant('Select'),
|
||||||
|
properties,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (result.canceled) {
|
||||||
|
return new DirectoryUpload()
|
||||||
|
}
|
||||||
|
paths = result.filePaths
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = new DirectoryUpload()
|
||||||
|
root.pushChildren(await this.getAllFiles(paths[0].split(path.sep).join(path.posix.sep), new DirectoryUpload(path.basename(paths[0]))))
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
async startDownload (name: string, mode: number, size: number, filePath?: string): Promise<FileDownload|null> {
|
async startDownload (name: string, mode: number, size: number, filePath?: string): Promise<FileDownload|null> {
|
||||||
if (!filePath) {
|
if (!filePath) {
|
||||||
const result = await this.electron.dialog.showSaveDialog(
|
const result = await this.electron.dialog.showSaveDialog(
|
||||||
|
@@ -32,18 +32,18 @@ h3.mb-3(translate) Window
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
.form-line(*ngIf='platform.supportsWindowControls && (hostApp.platform !== Platform.Windows || isWindowMaterialSupported)')
|
.form-line(*ngIf='platform.supportsWindowControls')
|
||||||
.header
|
.header
|
||||||
.title(*ngIf='hostApp.platform !== Platform.macOS', translate) Blurred background
|
.title(*ngIf='hostApp.platform !== Platform.macOS', translate) Acrylic background
|
||||||
.title(*ngIf='hostApp.platform === Platform.macOS', translate) Vibrancy
|
.title(*ngIf='hostApp.platform === Platform.macOS', translate) Vibrancy
|
||||||
.description(*ngIf='hostApp.platform === Platform.Linux', translate) Gives the window a blurred transparent background
|
.description(translate) Gives the window a blurred transparent background
|
||||||
|
|
||||||
toggle(
|
toggle(
|
||||||
[(ngModel)]='config.store.appearance.vibrancy',
|
[(ngModel)]='config.store.appearance.vibrancy',
|
||||||
(ngModelChange)='saveConfiguration()'
|
(ngModelChange)='saveConfiguration()'
|
||||||
)
|
)
|
||||||
|
|
||||||
.form-line(*ngIf='config.store.appearance.vibrancy && isWindowMaterialSupported')
|
.form-line(*ngIf='config.store.appearance.vibrancy && isFluentVibrancySupported && config.store.hacks.enableFluentBackground')
|
||||||
.header
|
.header
|
||||||
.title(translate) Background type
|
.title(translate) Background type
|
||||||
.btn-group
|
.btn-group
|
||||||
@@ -58,7 +58,7 @@ h3.mb-3(translate) Window
|
|||||||
label.btn.btn-secondary(
|
label.btn.btn-secondary(
|
||||||
for='vibrancyTypeBlur'
|
for='vibrancyTypeBlur'
|
||||||
)
|
)
|
||||||
span(translate) Acrylic
|
span(translate) Blur
|
||||||
input.btn-check(
|
input.btn-check(
|
||||||
type='radio',
|
type='radio',
|
||||||
name='vibracy',
|
name='vibracy',
|
||||||
@@ -70,7 +70,7 @@ h3.mb-3(translate) Window
|
|||||||
label.btn.btn-secondary(
|
label.btn.btn-secondary(
|
||||||
for='vibrancyTypeFluent'
|
for='vibrancyTypeFluent'
|
||||||
)
|
)
|
||||||
span Mica
|
span Fluent
|
||||||
|
|
||||||
.form-line(*ngIf='platform.supportsWindowControls')
|
.form-line(*ngIf='platform.supportsWindowControls')
|
||||||
.header
|
.header
|
||||||
@@ -422,3 +422,23 @@ h3.mt-4(translate) Hacks
|
|||||||
[(ngModel)]='config.store.hacks.disableGPU',
|
[(ngModel)]='config.store.hacks.disableGPU',
|
||||||
(ngModelChange)='config.save(); config.requestRestart()'
|
(ngModelChange)='config.save(); config.requestRestart()'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
.form-line(*ngIf='hostApp.platform === Platform.Windows && isFluentVibrancySupported')
|
||||||
|
.header
|
||||||
|
.title(translate) Enable fluent background option
|
||||||
|
.description(translate) Experimental Windows 10 background style known to cause issues
|
||||||
|
|
||||||
|
toggle(
|
||||||
|
[(ngModel)]='config.store.hacks.enableFluentBackground',
|
||||||
|
(ngModelChange)='config.save()'
|
||||||
|
)
|
||||||
|
|
||||||
|
.form-line(*ngIf='hostApp.platform === Platform.Windows && isFluentVibrancySupported')
|
||||||
|
.header
|
||||||
|
.title(translate) Disable fluent background while dragging
|
||||||
|
.description(translate) Fluent background sometimes causes drag lag
|
||||||
|
|
||||||
|
toggle(
|
||||||
|
[(ngModel)]='config.store.hacks.disableVibrancyWhileDragging',
|
||||||
|
(ngModelChange)='config.save(); config.requestRestart()'
|
||||||
|
)
|
||||||
|
@@ -8,10 +8,10 @@ import {
|
|||||||
HostAppService,
|
HostAppService,
|
||||||
Platform,
|
Platform,
|
||||||
isWindowsBuild,
|
isWindowsBuild,
|
||||||
|
WIN_BUILD_FLUENT_BG_SUPPORTED,
|
||||||
BaseComponent,
|
BaseComponent,
|
||||||
Screen,
|
Screen,
|
||||||
PlatformService,
|
PlatformService,
|
||||||
WIN_BUILD_WINDOW_MATERIAL_SUPPORTED,
|
|
||||||
} from 'tabby-core'
|
} from 'tabby-core'
|
||||||
|
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
export class WindowSettingsTabComponent extends BaseComponent {
|
export class WindowSettingsTabComponent extends BaseComponent {
|
||||||
screens: Screen[]
|
screens: Screen[]
|
||||||
Platform = Platform
|
Platform = Platform
|
||||||
isWindowMaterialSupported = false
|
isFluentVibrancySupported = false
|
||||||
|
|
||||||
@HostBinding('class.content-box') true
|
@HostBinding('class.content-box') true
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ export class WindowSettingsTabComponent extends BaseComponent {
|
|||||||
this.screens = dockingService.getScreens()
|
this.screens = dockingService.getScreens()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isWindowMaterialSupported = isWindowsBuild(WIN_BUILD_WINDOW_MATERIAL_SUPPORTED)
|
this.isFluentVibrancySupported = isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)
|
||||||
}
|
}
|
||||||
|
|
||||||
@debounce(500)
|
@debounce(500)
|
||||||
|
@@ -23,11 +23,15 @@
|
|||||||
|
|
||||||
button.btn.btn-link.btn-sm.flex-shrink-0.d-flex((click)='upload()')
|
button.btn.btn-link.btn-sm.flex-shrink-0.d-flex((click)='upload()')
|
||||||
i.fas.fa-upload.me-1
|
i.fas.fa-upload.me-1
|
||||||
div(translate) Upload
|
div(translate) Upload files
|
||||||
|
|
||||||
|
button.btn.btn-link.btn-sm.flex-shrink-0.d-flex((click)='uploadFolder()')
|
||||||
|
i.fas.fa-upload.me-1
|
||||||
|
div(translate) Upload folder
|
||||||
|
|
||||||
button.btn.btn-link.text-decoration-none((click)='close()') !{require('../../../tabby-core/src/icons/times.svg')}
|
button.btn.btn-link.text-decoration-none((click)='close()') !{require('../../../tabby-core/src/icons/times.svg')}
|
||||||
|
|
||||||
.body(dropZone, (transfer)='uploadOne($event)')
|
.body(dropZone, (transfer)='uploadOneFolder($event)')
|
||||||
a.alert.alert-info.d-flex.align-items-center(
|
a.alert.alert-info.d-flex.align-items-center(
|
||||||
*ngIf='shouldShowCWDTip && !cwdDetectionAvailable',
|
*ngIf='shouldShowCWDTip && !cwdDetectionAvailable',
|
||||||
(click)='platform.openExternal("https://tabby.sh/go/cwd-detection")'
|
(click)='platform.openExternal("https://tabby.sh/go/cwd-detection")'
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import * as C from 'constants'
|
import * as C from 'constants'
|
||||||
import { posix as path } from 'path'
|
import { posix as path } from 'path'
|
||||||
import { Component, Input, Output, EventEmitter, Inject, Optional } from '@angular/core'
|
import { Component, Input, Output, EventEmitter, Inject, Optional } from '@angular/core'
|
||||||
import { FileUpload, MenuItemOptions, NotificationsService, PlatformService } from 'tabby-core'
|
import { FileUpload, DirectoryUpload, MenuItemOptions, NotificationsService, PlatformService } from 'tabby-core'
|
||||||
import { SFTPSession, SFTPFile } from '../session/sftp'
|
import { SFTPSession, SFTPFile } from '../session/sftp'
|
||||||
import { SSHSession } from '../session/ssh'
|
import { SSHSession } from '../session/ssh'
|
||||||
import { SFTPContextMenuItemProvider } from '../api'
|
import { SFTPContextMenuItemProvider } from '../api'
|
||||||
@@ -180,6 +180,30 @@ export class SFTPPanelComponent {
|
|||||||
await Promise.all(transfers.map(t => this.uploadOne(t)))
|
await Promise.all(transfers.map(t => this.uploadOne(t)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async uploadFolder (): Promise<void> {
|
||||||
|
const transfer = await this.platform.startUploadDirectory()
|
||||||
|
await this.uploadOneFolder(transfer)
|
||||||
|
}
|
||||||
|
|
||||||
|
async uploadOneFolder (transfer: DirectoryUpload, accumPath = ''): Promise<void> {
|
||||||
|
const savedPath = this.path
|
||||||
|
for(const t of transfer.getChildrens()) {
|
||||||
|
if (t instanceof DirectoryUpload) {
|
||||||
|
try {
|
||||||
|
await this.sftp.mkdir(path.posix.join(this.path, accumPath, t.getName()))
|
||||||
|
} catch {
|
||||||
|
// Intentionally ignoring errors from making duplicate dirs.
|
||||||
|
}
|
||||||
|
await this.uploadOneFolder(t, path.posix.join(accumPath, t.getName()))
|
||||||
|
} else {
|
||||||
|
await this.sftp.upload(path.posix.join(this.path, accumPath, t.getName()), t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.path === savedPath) {
|
||||||
|
await this.navigate(this.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async uploadOne (transfer: FileUpload): Promise<void> {
|
async uploadOne (transfer: FileUpload): Promise<void> {
|
||||||
const savedPath = this.path
|
const savedPath = this.path
|
||||||
await this.sftp.upload(path.join(this.path, transfer.getName()), transfer)
|
await this.sftp.upload(path.join(this.path, transfer.getName()), transfer)
|
||||||
|
@@ -13,6 +13,7 @@ import { ResizeEvent, BaseTerminalProfile } from './interfaces'
|
|||||||
import { TerminalDecorator } from './decorator'
|
import { TerminalDecorator } from './decorator'
|
||||||
import { SearchPanelComponent } from '../components/searchPanel.component'
|
import { SearchPanelComponent } from '../components/searchPanel.component'
|
||||||
import { MultifocusService } from '../services/multifocus.service'
|
import { MultifocusService } from '../services/multifocus.service'
|
||||||
|
import { getTerminalBackgroundColor } from '../helpers'
|
||||||
|
|
||||||
|
|
||||||
const INACTIVE_TAB_UNLOAD_DELAY = 1000 * 30
|
const INACTIVE_TAB_UNLOAD_DELAY = 1000 * 30
|
||||||
@@ -575,14 +576,7 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
|
|||||||
configure (): void {
|
configure (): void {
|
||||||
this.frontend?.configure(this.profile)
|
this.frontend?.configure(this.profile)
|
||||||
|
|
||||||
if (!this.themes.findCurrentTheme().followsColorScheme && this.config.store.terminal.background === 'colorScheme') {
|
this.backgroundColor = getTerminalBackgroundColor(this.config, this.themes, this.profile.terminalColorScheme)
|
||||||
const scheme = this.profile.terminalColorScheme ?? this.config.store.terminal.colorScheme
|
|
||||||
if (scheme.background) {
|
|
||||||
this.backgroundColor = scheme.background
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.backgroundColor = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zoomIn (): void {
|
zoomIn (): void {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import deepEqual from 'deep-equal'
|
||||||
import { BehaviorSubject, filter, firstValueFrom, takeUntil } from 'rxjs'
|
import { BehaviorSubject, filter, firstValueFrom, takeUntil } from 'rxjs'
|
||||||
import { Injector } from '@angular/core'
|
import { Injector } from '@angular/core'
|
||||||
import { ConfigService, getCSSFontFamily, getWindows10Build, HostAppService, HotkeysService, Platform, PlatformService, ThemesService } from 'tabby-core'
|
import { ConfigService, getCSSFontFamily, getWindows10Build, HostAppService, HotkeysService, Platform, PlatformService, ThemesService } from 'tabby-core'
|
||||||
@@ -11,9 +12,9 @@ import { Unicode11Addon } from '@xterm/addon-unicode11'
|
|||||||
import { SerializeAddon } from '@xterm/addon-serialize'
|
import { SerializeAddon } from '@xterm/addon-serialize'
|
||||||
import { ImageAddon } from '@xterm/addon-image'
|
import { ImageAddon } from '@xterm/addon-image'
|
||||||
import { CanvasAddon } from '@xterm/addon-canvas'
|
import { CanvasAddon } from '@xterm/addon-canvas'
|
||||||
import './xterm.css'
|
|
||||||
import deepEqual from 'deep-equal'
|
|
||||||
import { BaseTerminalProfile, TerminalColorScheme } from '../api/interfaces'
|
import { BaseTerminalProfile, TerminalColorScheme } from '../api/interfaces'
|
||||||
|
import { getTerminalBackgroundColor } from '../helpers'
|
||||||
|
import './xterm.css'
|
||||||
|
|
||||||
const COLOR_NAMES = [
|
const COLOR_NAMES = [
|
||||||
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white',
|
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white',
|
||||||
@@ -361,21 +362,21 @@ export class XTermFrontend extends Frontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private configureColors (scheme: TerminalColorScheme|undefined): void {
|
private configureColors (scheme: TerminalColorScheme|undefined): void {
|
||||||
const config = this.configService.store
|
const appColorScheme = this.themes._getActiveColorScheme() as TerminalColorScheme
|
||||||
|
|
||||||
scheme = scheme ?? this.themes._getActiveColorScheme()
|
scheme = scheme ?? appColorScheme
|
||||||
|
|
||||||
const theme: ITheme = {
|
const theme: ITheme = {
|
||||||
foreground: scheme!.foreground,
|
foreground: scheme.foreground,
|
||||||
selectionBackground: scheme!.selection ?? '#88888888',
|
selectionBackground: scheme.selection ?? '#88888888',
|
||||||
selectionForeground: scheme!.selectionForeground ?? undefined,
|
selectionForeground: scheme.selectionForeground ?? undefined,
|
||||||
background: !this.themes.findCurrentTheme().followsColorScheme && config.terminal.background === 'colorScheme' ? scheme!.background : '#00000000',
|
background: getTerminalBackgroundColor(this.configService, this.themes, scheme) ?? '#00000000',
|
||||||
cursor: scheme!.cursor,
|
cursor: scheme.cursor,
|
||||||
cursorAccent: scheme!.cursorAccent,
|
cursorAccent: scheme.cursorAccent,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < COLOR_NAMES.length; i++) {
|
for (let i = 0; i < COLOR_NAMES.length; i++) {
|
||||||
theme[COLOR_NAMES[i]] = scheme!.colors[i]
|
theme[COLOR_NAMES[i]] = scheme.colors[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deepEqual(this.configuredTheme, theme)) {
|
if (!deepEqual(this.configuredTheme, theme)) {
|
||||||
|
21
tabby-terminal/src/helpers.ts
Normal file
21
tabby-terminal/src/helpers.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { TerminalColorScheme } from './api/interfaces'
|
||||||
|
import { ConfigService, ThemesService } from 'tabby-core'
|
||||||
|
|
||||||
|
export function getTerminalBackgroundColor (
|
||||||
|
config: ConfigService,
|
||||||
|
themes: ThemesService,
|
||||||
|
scheme?: TerminalColorScheme,
|
||||||
|
): string|null {
|
||||||
|
const appTheme = themes.findCurrentTheme()
|
||||||
|
const appColorScheme = themes._getActiveColorScheme() as TerminalColorScheme
|
||||||
|
|
||||||
|
// Use non transparent background when:
|
||||||
|
// - legacy theme and user choses colorScheme based BG
|
||||||
|
// - or new theme but profile-specific scheme is used
|
||||||
|
const shouldUseCSBackground =
|
||||||
|
!appTheme.followsColorScheme && config.store.terminal.background === 'colorScheme'
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
|| appTheme.followsColorScheme && scheme?.name !== appColorScheme.name
|
||||||
|
|
||||||
|
return shouldUseCSBackground && scheme ? scheme.background : null
|
||||||
|
}
|
@@ -2,7 +2,7 @@ import '@vaadin/vaadin-context-menu'
|
|||||||
import copyToClipboard from 'copy-text-to-clipboard'
|
import copyToClipboard from 'copy-text-to-clipboard'
|
||||||
import { Injectable, Inject } from '@angular/core'
|
import { Injectable, Inject } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { PlatformService, ClipboardContent, MenuItemOptions, MessageBoxOptions, MessageBoxResult, FileUpload, FileUploadOptions, FileDownload, HTMLFileUpload } from 'tabby-core'
|
import { PlatformService, ClipboardContent, MenuItemOptions, MessageBoxOptions, MessageBoxResult, FileUpload, FileUploadOptions, FileDownload, HTMLFileUpload, DirectoryUpload } from 'tabby-core'
|
||||||
|
|
||||||
// eslint-disable-next-line no-duplicate-imports
|
// eslint-disable-next-line no-duplicate-imports
|
||||||
import type { ContextMenuElement, ContextMenuItem } from '@vaadin/vaadin-context-menu'
|
import type { ContextMenuElement, ContextMenuItem } from '@vaadin/vaadin-context-menu'
|
||||||
@@ -135,6 +135,10 @@ export class WebPlatformService extends PlatformService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async startUploadDirectory (_paths?: string[]): Promise<DirectoryUpload> {
|
||||||
|
return new DirectoryUpload()
|
||||||
|
}
|
||||||
|
|
||||||
setErrorHandler (handler: (_: any) => void): void {
|
setErrorHandler (handler: (_: any) => void): void {
|
||||||
window.addEventListener('error', handler)
|
window.addEventListener('error', handler)
|
||||||
}
|
}
|
||||||
|
@@ -5623,10 +5623,10 @@ lzma-native@^8.0.5, lzma-native@^8.0.6:
|
|||||||
node-gyp-build "^4.2.1"
|
node-gyp-build "^4.2.1"
|
||||||
readable-stream "^3.6.0"
|
readable-stream "^3.6.0"
|
||||||
|
|
||||||
macos-release@^3.1.0:
|
macos-release@^3.3.0:
|
||||||
version "3.1.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-3.1.0.tgz#6165bb0736ae567ed6649e36ce6a24d87cbb7aca"
|
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-3.3.0.tgz#92cb67bc66d67c3fde4a9e14f5f909afa418b072"
|
||||||
integrity sha512-/M/R0gCDgM+Cv1IuBG1XGdfTFnMEG6PZeT+KGWHO/OG+imqmaD9CH5vHBTycEM3+Kc4uG2Il+tFAuUWLqQOeUA==
|
integrity sha512-tPJQ1HeyiU2vRruNGhZ+VleWuMQRro8iFtJxYgnS4NQe+EukKF6aGiIT+7flZhISAt2iaXBCfFGvAyif7/f8nQ==
|
||||||
|
|
||||||
magic-string@^0.27.0:
|
magic-string@^0.27.0:
|
||||||
version "0.27.0"
|
version "0.27.0"
|
||||||
|
Reference in New Issue
Block a user