Compare commits

...

12 Commits

Author SHA1 Message Date
Leonard Hecker
e372202c3f wip 2025-09-02 21:45:34 +02:00
Leonard Hecker
5ddf429688 wip 2025-09-02 19:47:21 +02:00
Leonard Hecker
8d41ace320 Avoid reentrancy issues when dropping AppHost (#19296)
tl;dr: ~Apphost() may pump the message loop.
That's no bueno. See comments in the diff.

Additionally, this PR enables `_assertIsMainThread` in
release to trace down mysterious crashes in those builds.
2025-09-01 15:33:11 +02:00
Leonard Hecker
7849b00cbd Fix CoreWindow being destroyed after handoff (#19298)
As per: https://github.com/microsoft/terminal/discussions/19280#discussioncomment-14237148

## Validation Steps Performed
* Launch wtd via handoff (spawn cmd, etc.)
* Shift+Click the tab bar + button to create a new window
* Close the initial window
* UI doesn't lock up 
2025-09-01 15:32:58 +02:00
Leonard Hecker
5899343237 Fix a race condition around Open/CloseClipboard (#19297)
tl;dr: Open/CloseClipboard are surprisingly not thread-safe.

## Validation Steps Performed
* Copy a large amount of text (>1MB)
* Run `edit.exe`
* Press and hold Ctrl+Shift+V
* Doesn't crash 
2025-08-29 20:20:53 +02:00
Windows Console Service Bot
1283c0f5b9 Localization Updates - main - 08/26/2025 03:03:22 (#19278) 2025-08-29 00:32:22 +02:00
Dustin L. Howett
4272151adc Include Profile.BellSound as a media resource (#19289)
I legitimately cannot figure out how I forgot this. Bell should support
all the same validation as other media resources! Technically this means
you can set `bellSound` to `desktopWallpaper`, but... we'll pretend that
makes sense.

I reworked the viewmodel to be a little more sensible. It no longer
requires somebody else to check that its files exist. The settings UI
now also displays `File not found` in the _preview_ for the bell if it
is a single file which failed validation!
2025-08-28 00:05:51 +00:00
Dustin L. Howett
bd14f69080 sb: add appId to the StoreBroker blobs (new AERO requirement) (#19290)
> _I am altering the deal. Pray I do not alter it further._
> -the AERO team, maybe
2025-08-27 10:22:28 -07:00
Dustin L. Howett
91c9a14a71 env: don't explode when GetShortPathNameW fails (#19284)
It fails inside app containers (!) such as the one used by LocalTests.
2025-08-26 21:50:32 +00:00
Dustin L. Howett
9e10436a80 Move adjustProcessPriorityThrottled ctor earlier (#19283)
Test Impact: The LocalTests do not call `Initialize(HWND)`, so we would
fail on launch.
Also, we have `Create()` and `Initialize()` and `event Initialized` (the
last of which is not called from either of the first two...)
2025-08-26 21:34:01 +00:00
Dustin L. Howett
a9b660cc36 version: bump to 1.25 on main (#19276) 2025-08-25 17:06:19 -05:00
Dustin L. Howett
7b754e3d8e Localization Updates - 08/25/2025 21:39:33 (#19277)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
2025-08-25 17:02:41 -05:00
67 changed files with 618 additions and 474 deletions

View File

@@ -56,11 +56,11 @@ Dies ist ein Open Source-Projekt, und wir freuen uns über die Teilnahme der Com
<ReleaseNotes>
Version __VERSION_NUMBER__
- Wir haben der Benutzeroberfläche durchschnittliche Einstellungen hinzugefügt, die nur einmal in der JSON-Datei vorhanden waren, einschließlich einer neuen Seite zum Anpassen des Layouts Ihres Menüs "Neue Registerkarte"!
- Wir haben die Fensterverwaltung zurückgesetzt, um die Zuverlässigkeit zu verbessern; Melden Sie alle Fehler, die mit dem alias "wt.exe" auftreten.
- Profile zeigen jetzt ein Symbol an, wenn sie ausgeblendet wurden oder auf programme verweisen, die deinstalliert wurden.
Eine komplett neue Erweiterungsseite, die anzeigt, was in Ihrem Terminal installiert ist
Die Befehlspalette wird jetzt sowohl in Ihrer Muttersprache als auch auf Englisch angezeigt
Neue VT-Features wie synchronisiertes Rendering, neue Farbschemas, Konfiguration für schnelle Mausaktionen wie Zoomen und mehr
Weitere Details finden Sie auf unserer GitHub-Releasesseite.
Weitere Informationen finden Sie auf unserer GitHub-Releaseseite.
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,11 +56,11 @@ Este es un proyecto de fuente abierta y animamos a la comunidad a participar. Pa
<ReleaseNotes>
Versión __VERSION_NUMBER__
- Hemos agregado decenas de configuraciones a la interfaz de usuario que solo existían una vez en el archivo JSON, incluida una página nueva para personalizar el diseño del menú Nueva pestaña.
- Tenemos administración de ventanas rearchitecdas para mejorar la confiabilidad; envíe los errores que encuentre con el alias de wt.exe.
- Ahora, los perfiles muestran un icono si se han ocultado o hacen referencia a programas que se han desinstalado.
- Página Extensiones completamente nueva que muestra lo que se ha instalado en tu terminal
- La paleta de comandos ahora se muestra en tu idioma nativo, así como en inglés
- Nuevas características de VT, como la representación sincronizada, nuevos esquemas de color, configuración para acciones rápidas del ratón, como el zoom, y más
Consulte nuestra página de versiones de GitHub para obtener más detalles.
Consulta la página de versiones de GitHub para más información.
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -54,13 +54,13 @@ Il sagit dun projet open source et nous vous invitons à participer dans l
</DevStudio>
<ReleaseNotes>
__VERSION_NUMBER__ de version
Version __VERSION_NUMBER__
- Nous avons ajouté des milliers de paramètres à linterface utilisateur qui nexistaient auparavant que dans le fichier JSON, y compris une nouvelle page pour personnaliser la disposition de votre menu Nouvel onglet !
- Nous avons réarchitialiser la gestion des fenêtres pour améliorer la fiabilité ; entrez les bogues rencontrés avec lalias wt.exe
- Les profils affichent désormais une icône sils ont été masqués ou sils font référence à des programmes qui ont été désinstallés.
- Une toute nouvelle page Extensions qui montre ce qui a été installé dans votre terminal
- La palette de commandes saffiche désormais dans votre langue native, ainsi quen anglais
- Nouvelles fonctionnalités VT telles que le rendu synchronisé, de nouveaux schémas de couleurs, la configuration pour des actions rapides de la souris comme le zoom, et plus encore
Pour plus dinformations, consultez notre page des mises en production GitHub.
Veuillez consulter notre page des versions GitHub pour découvrir dautres détails.
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -54,13 +54,13 @@ Si tratta di un progetto open source e la partecipazione della community è molt
</DevStudio>
<ReleaseNotes>
Versione __VERSION_NUMBER__
Versione __VERSION_NUMBER__
- Sono state aggiunte decine di impostazioni all'interfaccia utente che una volta esisteva solo nel file JSON, inclusa una nuova pagina per personalizzare il layout del menu Nuova scheda.
- È stata riattivata la gestione delle finestre per migliorare l'affidabilità; inserire eventuali bug riscontrati con l'alias wt.exe
- I profili ora mostrano un'icona se sono stati nascosti o fanno riferimento ai programmi che sono stati disinstallati.
- Una pagina Estensioni completamente nuova che mostra ciò che è stato installato nel terminale
- Il riquadro comandi ora viene visualizzato nella tua lingua di origine oltre che in inglese
- Nuove funzionalità VT come il rendering sincronizzato, le nuove combinazioni di colori, la configurazione per azioni rapide del mouse come lo zoom e altro ancora
Per altri dettagli, vedere la pagina delle versioni di GitHub.
Per altri dettagli, vedi la pagina delle release di GitHub.
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,11 +56,11 @@
<ReleaseNotes>
バージョン __VERSION_NUMBER__
- [新しいタブ] メニューのレイアウトをカスタマイズするための新しいページを含む、一度だけ JSON ファイルに存在した UI に多数の設定を追加しました。
- 信頼性を向上させるためにウィンドウ管理を再選択しました。wt.exe エイリアスで発生したバグを報告してください
- プロファイルが非表示になっているか、アンインストールされたプログラムを参照している場合にアイコンが表示されるようになりました。
- ターミナルに何がインストールされているかを表示する新しい [拡張機能] ページ
- コマンド パレットがネイティブ言語と英語で表示されるようになりました
- 同期レンダリング、新しい配色、ズームなどのクイック マウス操作の構成などの、新しい VT 機能
詳細については、GitHub リリース ページを参照してください。
詳細については、GitHub リリース ページをご覧ください。
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,9 +56,9 @@
<ReleaseNotes>
버전 __VERSION_NUMBER__
- 새 탭 메뉴의 레이아웃을 사용자 지정하기 위한 새 페이지를 포함하여 JSON 파일에 한 번만 존재했던 UI에 수천 개의 설정을 추가했습니다.
- 안정성을 개선하기 위해 창 관리를 다시 보관했습니다. wt.exe 별칭에 발생한 버그를 제출하세요.
- 프로필이 숨겨졌거나 제거된 프로그램을 참조하는 경우 이제 프로필에 아이콘이 표시됩니다.
- 터미널에 설치된 항목을 보여 주는 완전히 새로운 확장 페이지
- 명령 팔레트가 이제 영어뿐만 아니라 모국어로도 표시
- 동기화된 렌더링, 새로운 색 구성표, 확대/축소와 같은 빠른 마우스 동작을 위한 구성 등 새로운 VT 기능이 추가
자세한 내용은 GitHub 릴리스 페이지를 참조하세요.
</ReleaseNotes>

View File

@@ -54,13 +54,13 @@ Este é um projeto de código aberto e a participação da comunidade é bem-vin
</DevStudio>
<ReleaseNotes>
Versão __VERSION_NUMBER__
Version __VERSION_NUMBER__
- Adicionamos várias configurações à interface do usuário que só existiam no arquivo JSON, incluindo uma nova página para personalizar o layout do menu Nova Guia!
- Temos o gerenciamento de janelas rearmado para melhorar a confiabilidade; registre todos os bugs encontrados com o wt.exe alias
- Os perfis agora mostram um ícone se eles foram ocultos ou se referem a programas que foram desinstalados.
Uma nova página de Extensões que mostra o que foi instalado no seu Terminal
A Paleta de Comandos agora aparece no seu idioma nativo, além do inglês
Novos recursos da VT, como renderização sincronizada, novos esquemas de cores, configuração para ações rápidas do mouse, como zoom, e muito mais
Consulte nossa página de versões do GitHub para obter detalhes adicionais.
Confira nossa página de lançamentos no GitHub para obter mais detalhes.
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,11 +56,11 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ẁē'νё àðđέď đöžзńş öƒ śėŧťїńģš тб тнè ÛĮ ťħąт ŏņ¢з όⁿℓγ έжіѕŧéð іή тђε ЈŠΩŃ ƒїℓė, ĭňĉŀџđіņģ å ňэẅ φâģé ƒøя ςŭśŧŏmïżϊñģ тħέ ĺαŷöυτ öƒ убµř Йέẁ Ţàъ мęήµ! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁè ĥаνė řэąřčħΐŧέсτέð щįлďοш мǻňαĝēмêиť ťô ϊmрябνé ŗĕŀĩāвîĺïтγ; ρŀěăѕе ƒíŀё αⁿу вûġš ÿøú εʼnćōùлťēѓ ẃïτħ ŧћё wt.exe ǻļĭâś !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Рґøƒíŀêŝ ňöẁ šћθẁ ãй ĭčöñ ίƒ ŧħэŷ'νę ъеєл ђіðδэñ őř řєƒěґ ŧσ φяοġгаmŝ ẅђíçĥ ẁ℮гέ џňϊйşťàľĺèð. !!! !!! !!! !!! !!! !!! !!! !!! !!! !
- Ą ωћόĺé ņέш ∑×τзńşĩōиŝ ρâģε τђат šнòωş ωħąт нǻś ъеēñ įηšтǻľĺéδ ĭʼnтο ўбμŗ Ţзřmĭňāŀ !!! !!! !!! !!! !!! !!! !!! !!!
- €όммаήδ Рдĺēтţĕ пŏẅ şĥŏшś üρ ϊñ ỳоũѓ йαťïνє ļäŋģµаġέ άś ŵєŀľ åś Σиĝℓĭŝђ !!! !!! !!! !!! !!! !!! !!!
- ∏еẅ VΤ ƒэåŧύґέŝ şűçн ăŝ ѕỳňсĥŗǿйìźėð гēŋďзříⁿğ, ηĕш ćôĺõг şĉћěмєѕ, çóńƒіĝџŗáτїöπ ƒοг qũī¢ķ möűšë ąćŧϊόņŝ ľîķє žøōmίйğ, ǻⁿđ мόřε !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
Рļèāŝє ŝèĕ θџŗ ĢίťĤцъ řέĺэªşэš ρąĝę ƒόř áďđїτϊōπαľ đэŧдįļŝ. !!! !!! !!! !!! !!! !!!
Ρĺęąŝэ ѕєě õμя ĞĭтΗύв řєĺэдšέŝ рάġě ƒοґ àďđϊтїõлаℓ ðêţǻїłş. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,11 +56,11 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ẁē'νё àðđέď đöžзńş öƒ śėŧťїńģš тб тнè ÛĮ ťħąт ŏņ¢з όⁿℓγ έжіѕŧéð іή тђε ЈŠΩŃ ƒїℓė, ĭňĉŀџđіņģ å ňэẅ φâģé ƒøя ςŭśŧŏmïżϊñģ тħέ ĺαŷöυτ öƒ убµř Йέẁ Ţàъ мęήµ! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁè ĥаνė řэąřčħΐŧέсτέð щįлďοш мǻňαĝēмêиť ťô ϊmрябνé ŗĕŀĩāвîĺïтγ; ρŀěăѕе ƒíŀё αⁿу вûġš ÿøú εʼnćōùлťēѓ ẃïτħ ŧћё wt.exe ǻļĭâś !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Рґøƒíŀêŝ ňöẁ šћθẁ ãй ĭčöñ ίƒ ŧħэŷ'νę ъеєл ђіðδэñ őř řєƒěґ ŧσ φяοġгаmŝ ẅђíçĥ ẁ℮гέ џňϊйşťàľĺèð. !!! !!! !!! !!! !!! !!! !!! !!! !!! !
- Ą ωћόĺé ņέш ∑×τзńşĩōиŝ ρâģε τђат šнòωş ωħąт нǻś ъеēñ įηšтǻľĺéδ ĭʼnтο ўбμŗ Ţзřmĭňāŀ !!! !!! !!! !!! !!! !!! !!! !!!
- €όммаήδ Рдĺēтţĕ пŏẅ şĥŏшś üρ ϊñ ỳоũѓ йαťïνє ļäŋģµаġέ άś ŵєŀľ åś Σиĝℓĭŝђ !!! !!! !!! !!! !!! !!! !!!
- ∏еẅ VΤ ƒэåŧύґέŝ şűçн ăŝ ѕỳňсĥŗǿйìźėð гēŋďзříⁿğ, ηĕш ćôĺõг şĉћěмєѕ, çóńƒіĝџŗáτїöπ ƒοг qũī¢ķ möűšë ąćŧϊόņŝ ľîķє žøōmίйğ, ǻⁿđ мόřε !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
Рļèāŝє ŝèĕ θџŗ ĢίťĤцъ řέĺэªşэš ρąĝę ƒόř áďđїτϊōπαľ đэŧдįļŝ. !!! !!! !!! !!! !!! !!!
Ρĺęąŝэ ѕєě õμя ĞĭтΗύв řєĺэдšέŝ рάġě ƒοґ àďđϊтїõлаℓ ðêţǻїłş. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,11 +56,11 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ẁē'νё àðđέď đöžзńş öƒ śėŧťїńģš тб тнè ÛĮ ťħąт ŏņ¢з όⁿℓγ έжіѕŧéð іή тђε ЈŠΩŃ ƒїℓė, ĭňĉŀџđіņģ å ňэẅ φâģé ƒøя ςŭśŧŏmïżϊñģ тħέ ĺαŷöυτ öƒ убµř Йέẁ Ţàъ мęήµ! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁè ĥаνė řэąřčħΐŧέсτέð щįлďοш мǻňαĝēмêиť ťô ϊmрябνé ŗĕŀĩāвîĺïтγ; ρŀěăѕе ƒíŀё αⁿу вûġš ÿøú εʼnćōùлťēѓ ẃïτħ ŧћё wt.exe ǻļĭâś !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Рґøƒíŀêŝ ňöẁ šћθẁ ãй ĭčöñ ίƒ ŧħэŷ'νę ъеєл ђіðδэñ őř řєƒěґ ŧσ φяοġгаmŝ ẅђíçĥ ẁ℮гέ џňϊйşťàľĺèð. !!! !!! !!! !!! !!! !!! !!! !!! !!! !
- Ą ωћόĺé ņέш ∑×τзńşĩōиŝ ρâģε τђат šнòωş ωħąт нǻś ъеēñ įηšтǻľĺéδ ĭʼnтο ўбμŗ Ţзřmĭňāŀ !!! !!! !!! !!! !!! !!! !!! !!!
- €όммаήδ Рдĺēтţĕ пŏẅ şĥŏшś üρ ϊñ ỳоũѓ йαťïνє ļäŋģµаġέ άś ŵєŀľ åś Σиĝℓĭŝђ !!! !!! !!! !!! !!! !!! !!!
- ∏еẅ VΤ ƒэåŧύґέŝ şűçн ăŝ ѕỳňсĥŗǿйìźėð гēŋďзříⁿğ, ηĕш ćôĺõг şĉћěмєѕ, çóńƒіĝџŗáτїöπ ƒοг qũī¢ķ möűšë ąćŧϊόņŝ ľîķє žøōmίйğ, ǻⁿđ мόřε !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
Рļèāŝє ŝèĕ θџŗ ĢίťĤцъ řέĺэªşэš ρąĝę ƒόř áďđїτϊōπαľ đэŧдįļŝ. !!! !!! !!! !!! !!! !!!
Ρĺęąŝэ ѕєě õμя ĞĭтΗύв řєĺэдšέŝ рάġě ƒοґ àďđϊтїõлаℓ ðêţǻїłş. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,9 +56,9 @@
<ReleaseNotes>
Версия __VERSION_NUMBER__
- Мы добавили в пользовательский интерфейс десятки параметров, которые существовали только в JSON-файле, включая новую страницу для настройки макета меню "Новая вкладка".
- Для повышения надежности мы переупоряхлили управление окнами; создайте все ошибки, обнаруженные с wt.exe псевдонимом
- Профили теперь показывают значок, если они скрыты или ссылаются на программы, которые были удалены.
Новая страница расширений, на которой отображается информация о том, что было установлено в вашем терминале
Палитра команд теперь доступна на вашем языке, а также на английском
Новые функции VT, например синхронизированная отрисовка, новые цветовые схемы, настройка быстрых действий мыши, таких как масштабирование, и т. д.
Дополнительные сведения см. на странице выпусков GitHub.
</ReleaseNotes>

View File

@@ -54,13 +54,13 @@
</DevStudio>
<ReleaseNotes>
版本 __VERSION_NUMBER__
Version __VERSION_NUMBER__
- 我们向用户界面添加了许多设置,这些设置仅存在于 JSON 文件中,包括用于自定义“新建标签页”菜单布局的新页面!
- 我们已重新检测窗口管理以提高可靠性;请将遇到的任何 bug 归档为 wt.exe 别名
- 如果配置文件已隐藏或引用已卸载的程序,则它们现在将显示一个图标。
- 一个全新的“扩展”页,显示已安装到终端的内容
- 命令面板现在以你的母语和英语显示
- 新的 VT 功能,例如同步渲染、新配色方案、快速鼠标操作(如缩放)的配置等
有关其他详细信息,请参阅 GitHub 发布页面。
有关其他详细信息,请参阅我们的 GitHub 发布页面。
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -54,13 +54,13 @@
</DevStudio>
<ReleaseNotes>
版本 __VERSION_NUMBER__
Version __VERSION_NUMBER__
- 我們已新增數十個只存在於 JSON 檔案中的設定到 UI包括自定義 [新索引標籤] 功能表版面配置的新頁面!
- 我們已重新設定視窗管理,以改善可靠性;請提出您在 wt.exe 別名遇到的任何錯誤
- 設定文件現在會在隱藏或參照已卸載的程式時顯示圖示。
- 全新的延伸模組頁面會顯示已安裝在您終端機中的內容
- 命令選擇區現在以您的母語和英文顯示
- 新的 VT 功能,例如同步轉譯、新的色彩配置、快速滑鼠動作 (例如縮放) 設定等等
如需詳細數據,請參閱我們的 GitHub 版本頁面。
如需更多詳細資料,請參閱我們的 GitHub 發行版本頁面。
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -20,6 +20,7 @@
"DisableAutoPackageNameFormatting": false
},
"appSubmission": {
"appId": "9N8G5RFZ9XK3",
"productId": "00014050269303149694",
"targetPublishMode": "NotSet",
"targetPublishDate": null,

View File

@@ -56,12 +56,9 @@ Dies ist ein Open Source-Projekt, und wir freuen uns über die Teilnahme an der
<ReleaseNotes>
Version __VERSION_NUMBER__
Wir haben umgeschrieben, wie Konsolenanwendungen im Terminal gehostet werden! Melden Sie alle auftretenden Fehler.
Terminal unterstützt jetzt Sixels!
Sie können jetzt einen angedockten Bereich öffnen, der Ausschnitte von Befehlen enthält, die Sie gespeichert haben, um sie später zu verwenden.
Für Benutzer der Eingabeaufforderung der neuesten Version von Windows 11 wird möglicherweise ein QuickInfo-Symbol angezeigt, das installierbare Software von WinGet vorschlägt.
Ausgewählter Text wird jetzt viel sichtbarer (und anpassbarer!).
- Eine Reihe von Zuverlässigkeitsfehlern, Benutzerfreundlichkeitsproblemen und Ärgernissen wurden behoben.
Wir haben der Benutzeroberfläche Dutzende von Einstellungen hinzugefügt, die nur einmal in der JSON-Datei vorhanden waren, einschließlich einer neuen Seite zum Anpassen des Layouts Ihres Menüs „Neue Registerkarte“!
Wir haben die Fensterverwaltung umgestaltet, um die Zuverlässigkeit zu verbessern. Melden Sie alle Fehler, die beim alias „wt.exe“ auftreten
Profile zeigen jetzt ein Symbol an, wenn sie ausgeblendet wurden oder auf Programme verweisen, die deinstalliert wurden.
Weitere Informationen finden Sie auf unserer GitHub-Releaseseite.
</ReleaseNotes>

View File

@@ -56,12 +56,9 @@ Este es un proyecto de fuente abierta y animamos a la comunidad a participar. Pa
<ReleaseNotes>
Versión __VERSION_NUMBER__
- Hemos reescrito cómo se hospedan las aplicaciones de consola en Terminal. Informe de los errores que encuentre.
- Terminal ahora admite síxeles.
- Ahora puede abrir un panel acoplado que contenga fragmentos de comandos que haya guardado para usarlos más adelante
- Los usuarios del símbolo del sistema de la versión más reciente de Windows 11 pueden ver un icono de "sugerencia rápida" que sugiere software instalable de WinGet
- El texto seleccionado ahora será mucho más visible (y personalizable)
- Se han corregido varios errores de fiabilidad, problemas de comodidad y molestias.
- Hemos añadido decenas de configuraciones a la interfaz de usuario que antes solo existían en el archivo JSON, incluida una nueva página para personalizar el diseño del menú Nueva pestaña.
- Hemos reestructurado la gestión de ventanas para mejorar la fiabilidad; informe de cualquier error que encuentre con el alias wt.exe
- Ahora, los perfiles muestran un icono si han sido ocultados o hacen referencia a programas que han sido desinstalados.
Consulte la página de versiones de GitHub para más información.
</ReleaseNotes>

View File

@@ -56,12 +56,9 @@ Il sagit dun projet open source et nous encourageons la participation à l
<ReleaseNotes>
Version __VERSION_NUMBER__
Nous avons réécrit la manière dont les applications de console sont hébergées dans Terminal ! Veuillez signaler tout bogue que vous rencontrez.
Terminal prend désormais en charge Sixels !
Vous pouvez maintenant ouvrir un panneau ancré contenant des extraits de commandes que vous avez enregistrées pour les utiliser ultérieurement
Les utilisateurs de linvite de commande sur la dernière version de Windows 11 peuvent voir une icône « astuce rapide » qui suggère un logiciel installable à partir de WinGet
Le texte sélectionné sera désormais beaucoup plus visible (et personnalisable !)
Un certain nombre de bogues de fiabilité, de problèmes de commodité et de désagréments ont été corrigés.
- Nous avons ajouté des dizaines de paramètres à linterface utilisateur qui nexistaient auparavant que dans le fichier JSON, y compris une nouvelle page pour personnaliser la disposition de votre menu Nouvel onglet.
- Nous avons fait une refonte de la gestion des fenêtres pour améliorer la fiabilité. Veuillez signaler les bogues que vous rencontrez avec lalias wt.exe.
- Les profils affichent désormais une icône sils ont été masqués ou sils font référence à des programmes qui ont été désinstallés.
Veuillez consulter notre page des versions GitHub pour découvrir dautres détails.
</ReleaseNotes>

View File

@@ -56,12 +56,9 @@ Si tratta di un progetto open source e la partecipazione della community è molt
<ReleaseNotes>
Versione __VERSION_NUMBER__
- Abbiamo cambiato il modo in cui le applicazioni della console vengono ospitate allinterno di Terminale. Segnala eventuali bug riscontrati.
- Ora Terminale supporta i Sixel.
- Puoi aprire un pannello ancorato contenente frammenti di comandi salvati per usarli in seguito
- Gli utenti che usano il prompt dei comandi nella versione più recente di Windows 11 potrebbero visualizzare unicona di “suggerimento rapido” che consiglia il software installabile da WinGet
- Il testo selezionato sarà ora molto più visibile, oltre che personalizzabile.
- Sono stati risolti diversi bug di affidabilità e problemi di ordine pratico.
- Abbiamo aggiunto decine di impostazioni all'interfaccia utente che in precedenza esistevano solo nel file JSON, inclusa una nuova pagina per personalizzare il layout del menu Nuova scheda.
- Abbiamo riprogettato la gestione delle finestre per migliorarne l'affidabilità; segnala eventuali bug riscontrati con l'alias wt.exe
- I profili ora mostrano un'icona se sono stati nascosti o se fanno riferimento a programmi disinstallati.
Per altri dettagli, vedi la pagina delle release di GitHub.
</ReleaseNotes>

View File

@@ -56,12 +56,9 @@
<ReleaseNotes>
バージョン __VERSION_NUMBER__
- ターミナル内でのコンソール アプリケーションのホスト方法を書き換えました。発生したバグを報告してください
- ターミナルで Sixels がサポートされるようになりました。
- 後で使用するために保存したコマンドのスニペットを含むドッキング パネルを開けるようになりました
- 最新の Windows 11 リリースのコマンド プロンプト ユーザーには、WinGet からインストール可能なソフトウェアを提案する "クイック ヒント" アイコンが表示される場合があります
- 選択したテキストが大幅に見やすくなりました (カスタマイズも可能です)
- 信頼性に関するバグ、利便性の問題、不快な問題の多くが修正されました。
- 新しいタブ メニューのレイアウトをカスタマイズするための新しいページなど、以前は JSON ファイルにしかなかった設定が UI に多数追加されました
- 信頼性を向上させるために、ウィンドウ管理を再設計しました。wt.exe エイリアスで発生したバグを報告してください
- プロファイルが非表示になっている場合や、アンインストールされたプログラムを参照している場合に、アイコンが表示されるようになりました
詳細については、GitHub リリース ページをご覧ください。
</ReleaseNotes>

View File

@@ -56,12 +56,9 @@
<ReleaseNotes>
버전 __VERSION_NUMBER__
- 콘솔 애플리케이션이 터미널 내에서 호스팅되는 방법을 다시 작성했습니다. 버그가 발생하면 보고해 주세요.
- 터미널에서 이제 Sixels를 지원합니다.
- 이제 나중에 사용하기 위해 저장한 명령 조각이 포함된 도킹된 패널을 열 수 있습니다.
- 최신 Windows 11 릴리스의 명령 프롬프트 사용자는 WinGet에서 설치 가능한 소프트웨어를 추천하는 "간단한 팁" 아이콘을 볼 수 있습니다.
- 이제 선택한 텍스트가 훨씬 더 잘 보입니다(사용자 지정 가능).
- 여러 안정성 버그, 편의성 문제, 불편 사항이 수정되었습니다.
- 새 탭 메뉴의 레이아웃을 사용자 지정하기 위한 새 페이지를 포함하여 JSON 파일에만 존재했던 수십 개의 설정을 UI에 추가
- 안정성을 개선하기 위해 창 관리 구조를 재구성했습니다. wt.exe 별칭과 관련하여 발생한 버그 신고
- 프로필이 숨겨졌거나 제거된 프로그램을 참조하는 경우 이제 프로필에 아이콘이 표시됩니다.
자세한 내용은 GitHub 릴리스 페이지를 참조하세요.
</ReleaseNotes>

View File

@@ -54,14 +54,11 @@ Este é um projeto de código aberto e a participação da comunidade é bem-vin
</DevStudio>
<ReleaseNotes>
Versão __VERSION_NUMBER__
Version __VERSION_NUMBER__
Reescrevemos a forma como os aplicativos de console são hospedados no Terminal! Relate os bugs encontrados.
O terminal agora oferece suporte ao Sixels!
Agora você pode abrir um painel acoplado contendo snippets de comandos que você salvou para usar mais tarde
Os usuários do Prompt de Comando na versão mais recente do Windows 11 podem ver um ícone de "dica rápida", que sugere softwares instaláveis a partir do WinGet
O texto selecionado agora ficará muito mais visível (e personalizável!)
Vários bugs de confiabilidade, problemas de conveniência e incômodos foram resolvidos.
Adicionamos várias configurações à interface do usuário que antes só existiam no arquivo JSON, incluindo uma nova página para personalizar o layout do seu menu Nova Guia!
Reestruturamos o gerenciamento de janelas para melhorar a confiabilidade; registre os bugs que você encontrar com o alias wt.exe
Os perfis agora exibem um ícone se estiverem ocultos ou se referirem a programas que foram desinstalados.
Confira nossa página de lançamentos no GitHub para obter mais detalhes.
</ReleaseNotes>

View File

@@ -56,14 +56,11 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ẁē'νё ŕéẁѓĭτťёñ ћοώ ĉòπşõℓε άррℓіċªťįõпѕ αяе ĥθѕťэđ įŋšιďé Ţєямїńąℓ! Рļéаšė яёροřτ αņу ьϋģš ýõμ éпćŏџήţęя. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!
- Ţëямΐʼnαļ ńóẃ ŝüррöятš Śїхέłś! !!! !!! !!!
- ¥оų ĉåи ńòŵ θρėñ д đбčĸэď ράńέļ ċőлŧăīņϊňģ śⁿіφφëťś оƒ ςōмmàⁿďş ŷŏũ ĥªν℮ şåνěđ τσ üśε łαťэŗ !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ćοмmäлđ Рřōmφť üş℮ŗѕ öη τће ļāťëšτ Щīйđôώѕ 11 řёℓеаѕĕ måў ŝэε ά "qůïςκ ŧĭр" ιсôñ τĥдт šűğģєѕŧѕ ίńśŧăłłавļз šôƒţẁαгέ ƒґόm ЩĩйĞéţ !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Śєļèċťєď ţĕжт ωϊŀļ йǿẃ ьέ mџ¢н мǿѓε νĭŝϊъļė (άŋđ сŭŝтŏмΐżдьļē!) !!! !!! !!! !!! !!! !!! !
- Ä ņϋmъŗ ŏƒ ѓēŀїаъïļŧÿ ьüĝś, ςôⁿνėηĭ℮иć℮ îѕšůëş ăπð âлňбγдňçėŝ ћªνε ъēёп ƒΐ×еð. !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁē'νё àðđέď đöžзńş öƒ śėŧťїńģš тб тнè ÛĮ ťħąт ŏņ¢з όⁿℓγ έжіѕŧéð іή тђε ЈŠΩŃ ƒїℓė, ĭňĉŀџđіņģ å ňэẅ φâģé ƒøя ςŭśŧŏmïżϊñģ тħέ ĺαŷöυτ öƒ убµř Йέẁ Ţàъ мęήµ! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁè ĥаνė řэąřčħΐŧέсτέð щįлďοш мǻňαĝēмêиť ťô ϊmрябνé ŗĕŀĩāвîĺïтγ; ρŀěăѕе ƒíŀё αⁿу вûġš ÿøú εʼnćōùлťēѓ ẃïτħ ŧћё wt.exe ǻļĭâś !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Рґøƒíŀêŝ ňöẁ šћθẁ ãй ĭčöñ ίƒ ŧħэŷ'νę ъеєл ђіðδэñ őř řєƒěґ ŧσ φяοġгаmŝ ẅђíçĥ ẁ℮гέ џňϊйşťàľĺèð. !!! !!! !!! !!! !!! !!! !!! !!! !!! !
Ρĺёàŝ℮ ŝез ǿúг ĢīťНŭъ řěłεαśèŝ φāğ℮ ƒóѓ дďδітĭøиąℓ ð℮тªїľŝ. !!! !!! !!! !!! !!! !!!
Рļèāŝє ŝèĕ θџŗ ĢίťĤцъ řέĺэªşэš ρąĝę ƒόř áďđїτϊōπαľ đэŧдįļŝ. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,14 +56,11 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ẁē'νё ŕéẁѓĭτťёñ ћοώ ĉòπşõℓε άррℓіċªťįõпѕ αяе ĥθѕťэđ įŋšιďé Ţєямїńąℓ! Рļéаšė яёροřτ αņу ьϋģš ýõμ éпćŏџήţęя. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!
- Ţëямΐʼnαļ ńóẃ ŝüррöятš Śїхέłś! !!! !!! !!!
- ¥оų ĉåи ńòŵ θρėñ д đбčĸэď ράńέļ ċőлŧăīņϊňģ śⁿіφφëťś оƒ ςōмmàⁿďş ŷŏũ ĥªν℮ şåνěđ τσ üśε łαťэŗ !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ćοмmäлđ Рřōmφť üş℮ŗѕ öη τће ļāťëšτ Щīйđôώѕ 11 řёℓеаѕĕ måў ŝэε ά "qůïςκ ŧĭр" ιсôñ τĥдт šűğģєѕŧѕ ίńśŧăłłавļз šôƒţẁαгέ ƒґόm ЩĩйĞéţ !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Śєļèċťєď ţĕжт ωϊŀļ йǿẃ ьέ mџ¢н мǿѓε νĭŝϊъļė (άŋđ сŭŝтŏмΐżдьļē!) !!! !!! !!! !!! !!! !!! !
- Ä ņϋmъŗ ŏƒ ѓēŀїаъïļŧÿ ьüĝś, ςôⁿνėηĭ℮иć℮ îѕšůëş ăπð âлňбγдňçėŝ ћªνε ъēёп ƒΐ×еð. !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁē'νё àðđέď đöžзńş öƒ śėŧťїńģš тб тнè ÛĮ ťħąт ŏņ¢з όⁿℓγ έжіѕŧéð іή тђε ЈŠΩŃ ƒїℓė, ĭňĉŀџđіņģ å ňэẅ φâģé ƒøя ςŭśŧŏmïżϊñģ тħέ ĺαŷöυτ öƒ убµř Йέẁ Ţàъ мęήµ! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁè ĥаνė řэąřčħΐŧέсτέð щįлďοш мǻňαĝēмêиť ťô ϊmрябνé ŗĕŀĩāвîĺïтγ; ρŀěăѕе ƒíŀё αⁿу вûġš ÿøú εʼnćōùлťēѓ ẃïτħ ŧћё wt.exe ǻļĭâś !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Рґøƒíŀêŝ ňöẁ šћθẁ ãй ĭčöñ ίƒ ŧħэŷ'νę ъеєл ђіðδэñ őř řєƒěґ ŧσ φяοġгаmŝ ẅђíçĥ ẁ℮гέ џňϊйşťàľĺèð. !!! !!! !!! !!! !!! !!! !!! !!! !!! !
Ρĺёàŝ℮ ŝез ǿúг ĢīťНŭъ řěłεαśèŝ φāğ℮ ƒóѓ дďδітĭøиąℓ ð℮тªїľŝ. !!! !!! !!! !!! !!! !!!
Рļèāŝє ŝèĕ θџŗ ĢίťĤцъ řέĺэªşэš ρąĝę ƒόř áďđїτϊōπαľ đэŧдįļŝ. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,14 +56,11 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ẁē'νё ŕéẁѓĭτťёñ ћοώ ĉòπşõℓε άррℓіċªťįõпѕ αяе ĥθѕťэđ įŋšιďé Ţєямїńąℓ! Рļéаšė яёροřτ αņу ьϋģš ýõμ éпćŏџήţęя. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!
- Ţëямΐʼnαļ ńóẃ ŝüррöятš Śїхέłś! !!! !!! !!!
- ¥оų ĉåи ńòŵ θρėñ д đбčĸэď ράńέļ ċőлŧăīņϊňģ śⁿіφφëťś оƒ ςōмmàⁿďş ŷŏũ ĥªν℮ şåνěđ τσ üśε łαťэŗ !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ćοмmäлđ Рřōmφť üş℮ŗѕ öη τће ļāťëšτ Щīйđôώѕ 11 řёℓеаѕĕ måў ŝэε ά "qůïςκ ŧĭр" ιсôñ τĥдт šűğģєѕŧѕ ίńśŧăłłавļз šôƒţẁαгέ ƒґόm ЩĩйĞéţ !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Śєļèċťєď ţĕжт ωϊŀļ йǿẃ ьέ mџ¢н мǿѓε νĭŝϊъļė (άŋđ сŭŝтŏмΐżдьļē!) !!! !!! !!! !!! !!! !!! !
- Ä ņϋmъŗ ŏƒ ѓēŀїаъïļŧÿ ьüĝś, ςôⁿνėηĭ℮иć℮ îѕšůëş ăπð âлňбγдňçėŝ ћªνε ъēёп ƒΐ×еð. !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁē'νё àðđέď đöžзńş öƒ śėŧťїńģš тб тнè ÛĮ ťħąт ŏņ¢з όⁿℓγ έжіѕŧéð іή тђε ЈŠΩŃ ƒїℓė, ĭňĉŀџđіņģ å ňэẅ φâģé ƒøя ςŭśŧŏmïżϊñģ тħέ ĺαŷöυτ öƒ убµř Йέẁ Ţàъ мęήµ! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Ẁè ĥаνė řэąřčħΐŧέсτέð щįлďοш мǻňαĝēмêиť ťô ϊmрябνé ŗĕŀĩāвîĺïтγ; ρŀěăѕе ƒíŀё αⁿу вûġš ÿøú εʼnćōùлťēѓ ẃïτħ ŧћё wt.exe ǻļĭâś !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- Рґøƒíŀêŝ ňöẁ šћθẁ ãй ĭčöñ ίƒ ŧħэŷ'νę ъеєл ђіðδэñ őř řєƒěґ ŧσ φяοġгаmŝ ẅђíçĥ ẁ℮гέ џňϊйşťàľĺèð. !!! !!! !!! !!! !!! !!! !!! !!! !!! !
Ρĺёàŝ℮ ŝез ǿúг ĢīťНŭъ řěłεαśèŝ φāğ℮ ƒóѓ дďδітĭøиąℓ ð℮тªїľŝ. !!! !!! !!! !!! !!! !!!
Рļèāŝє ŝèĕ θџŗ ĢίťĤцъ řέĺэªşэš ρąĝę ƒόř áďđїτϊōπαľ đэŧдįļŝ. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,12 +56,9 @@
<ReleaseNotes>
Версия __VERSION_NUMBER__
Мы переписали, как консольные приложения размещаются внутри Терминала! Сообщайте о любых ошибках, с которыми вы столкнулись.
Терминал теперь поддерживает форматы Sixel!
Теперь вы можете открыть закрепленную панель, содержащую фрагменты команд, которые вы сохранили для использования в дальнейшем
Пользователи командной строки в новейшем выпуске Windows 11 могут увидеть значок "краткой подсказки", который предлагает устанавливаемые программы из WinGet
Выделенный текст теперь станет более видимым (и настраиваемым!)
Исправлено несколько ошибок надежности, проблем с удобством, а также устранены раздражающие моменты.
Мы добавили в пользовательский интерфейс десятки параметров, которые ранее существовали только в JSON-файле, включая новую страницу для настройки макета меню новой вкладки.
Мы переработали управление окнами для повышения надежности. Сообщайте о любых ошибках, которые вы обнаружите с псевдонимом wt.exe
Профили теперь отображают значок, если они были скрыты или ссылаются на программы, которые были удалены.
Дополнительные сведения см. на странице выпусков GitHub.
</ReleaseNotes>

View File

@@ -56,12 +56,9 @@
<ReleaseNotes>
Version __VERSION_NUMBER__
- 我们已改变主机应用程序在终端内的托管方式!请报告遇到的任何 bug。
- 终端现在支持 Sixels!
- 现在可以打开一个停靠面板,其中包含已保存供以后使用的命令片段
- 最新 Windows 11 版本上的命令提示用户可能会看到“快速提示”图标,该图标建议从 WinGet 安装软件
- 所选文本现在将具有更高的可见性(和可自定义性!)
- 修复了许多可靠性 bug、便利性问题和令人烦恼的问题。
- 我们向用户界面添加了许多之前仅存在于 JSON 文件中的设置,包括用于自定义“新建标签页”菜单布局的新页面!
- 我们已重新架构窗口管理以提高可靠性; 请使用 wt.exe 别名提交您遇到的任何错误
- 配置文件如果已被隐藏或引用了已卸载的程序,现在会显示一个图标。
有关其他详细信息,请参阅我们的 GitHub 发布页面。
</ReleaseNotes>

View File

@@ -54,16 +54,13 @@
</DevStudio>
<ReleaseNotes>
版本 __VERSION_NUMBER__
Version __VERSION_NUMBER__
- 我們已重寫主機應用程式在終端機內託管的方式!請報告您遇到的錯誤。
- 終端機現在支援 Sixels!
- 現在,您可以開啟包含已儲存命令程式碼片段的固定面板,以供稍後使用
- 最新 Windows 11 版本中的 [命令提示] 使用者可能會看到「快速提示」圖示,建議可自 WinGet 安裝的軟體
- 選取的文字現在會更明顯 (且可自訂!)
- 已修正一些可靠性錯誤、便利性問題和令人困擾的問題。
- 我們已在使用者介面中新增數十個曾經僅存在於 JSON 檔案中的設定,包括一個可自訂新索引標籤選單版面配置的新頁面!
- 我們已重新架構視窗管理以提升可靠性; 如果您在使用 wt.exe 別名時遇到任何錯誤,請提交錯誤回報
- 如果設定檔已隱藏或參照已解除安裝的程式,現在會顯示圖示。
如需更多詳細資,請參閱我們的 GitHub 發行頁面。
如需更多詳細資,請參閱我們的 GitHub 發行版本頁面。
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -20,6 +20,7 @@
"DisableAutoPackageNameFormatting": false
},
"appSubmission": {
"appId": "9N0DX20HK701",
"productId": "00013926773940052066",
"targetPublishMode": "NotSet",
"targetPublishDate": null,

View File

@@ -5,7 +5,7 @@
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2025</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>24</VersionMinor>
<VersionMinor>25</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
<VersionInfoCulture>1033</VersionInfoCulture>
<!-- The default has a spacing problem -->

View File

@@ -3012,6 +3012,12 @@
"description": "If set to true, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamically generated profiles, while leaving them in your settings file.",
"type": "boolean"
},
"minimumBufferWidth": {
"default": 0,
"description": "The width of the backing text buffer. If it's wider than the viewport, a horizontal scrollbar is shown.",
"minimum": 0,
"type": "integer"
},
"historySize": {
"default": 9001,
"description": "The number of lines above the ones displayed in the window you can scroll back to.",

View File

@@ -516,7 +516,7 @@ namespace winrt::TerminalApp::implementation
ASSERT_UI_THREAD();
auto control = GetActiveTerminalControl();
const auto currentOffset = control.ScrollOffset();
const auto currentOffset = control.ScrollOffset().Y;
control.ScrollViewport(::base::ClampAdd(currentOffset, delta));
}

View File

@@ -60,8 +60,42 @@ namespace winrt
namespace clipboard
{
wil::unique_close_clipboard_call open(HWND hwnd)
static SRWLOCK lock = SRWLOCK_INIT;
struct ClipboardHandle
{
explicit ClipboardHandle(bool open) :
_open{ open }
{
}
~ClipboardHandle()
{
if (_open)
{
ReleaseSRWLockExclusive(&lock);
CloseClipboard();
}
}
explicit operator bool() const noexcept
{
return _open;
}
private:
bool _open = false;
};
ClipboardHandle open(HWND hwnd)
{
// Turns out, OpenClipboard/CloseClipboard are not thread-safe whatsoever,
// and on CloseClipboard, the GetClipboardData handle may get freed.
// The problem is that WinUI also uses OpenClipboard (through WinRT which uses OLE),
// and so even with this mutex we can still crash randomly if you copy something via WinUI.
// Makes you wonder how many Windows apps are subtly broken, huh.
AcquireSRWLockExclusive(&lock);
bool success = false;
// OpenClipboard may fail to acquire the internal lock --> retry.
@@ -80,7 +114,12 @@ namespace clipboard
Sleep(sleep);
}
return wil::unique_close_clipboard_call{ success };
if (!success)
{
ReleaseSRWLockExclusive(&lock);
}
return ClipboardHandle{ success };
}
void write(wil::zwstring_view text, std::string_view html, std::string_view rtf)
@@ -220,16 +259,6 @@ namespace winrt::TerminalApp::implementation
}
}
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
DispatcherQueue::GetForCurrentThread(),
til::throttled_func_options{
.delay = std::chrono::milliseconds{ 100 },
.debounce = true,
.trailing = true,
},
[=]() {
_adjustProcessPriority();
});
_hostingHwnd = hwnd;
return S_OK;
}
@@ -410,6 +439,17 @@ namespace winrt::TerminalApp::implementation
// them.
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
DispatcherQueue::GetForCurrentThread(),
til::throttled_func_options{
.delay = std::chrono::milliseconds{ 100 },
.debounce = true,
.trailing = true,
},
[=]() {
_adjustProcessPriority();
});
}
Windows::UI::Xaml::Automation::Peers::AutomationPeer TerminalPage::OnCreateAutomationPeer()
@@ -2302,7 +2342,7 @@ namespace winrt::TerminalApp::implementation
{
// The magic value of WHEEL_PAGESCROLL indicates that we need to scroll the entire page
realRowsToScroll = _systemRowsToScroll == WHEEL_PAGESCROLL ?
tabImpl->GetActiveTerminalControl().ViewHeight() :
tabImpl->GetActiveTerminalControl().ViewSize().Y :
_systemRowsToScroll;
}
else
@@ -2743,7 +2783,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& control{ _GetActiveControl() })
{
const auto termHeight = control.ViewHeight();
const auto termHeight = control.ViewSize().Y;
auto scrollDelta = _ComputeScrollDelta(scrollDirection, termHeight);
tabImpl->Scroll(scrollDelta);
}

View File

@@ -279,7 +279,7 @@ namespace winrt::TerminalApp::implementation
auto sounds{ _profile.BellSound() };
if (sounds && sounds.Size() > 0)
{
winrt::hstring soundPath{ wil::ExpandEnvironmentStringsW<std::wstring>(sounds.GetAt(rand() % sounds.Size()).c_str()) };
winrt::hstring soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
winrt::Windows::Foundation::Uri uri{ soundPath };
_playBellSound(uri);
}

View File

@@ -708,7 +708,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return false;
}
void ControlCore::UserScrollViewport(const int viewTop)
void ControlCore::UserScrollViewport(const til::point viewTop)
{
{
// This is a scroll event that wasn't initiated by the terminal
@@ -1483,10 +1483,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return _terminal->GetTaskbarProgress();
}
int ControlCore::ScrollOffset()
Core::Point ControlCore::ScrollOffset() const
{
const auto lock = _terminal->LockForReading();
return _terminal->GetScrollOffset();
return _terminal->GetScrollOffset().to_core_point();
}
// Function Description:
@@ -1494,10 +1494,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// height of the viewport.
// Return Value:
// - The height of the terminal in lines of text
int ControlCore::ViewHeight() const
Core::Point ControlCore::ViewSize() const
{
const auto lock = _terminal->LockForReading();
return _terminal->GetViewport().Height();
return _terminal->GetViewport().Dimensions().to_core_point();
}
// Function Description:
@@ -1505,10 +1505,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// history AND the viewport.
// Return Value:
// - The height of the terminal in lines of text
int ControlCore::BufferHeight() const
Core::Point ControlCore::BufferSize() const
{
const auto lock = _terminal->LockForReading();
return _terminal->GetBufferHeight();
return _terminal->GetBufferSize().to_core_point();
}
void ControlCore::_terminalWarningBell()
@@ -2596,7 +2596,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ControlCore::ScrollToMark(const Control::ScrollToMarkDirection& direction)
{
const auto lock = _terminal->LockForWriting();
const auto currentOffset = ScrollOffset();
const auto currentOffset = ScrollOffset().Y;
const auto& marks{ _terminal->GetMarkExtents() };
std::optional<::MarkExtents> tgt;
@@ -2605,7 +2605,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
case ScrollToMarkDirection::Last:
{
int highest = currentOffset;
auto highest = currentOffset;
for (const auto& mark : marks)
{
const auto newY = mark.start.y;
@@ -2619,7 +2619,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
case ScrollToMarkDirection::First:
{
int lowest = currentOffset;
auto lowest = currentOffset;
for (const auto& mark : marks)
{
const auto newY = mark.start.y;
@@ -2633,7 +2633,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
case ScrollToMarkDirection::Next:
{
int minDistance = INT_MAX;
auto minDistance = til::CoordTypeMax;
for (const auto& mark : marks)
{
const auto delta = mark.start.y - currentOffset;
@@ -2648,7 +2648,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
case ScrollToMarkDirection::Previous:
default:
{
int minDistance = INT_MAX;
auto minDistance = til::CoordTypeMax;
for (const auto& mark : marks)
{
const auto delta = currentOffset - mark.start.y;
@@ -2662,29 +2662,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
const auto viewHeight = ViewHeight();
const auto bufferSize = BufferHeight();
const auto scrollOffsetX = ScrollOffset().X;
const auto viewHeight = ViewSize().Y;
const auto bufferSize = BufferSize().Y;
// UserScrollViewport, to update the Terminal about where the viewport should be
// then raise a _terminalScrollPositionChanged to inform the control to update the scrollbar.
if (tgt.has_value())
til::CoordType y = 0;
if (tgt)
{
UserScrollViewport(tgt->start.y);
_terminalScrollPositionChanged(tgt->start.y, viewHeight, bufferSize);
y = tgt->start.y;
}
else
else if (direction == ScrollToMarkDirection::Last || direction == ScrollToMarkDirection::Next)
{
if (direction == ScrollToMarkDirection::Last || direction == ScrollToMarkDirection::Next)
{
UserScrollViewport(BufferHeight());
_terminalScrollPositionChanged(BufferHeight(), viewHeight, bufferSize);
}
else if (direction == ScrollToMarkDirection::First || direction == ScrollToMarkDirection::Previous)
{
UserScrollViewport(0);
_terminalScrollPositionChanged(0, viewHeight, bufferSize);
}
y = bufferSize;
}
UserScrollViewport({ scrollOffsetX, y });
_terminalScrollPositionChanged(y, viewHeight, bufferSize);
}
void ControlCore::_terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength)

View File

@@ -170,9 +170,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TerminalConnection::ConnectionState ConnectionState() const;
int ScrollOffset();
int ViewHeight() const;
int BufferHeight() const;
Core::Point ScrollOffset() const;
Core::Point ViewSize() const;
Core::Point BufferSize() const;
bool HasSelection() const;
bool HasMultiLineSelection() const;
@@ -208,7 +208,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const ::Microsoft::Terminal::Core::ControlKeyStates states,
const short wheelDelta,
const ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state);
void UserScrollViewport(const int viewTop);
void UserScrollViewport(const til::point viewTop);
void ClearBuffer(Control::ClearBufferType clearType);

View File

@@ -403,8 +403,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ControlInteractivity::TouchMoved(const winrt::Windows::Foundation::Point newTouchPoint,
const bool focused)
{
if (focused &&
_touchAnchor)
if (focused && _touchAnchor)
{
const auto anchor = _touchAnchor.value();
@@ -413,23 +412,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto fontSizeInDips{ _core->FontSizeInDips() };
// Get the difference between the point we've dragged to and the start of the touch.
const auto dy = static_cast<float>(newTouchPoint.Y - anchor.Y);
const auto dx = newTouchPoint.X - anchor.X;
const auto dy = newTouchPoint.Y - anchor.Y;
// Start viewport scroll after we've moved more than a half row of text
if (std::abs(dy) > (fontSizeInDips.Height / 2.0f))
// Start viewport scroll after we've moved more than a half row/col of text
if (std::abs(dx) > (fontSizeInDips.Width * 0.5f) || std::abs(dy) > (fontSizeInDips.Height * 0.5f))
{
const auto currentOffset = _core->ScrollOffset();
// Multiply by -1, because moving the touch point down will
// create a positive delta, but we want the viewport to move up,
// so we'll need a negative scroll amount (and the inverse for
// panning down)
const auto numRows = dy / -fontSizeInDips.Height;
const auto currentOffset = _core->ScrollOffset();
const auto newValue = numRows + currentOffset;
const auto x = (dx / -fontSizeInDips.Width) + currentOffset.X;
const auto y = (dy / -fontSizeInDips.Height) + currentOffset.Y;
// Update the Core's viewport position, and raise a
// ScrollPositionChanged event to update the scrollbar
UpdateScrollbar(newValue);
UpdateScrollbar({ x, y });
// Use this point as our new scroll anchor.
_touchAnchor = newTouchPoint;
@@ -574,11 +574,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// underneath us. We wouldn't know - we don't want the overhead of
// another ScrollPositionChanged handler. If the scrollbar should be
// somewhere other than where it is currently, then start from that row.
const auto currentInternalRow = std::lround(_internalScrollbarPosition);
const auto currentInternalRow = std::lround(_internalScrollbarPosition.Y);
const auto currentCoreRow = _core->ScrollOffset();
const auto currentOffset = currentInternalRow == currentCoreRow ?
_internalScrollbarPosition :
currentCoreRow;
const auto currentOffset = currentInternalRow == currentCoreRow.Y ? _internalScrollbarPosition.Y : currentCoreRow.Y;
// negative = down, positive = up
// However, for us, the signs are flipped.
@@ -589,12 +587,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// WHEEL_PAGESCROLL is a Win32 constant that represents the "scroll one page
// at a time" setting. If we ignore it, we will scroll a truly absurd number
// of rows.
const auto rowsToScroll{ _rowsToScroll == WHEEL_PAGESCROLL ? _core->ViewHeight() : _rowsToScroll };
const auto rowsToScroll{ _rowsToScroll == WHEEL_PAGESCROLL ? _core->ViewSize().Y : _rowsToScroll };
const auto newValue = rowsToScroll * rowDelta + currentOffset;
// Update the Core's viewport position, and raise a
// ScrollPositionChanged event to update the scrollbar
UpdateScrollbar(newValue);
UpdateScrollbar({ static_cast<float>(currentCoreRow.X), newValue });
if (isLeftButtonPressed)
{
@@ -620,26 +618,38 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - newValue: The new top of the viewport
// Return Value:
// - <none>
void ControlInteractivity::UpdateScrollbar(const float newValue)
void ControlInteractivity::UpdateScrollbar(winrt::Windows::Foundation::Point newValue)
{
const auto bufferSize = _core->BufferSize();
const auto scrollOffsetBefore = til::point{ _core->ScrollOffset() };
// Set this as the new value of our internal scrollbar representation.
// We're doing this so we can accumulate fractional amounts of a row to
// scroll each time the mouse scrolls.
_internalScrollbarPosition = std::clamp(newValue, 0.0f, static_cast<float>(_core->BufferHeight()));
_internalScrollbarPosition.X = std::clamp(newValue.X, 0.0f, static_cast<float>(bufferSize.X));
_internalScrollbarPosition.Y = std::clamp(newValue.Y, 0.0f, static_cast<float>(bufferSize.Y));
// If the new scrollbar position, rounded to an int, is at a different
// row, then actually update the scroll position in the core, and raise
// a ScrollPositionChanged to inform the control.
const auto viewTop = std::lround(_internalScrollbarPosition);
if (viewTop != _core->ScrollOffset())
{
_core->UserScrollViewport(viewTop);
const til::point scrollOffset{
std::lround(_internalScrollbarPosition.X),
std::lround(_internalScrollbarPosition.Y),
};
// _core->ScrollOffset() is now set to newValue
ScrollPositionChanged.raise(*this,
winrt::make<ScrollPositionChangedArgs>(_core->ScrollOffset(),
_core->ViewHeight(),
_core->BufferHeight()));
if (scrollOffset != scrollOffsetBefore)
{
_core->UserScrollViewport(scrollOffset);
if (scrollOffset.y != scrollOffsetBefore.y)
{
ScrollPositionChanged.raise(
*this,
winrt::make<ScrollPositionChangedArgs>(
scrollOffset.y,
_core->ViewSize().Y,
bufferSize.Y));
}
}
}
@@ -706,16 +716,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return pixelPosition / fontSize;
}
bool ControlInteractivity::_sendMouseEventHelper(const til::point terminalPosition,
bool ControlInteractivity::_sendMouseEventHelper(til::point terminalPosition,
const unsigned int pointerUpdateKind,
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
const SHORT wheelDelta,
Control::MouseButtonState buttonState)
{
const auto adjustment = _core->BufferHeight() - _core->ScrollOffset() - _core->ViewHeight();
// If the click happened outside the active region, core should get a chance to filter it out or clamp it.
const auto adjustedY = terminalPosition.y - adjustment;
return _core->SendMouseEvent({ terminalPosition.x, adjustedY }, pointerUpdateKind, modifiers, wheelDelta, toInternalMouseState(buttonState));
terminalPosition -= til::point{ _core->BufferSize() };
terminalPosition += til::point{ _core->ScrollOffset() };
terminalPosition += til::point{ _core->ViewSize() };
return _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, wheelDelta, toInternalMouseState(buttonState));
}
// Method Description:

View File

@@ -78,7 +78,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const Core::Point pixelPosition,
const Control::MouseButtonState state);
void UpdateScrollbar(const float newValue);
void UpdateScrollbar(winrt::Windows::Foundation::Point newValue);
#pragma endregion
@@ -111,7 +111,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
winrt::com_ptr<ControlCore> _core{ nullptr };
UINT _rowsToScroll = 3;
float _internalScrollbarPosition = 0;
winrt::Windows::Foundation::Point _internalScrollbarPosition{};
// If this is set, then we assume we are in the middle of panning the
// viewport via touch input.

View File

@@ -64,7 +64,7 @@ namespace Microsoft.Terminal.Control
Microsoft.Terminal.Core.Point pixelPosition,
MouseButtonState state);
void UpdateScrollbar(Single newValue);
void UpdateScrollbar(Windows.Foundation.Point newValue);
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> ScrollPositionChanged;

View File

@@ -301,7 +301,7 @@ HRESULT HwndTerminal::Initialize()
_renderEngine = std::move(engine);
_terminal->Create({ 80, 25 }, 9001, *_renderer);
_terminal->Create({ 80, 25 }, 0, 9001, *_renderer);
_terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
_terminal->SetCopyToClipboardCallback([=](wil::zwstring_view text) noexcept { _CopyTextToSystemClipboard(text, {}, {}); });
_renderer->EnablePainting();
@@ -592,7 +592,8 @@ try
if (const auto publicTerminal = static_cast<const HwndTerminal*>(terminal); publicTerminal && publicTerminal->_terminal)
{
const auto lock = publicTerminal->_terminal->LockForWriting();
publicTerminal->_terminal->UserScrollViewport(viewTop);
const auto current = publicTerminal->_terminal->GetScrollOffset();
publicTerminal->_terminal->UserScrollViewport({ current.x, viewTop });
}
}
CATCH_LOG()
@@ -962,7 +963,7 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
for (size_t tableIndex = 0; tableIndex < 16; tableIndex++)
{
// It's using gsl::at to check the index is in bounds, but the analyzer still calls this array-to-pointer-decay
GSL_SUPPRESS(bounds .3)
GSL_SUPPRESS(bounds.3)
renderSettings.SetColorTableEntry(tableIndex, gsl::at(theme.ColorTable, tableIndex));
}
@@ -1185,7 +1186,7 @@ void HwndTerminal::ChangeViewport(const til::inclusive_rect& NewWindow)
return;
}
const auto lock = _terminal->LockForWriting();
_terminal->UserScrollViewport(NewWindow.top);
_terminal->UserScrollViewport({ NewWindow.left, NewWindow.top });
}
HRESULT HwndTerminal::GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept

View File

@@ -38,9 +38,9 @@ namespace Microsoft.Terminal.Control
Windows.Foundation.IReference<Windows.UI.Color> TabColor { get; };
Int32 ScrollOffset { get; };
Int32 ViewHeight { get; };
Int32 BufferHeight { get; };
Microsoft.Terminal.Core.Point ScrollOffset { get; };
Microsoft.Terminal.Core.Point ViewSize { get; };
Microsoft.Terminal.Core.Point BufferSize { get; };
Boolean HasSelection { get; };
Boolean HasMultiLineSelection { get; };

View File

@@ -176,7 +176,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void InteractivityAutomationPeer::ChangeViewport(const til::inclusive_rect& NewWindow)
{
_interactivity->UpdateScrollbar(static_cast<float>(NewWindow.top));
_interactivity->UpdateScrollbar({ static_cast<float>(NewWindow.left), static_cast<float>(NewWindow.top) });
}
#pragma endregion

View File

@@ -549,7 +549,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_isInternalScrollBarUpdate = true;
auto scrollBar = ScrollBar();
auto scrollBar = VerticalScrollBar();
if (update.newValue)
{
scrollBar.Value(*update.newValue);
@@ -612,7 +612,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto pipHeight = lround(1 * scaleFactor);
const auto maxOffsetY = drawableRange - pipHeight;
const auto offsetScale = maxOffsetY / gsl::narrow_cast<float>(update.newMaximum + update.newViewportSize);
const auto offsetScale = maxOffsetY / static_cast<float>(update.newMaximum + update.newViewportSize);
// A helper to turn a TextBuffer row offset into a bitmap offset.
const auto dataAt = [&](til::CoordType row) [[msvc::forceinline]] {
const auto y = std::clamp<long>(lrintf(row * offsetScale), 0, maxOffsetY);
@@ -798,7 +798,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Clear search highlights scroll marks (by triggering an update after closing the search box)
if (_showMarksInScrollbar)
{
const auto scrollBar = ScrollBar();
const auto scrollBar = VerticalScrollBar();
ScrollBarUpdate update{
.newValue = scrollBar.Value(),
.newMaximum = scrollBar.Maximum(),
@@ -940,19 +940,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
SwapChainPanel().Margin(newMargin);
// Apply settings for scrollbar
auto indicatorMode = Controls::Primitives::ScrollingIndicatorMode::MouseIndicator;
auto visibility = Visibility::Visible;
if (settings.ScrollState() == ScrollbarState::Hidden)
{
// In the scenario where the user has turned off the OS setting to automatically hide scrollbars, the
// Terminal scrollbar would still be visible; so, we need to set the control's visibility accordingly to
// achieve the intended effect.
ScrollBar().IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::None);
ScrollBar().Visibility(Visibility::Collapsed);
indicatorMode = Controls::Primitives::ScrollingIndicatorMode::None;
visibility = Visibility::Collapsed;
}
else // (default or Visible)
for (auto&& scrollbar : { HorizontalScrollBar(), VerticalScrollBar() })
{
// Default behavior
ScrollBar().IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::MouseIndicator);
ScrollBar().Visibility(Visibility::Visible);
scrollbar.IndicatorMode(indicatorMode);
scrollbar.Visibility(visibility);
}
_interactivity.UpdateSettings();
@@ -1396,13 +1397,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_core.EnablePainting();
auto bufferHeight = _core.BufferHeight();
{
const auto bufferSize = _core.ViewSize();
ScrollBar().Maximum(0);
ScrollBar().Minimum(0);
ScrollBar().Value(0);
ScrollBar().ViewportSize(bufferHeight);
ScrollBar().LargeChange(bufferHeight); // scroll one "screenful" at a time when the scroll bar is clicked
const auto hori = HorizontalScrollBar();
hori.Maximum(400);
hori.Minimum(0);
hori.Value(0);
hori.ViewportSize(bufferSize.X);
hori.LargeChange(bufferSize.X);
const auto vert = VerticalScrollBar();
vert.Maximum(0);
vert.Minimum(0);
vert.Value(0);
vert.ViewportSize(bufferSize.Y);
vert.LargeChange(bufferSize.Y); // scroll one "screenful" at a time when the scroll bar is clicked
}
// Set up blinking cursor
int blinkTime = GetCaretBlinkTime();
@@ -2243,8 +2254,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_core.AdjustFontSize(fontSizeDelta);
}
void TermControl::_ScrollbarChangeHandler(const Windows::Foundation::IInspectable& /*sender*/,
const Controls::Primitives::RangeBaseValueChangedEventArgs& args)
void TermControl::_HorizontalScrollBarChangeHandler(const Windows::Foundation::IInspectable& /*sender*/,
const Controls::Primitives::RangeBaseValueChangedEventArgs& args)
{
if (_isInternalScrollBarUpdate || _IsClosing())
{
@@ -2255,7 +2266,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
const auto newValue = args.NewValue();
_interactivity.UpdateScrollbar(static_cast<float>(newValue));
const auto scrollOffset = _core.ScrollOffset();
_interactivity.UpdateScrollbar({ static_cast<float>(newValue), static_cast<float>(scrollOffset.Y) });
}
void TermControl::_VerticalScrollBarChangeHandler(const Windows::Foundation::IInspectable& /*sender*/,
const Controls::Primitives::RangeBaseValueChangedEventArgs& args)
{
if (_isInternalScrollBarUpdate || _IsClosing())
{
// The update comes from ourselves, more specifically from the
// terminal. So we don't have to update the terminal because it
// already knows.
return;
}
const auto newValue = args.NewValue();
const auto scrollOffset = _core.ScrollOffset();
_interactivity.UpdateScrollbar({ static_cast<float>(scrollOffset.X), static_cast<float>(newValue) });
// User input takes priority over terminal events so cancel
// any pending scroll bar update if the user scrolls.
@@ -2366,9 +2394,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
if (_lastAutoScrollUpdateTime)
{
static constexpr auto microSecPerSec = 1000000.0;
const auto deltaTime = std::chrono::duration_cast<std::chrono::microseconds>(timeNow - *_lastAutoScrollUpdateTime).count() / microSecPerSec;
ScrollBar().Value(ScrollBar().Value() + _autoScrollVelocity * deltaTime);
const auto deltaTime = std::chrono::duration<double>(timeNow - *_lastAutoScrollUpdateTime).count();
VerticalScrollBar().Value(VerticalScrollBar().Value() + _autoScrollVelocity * deltaTime);
if (_autoScrollingPointerPoint)
{
@@ -2764,10 +2791,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - viewTop: the viewTop to scroll to
void TermControl::ScrollViewport(int viewTop)
{
ScrollBar().Value(viewTop);
VerticalScrollBar().Value(viewTop);
}
int TermControl::ScrollOffset() const
Core::Point TermControl::ScrollOffset() const
{
return _core.ScrollOffset();
}
@@ -2776,14 +2803,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - Gets the height of the terminal in lines of text
// Return Value:
// - The height of the terminal in lines of text
int TermControl::ViewHeight() const
Core::Point TermControl::ViewSize() const
{
return _core.ViewHeight();
return _core.ViewSize();
}
int TermControl::BufferHeight() const
Core::Point TermControl::BufferSize() const
{
return _core.BufferHeight();
return _core.BufferSize();
}
// Function Description:
@@ -2964,10 +2991,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto fontSize = _core.FontSizeInDips();
auto width = fontSize.Width;
auto height = fontSize.Height;
// Reserve additional space if scrollbar is intended to be visible
if (_core.Settings().ScrollState() != ScrollbarState::Hidden)
{
width += static_cast<float>(ScrollBar().ActualWidth());
width += static_cast<float>(VerticalScrollBar().ActualWidth());
height += static_cast<float>(HorizontalScrollBar().ActualHeight());
}
// Account for the size of any padding
@@ -2999,13 +3028,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto fontDimension = widthOrHeight ? fontSize.Width : fontSize.Height;
const auto padding = GetPadding();
auto nonTerminalArea = gsl::narrow_cast<float>(widthOrHeight ?
padding.Left + padding.Right :
padding.Top + padding.Bottom);
auto nonTerminalArea = static_cast<float>(widthOrHeight ?
padding.Left + padding.Right :
padding.Top + padding.Bottom);
if (widthOrHeight && _core.Settings().ScrollState() != ScrollbarState::Hidden)
if (_core.Settings().ScrollState() != ScrollbarState::Hidden)
{
nonTerminalArea += gsl::narrow_cast<float>(ScrollBar().ActualWidth());
const auto scrollbar = widthOrHeight ? VerticalScrollBar() : HorizontalScrollBar();
nonTerminalArea += static_cast<float>(scrollbar.ActualWidth());
}
const auto gridSize = dimension - nonTerminalArea;
@@ -3643,7 +3673,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto selectionAnchor{ movingEnd ? markerData.EndPos : markerData.StartPos };
const auto& marker{ movingEnd ? SelectionEndMarker() : SelectionStartMarker() };
const auto& otherMarker{ movingEnd ? SelectionStartMarker() : SelectionEndMarker() };
if (selectionAnchor.Y < 0 || selectionAnchor.Y >= _core.ViewHeight())
if (selectionAnchor.Y < 0 || selectionAnchor.Y >= _core.ViewSize().Y)
{
// if the endpoint is outside of the viewport,
// just hide the markers
@@ -3869,7 +3899,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
if (_showMarksInScrollbar)
{
const auto scrollBar = ScrollBar();
const auto scrollBar = VerticalScrollBar();
ScrollBarUpdate update{
.newValue = scrollBar.Value(),
.newMaximum = scrollBar.Maximum(),

View File

@@ -94,9 +94,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TerminalConnection::ConnectionState ConnectionState() const;
int ScrollOffset() const;
int ViewHeight() const;
int BufferHeight() const;
Core::Point ScrollOffset() const;
Core::Point ViewSize() const;
Core::Point BufferSize() const;
bool HasSelection() const;
bool HasMultiLineSelection() const;
@@ -371,7 +371,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _PointerReleasedHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
void _PointerExitedHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
void _MouseWheelHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
void _ScrollbarChangeHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs& e);
void _HorizontalScrollBarChangeHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs& e);
void _VerticalScrollBarChangeHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs& e);
void _QuickFixButton_PointerEntered(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
void _QuickFixButton_PointerExited(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);

View File

@@ -94,17 +94,17 @@
12dips. This is harder for folks to hit with the mouse, and isn't
consistent with the rest of the scrollbars on the platform (as much
as they can be).
To work around this, we have to entirely copy the template for the
ScrollBar into our XAML file. We're then also re-defining
ScrollBarSize here to 16, so that the new template will pick up on
the new value.
This is kinda a pain, and we have to be careful to be sure to ingest
an updated version of the template any time we update MUX. The
latest ControlsV2 version of the template can be found at:
https://github.com/microsoft/microsoft-ui-xaml/blob/main/dev/CommonStyles/ScrollBar_themeresources.xaml#L218
Additionally we have:
* removed the corner radius, because that should be flush
with the top of the window above the TermControl.
@@ -113,7 +113,7 @@
the Win11-style WinUI ScrollView. If you also have the "Always show scrollbars" setting enabled in
the settings app (do it if you haven't already), it avoids any and all animations during startup which
makes the app start feel noticeably better and also shaves off another ~167ms of our "busy time".
We're also planning on making this adjustable in the future
(GH#9218), where we might need this anyways.
-->
@@ -1338,7 +1338,19 @@
SearchChanged="_SearchChanged" />
</Grid>
<ScrollBar x:Name="ScrollBar"
<ScrollBar x:Name="HorizontalScrollBar"
VerticalAlignment="Bottom"
IndicatorMode="MouseIndicator"
IsTabStop="False"
LargeChange="4"
Maximum="1"
Orientation="Horizontal"
SmallChange="1"
Style="{StaticResource ForkedScrollbarTemplate}"
ValueChanged="_HorizontalScrollBarChangeHandler"
ViewportSize="10" />
<ScrollBar x:Name="VerticalScrollBar"
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
@@ -1347,11 +1359,9 @@
LargeChange="4"
Maximum="1"
Orientation="Vertical"
PointerPressed="_CapturePointer"
PointerReleased="_ReleasePointerCapture"
SmallChange="1"
Style="{StaticResource ForkedScrollbarTemplate}"
ValueChanged="_ScrollbarChangeHandler"
ValueChanged="_VerticalScrollBarChangeHandler"
ViewportSize="10" />
<Image x:Name="ScrollBarCanvas"

View File

@@ -7,6 +7,7 @@ namespace Microsoft.Terminal.Core
{
interface ICoreSettings requires ICoreAppearance
{
Int32 MinimumBufferWidth;
// TODO:MSFT:20642297 - define a sentinel for Infinite Scrollback
Int32 HistorySize;
Int32 InitialRows;

View File

@@ -1,33 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "ControlKeyStates.hpp"
namespace Microsoft::Terminal::Core
{
class ITerminalInput
{
public:
virtual ~ITerminalInput() {}
ITerminalInput(const ITerminalInput&) = default;
ITerminalInput(ITerminalInput&&) = default;
ITerminalInput& operator=(const ITerminalInput&) = default;
ITerminalInput& operator=(ITerminalInput&&) = default;
[[nodiscard]] virtual ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0;
[[nodiscard]] virtual ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
[[nodiscard]] virtual ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
[[nodiscard]] virtual ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType FocusChanged(const bool focused) = 0;
[[nodiscard]] virtual HRESULT UserResize(const til::size size) noexcept = 0;
virtual void UserScrollViewport(const int viewTop) = 0;
virtual int GetScrollOffset() = 0;
virtual void TrySnapOnInput() = 0;
protected:
ITerminalInput() = default;
};
}

View File

@@ -40,12 +40,23 @@ Terminal::Terminal(TestDummyMarker) :
#endif
}
void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Renderer& renderer)
void Terminal::Create(
til::size viewportSize,
til::CoordType minimumBufferWidth,
til::CoordType scrollbackLines,
Renderer& renderer)
{
viewportSize.width = Utils::ClampToShortMax(viewportSize.width, 1);
viewportSize.height = Utils::ClampToShortMax(viewportSize.height, 1);
_minimumBufferWidth = Utils::ClampToShortMax(minimumBufferWidth, 0);
_scrollbackLines = Utils::ClampToShortMax(scrollbackLines, 1);
_mutableViewport = Viewport::FromDimensions({ 0, 0 }, viewportSize);
_scrollbackLines = scrollbackLines;
const til::size bufferSize{ viewportSize.width,
Utils::ClampToShortMax(viewportSize.height + scrollbackLines, 1) };
const til::size bufferSize{
std::max(viewportSize.width, _minimumBufferWidth),
Utils::ClampToShortMax(viewportSize.height + _scrollbackLines, 1),
};
const TextAttribute attr{};
const UINT cursorSize = 12;
_mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, &renderer);
@@ -63,11 +74,11 @@ void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Re
void Terminal::CreateFromSettings(ICoreSettings settings,
Renderer& renderer)
{
const til::size viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
Utils::ClampToShortMax(settings.InitialRows(), 1) };
// TODO:MSFT:20642297 - Support infinite scrollback here, if HistorySize is -1
Create(viewportSize, Utils::ClampToShortMax(settings.HistorySize(), 0), renderer);
const til::size viewportSize{
settings.InitialCols(),
settings.InitialRows(),
};
Create(viewportSize, settings.MinimumBufferWidth(), settings.HistorySize(), renderer);
UpdateSettings(settings);
}
@@ -285,12 +296,14 @@ try
return S_OK;
}
const auto newBufferHeight = std::clamp(viewportSize.height + _scrollbackLines, 1, SHRT_MAX);
const til::size bufferSize{ viewportSize.width, newBufferHeight };
const til::size bufferSize{
std::max(viewportSize.width, _minimumBufferWidth),
Utils::ClampToShortMax(viewportSize.height + _scrollbackLines, 1),
};
// If the original buffer had _no_ scroll offset, then we should be at the
// bottom in the new buffer as well. Track that case now.
const auto originalOffsetWasZero = _scrollOffset == 0;
const auto originalOffsetWasZero = _scrollOffset.y == 0;
// GH#3848 - We'll initialize the new buffer with the default attributes,
// but after the resize, we'll want to make sure that the new buffer's
@@ -434,7 +447,7 @@ try
// If the old scrolloffset was 0, then we weren't scrolled back at all
// before, and shouldn't be now either.
_scrollOffset = originalOffsetWasZero ? 0 : static_cast<int>(::base::ClampSub(_mutableViewport.Top(), newVisibleTop));
_scrollOffset.y = originalOffsetWasZero ? 0 : static_cast<int>(::base::ClampSub(_mutableViewport.Top(), newVisibleTop));
_mainBuffer->TriggerRedrawAll();
_NotifyScrollEvent();
@@ -457,9 +470,9 @@ void Terminal::Write(std::wstring_view stringView)
// - <none>
void Terminal::TrySnapOnInput()
{
if (_snapOnInput && _scrollOffset != 0)
if (_snapOnInput && _scrollOffset.y != 0)
{
_scrollOffset = 0;
_scrollOffset.y = 0;
_NotifyScrollEvent();
}
}
@@ -993,18 +1006,18 @@ Viewport Terminal::_GetMutableViewport() const noexcept
_mutableViewport;
}
til::CoordType Terminal::GetBufferHeight() const noexcept
til::size Terminal::GetBufferSize() const noexcept
{
return _GetMutableViewport().BottomExclusive();
return _GetMutableViewport().BottomRightExclusive().to_size();
}
// ViewStartIndex is also the length of the scrollback
int Terminal::ViewStartIndex() const noexcept
til::CoordType Terminal::ViewStartIndex() const noexcept
{
return _inAltBuffer() ? 0 : _mutableViewport.Top();
}
int Terminal::ViewEndIndex() const noexcept
til::CoordType Terminal::ViewEndIndex() const noexcept
{
return _inAltBuffer() ? _altBufferSize.height - 1 : _mutableViewport.BottomInclusive();
}
@@ -1034,14 +1047,14 @@ const TerminalInput& Terminal::_getTerminalInput() const noexcept
}
// _VisibleStartIndex is the first visible line of the buffer
int Terminal::_VisibleStartIndex() const noexcept
til::CoordType Terminal::_VisibleStartIndex() const noexcept
{
return _inAltBuffer() ? 0 : std::max(0, _mutableViewport.Top() - _scrollOffset);
return _inAltBuffer() ? 0 : std::max(0, _mutableViewport.Top() - _scrollOffset.y);
}
int Terminal::_VisibleEndIndex() const noexcept
til::CoordType Terminal::_VisibleEndIndex() const noexcept
{
return _inAltBuffer() ? _altBufferSize.height - 1 : std::max(0, _mutableViewport.BottomInclusive() - _scrollOffset);
return _inAltBuffer() ? _altBufferSize.height - 1 : std::max(0, _mutableViewport.BottomInclusive() - _scrollOffset.y);
}
Viewport Terminal::_GetVisibleViewport() const noexcept
@@ -1049,27 +1062,25 @@ Viewport Terminal::_GetVisibleViewport() const noexcept
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
// viewport's size hasn't been updated yet. In that case, use the
// temporarily stashed _altBufferSize instead.
const til::point origin{ 0, _VisibleStartIndex() };
const auto size{ _inAltBuffer() ? _altBufferSize :
_mutableViewport.Dimensions() };
return Viewport::FromDimensions(origin,
size);
const til::point origin{ _scrollOffset.x, _VisibleStartIndex() };
const auto size{ _inAltBuffer() ? _altBufferSize : _mutableViewport.Dimensions() };
return Viewport::FromDimensions(origin, size);
}
void Terminal::_PreserveUserScrollOffset(const int viewportDelta) noexcept
void Terminal::_PreserveUserScrollOffset(const til::CoordType viewportDelta) noexcept
{
// When the mutable viewport is moved down, and there's an active selection,
// or the visible viewport isn't already at the bottom, then we want to keep
// the visible viewport where it is. To do this, we adjust the scroll offset
// by the same amount that we've just moved down.
if (viewportDelta > 0 && (IsSelectionActive() || _scrollOffset != 0))
if (viewportDelta > 0 && (IsSelectionActive() || _scrollOffset.y != 0))
{
const auto maxScrollOffset = _activeBuffer().GetSize().Height() - _mutableViewport.Height();
_scrollOffset = std::min(_scrollOffset + viewportDelta, maxScrollOffset);
_scrollOffset.y = std::min(_scrollOffset.y + viewportDelta, maxScrollOffset);
}
}
void Terminal::UserScrollViewport(const int viewTop)
void Terminal::UserScrollViewport(const til::point viewTop)
{
// Clear the regex pattern tree so the renderer does not try to render them while scrolling
_clearPatternTree();
@@ -1079,12 +1090,10 @@ void Terminal::UserScrollViewport(const int viewTop)
return;
}
const auto clampedNewTop = std::max(0, viewTop);
const auto realTop = ViewStartIndex();
const auto newDelta = realTop - clampedNewTop;
// if viewTop > realTop, we want the offset to be 0.
_scrollOffset = std::max(0, newDelta);
const auto origin = _inAltBuffer() ? til::point{} : _mutableViewport.Origin();
_scrollOffset.x = viewTop.x; // TODO: All of this is wrong and broken
_scrollOffset.y = std::max(0, origin.y - std::max(0, viewTop.y));
// We can use the void variant of TriggerScroll here because
// we adjusted the viewport so it can detect the difference
@@ -1092,9 +1101,16 @@ void Terminal::UserScrollViewport(const int viewTop)
_activeBuffer().TriggerScroll();
}
int Terminal::GetScrollOffset() noexcept
til::point Terminal::GetScrollOffset() noexcept
{
return _VisibleStartIndex();
if (_inAltBuffer())
{
return til::point{};
}
const auto x = std::max(0, _mutableViewport.Left() - _scrollOffset.x);
const auto y = std::max(0, _mutableViewport.Top() - _scrollOffset.y);
return { x, y };
}
void Terminal::_NotifyScrollEvent()
@@ -1107,7 +1123,7 @@ void Terminal::_NotifyScrollEvent()
const auto visible = _GetVisibleViewport();
const auto top = visible.Top();
const auto height = visible.Height();
const auto bottom = this->GetBufferHeight();
const auto bottom = GetBufferSize().height;
_pfnScrollPositionChanged(top, height, bottom);
}
}
@@ -1634,7 +1650,7 @@ til::point Terminal::GetViewportRelativeCursorPosition() const noexcept
const auto absoluteCursorPosition{ GetCursorPosition() };
const auto mutableViewport{ _GetMutableViewport() };
const auto relativeCursorPos = absoluteCursorPosition - mutableViewport.Origin();
return { relativeCursorPos.x, relativeCursorPos.y + _scrollOffset };
return { relativeCursorPos.x + _scrollOffset.x, relativeCursorPos.y + _scrollOffset.y };
}
void Terminal::PreviewText(std::wstring_view input)

View File

@@ -5,15 +5,14 @@
#include <conattrs.hpp>
#include "../../inc/DefaultSettings.h"
#include "../../buffer/out/textBuffer.hpp"
#include "../../cascadia/terminalcore/ControlKeyStates.hpp"
#include "../../inc/DefaultSettings.h"
#include "../../renderer/inc/IRenderData.hpp"
#include "../../terminal/adapter/ITerminalApi.hpp"
#include "../../terminal/parser/StateMachine.hpp"
#include "../../terminal/input/terminalInput.hpp"
#include "../../terminal/parser/StateMachine.hpp"
#include "../../types/inc/Viewport.hpp"
#include "../../types/inc/GlyphWidth.hpp"
#include "../../cascadia/terminalcore/ITerminalInput.hpp"
#include <til/generational.h>
#include <til/ticket_lock.h>
@@ -54,7 +53,6 @@ namespace TerminalCoreUnitTests
class Microsoft::Terminal::Core::Terminal final :
public Microsoft::Console::VirtualTerminal::ITerminalApi,
public Microsoft::Terminal::Core::ITerminalInput,
public Microsoft::Console::Render::IRenderData
{
using RenderSettings = Microsoft::Console::Render::RenderSettings;
@@ -83,9 +81,11 @@ public:
Terminal();
Terminal(TestDummyMarker);
void Create(til::size viewportSize,
til::CoordType scrollbackLines,
Microsoft::Console::Render::Renderer& renderer);
void Create(
til::size viewportSize,
til::CoordType minimumBufferWidth,
til::CoordType scrollbackLines,
Microsoft::Console::Render::Renderer& renderer);
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
Microsoft::Console::Render::Renderer& renderer);
@@ -110,10 +110,10 @@ public:
[[nodiscard]] std::unique_lock<til::recursive_ticket_lock> LockForWriting() noexcept;
til::recursive_ticket_lock_suspension SuspendLock() noexcept;
til::CoordType GetBufferHeight() const noexcept;
til::size GetBufferSize() const noexcept;
int ViewStartIndex() const noexcept;
int ViewEndIndex() const noexcept;
til::CoordType ViewStartIndex() const noexcept;
til::CoordType ViewEndIndex() const noexcept;
RenderSettings& GetRenderSettings() noexcept;
const RenderSettings& GetRenderSettings() const noexcept;
@@ -170,16 +170,16 @@ public:
#pragma region ITerminalInput
// These methods are defined in Terminal.cpp
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType FocusChanged(const bool focused) override;
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown);
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state);
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states);
[[nodiscard]] ::Microsoft::Console::VirtualTerminal::TerminalInput::OutputType FocusChanged(const bool focused);
[[nodiscard]] HRESULT UserResize(const til::size viewportSize) noexcept override;
void UserScrollViewport(const int viewTop) override;
int GetScrollOffset() noexcept override;
[[nodiscard]] HRESULT UserResize(const til::size viewportSize) noexcept;
void UserScrollViewport(const til::point viewTop);
til::point GetScrollOffset() noexcept;
void TrySnapOnInput() override;
void TrySnapOnInput();
bool IsTrackingMouseInput() const noexcept;
bool ShouldSendAlternateScroll(const unsigned int uiButton, const int32_t delta) const noexcept;
@@ -414,6 +414,7 @@ private:
std::unique_ptr<TextBuffer> _mainBuffer;
std::unique_ptr<TextBuffer> _altBuffer;
Microsoft::Console::Types::Viewport _mutableViewport;
til::CoordType _minimumBufferWidth = 0;
til::CoordType _scrollbackLines = 0;
bool _detectURLs = false;
bool _clipboardOperationsAllowed = true;
@@ -423,7 +424,7 @@ private:
// _scrollOffset is the number of lines above the viewport that are currently visible
// If _scrollOffset is 0, then the visible region of the buffer is the viewport.
til::CoordType _scrollOffset = 0;
til::point _scrollOffset;
// TODO this might not be the value we want to store.
// We might want to store the height in the scrollback that's currently visible.
// Think on this some more.
@@ -461,13 +462,13 @@ private:
Console::VirtualTerminal::TerminalInput& _getTerminalInput() noexcept;
const Console::VirtualTerminal::TerminalInput& _getTerminalInput() const noexcept;
int _VisibleStartIndex() const noexcept;
int _VisibleEndIndex() const noexcept;
til::CoordType _VisibleStartIndex() const noexcept;
til::CoordType _VisibleEndIndex() const noexcept;
Microsoft::Console::Types::Viewport _GetMutableViewport() const noexcept;
Microsoft::Console::Types::Viewport _GetVisibleViewport() const noexcept;
void _PreserveUserScrollOffset(const int viewportDelta) noexcept;
void _PreserveUserScrollOffset(const til::CoordType viewportDelta) noexcept;
til::CoordType _ScrollToPoints(const til::point coordStart, const til::point coordEnd);
void _NotifyScrollEvent();

View File

@@ -1019,13 +1019,13 @@ void Terminal::_ScrollToPoint(const til::point pos)
if (const auto amtAboveView = visibleViewport.Top() - pos.y; amtAboveView > 0)
{
// anchor is above visible viewport, scroll by that amount
_scrollOffset += amtAboveView;
_scrollOffset.y += amtAboveView;
}
else
{
// anchor is below visible viewport, scroll by that amount
const auto amtBelowView = pos.y - visibleViewport.BottomInclusive();
_scrollOffset -= amtBelowView;
_scrollOffset.y -= amtBelowView;
}
_NotifyScrollEvent();
_activeBuffer().TriggerScroll();

View File

@@ -179,7 +179,7 @@ til::CoordType Terminal::_ScrollToPoints(const til::point coordStart, const til:
if (coordStart.y < _VisibleStartIndex())
{
// recalculate the scrollOffset
_scrollOffset = ViewStartIndex() - coordStart.y;
_scrollOffset.y = ViewStartIndex() - coordStart.y;
notifyScrollChange = true;
}
else if (coordEnd.y > _VisibleEndIndex())
@@ -188,7 +188,7 @@ til::CoordType Terminal::_ScrollToPoints(const til::point coordStart, const til:
// beneath the current visible viewport, it may be within the
// current mutableViewport and the scrollOffset will be smaller
// than 0
_scrollOffset = std::max(0, ViewStartIndex() - coordStart.y);
_scrollOffset.y = std::max(0, ViewStartIndex() - coordStart.y);
notifyScrollChange = true;
}

View File

@@ -720,7 +720,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
_MarkDuplicateBellSoundDirectories();
_CheckBellSoundsExistence();
_NotifyChanges(L"CurrentBellSounds");
}
@@ -732,19 +731,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
if (!_profile.HasBellSound())
{
std::vector<hstring> newSounds;
std::vector<IMediaResource> newSounds;
if (const auto inheritedSounds = _profile.BellSound())
{
// copy inherited bell sounds to the current layer
newSounds.reserve(inheritedSounds.Size());
for (const auto sound : inheritedSounds)
{
newSounds.push_back(sound);
}
newSounds = wil::to_vector(inheritedSounds);
}
// if we didn't inherit any bell sounds,
// we should still set the bell sound to an empty list (instead of null)
_profile.BellSound(winrt::single_threaded_vector<hstring>(std::move(newSounds)));
_profile.BellSound(winrt::single_threaded_vector(std::move(newSounds)));
}
}
@@ -768,56 +762,35 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
// Method Description:
// - Check if the bell sounds exist on disk. Mark any that don't exist
// so that they show the appropriate UI
safe_void_coroutine ProfileViewModel::_CheckBellSoundsExistence()
BellSoundViewModel::BellSoundViewModel(const Model::IMediaResource& resource) :
_resource{ resource }
{
co_await winrt::resume_background();
std::vector<Editor::BellSoundViewModel> markedSounds;
for (auto&& sound : _CurrentBellSounds)
if (_resource.Ok() && _resource.Path() != _resource.Resolved())
{
if (!std::filesystem::exists(std::wstring_view{ sound.Path() }))
{
markedSounds.push_back(sound);
}
// If the resource was resolved to something other than its path, show the path!
_ShowDirectory = true;
}
co_await winrt::resume_foreground(_dispatcher);
for (auto&& sound : markedSounds)
{
get_self<BellSoundViewModel>(sound)->FileExists(false);
}
}
BellSoundViewModel::BellSoundViewModel(hstring path) :
_Path{ path }
{
PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
if (args.PropertyName() == L"FileExists")
{
_NotifyChanges(L"DisplayPath", L"SubText");
}
});
}
hstring BellSoundViewModel::DisplayPath() const
{
if (_FileExists)
if (_resource.Ok())
{
// filename
const std::filesystem::path filePath{ std::wstring_view{ _Path } };
// filename; start from the resolved path to show where it actually landed
auto resolvedPath{ _resource.Resolved() };
const std::filesystem::path filePath{ std::wstring_view{ resolvedPath } };
return hstring{ filePath.filename().wstring() };
}
return _Path;
return _resource.Path();
}
hstring BellSoundViewModel::SubText() const
{
if (_FileExists)
if (_resource.Ok())
{
// Directory
const std::filesystem::path filePath{ std::wstring_view{ _Path } };
auto resolvedPath{ _resource.Resolved() };
const std::filesystem::path filePath{ std::wstring_view{ resolvedPath } };
return hstring{ filePath.parent_path().wstring() };
}
return RS_(L"Profile_BellSoundNotFound");
@@ -825,17 +798,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
hstring ProfileViewModel::BellSoundPreview()
{
const auto& currentSound = BellSound();
if (!currentSound || currentSound.Size() == 0)
if (!_CurrentBellSounds || _CurrentBellSounds.Size() == 0)
{
return RS_(L"Profile_BellSoundPreviewDefault");
}
else if (currentSound.Size() == 1)
if (_CurrentBellSounds.Size() > 1)
{
std::filesystem::path filePath{ std::wstring_view{ currentSound.GetAt(0) } };
return hstring{ filePath.filename().wstring() };
return RS_(L"Profile_BellSoundPreviewMultiple");
}
return RS_(L"Profile_BellSoundPreviewMultiple");
const auto currentBellSound = _CurrentBellSounds.GetAt(0);
if (currentBellSound.FileExists())
{
return currentBellSound.DisplayPath();
}
return RS_(L"Profile_BellSoundNotFound");
}
void ProfileViewModel::RequestAddBellSound(hstring path)
@@ -844,9 +822,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// copy it over to the current layer and apply modifications
_PrepareModelForBellSoundModification();
// No need to check if the file exists. We came from the FilePicker. That's good enough.
_CurrentBellSounds.Append(winrt::make<BellSoundViewModel>(path));
_profile.BellSound().Append(path);
auto bellResource{ MediaResourceHelper::FromString(path) };
bellResource.Resolve(path); // No need to check if the file exists. We came from the FilePicker. That's good enough.
_CurrentBellSounds.Append(winrt::make<BellSoundViewModel>(bellResource));
_profile.BellSound().Append(bellResource);
_NotifyChanges(L"CurrentBellSounds");
}

View File

@@ -30,13 +30,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
struct BellSoundViewModel : BellSoundViewModelT<BellSoundViewModel>, ViewModelHelper<BellSoundViewModel>
{
public:
BellSoundViewModel(hstring path);
BellSoundViewModel(const Model::IMediaResource& resource);
hstring Path() const { return _resource.Path(); }
bool FileExists() const { return _resource.Ok(); }
hstring DisplayPath() const;
hstring SubText() const;
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, FileExists, true);
VIEW_MODEL_OBSERVABLE_PROPERTY(hstring, Path);
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, ShowDirectory);
private:
Model::IMediaResource _resource;
};
struct ProfileViewModel : ProfileViewModelT<ProfileViewModel>, ViewModelHelper<ProfileViewModel>
@@ -149,6 +152,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
OBSERVABLE_PROJECTED_SETTING(_profile, AntialiasingMode);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Opacity);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), UseAcrylic);
OBSERVABLE_PROJECTED_SETTING(_profile, MinimumBufferWidth);
OBSERVABLE_PROJECTED_SETTING(_profile, HistorySize);
OBSERVABLE_PROJECTED_SETTING(_profile, SnapOnInput);
OBSERVABLE_PROJECTED_SETTING(_profile, AltGrAliasing);
@@ -190,7 +194,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void _InitializeCurrentBellSounds();
void _PrepareModelForBellSoundModification();
void _MarkDuplicateBellSoundDirectories();
safe_void_coroutine _CheckBellSoundsExistence();
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _MonospaceFontList;
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _FontList;
static Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> _BuiltInIcons;

View File

@@ -27,7 +27,7 @@ namespace Microsoft.Terminal.Settings.Editor
runtimeclass BellSoundViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String Path;
String Path { get; };
String DisplayPath { get; };
String SubText { get; };
Boolean ShowDirectory { get; };
@@ -145,11 +145,12 @@ namespace Microsoft.Terminal.Settings.Editor
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Commandline);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, StartingDirectory);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.TextAntialiasingMode, AntialiasingMode);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Int32, MinimumBufferWidth);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Int32, HistorySize);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SnapOnInput);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AltGrAliasing);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.BellStyle, BellStyle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.Collections.IVector<String>, BellSound);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.Collections.IVector<Microsoft.Terminal.Settings.Model.IMediaResource>, BellSound);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, Elevate);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ReloadEnvironmentVariables);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RightClickContextMenu);

View File

@@ -66,6 +66,19 @@
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- Minimum Buffer Width -->
<local:SettingContainer x:Uid="Profile_MinimumBufferWidth"
ClearSettingValue="{x:Bind Profile.ClearMinimumBufferWidth}"
HasSettingValue="{x:Bind Profile.HasMinimumBufferWidth, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.MinimumBufferWidthOverrideSource, Mode=OneWay}">
<muxc:NumberBox x:Uid="Profile_MinimumBufferWidthBox"
LargeChange="100"
Minimum="0"
SmallChange="10"
Style="{StaticResource NumberBoxSettingStyle}"
Value="{x:Bind Profile.MinimumBufferWidth, Mode=TwoWay}" />
</local:SettingContainer>
<!-- History Size -->
<local:SettingContainer x:Uid="Profile_HistorySize"
ClearSettingValue="{x:Bind Profile.ClearHistorySize}"

View File

@@ -1105,6 +1105,17 @@
<value>If enabled, the profile will open in an Admin terminal window automatically. If the current window is already running as admin, it will open in this window.</value>
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
</data>
<data name="Profile_MinimumBufferWidth.Header" xml:space="preserve">
<value>Minimum Buffer Width</value>
<comment>"Buffer Width" refers to the width of a terminal buffer (as opposed to the viewport width)</comment>
</data>
<data name="Profile_MinimumBufferWidthBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Minimum Buffer Width</value>
<comment>"Buffer Width" refers to the width of a terminal buffer (as opposed to the viewport width)</comment>
</data>
<data name="Profile_MinimumBufferWidth.HelpText" xml:space="preserve">
<value>The width of the backing text buffer. If it's wider than the viewport, a horizontal scrollbar is shown.</value>
</data>
<data name="Profile_HistorySize.Header" xml:space="preserve">
<value>History size</value>
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>

View File

@@ -79,6 +79,7 @@ Author(s):
// * IControlSettings.idl or ICoreSettings.idl
// * ControlProperties.h
#define MTSM_PROFILE_SETTINGS(X) \
X(int32_t, MinimumBufferWidth, "minimumBufferWidth", 0) \
X(int32_t, HistorySize, "historySize", DEFAULT_HISTORY_SIZE) \
X(bool, SnapOnInput, "snapOnInput", true) \
X(bool, AltGrAliasing, "altGrAliasing", true) \
@@ -95,7 +96,7 @@ Author(s):
X(Model::BellStyle, BellStyle, "bellStyle", BellStyle::Audible) \
X(IEnvironmentVariableMap, EnvironmentVariables, "environment", nullptr) \
X(bool, RightClickContextMenu, "rightClickContextMenu", false) \
X(Windows::Foundation::Collections::IVector<winrt::hstring>, BellSound, "bellSound", nullptr) \
X(Windows::Foundation::Collections::IVector<IMediaResource>, BellSound, "bellSound", nullptr) \
X(bool, Elevate, "elevate", false) \
X(bool, AutoMarkPrompts, "autoMarkPrompts", true) \
X(bool, ShowMarks, "showMarksOnScrollbar", false) \

View File

@@ -121,16 +121,10 @@ winrt::com_ptr<Profile> Profile::CopySettings() const
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_COPY)
#undef PROFILE_SETTINGS_COPY
// BellSound is an IVector<hstring>, so we need to manually copy it over
if (_BellSound)
{
std::vector<hstring> sounds;
sounds.reserve(_BellSound->Size());
for (const auto& sound : *_BellSound)
{
sounds.emplace_back(sound);
}
profile->_BellSound = single_threaded_vector(std::move(sounds));
// BellSound is an IVector<>, so we need to make a new vector pointing at the same objects
profile->_BellSound = winrt::single_threaded_vector(wil::to_vector(*_BellSound));
}
if (_UnfocusedAppearance)
@@ -560,6 +554,16 @@ void Profile::ResolveMediaResources(const Model::MediaResourceResolver& resolver
{
container->ResolveMediaResources(resolver);
}
if (const auto [bellSoundSource, bellSounds]{ _getBellSoundOverrideSourceAndValueImpl() };
bellSoundSource && bellSounds && *bellSounds && bellSounds->Size() > 0)
{
for (const auto& bellSound : *bellSounds)
{
ResolveMediaResource(bellSoundSource->_Origin, bellSoundSource->SourceBasePath, bellSound, resolver);
}
// It's important that we keep the invalid bell sounds in the list, because we may want to write it back out to disk
}
}
void Profile::LogSettingChanges(std::set<std::string>& changes, const std::string_view& context) const

View File

@@ -68,6 +68,7 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.TextAntialiasingMode, AntialiasingMode);
INHERITABLE_PROFILE_SETTING(Int32, MinimumBufferWidth);
INHERITABLE_PROFILE_SETTING(Int32, HistorySize);
INHERITABLE_PROFILE_SETTING(Boolean, SnapOnInput);
INHERITABLE_PROFILE_SETTING(Boolean, AltGrAliasing);
@@ -76,7 +77,7 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_PROFILE_SETTING(Windows.Foundation.Collections.IMap<String COMMA String>, EnvironmentVariables);
INHERITABLE_PROFILE_SETTING(Windows.Foundation.Collections.IVector<String>, BellSound);
INHERITABLE_PROFILE_SETTING(Windows.Foundation.Collections.IVector<IMediaResource>, BellSound);
INHERITABLE_PROFILE_SETTING(Boolean, Elevate);
INHERITABLE_PROFILE_SETTING(Boolean, AutoMarkPrompts);

View File

@@ -292,6 +292,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
void TerminalSettings::_ApplyProfileSettings(const Profile& profile)
{
// Fill in the Terminal Setting's CoreSettings from the profile
_MinimumBufferWidth = profile.MinimumBufferWidth();
_HistorySize = profile.HistorySize();
_SnapOnInput = profile.SnapOnInput();
_AltGrAliasing = profile.AltGrAliasing();

View File

@@ -80,6 +80,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
INHERITABLE_SETTING(Model::TerminalSettings, til::color, DefaultForeground, DEFAULT_FOREGROUND);
INHERITABLE_SETTING(Model::TerminalSettings, til::color, DefaultBackground, DEFAULT_BACKGROUND);
INHERITABLE_SETTING(Model::TerminalSettings, til::color, SelectionBackground, DEFAULT_FOREGROUND);
INHERITABLE_SETTING(Model::TerminalSettings, int32_t, MinimumBufferWidth, 0);
INHERITABLE_SETTING(Model::TerminalSettings, int32_t, HistorySize, DEFAULT_HISTORY_SIZE);
INHERITABLE_SETTING(Model::TerminalSettings, int32_t, InitialRows, 30);
INHERITABLE_SETTING(Model::TerminalSettings, int32_t, InitialCols, 80);

View File

@@ -91,6 +91,7 @@ namespace SettingsModelUnitTests
TEST_METHOD(ProfileInheritsInvalidIconAndHasNoCommandline);
TEST_METHOD(ProfileSpecifiesNullIcon);
TEST_METHOD(ProfileSpecifiesNullIconAndHasNoCommandline);
TEST_METHOD(ProfileOverwritesBellSound);
// FRAGMENT BEHAVIORS
TEST_METHOD(FragmentUpdatesBaseProfile);
@@ -125,7 +126,11 @@ namespace SettingsModelUnitTests
"backgroundImage": "imagePathFromBase",
"guid": "{862d46aa-cc9c-4e6c-b872-9cadaafcdbbe}",
"icon": "iconFromBase",
"name": "Base"
"name": "Base",
"bellSound": [
"C:\\Windows\\Media\\Alarm01.wav",
"C:\\Windows\\Media\\Alarm02.wav"
]
},
{
"backgroundImage": "focusedImagePathFromBase",
@@ -167,7 +172,7 @@ namespace SettingsModelUnitTests
]
})" };
static constexpr int numberOfMediaResourcesInDefaultSettings{ 9 };
static constexpr int numberOfMediaResourcesInDefaultSettings{ 11 };
struct Fragment
{
@@ -1021,6 +1026,37 @@ namespace SettingsModelUnitTests
VERIFY_IS_TRUE(icon.Ok()); // Profile with commandline always has an icon
VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved());
}
// A profile replaces the bell sounds (2) in the base settings; all bell sounds retained
void MediaResourceTests::ProfileOverwritesBellSound()
{
WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{};
winrt::com_ptr<implementation::CascadiaSettings> settings;
{
auto [t, e] = requireCalled([&](auto&&, auto&&, auto&& resource) {
// All resources are invalid.
resource.Reject();
});
g_mediaResolverHook = t;
settings = createSettings(R"({
"profiles": {
"list": [
{
"guid": "{862d46aa-cc9c-4e6c-b872-9cadaafcdbbe}",
"bellSound": [
"does not matter; resolved rejected"
],
},
]
}
})");
}
auto profile{ settings->GetProfileByName(L"Base") };
auto bellSounds{ profile.BellSound() };
VERIFY_ARE_EQUAL(1u, bellSounds.Size());
VERIFY_IS_FALSE(bellSounds.GetAt(0).Ok());
}
#pragma endregion
#pragma region Real Resolver Tests

View File

@@ -253,6 +253,29 @@ void WindowEmperor::CreateNewWindow(winrt::TerminalApp::WindowRequestedArgs args
_windowCount += 1;
_windows.emplace_back(std::move(host));
if (_windowCount == 1)
{
// The first CoreWindow is created implicitly by XAML and parented to the
// first XAML island. We parent it to our initial window for 2 reasons:
// * On Windows 10 the CoreWindow will show up as a visible window on the taskbar
// due to a WinUI bug, and this will hide it, because our initial window is hidden.
// * When we DestroyWindow() the island it will destroy the CoreWindow,
// and it's not possible to recreate it. That's also a WinUI bug.
//
// Note that this must be done after the first window (= first island) is created.
if (const auto coreWindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread())
{
if (const auto interop = coreWindow.try_as<ICoreWindowInterop>())
{
HWND coreHandle = nullptr;
if (SUCCEEDED(interop->get_WindowHandle(&coreHandle)) && coreHandle)
{
SetParent(coreHandle, _window.get());
}
}
}
}
}
AppHost* WindowEmperor::_mostRecentWindow() const noexcept
@@ -395,24 +418,6 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectoryW(system32.c_str()));
}
// The first CoreWindow is created implicitly by XAML and parented to the
// first XAML island. We parent it to our initial window for 2 reasons:
// * On Windows 10 the CoreWindow will show up as a visible window on the taskbar
// due to a WinUI bug, and this will hide it, because our initial window is hidden.
// * When we DestroyWindow() the island it will destroy the CoreWindow,
// and it's not possible to recreate it. That's also a WinUI bug.
if (const auto coreWindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread())
{
if (const auto interop = coreWindow.try_as<ICoreWindowInterop>())
{
HWND coreHandle = nullptr;
if (SUCCEEDED(interop->get_WindowHandle(&coreHandle)) && coreHandle)
{
SetParent(coreHandle, _window.get());
}
}
}
{
TerminalConnection::ConptyConnection::NewConnection([this](TerminalConnection::ConptyConnection conn) {
TerminalApp::CommandlineArgs args;
@@ -544,6 +549,8 @@ void WindowEmperor::_dispatchSpecialKey(const MSG& msg) const
void WindowEmperor::_dispatchCommandline(winrt::TerminalApp::CommandlineArgs args)
{
_assertIsMainThread();
const auto exitCode = args.ExitCode();
if (const auto msg = args.ExitMessage(); !msg.empty())
@@ -681,6 +688,8 @@ safe_void_coroutine WindowEmperor::_dispatchCommandlineCurrentDesktop(winrt::Ter
bool WindowEmperor::_summonWindow(const SummonWindowSelectionArgs& args) const
{
_assertIsMainThread();
AppHost* window = nullptr;
if (args.WindowID)
@@ -721,6 +730,8 @@ bool WindowEmperor::_summonWindow(const SummonWindowSelectionArgs& args) const
void WindowEmperor::_summonAllWindows() const
{
_assertIsMainThread();
TerminalApp::SummonWindowBehavior args;
args.ToggleVisibility(false);
@@ -858,6 +869,9 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c
// Did the window counter get out of sync? It shouldn't.
assert(_windowCount == gsl::narrow_cast<int32_t>(_windows.size()));
// !!! NOTE !!!
// At least theoretically the lParam pointer may be invalid.
// We should only access it if we find it in our _windows array.
const auto host = reinterpret_cast<AppHost*>(lParam);
auto it = _windows.begin();
const auto end = _windows.end();
@@ -866,7 +880,15 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c
{
if (host == it->get())
{
host->Close();
// NOTE: The AppHost destructor is highly non-trivial.
//
// It _may_ call into XAML, which _may_ pump the message loop, which would then recursively
// re-enter this function, which _may_ then handle another WM_CLOSE_TERMINAL_WINDOW,
// which would change the _windows array, and invalidate our iterator and crash.
//
// We can prevent this by deferring destruction until after the erase() call.
const auto strong = *it;
strong->Close();
_windows.erase(it);
break;
}

View File

@@ -84,14 +84,14 @@ private:
int32_t _windowCount = 0;
int32_t _messageBoxCount = 0;
#ifdef NDEBUG
#if 0 // #ifdef NDEBUG
static constexpr void _assertIsMainThread() noexcept
{
}
#else
void _assertIsMainThread() const noexcept
{
assert(_mainThreadId == GetCurrentThreadId());
WI_ASSERT_MSG(_mainThreadId == GetCurrentThreadId(), "This part of WindowEmperor must be accessed from the UI thread");
}
DWORD _mainThreadId = GetCurrentThreadId();
#endif

View File

@@ -33,6 +33,7 @@
// --------------------------- Core Settings ---------------------------
// All of these settings are defined in ICoreSettings.
#define CORE_SETTINGS(X) \
X(int32_t, MinimumBufferWidth, 0) \
X(int32_t, HistorySize, DEFAULT_HISTORY_SIZE) \
X(int32_t, InitialRows, 30) \
X(int32_t, InitialCols, 80) \

View File

@@ -366,12 +366,13 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
if (til::compare_ordinal_insensitive(var, temp) == 0 ||
til::compare_ordinal_insensitive(var, tmp) == 0)
{
return til::details::wil_env::GetShortPathNameW<std::wstring, 256>(value.data());
}
else
{
return std::wstring{ value };
std::wstring shortPath;
if (SUCCEEDED((til::details::wil_env::GetShortPathNameW<std::wstring, 256>(value.data(), shortPath))))
{
return shortPath;
}
}
return std::wstring{ value };
}
static bool is_path_var(std::wstring_view input) noexcept

View File

@@ -23,6 +23,8 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
}
}
struct size;
struct point
{
CoordType x = 0;
@@ -165,6 +167,9 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
return gsl::narrow<T>(y);
}
// Defined in size.h
constexpr size to_size() const noexcept;
#ifdef _WINDEF_
explicit constexpr point(const POINT other) noexcept :
x{ other.x }, y{ other.y }

View File

@@ -117,6 +117,11 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
return gsl::narrow<T>(static_cast<int64_t>(width) * static_cast<int64_t>(height));
}
constexpr point to_point() const noexcept
{
return { width, height };
}
#ifdef _WINDEF_
explicit constexpr size(const SIZE other) noexcept :
width{ other.cx }, height{ other.cy }
@@ -170,6 +175,18 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
}
#endif
#ifdef WINRT_Microsoft_Terminal_Core_H
explicit constexpr size(const winrt::Microsoft::Terminal::Core::Point other) :
width{ other.X }, height{ other.Y }
{
}
winrt::Microsoft::Terminal::Core::Point to_core_point() const noexcept
{
return { width, height };
}
#endif
std::wstring to_string() const
{
return wil::str_printf<std::wstring>(L"[W:%d, H:%d]", width, height);
@@ -179,6 +196,11 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
CoordType height = 0;
};
constexpr size point::to_size() const noexcept
{
return size{ x, y };
}
constexpr size wrap_coord_size(const COORD sz) noexcept
{
return { sz.X, sz.Y };