mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-20 13:57:43 +00:00
Compare commits
85 Commits
v1.25.1322
...
dev/cazamo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e9e381ceb | ||
|
|
9a54114e89 | ||
|
|
cd871b1891 | ||
|
|
b05ae68828 | ||
|
|
ba90c58e56 | ||
|
|
b6f97066b2 | ||
|
|
0d957cf914 | ||
|
|
70d51c5b5b | ||
|
|
cc67c30cb3 | ||
|
|
dba14ebb48 | ||
|
|
40be63499d | ||
|
|
41e08a68bd | ||
|
|
90fdd9bd61 | ||
|
|
5279226646 | ||
|
|
81170aff78 | ||
|
|
c90ace8326 | ||
|
|
e9a1fe57be | ||
|
|
fd30d00304 | ||
|
|
44456be4eb | ||
|
|
73af681149 | ||
|
|
ffaa89eba3 | ||
|
|
d18b3f519b | ||
|
|
fe8730ad3f | ||
|
|
c334f91f80 | ||
|
|
14f4271954 | ||
|
|
3104c8feb2 | ||
|
|
01f8a4031d | ||
|
|
2870a702f4 | ||
|
|
ec939aabda | ||
|
|
be5dcf8e7a | ||
|
|
578884569d | ||
|
|
4ce79d7289 | ||
|
|
69e4590bc5 | ||
|
|
a1a43a4ff5 | ||
|
|
3ab2acc2ad | ||
|
|
eea035cb8e | ||
|
|
184870d12d | ||
|
|
f5d411d468 | ||
|
|
40316ebb28 | ||
|
|
98a4ccbd0e | ||
|
|
973bd41fd2 | ||
|
|
33546f195a | ||
|
|
72f59b2a8c | ||
|
|
61d97526cd | ||
|
|
db209a128d | ||
|
|
3ea52fd3a5 | ||
|
|
85513496f4 | ||
|
|
5f3db13e5f | ||
|
|
a7a928cfc9 | ||
|
|
9df166efec | ||
|
|
aeb531f666 | ||
|
|
c23e507c20 | ||
|
|
c49bc1a789 | ||
|
|
da0446a7d1 | ||
|
|
e0400150d0 | ||
|
|
4aa56b0d7b | ||
|
|
c562dad15d | ||
|
|
0f5d883c59 | ||
|
|
ad7b34e55f | ||
|
|
ddf514e99e | ||
|
|
d4425a397c | ||
|
|
0e19570468 | ||
|
|
f8b4e19e51 | ||
|
|
2e33056fd8 | ||
|
|
14ee19fc27 | ||
|
|
987fce20a1 | ||
|
|
040c730a44 | ||
|
|
d04d15f4c4 | ||
|
|
6d7fac999a | ||
|
|
e6ea8ace6d | ||
|
|
36fb444d3e | ||
|
|
e2d51636cd | ||
|
|
80e4b3c947 | ||
|
|
e2110e716c | ||
|
|
9e4986edb0 | ||
|
|
30b1456ffe | ||
|
|
5bd9e9fd89 | ||
|
|
8cad67020f | ||
|
|
5828fb5ce5 | ||
|
|
55f96bc10d | ||
|
|
77bae1ff7a | ||
|
|
0f6ee4ad2e | ||
|
|
59c7e3b73c | ||
|
|
26bcbf3656 | ||
|
|
83d0d9df14 |
3
.github/actions/spelling/expect/expect.txt
vendored
3
.github/actions/spelling/expect/expect.txt
vendored
@@ -1135,6 +1135,7 @@ NOSIZE
|
||||
NOSNAPSHOT
|
||||
NOTHOUSANDS
|
||||
NOTICKS
|
||||
notif
|
||||
NOTIMEOUTIFNOTHUNG
|
||||
NOTIMPL
|
||||
NOTOPMOST
|
||||
@@ -1796,6 +1797,7 @@ UPKEY
|
||||
upss
|
||||
uregex
|
||||
URegular
|
||||
urxvt
|
||||
usebackq
|
||||
USECALLBACK
|
||||
USECOLOR
|
||||
@@ -1882,6 +1884,7 @@ WCIA
|
||||
WCIW
|
||||
wcs
|
||||
WCSHELPER
|
||||
wcsicmp
|
||||
wcsrev
|
||||
wcswidth
|
||||
wddm
|
||||
|
||||
8
.github/workflows/spelling2.yml
vendored
8
.github/workflows/spelling2.yml
vendored
@@ -93,7 +93,7 @@ jobs:
|
||||
steps:
|
||||
- name: check-spelling
|
||||
id: spelling
|
||||
uses: check-spelling/check-spelling@v0.0.25
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
with:
|
||||
suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
|
||||
checkout: true
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@v0.0.25
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
with:
|
||||
checkout: true
|
||||
spell_check_this: microsoft/terminal@main
|
||||
@@ -171,7 +171,7 @@ jobs:
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@v0.0.25
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
with:
|
||||
checkout: true
|
||||
spell_check_this: microsoft/terminal@main
|
||||
@@ -197,7 +197,7 @@ jobs:
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: apply spelling updates
|
||||
uses: check-spelling/check-spelling@v0.0.25
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
with:
|
||||
experimental_apply_changes_via_bot: ${{ github.repository_owner != 'microsoft' && 1 }}
|
||||
checkout: true
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
- [Via Chocolatey (unofficial)](#via-chocolatey-unofficial)
|
||||
- [Via Scoop (unofficial)](#via-scoop-unofficial)
|
||||
- [Installing Windows Terminal Canary](#installing-windows-terminal-canary)
|
||||
- [Windows Terminal Roadmap](#windows-terminal-roadmap)
|
||||
- [Terminal \& Console Overview](#terminal--console-overview)
|
||||
- [Windows Terminal](#windows-terminal)
|
||||
- [The Windows Console Host](#the-windows-console-host)
|
||||
@@ -178,11 +177,6 @@ _Learn more about the [types of Windows Terminal distributions](https://learn.mi
|
||||
|
||||
---
|
||||
|
||||
## Windows Terminal Roadmap
|
||||
|
||||
The plan for the Windows Terminal [is described here](/doc/roadmap-2023.md) and
|
||||
will be updated as the project proceeds.
|
||||
|
||||
## Terminal & Console Overview
|
||||
|
||||
Please take a few minutes to review the overview below before diving into the
|
||||
|
||||
@@ -56,9 +56,10 @@ Dies ist ein Open Source-Projekt, und wir freuen uns über die Teilnahme der Com
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
– 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
|
||||
– Endlich die Möglichkeit, nach beliebigen Einstellungen zu suchen!
|
||||
– Ein neuer nativer Editor für Tastenkombinationen, Aktionen und Einträge in der Befehlspalette.
|
||||
– Neue Community-Übersetzungen für Serbisch und Ukrainisch
|
||||
– Unterstützung für das „Kitty“-Tastaturprotokoll für hochauflösende Eingabecodierung
|
||||
|
||||
Weitere Informationen finden Sie auf unserer GitHub-Releaseseite.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -54,11 +54,12 @@ This is an open source project and we welcome community participation. To partic
|
||||
<!-- _locComment_text="{MaxLength=255} App DevStudio" -->
|
||||
</DevStudio>
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe} App Release Note" -->Version __VERSION_NUMBER__
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe}{Locked=Kitty} App Release Note" -->Version __VERSION_NUMBER__
|
||||
|
||||
- A whole new Extensions page that shows what has been installed into your Terminal
|
||||
- Command Palette now shows up in your native language as well as English
|
||||
- New VT features such as synchronized rendering, new color schemes, configuration for quick mouse actions like zooming, and more
|
||||
- Finally, the ability to search for any setting!
|
||||
- A new native editor for key bindings, actions and command palette entries.
|
||||
- New community localizations to Serbian and Ukrainian
|
||||
- Support for the "Kitty" keyboard protocol for high-fidelity input encoding
|
||||
|
||||
Please see our GitHub releases page for additional details.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -54,11 +54,12 @@ Este es un proyecto de fuente abierta y animamos a la comunidad a participar. Pa
|
||||
|
||||
</DevStudio>
|
||||
<ReleaseNotes>
|
||||
Versión __VERSION_NUMBER__
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
- 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
|
||||
- Por último, la capacidad de buscar cualquier configuración.
|
||||
- Nuevo editor nativo para asignaciones de teclas, acciones y entradas de la paleta de comandos.
|
||||
- Nuevas localizaciones comunitarias para serbio y ucraniano
|
||||
- Soporte para el protocolo de teclado "Kitty" para codificación de entrada de alta fidelidad
|
||||
|
||||
Consulta la página de versiones de GitHub para más información.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,11 +56,12 @@ Il s’agit d’un projet open source et nous vous invitons à participer dans l
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
- Une toute nouvelle page Extensions qui montre ce qui a été installé dans votre terminal
|
||||
- La palette de commandes s’affiche désormais dans votre langue native, ainsi qu’en 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
|
||||
- Enfin, la possibilité de rechercher n’importe quel paramètre !
|
||||
- Un nouvel éditeur natif pour les raccourcis clavier, les actions et les entrées de la palette de commandes.
|
||||
- De nouvelles localisations communautaires en serbe et en ukrainien
|
||||
- Une prise en charge du protocole clavier « Kitty » pour un encodage d’entrée à haute fidélité
|
||||
|
||||
Veuillez consulter notre page des versions GitHub pour découvrir d’autres détails.
|
||||
Consultez notre page des versions de GitHub pour plus de détails.
|
||||
</ReleaseNotes>
|
||||
<ScreenshotCaptions>
|
||||
<!-- Valid length: 200 character limit, up to 9 elements per platform -->
|
||||
|
||||
@@ -54,11 +54,12 @@ Si tratta di un progetto open source e la partecipazione della community è molt
|
||||
|
||||
</DevStudio>
|
||||
<ReleaseNotes>
|
||||
Versione __VERSION_NUMBER__
|
||||
Versione __VERSION_NUMBER__
|
||||
|
||||
- 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
|
||||
- Finalmente è possibile cercare qualsiasi impostazione
|
||||
- Nuovo editor nativo per le associazioni di tasti, le azioni e le voci del riquadro comandi.
|
||||
- Nuove localizzazioni della community in serbo e ucraino
|
||||
- Supporto per il protocollo di tastiera "Kitty" per una codifica dell'input ad alta fedeltà
|
||||
|
||||
Per altri dettagli, vedi la pagina delle release di GitHub.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,10 @@
|
||||
<ReleaseNotes>
|
||||
バージョン __VERSION_NUMBER__
|
||||
|
||||
- ターミナルに何がインストールされているかを表示する新しい [拡張機能] ページ
|
||||
- コマンド パレットがネイティブ言語と英語で表示されるようになりました
|
||||
- 同期レンダリング、新しい配色、ズームなどのクイック マウス操作の構成などの、新しい VT 機能
|
||||
- 最後に、任意の設定を検索する機能です。
|
||||
- キー バインド、アクション、コマンド パレット エントリ用の新しいネイティブ エディター。
|
||||
- セルビア語とウクライナ語への新しいコミュニティ ローカライズ
|
||||
- 高忠実度入力エンコード用の "Kitty" キーボード プロトコルのサポート
|
||||
|
||||
詳細については、GitHub リリース ページをご覧ください。
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,11 +56,12 @@
|
||||
<ReleaseNotes>
|
||||
버전 __VERSION_NUMBER__
|
||||
|
||||
- 터미널에 설치된 항목을 보여 주는 완전히 새로운 확장 페이지
|
||||
- 명령 팔레트가 이제 영어뿐만 아니라 모국어로도 표시
|
||||
- 동기화된 렌더링, 새로운 색 구성표, 확대/축소와 같은 빠른 마우스 동작을 위한 구성 등 새로운 VT 기능이 추가
|
||||
- 드디어 모든 설정을 검색할 수 있게 되었어요!
|
||||
- 키 바인딩, 작업, 명령 팔레트 항목을 위한 새로운 기본 편집기가 추가되었습니다.
|
||||
- 세르비아어와 우크라이나어 커뮤니티 지역화를 새롭게 지원합니다.
|
||||
- 고품질 입력 인코딩을 위해 "Kitty" 키보드 프로토콜을 지원합니다.
|
||||
|
||||
자세한 내용은 GitHub 릴리스 페이지를 참조하세요.
|
||||
자세한 정보는 GitHub 릴리스 페이지를 참고하세요.
|
||||
</ReleaseNotes>
|
||||
<ScreenshotCaptions>
|
||||
<!-- Valid length: 200 character limit, up to 9 elements per platform -->
|
||||
|
||||
@@ -56,9 +56,10 @@ Este é um projeto de código aberto e a participação da comunidade é bem-vin
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
– 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
|
||||
- Finalmente, a possibilidade de pesquisar qualquer configuração!
|
||||
- Um novo editor nativo para combinações de teclas, ações e entradas na paleta de comandos.
|
||||
- Novas localizações da comunidade para sérvio e ucraniano
|
||||
- Suporte para o protocolo de teclado "Kitty" para codificação de entrada de alta fidelidade
|
||||
|
||||
Confira nossa página de lançamentos no GitHub para obter mais detalhes.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,10 @@
|
||||
<ReleaseNotes>
|
||||
Версия __VERSION_NUMBER__
|
||||
|
||||
– Новая страница расширений, на которой отображается информация о том, что было установлено в вашем терминале
|
||||
– Палитра команд теперь доступна на вашем языке, а также на английском
|
||||
– Новые функции VT, например синхронизированная отрисовка, новые цветовые схемы, настройка быстрых действий мыши, таких как масштабирование, и т. д.
|
||||
– Наконец-то появилась возможность поиска любых параметров!
|
||||
– Новый собственный редактор для настраиваемых сочетаний клавиш, действий и записей палитры команд.
|
||||
– Новые локализации сообщества на сербский и украинский языки
|
||||
– Поддержка протокола клавиатуры Kitty для высокоточного кодирования ввода
|
||||
|
||||
Дополнительные сведения см. на странице выпусков GitHub.
|
||||
</ReleaseNotes>
|
||||
|
||||
182
build/StoreSubmission/Preview/PDPs/sr-Cyrl-RS/PDP.xml
Normal file
182
build/StoreSubmission/Preview/PDPs/sr-Cyrl-RS/PDP.xml
Normal file
@@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ProductDescription language="sr-cyrl-rs" xmlns="http://schemas.microsoft.com/appx/2012/ProductDescription" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" Release="">
|
||||
<AppStoreName _locID="App_AppStoreName">
|
||||
<!-- This is optional. AppStoreName is typically extracted from your package's AppxManifest DisplayName property. -->
|
||||
<!-- Uncomment (and localize) this Store name if your application package does not contain a localization for the DisplayName in this language. -->
|
||||
<!-- Leaving this uncommented for a language that your application package DOES contain a DisplayName for will result in a submission failure with the API. -->
|
||||
<!-- _locComment_text="{MaxLength=200} App AppStoreName" -->
|
||||
<!-- Windows Terminal -->
|
||||
</AppStoreName>
|
||||
<Keywords>
|
||||
<!-- Valid length: 30 character limit, up to 7 elements -->
|
||||
<Keyword _locID="App_keyword1">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 1" -->Терминал</Keyword>
|
||||
<Keyword _locID="App_keyword2">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 2" -->Конзола</Keyword>
|
||||
<Keyword _locID="App_keyword3">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 3" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword4">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 4" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword5">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 5" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword6">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 6" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword7">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 7" -->
|
||||
</Keyword>
|
||||
</Keywords>
|
||||
<Description _locID="App_Description">
|
||||
<!-- _locComment_text="{MaxLength=10000} App Description" -->Ово је изградња прегледа апликације Windows терминал. Она садржи најновије могућности које се још увек развијају. Windows терминал је модерна, брза, ефикасна, моћна и продуктивна апликација терминала за кориснике алата из командне линије и љуски као што су Command Prompt, PowerShell, и WSL. Неке од његових главних функционалности су вишеструке картице, панели, подршка за Уникод и UTF-8, GPU убрзани механизам за исцртавање текста, произвољне теме, стилови и конфигурације.
|
||||
|
||||
Ово је пројекат отвореног кода и учешће заједнице је добродошло. Ако желите да учествујете, молимо вас да посетите https://github.com/microsoft/terminal </Description>
|
||||
<ShortDescription _locID="App_ShortDescription">
|
||||
<!-- Only used for games. This description appears in the Information section of the Game Hub on Xbox One, and helps customers understand more about your game. -->
|
||||
<!-- _locComment_text="{MaxLength=500} App ShortDescription" -->
|
||||
</ShortDescription>
|
||||
<ShortTitle _locID="App_ShortTitle">
|
||||
<!-- A shorter version of your product's name. If provided, this shorter name may appear in various places on Xbox One (during installation, in Achievements, etc.) in place of the full title of your product. -->
|
||||
<!-- _locComment_text="{MaxLength=50} App ShortTitle" -->
|
||||
</ShortTitle>
|
||||
<SortTitle _locID="App_SortTitle">
|
||||
<!-- If your product could be alphabetized in different ways, you can enter another version here. This may help customers find the product more quickly when searching. -->
|
||||
<!-- _locComment_text="{MaxLength=255} App SortTitle" -->
|
||||
</SortTitle>
|
||||
<VoiceTitle _locID="App_VoiceTitle">
|
||||
<!-- An alternate name for your product that, if provided, may be used in the audio experience on Xbox One when using Kinect or a headset. -->
|
||||
<!-- _locComment_text="{MaxLength=255} App VoiceTitle" -->
|
||||
</VoiceTitle>
|
||||
<DevStudio _locID="App_DevStudio">
|
||||
<!-- Specify this value if you want to include a "Developed by" field in the listing. (The "Published by" field will list the publisher display name associated with your account, whether or not you provide a devStudio value.) -->
|
||||
<!-- _locComment_text="{MaxLength=255} App DevStudio" -->
|
||||
</DevStudio>
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe}{Locked=Kitty} App Release Note" -->Верзија __VERSION_NUMBER__
|
||||
|
||||
- Коначно, могућност претраге било ког подешавања!
|
||||
- Нови својствени едитор ставки пречица на тастатури, акција и командне палете
|
||||
- Нова локализација заједнице на српски и украјински језик
|
||||
- Подршка за „Kitty” протокол тастатуре који омогућава верно кодирање уноса
|
||||
|
||||
За више детаља, молимо вас да посетите нашу GitHub страницу издања.
|
||||
</ReleaseNotes>
|
||||
<ScreenshotCaptions>
|
||||
<!-- Valid length: 200 character limit, up to 9 elements per platform -->
|
||||
<!-- Valid attributes: any of DesktopImage, MobileImage, XboxImage, SurfaceHubImage, and HoloLensImage -->
|
||||
<Caption DesktopImage="acrylic-emoji.png" _locID="App_caption1">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 1" -->
|
||||
</Caption>
|
||||
<Caption DesktopImage="panes.png" _locID="App_caption2">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 2" -->
|
||||
</Caption>
|
||||
<Caption DesktopImage="htop.png" _locID="App_caption3">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 3" -->
|
||||
</Caption>
|
||||
</ScreenshotCaptions>
|
||||
<AdditionalAssets>
|
||||
<!-- Valid elements:-->
|
||||
<!-- HeroImage414x180, HeroImage846x468, HeroImage558x756, HeroImage414x468, HeroImage558x558, HeroImage2400x1200,-->
|
||||
<!-- ScreenshotWXGA, ScreenshotHD720, ScreenshotWVGA, Doublewide, Panoramic, Square,-->
|
||||
<!-- SmallMobileTile, SmallXboxLiveTile, LargeMobileTile, LargeXboxLiveTile, Tile,-->
|
||||
<!-- DesktopIcon, Icon (use this value for the 1:1 300x300 pixels logo), AchievementIcon,-->
|
||||
<!-- ChallengePromoIcon, RewardDisplayIcon, Icon150X150, Icon71X71,-->
|
||||
<!-- BoxArt, BrandedKeyArt, PosterArt, FeaturedPromotionalArt, PromotionalArt16x9, TitledHeroArt-->
|
||||
<!-- There is no content for any of these elements, just a single attribute called FileName. -->
|
||||
<PosterArt FileName="Store Poster Art.png" />
|
||||
<BoxArt FileName="Store Box Art.png" />
|
||||
<PromotionalArt16x9 FileName="Store Thumbnail.png" />
|
||||
</AdditionalAssets>
|
||||
<Trailers>
|
||||
<!-- Maximum number of trailers permitted: 15 -->
|
||||
<Trailer FileName="CC0605_CommandLine_Teaser_WEB_MASTER_H264_1080p_23.976_-16LKFS_-3dbTP_ST.mp4">
|
||||
<Title _locID="App_trailerTitle1">
|
||||
<!-- _locComment_text="{MaxLength=255} Trailer title 1" -->Нови Windows терминал</Title>
|
||||
<Images>
|
||||
<!-- Current maximum of 1 image per trailer permitted. -->
|
||||
<Image FileName="Store Thumbnail.png">
|
||||
<!-- _locComment_text="{Locked} Trailer screenshot 1 description" -->
|
||||
</Image>
|
||||
</Images>
|
||||
</Trailer>
|
||||
</Trailers>
|
||||
<AppFeatures>
|
||||
<!-- Valid length: 200 character limit, up to 20 elements -->
|
||||
<AppFeature _locID="App_feature1">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 1" -->Вишеструке картице</AppFeature>
|
||||
<AppFeature _locID="App_feature2">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 2" -->Пуна Уникод подршка</AppFeature>
|
||||
<AppFeature _locID="App_feature3">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 3" -->GPU-убрзано исцртавање текста</AppFeature>
|
||||
<AppFeature _locID="App_feature4">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 4" -->Потпуна прилагодљивост</AppFeature>
|
||||
<AppFeature _locID="App_feature5">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 5" -->Подела панела</AppFeature>
|
||||
<AppFeature _locID="App_feature6">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 6" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature7">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 7" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature8">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 8" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature9">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 9" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature10">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 10" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature11">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 11" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature12">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 12" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature13">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 13" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature14">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 14" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature15">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 15" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature16">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 16" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature17">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 17" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature18">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 18" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature19">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 19" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature20">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 20" -->
|
||||
</AppFeature>
|
||||
</AppFeatures>
|
||||
<RecommendedHardware>
|
||||
<!-- Valid length: 200 character limit, up to 11 elements -->
|
||||
<Recommendation _locID="App_RecommendedHW1">
|
||||
<!-- _locComment_text="{MaxLength=200} App Recommended Hardware 1" -->Тастатура</Recommendation>
|
||||
</RecommendedHardware>
|
||||
<MinimumHardware>
|
||||
<!-- Valid length: 200 character limit, up to 11 elements -->
|
||||
</MinimumHardware>
|
||||
<CopyrightAndTrademark _locID="App_CopyrightandTrademark">
|
||||
<!-- _locComment_text="{MaxLength=200} Copyright and Trademark" -->Copyright (c) Microsoft Corporation</CopyrightAndTrademark>
|
||||
<AdditionalLicenseTerms _locID="App_AdditionalLicenseTerms">
|
||||
<!-- _locComment_text="{MaxLength=10000} Additional License Terms" -->
|
||||
</AdditionalLicenseTerms>
|
||||
<WebsiteURL _locID="App_WebsiteURL">
|
||||
<!-- _locComment_text="{MaxLength=2048} WebsiteURL" -->https://github.com/microsoft/terminal</WebsiteURL>
|
||||
<SupportContactInfo _locID="App_SupportContactInfo">
|
||||
<!-- _locComment_text="{MaxLength=2048} Support Contact Info" -->https://github.com/microsoft/terminal/issues/new</SupportContactInfo>
|
||||
<PrivacyPolicyURL _locID="App_PrivacyURL">
|
||||
<!-- _locComment_text="{MaxLength=2048} Privacy Policy URL" -->https://go.microsoft.com/fwlink/?LinkID=521839</PrivacyPolicyURL>
|
||||
</ProductDescription>
|
||||
@@ -56,9 +56,10 @@
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe} App Release Note" -->Версія __VERSION_NUMBER__
|
||||
|
||||
- Цілком нова сторінка розширень, яка показує, що було встановлено у вашому терміналі
|
||||
- Палітра команд тепер відображається вашою рідною мовою, а також англійською
|
||||
- Нові функції віртуального автомата, такі як синхронізований рендеринг, нові колірні схеми, налаштування для швидких дій миші, таких як масштабування, тощо
|
||||
- Нарешті, можливість пошуку будь-якого налаштування!
|
||||
- Новий вбудований редактор для прив'язки клавіш, дій та палітри команд.
|
||||
- Нові локалізації спільноти на сербську та українську мови.
|
||||
- Підтримка протоколу клавіатури "Kitty" для високоточного кодування введення.
|
||||
|
||||
Будь ласка, перегляньте нашу сторінку релізів GitHub для отримання додаткової інформації.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,10 @@
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
- 一个全新的“扩展”页,显示已安装到终端的内容
|
||||
- 命令面板现在以你的母语和英语显示
|
||||
- 新的 VT 功能,例如同步渲染、新配色方案、快速鼠标操作(如缩放)的配置等
|
||||
- 终于可以搜索任何设置了!
|
||||
- 新增用于键绑定、操作和命令面板条目的原生编辑器。
|
||||
- 新增塞尔维亚语和乌克兰语社区本地化支持
|
||||
- 支持 "Kitty" 键盘协议,实现高保真输入编码
|
||||
|
||||
有关其他详细信息,请参阅我们的 GitHub 发布页面。
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,10 @@
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
- 全新的延伸模組頁面會顯示已安裝在您終端機中的內容
|
||||
- 命令選擇區現在以您的母語和英文顯示
|
||||
- 新的 VT 功能,例如同步轉譯、新的色彩配置、快速滑鼠動作 (例如縮放) 設定等等
|
||||
- 終於,提供可搜尋任何設定的功能!
|
||||
- 全新原生編輯器,支援按鍵繫結、動作及命令選擇區項目。
|
||||
- 新增社群本地語系化,包含塞爾維亞語與烏克蘭語
|
||||
- 支援高保真度輸入編碼的「Kitty」鍵盤通訊協定
|
||||
|
||||
如需更多詳細資料,請參閱我們的 GitHub 發行版本頁面。
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,9 @@ Dies ist ein Open Source-Projekt, und wir freuen uns über die Teilnahme an der
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
– 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.
|
||||
– 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 Informationen finden Sie auf unserer GitHub-Releaseseite.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,9 @@ This is an open source project and we welcome community participation. To partic
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe} App Release Note" -->Version __VERSION_NUMBER__
|
||||
|
||||
- We've added dozens of settings to the UI that once only existed in the JSON file, including a new page for customizing the layout of your New Tab menu!
|
||||
- We have rearchitected window management to improve reliability; please file any bugs you encounter with the wt.exe alias
|
||||
- Profiles now show an icon if they've been hidden or refer to programs which were uninstalled.
|
||||
- A whole new Extensions page that shows what has been installed into your Terminal
|
||||
- Command Palette now shows up in your native language as well as English
|
||||
- New VT features such as synchronized rendering, new color schemes, configuration for quick mouse actions like zooming, and more
|
||||
|
||||
Please see our GitHub releases page for additional details.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,9 @@ Este es un proyecto de fuente abierta y animamos a la comunidad a participar. Pa
|
||||
<ReleaseNotes>
|
||||
Versión __VERSION_NUMBER__
|
||||
|
||||
- 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.
|
||||
- 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 la página de versiones de GitHub para más información.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,11 +56,11 @@ Il s’agit d’un projet open source et nous encourageons la participation à l
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
- Nous avons ajouté des dizaines de paramètres à l’interface utilisateur qui n’existaient 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 l’alias wt.exe.
|
||||
- Les profils affichent désormais une icône s’ils ont été masqués ou s’ils font référence à des programmes qui ont été désinstallés.
|
||||
- Une toute nouvelle page Extensions qui affiche ce qui a été installé dans votre Terminal
|
||||
- La palette de commandes s’affiche désormais dans votre langue native, ainsi qu’en anglais
|
||||
- De nouvelles fonctionnalités VT, telles que le rendu synchronisé, de nouveaux schémas de couleurs, une configuration pour des actions rapides de la souris comme le zoom, et bien plus encore
|
||||
|
||||
Veuillez consulter notre page des versions GitHub pour découvrir d’autres détails.
|
||||
Consultez notre page des versions de GitHub pour plus de détails.
|
||||
</ReleaseNotes>
|
||||
<ScreenshotCaptions>
|
||||
<!-- Valid length: 200 character limit, up to 9 elements per platform -->
|
||||
|
||||
@@ -56,9 +56,9 @@ Si tratta di un progetto open source e la partecipazione della community è molt
|
||||
<ReleaseNotes>
|
||||
Versione __VERSION_NUMBER__
|
||||
|
||||
- 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.
|
||||
- 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, vedi la pagina delle release di GitHub.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
<ReleaseNotes>
|
||||
バージョン __VERSION_NUMBER__
|
||||
|
||||
- 新しいタブ メニューのレイアウトをカスタマイズするための新しいページなど、以前は JSON ファイルにしかなかった設定が UI に多数追加されました。
|
||||
- 信頼性を向上させるために、ウィンドウ管理を再設計しました。wt.exe エイリアスで発生したバグを報告してください
|
||||
- プロファイルが非表示になっている場合や、アンインストールされたプログラムを参照している場合に、アイコンが表示されるようになりました。
|
||||
- お使いのターミナルに何がインストールされているかを表示する新しい [拡張機能] ページ
|
||||
- コマンド パレットがネイティブ言語と英語で表示されるようになりました
|
||||
- 同期レンダリング、新しい配色、ズームなどのクイック マウス操作の構成などの、新しい VT 機能
|
||||
|
||||
詳細については、GitHub リリース ページをご覧ください。
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -56,9 +56,9 @@ Este é um projeto de código aberto e a participação da comunidade é bem-vin
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
– 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.
|
||||
– 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
|
||||
|
||||
Confira nossa página de lançamentos no GitHub para obter mais detalhes.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
<ReleaseNotes>
|
||||
Версия __VERSION_NUMBER__
|
||||
|
||||
– Мы добавили в пользовательский интерфейс десятки параметров, которые ранее существовали только в JSON-файле, включая новую страницу для настройки макета меню новой вкладки.
|
||||
– Мы переработали управление окнами для повышения надежности. Сообщайте о любых ошибках, которые вы обнаружите с псевдонимом wt.exe
|
||||
– Профили теперь отображают значок, если они были скрыты или ссылаются на программы, которые были удалены.
|
||||
– Новая страница расширений, на которой отображается информация о том, что было установлено в вашем терминале
|
||||
– Палитра команд теперь доступна на вашем языке, а также на английском
|
||||
– Новые функции VT, например синхронизированная отрисовка, новые цветовые схемы, настройка быстрых действий мыши, таких как масштабирование, и т. д.
|
||||
|
||||
Дополнительные сведения см. на странице выпусков GitHub.
|
||||
</ReleaseNotes>
|
||||
|
||||
181
build/StoreSubmission/Stable/PDPs/sr-Cyrl-RS/PDP.xml
Normal file
181
build/StoreSubmission/Stable/PDPs/sr-Cyrl-RS/PDP.xml
Normal file
@@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ProductDescription language="sr-cyrl-rs" xmlns="http://schemas.microsoft.com/appx/2012/ProductDescription" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" Release="">
|
||||
<AppStoreName _locID="App_AppStoreName">
|
||||
<!-- This is optional. AppStoreName is typically extracted from your package's AppxManifest DisplayName property. -->
|
||||
<!-- Uncomment (and localize) this Store name if your application package does not contain a localization for the DisplayName in this language. -->
|
||||
<!-- Leaving this uncommented for a language that your application package DOES contain a DisplayName for will result in a submission failure with the API. -->
|
||||
<!-- _locComment_text="{MaxLength=200} App AppStoreName" -->
|
||||
<!-- Windows Terminal -->
|
||||
</AppStoreName>
|
||||
<Keywords>
|
||||
<!-- Valid length: 30 character limit, up to 7 elements -->
|
||||
<Keyword _locID="App_keyword1">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 1" -->Терминал</Keyword>
|
||||
<Keyword _locID="App_keyword2">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 2" -->Конзола</Keyword>
|
||||
<Keyword _locID="App_keyword3">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 3" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword4">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 4" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword5">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 5" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword6">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 6" -->
|
||||
</Keyword>
|
||||
<Keyword _locID="App_keyword7">
|
||||
<!-- _locComment_text="{MaxLength=30} App keyword 7" -->
|
||||
</Keyword>
|
||||
</Keywords>
|
||||
<Description _locID="App_Description">
|
||||
<!-- _locComment_text="{MaxLength=10000} App Description" -->Windows терминал је модерна, брза, ефикасна, моћна и продуктивна апликација терминала за кориснике алата из командне линије и љуски као што су Command Prompt, PowerShell, и WSL. Неке од његових главних функционалности су вишеструке картице, панели, подршка за Уникод и UTF-8, GPU убрзани механизам за исцртавање текста, произвољне теме, стилови и конфигурације.
|
||||
|
||||
Ово је пројекат отвореног кода и учешће заједнице је добродошло. Ако желите да учествујете, молимо вас да посетите https://github.com/microsoft/terminal </Description>
|
||||
<ShortDescription _locID="App_ShortDescription">
|
||||
<!-- Only used for games. This description appears in the Information section of the Game Hub on Xbox One, and helps customers understand more about your game. -->
|
||||
<!-- _locComment_text="{MaxLength=500} App ShortDescription" -->
|
||||
</ShortDescription>
|
||||
<ShortTitle _locID="App_ShortTitle">
|
||||
<!-- A shorter version of your product's name. If provided, this shorter name may appear in various places on Xbox One (during installation, in Achievements, etc.) in place of the full title of your product. -->
|
||||
<!-- _locComment_text="{MaxLength=50} App ShortTitle" -->
|
||||
</ShortTitle>
|
||||
<SortTitle _locID="App_SortTitle">
|
||||
<!-- If your product could be alphabetized in different ways, you can enter another version here. This may help customers find the product more quickly when searching. -->
|
||||
<!-- _locComment_text="{MaxLength=255} App SortTitle" -->
|
||||
</SortTitle>
|
||||
<VoiceTitle _locID="App_VoiceTitle">
|
||||
<!-- An alternate name for your product that, if provided, may be used in the audio experience on Xbox One when using Kinect or a headset. -->
|
||||
<!-- _locComment_text="{MaxLength=255} App VoiceTitle" -->
|
||||
</VoiceTitle>
|
||||
<DevStudio _locID="App_DevStudio">
|
||||
<!-- Specify this value if you want to include a "Developed by" field in the listing. (The "Published by" field will list the publisher display name associated with your account, whether or not you provide a devStudio value.) -->
|
||||
<!-- _locComment_text="{MaxLength=255} App DevStudio" -->
|
||||
</DevStudio>
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe} App Release Note" -->Верзија __VERSION_NUMBER__
|
||||
|
||||
- Попуно нова страница Проширења која приказује шта је све инсталирано у ваш Терминал
|
||||
- Палета команди се сада приказује и на вашем матерњем језику, као и на енглеском
|
||||
- Нове VT функционалности као што су синхронизовано исцртавање, нове шеме боја, конфигурација за брзе акције мишем, као што је зумирање, и још тога
|
||||
|
||||
За више детаља, молимо вас да посетите нашу GitHub страницу издања.
|
||||
</ReleaseNotes>
|
||||
<ScreenshotCaptions>
|
||||
<!-- Valid length: 200 character limit, up to 9 elements per platform -->
|
||||
<!-- Valid attributes: any of DesktopImage, MobileImage, XboxImage, SurfaceHubImage, and HoloLensImage -->
|
||||
<Caption DesktopImage="acrylic-emoji.png" _locID="App_caption1">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 1" -->
|
||||
</Caption>
|
||||
<Caption DesktopImage="panes.png" _locID="App_caption2">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 2" -->
|
||||
</Caption>
|
||||
<Caption DesktopImage="htop.png" _locID="App_caption3">
|
||||
<!-- _locComment_text="{MaxLength=200} Screenshot caption 3" -->
|
||||
</Caption>
|
||||
</ScreenshotCaptions>
|
||||
<AdditionalAssets>
|
||||
<!-- Valid elements:-->
|
||||
<!-- HeroImage414x180, HeroImage846x468, HeroImage558x756, HeroImage414x468, HeroImage558x558, HeroImage2400x1200,-->
|
||||
<!-- ScreenshotWXGA, ScreenshotHD720, ScreenshotWVGA, Doublewide, Panoramic, Square,-->
|
||||
<!-- SmallMobileTile, SmallXboxLiveTile, LargeMobileTile, LargeXboxLiveTile, Tile,-->
|
||||
<!-- DesktopIcon, Icon (use this value for the 1:1 300x300 pixels logo), AchievementIcon,-->
|
||||
<!-- ChallengePromoIcon, RewardDisplayIcon, Icon150X150, Icon71X71,-->
|
||||
<!-- BoxArt, BrandedKeyArt, PosterArt, FeaturedPromotionalArt, PromotionalArt16x9, TitledHeroArt-->
|
||||
<!-- There is no content for any of these elements, just a single attribute called FileName. -->
|
||||
<PosterArt FileName="Store Poster Art.png" />
|
||||
<BoxArt FileName="Store Box Art.png" />
|
||||
<PromotionalArt16x9 FileName="Store Thumbnail.png" />
|
||||
</AdditionalAssets>
|
||||
<Trailers>
|
||||
<!-- Maximum number of trailers permitted: 15 -->
|
||||
<Trailer FileName="CC0605_CommandLine_Teaser_WEB_MASTER_H264_1080p_23.976_-16LKFS_-3dbTP_ST.mp4">
|
||||
<Title _locID="App_trailerTitle1">
|
||||
<!-- _locComment_text="{MaxLength=255} Trailer title 1" -->Нови Windows терминал</Title>
|
||||
<Images>
|
||||
<!-- Current maximum of 1 image per trailer permitted. -->
|
||||
<Image FileName="Store Thumbnail.png">
|
||||
<!-- _locComment_text="{Locked} Trailer screenshot 1 description" -->
|
||||
</Image>
|
||||
</Images>
|
||||
</Trailer>
|
||||
</Trailers>
|
||||
<AppFeatures>
|
||||
<!-- Valid length: 200 character limit, up to 20 elements -->
|
||||
<AppFeature _locID="App_feature1">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 1" -->Вишеструке картице</AppFeature>
|
||||
<AppFeature _locID="App_feature2">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 2" -->Пуна Уникод подршка</AppFeature>
|
||||
<AppFeature _locID="App_feature3">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 3" -->GPU-убрзано исцртавање текста</AppFeature>
|
||||
<AppFeature _locID="App_feature4">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 4" -->Потпуна прилагодљивост</AppFeature>
|
||||
<AppFeature _locID="App_feature5">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 5" -->Подела панела</AppFeature>
|
||||
<AppFeature _locID="App_feature6">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 6" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature7">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 7" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature8">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 8" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature9">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 9" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature10">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 10" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature11">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 11" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature12">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 12" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature13">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 13" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature14">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 14" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature15">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 15" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature16">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 16" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature17">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 17" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature18">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 18" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature19">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 19" -->
|
||||
</AppFeature>
|
||||
<AppFeature _locID="App_feature20">
|
||||
<!-- _locComment_text="{MaxLength=200} App Feature 20" -->
|
||||
</AppFeature>
|
||||
</AppFeatures>
|
||||
<RecommendedHardware>
|
||||
<!-- Valid length: 200 character limit, up to 11 elements -->
|
||||
<Recommendation _locID="App_RecommendedHW1">
|
||||
<!-- _locComment_text="{MaxLength=200} App Recommended Hardware 1" -->Тастатура</Recommendation>
|
||||
</RecommendedHardware>
|
||||
<MinimumHardware>
|
||||
<!-- Valid length: 200 character limit, up to 11 elements -->
|
||||
</MinimumHardware>
|
||||
<CopyrightAndTrademark _locID="App_CopyrightandTrademark">
|
||||
<!-- _locComment_text="{MaxLength=200} Copyright and Trademark" -->Copyright (c) Microsoft Corporation</CopyrightAndTrademark>
|
||||
<AdditionalLicenseTerms _locID="App_AdditionalLicenseTerms">
|
||||
<!-- _locComment_text="{MaxLength=10000} Additional License Terms" -->
|
||||
</AdditionalLicenseTerms>
|
||||
<WebsiteURL _locID="App_WebsiteURL">
|
||||
<!-- _locComment_text="{MaxLength=2048} WebsiteURL" -->https://github.com/microsoft/terminal</WebsiteURL>
|
||||
<SupportContactInfo _locID="App_SupportContactInfo">
|
||||
<!-- _locComment_text="{MaxLength=2048} Support Contact Info" -->https://github.com/microsoft/terminal/issues/new</SupportContactInfo>
|
||||
<PrivacyPolicyURL _locID="App_PrivacyURL">
|
||||
<!-- _locComment_text="{MaxLength=2048} Privacy Policy URL" -->https://go.microsoft.com/fwlink/?LinkID=521839</PrivacyPolicyURL>
|
||||
</ProductDescription>
|
||||
@@ -56,9 +56,9 @@
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe} App Release Note" -->Версія __VERSION_NUMBER__
|
||||
|
||||
- Ми додали десятки налаштувань до інтерфейсу користувача, які раніше існували лише у файлі JSON, включаючи нову сторінку для налаштування макета меню «Нова вкладка»!
|
||||
- Ми переробили архітектуру керування вікнами для підвищення надійності; будь ласка, повідомляйте про будь-які помилки, з якими ви зіткнулися, за допомогою псевдоніма wt.exe.
|
||||
- Профілі тепер відображають значок, якщо вони були приховані, або посилаються на програми, які було видалено.
|
||||
- Цілком нова сторінка розширень, яка показує, що було встановлено у вашому Терміналі
|
||||
- Палітра команд тепер відображається вашою рідною мовою, так само, як і англійською
|
||||
- Нові VT функції, такі як синхронізований рендеринг, нові колірні схеми, налаштування для швидких дій миші, таких як масштабування, тощо
|
||||
|
||||
Будь ласка, перегляньте нашу сторінку релізів GitHub для отримання додаткової інформації.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
- 我们向用户界面添加了许多之前仅存在于 JSON 文件中的设置,包括用于自定义“新建标签页”菜单布局的新页面!
|
||||
- 我们已重新架构窗口管理以提高可靠性; 请使用 wt.exe 别名提交您遇到的任何错误
|
||||
- 配置文件如果已被隐藏或引用了已卸载的程序,现在会显示一个图标。
|
||||
- 一个全新的“扩展”页,显示已安装到终端的内容
|
||||
- 命令面板现在以你的母语和英语显示
|
||||
- 新的 VT 功能,例如同步渲染、新配色方案、快速鼠标操作(如缩放)的配置等
|
||||
|
||||
有关其他详细信息,请参阅我们的 GitHub 发布页面。
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
<ReleaseNotes>
|
||||
Version __VERSION_NUMBER__
|
||||
|
||||
- 我們已在使用者介面中新增數十個曾經僅存在於 JSON 檔案中的設定,包括一個可自訂新索引標籤選單版面配置的新頁面!
|
||||
- 我們已重新架構視窗管理以提升可靠性; 如果您在使用 wt.exe 別名時遇到任何錯誤,請提交錯誤回報
|
||||
- 如果設定檔已隱藏或參照已解除安裝的程式,現在會顯示圖示。
|
||||
- 全新的延伸模組頁面會顯示已安裝在您終端機中的內容
|
||||
- 命令選擇區現在以您的母語和英文顯示
|
||||
- 新的 VT 功能,例如同步轉譯、新的色彩配置、快速滑鼠動作 (例如縮放) 設定等等
|
||||
|
||||
如需更多詳細資料,請參閱我們的 GitHub 發行版本頁面。
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
|
||||
<PGOBranch>release-1.25</PGOBranch>
|
||||
<PGOBranch>main</PGOBranch>
|
||||
|
||||
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
|
||||
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
|
||||
<XesBaseYearForStoreVersion>2026</XesBaseYearForStoreVersion>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>25</VersionMinor>
|
||||
<VersionMinor>26</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
<VersionInfoCulture>1033</VersionInfoCulture>
|
||||
<!-- The default has a spacing problem -->
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
"enum": [
|
||||
"audible",
|
||||
"window",
|
||||
"taskbar"
|
||||
"taskbar",
|
||||
"notification"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -70,6 +71,7 @@
|
||||
"audible",
|
||||
"taskbar",
|
||||
"window",
|
||||
"notification",
|
||||
"all",
|
||||
"none"
|
||||
]
|
||||
@@ -2470,13 +2472,6 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"safeUriSchemes": {
|
||||
"description": "Specifies a list of URI schemes that are considered safe. No confirmation will be required to open URIs with these schemes.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"rendering.graphicsAPI": {
|
||||
"description": "Direct3D 11 provides a more performant and feature-rich experience, whereas Direct2D is more stable. The default option \"Automatic\" will pick the API that best fits your graphics hardware. If you experience significant issues, consider using Direct2D.",
|
||||
"type": "string",
|
||||
@@ -2661,10 +2656,21 @@
|
||||
"type": "string"
|
||||
},
|
||||
"warning.confirmCloseAllTabs": {
|
||||
"deprecated": true,
|
||||
"description": "[Deprecated] Use \"warning.confirmOnClose\" instead.",
|
||||
"default": true,
|
||||
"description": "When set to \"true\" closing a window with multiple tabs open will require confirmation. When set to \"false\", the confirmation dialog will not appear.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"warning.confirmOnClose": {
|
||||
"default": "automatic",
|
||||
"description": "Controls when a confirmation dialog appears before closing tabs or windows.",
|
||||
"enum": [
|
||||
"never",
|
||||
"automatic",
|
||||
"always"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"useTabSwitcher": {
|
||||
"description": "[Deprecated] Replaced with the \"tabSwitcherMode\" setting.",
|
||||
"default": true,
|
||||
@@ -2781,6 +2787,11 @@
|
||||
"description": "When set to true, VT applications will be allowed to set the contents of the local clipboard using OSC 52 (Manipulate Selection Data).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"compatibility.allowOSC777": {
|
||||
"default": true,
|
||||
"description": "When set to true, applications can send OSC 777 escape sequences to trigger desktop toast notifications with a custom title and body.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"unfocusedAppearance": {
|
||||
"$ref": "#/$defs/AppearanceConfig",
|
||||
"description": "Sets the appearance of the terminal when it is unfocused.",
|
||||
@@ -2856,6 +2867,78 @@
|
||||
"description": "Sets the sound played when the application emits a BEL. When set to an array, the terminal will pick one of those sounds at random.",
|
||||
"$ref": "#/$defs/BellSound"
|
||||
},
|
||||
"notifyOnInactiveOutput": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification",
|
||||
"all",
|
||||
"none"
|
||||
]
|
||||
}
|
||||
],
|
||||
"description": "Controls how you are notified when an inactive tab produces new output."
|
||||
},
|
||||
"notifyOnNextPrompt": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification",
|
||||
"all",
|
||||
"none"
|
||||
]
|
||||
}
|
||||
],
|
||||
"description": "Controls how you are notified when a new shell prompt is detected. Requires shell integration."
|
||||
},
|
||||
"autoDetectRunningCommand": {
|
||||
"default": "disabled",
|
||||
"description": "Automatically detect when a command is running and show a progress indicator in the tab and taskbar.",
|
||||
"enum": [
|
||||
"disabled",
|
||||
"automatic",
|
||||
"progress"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"closeOnExit": {
|
||||
"default": "automatic",
|
||||
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"automatic\" (behave as \"graceful\" only for processes launched by terminal, behave as \"always\" otherwise)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",
|
||||
@@ -3181,6 +3264,11 @@
|
||||
"mingw"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"dragDropDelimiter": {
|
||||
"default": " ",
|
||||
"description": "The delimiter used when dropping multiple files onto the terminal.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1143,13 +1143,6 @@ til::CoordType ROW::GetTrailingColumnAtCharOffset(const ptrdiff_t offset) const
|
||||
return _createCharToColumnMapper(offset).GetTrailingColumnAt(offset);
|
||||
}
|
||||
|
||||
uint16_t ROW::GetCharOffset(til::CoordType col) const noexcept
|
||||
{
|
||||
const auto columns = GetReadableColumnCount();
|
||||
const auto colBeg = clamp(col, 0, columns);
|
||||
return _uncheckedCharOffset(gsl::narrow_cast<size_t>(colBeg));
|
||||
}
|
||||
|
||||
DelimiterClass ROW::DelimiterClassAt(til::CoordType column, const std::wstring_view& wordDelimiters) const noexcept
|
||||
{
|
||||
const auto col = _clampedColumn(column);
|
||||
|
||||
@@ -172,7 +172,6 @@ public:
|
||||
std::wstring_view GetText(til::CoordType columnBegin, til::CoordType columnEnd) const noexcept;
|
||||
til::CoordType GetLeadingColumnAtCharOffset(ptrdiff_t offset) const noexcept;
|
||||
til::CoordType GetTrailingColumnAtCharOffset(ptrdiff_t offset) const noexcept;
|
||||
uint16_t GetCharOffset(til::CoordType col) const noexcept;
|
||||
DelimiterClass DelimiterClassAt(til::CoordType column, const std::wstring_view& wordDelimiters) const noexcept;
|
||||
|
||||
auto AttrBegin() const noexcept { return _attr.begin(); }
|
||||
|
||||
@@ -219,6 +219,17 @@ til::CoordType TextBuffer::_estimateOffsetOfLastCommittedRow() const noexcept
|
||||
return std::max(0, gsl::narrow_cast<til::CoordType>(lastRowOffset - 2));
|
||||
}
|
||||
|
||||
bool TextBuffer::_isRowCommitted(til::CoordType y) const noexcept
|
||||
{
|
||||
auto offset = (_firstRow + y + 1 /* account for the scratch row */) % _height;
|
||||
if (offset < 0)
|
||||
{
|
||||
offset += _height;
|
||||
}
|
||||
const auto row = _buffer.get() + _bufferRowStride * offset;
|
||||
return row < _commitWatermark;
|
||||
}
|
||||
|
||||
// Retrieves a row from the buffer by its offset from the first row of the text buffer
|
||||
// (what corresponds to the top row of the screen buffer).
|
||||
const ROW& TextBuffer::GetRowByOffset(const til::CoordType index) const
|
||||
@@ -934,6 +945,10 @@ void TextBuffer::ResetLineRenditionRange(const til::CoordType startRow, const ti
|
||||
|
||||
LineRendition TextBuffer::GetLineRendition(const til::CoordType row) const
|
||||
{
|
||||
if (!_isRowCommitted(row)) [[unlikely]]
|
||||
{
|
||||
return LineRendition::SingleWidth;
|
||||
}
|
||||
return GetRowByOffset(row).GetLineRendition();
|
||||
}
|
||||
|
||||
@@ -1141,7 +1156,20 @@ DelimiterClass TextBuffer::_GetDelimiterClassAt(const til::point pos, const std:
|
||||
return GetRowByOffset(realPos.y).DelimiterClassAt(realPos.x, wordDelimiters);
|
||||
}
|
||||
|
||||
til::point TextBuffer::GetWordStart2(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional) const
|
||||
// Method Description:
|
||||
// - Get the start of the word at or before the given position
|
||||
// - When includeWhitespace is false, returns the start of the current delimiter class run
|
||||
// (selection behavior: stops at non-wrapped row boundaries)
|
||||
// - When includeWhitespace is true, also skips backward past any leading ControlChars
|
||||
// to include the preceding word (accessibility/UIA behavior: crosses all row boundaries)
|
||||
// Arguments:
|
||||
// - pos - the buffer position to start from
|
||||
// - wordDelimiters - characters considered as DelimiterClass::DelimiterChar
|
||||
// - includeWhitespace - when true, skip past leading whitespace to find the word start
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored
|
||||
// Return Value:
|
||||
// - The position of the first character of the word (inclusive)
|
||||
til::point TextBuffer::GetWordStart(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.BottomInclusiveRightExclusive()) };
|
||||
@@ -1174,7 +1202,7 @@ til::point TextBuffer::GetWordStart2(til::point pos, const std::wstring_view wor
|
||||
// 1. move to the beginning of the delimiter class run
|
||||
// 2. (includeWhitespace) if we were on a ControlChar, go back one more delimiter class run
|
||||
const auto initialDelimiter = bufferSize.IsInBounds(pos) ? _GetDelimiterClassAt(pos, wordDelimiters) : DelimiterClass::ControlChar;
|
||||
pos = _GetDelimiterClassRunStart(pos, wordDelimiters);
|
||||
pos = _GetDelimiterClassRunStart(pos, wordDelimiters, includeWhitespace);
|
||||
if (!includeWhitespace || pos.x == bufferSize.Left())
|
||||
{
|
||||
// Special case:
|
||||
@@ -1185,12 +1213,26 @@ til::point TextBuffer::GetWordStart2(til::point pos, const std::wstring_view wor
|
||||
else if (initialDelimiter == DelimiterClass::ControlChar)
|
||||
{
|
||||
bufferSize.DecrementInExclusiveBounds(pos);
|
||||
pos = _GetDelimiterClassRunStart(pos, wordDelimiters);
|
||||
pos = _GetDelimiterClassRunStart(pos, wordDelimiters, includeWhitespace);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
til::point TextBuffer::GetWordEnd2(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional) const
|
||||
// Method Description:
|
||||
// - Get the exclusive end of the word at or after the given position
|
||||
// - When includeWhitespace is false, returns the exclusive end of the current delimiter class run
|
||||
// (selection behavior: stops at non-wrapped row boundaries)
|
||||
// - When includeWhitespace is true, also skips forward past any trailing ControlChars
|
||||
// to include trailing whitespace (accessibility/UIA behavior: crosses all row boundaries)
|
||||
// - The result is clamped to limitOptional when provided
|
||||
// Arguments:
|
||||
// - pos - the buffer position to start from
|
||||
// - wordDelimiters - characters considered as DelimiterClass::DelimiterChar
|
||||
// - includeWhitespace - when true, skip past trailing whitespace to find the next word boundary
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored
|
||||
// Return Value:
|
||||
// - The exclusive end position of the word
|
||||
til::point TextBuffer::GetWordEnd(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.BottomInclusiveRightExclusive()) };
|
||||
@@ -1223,8 +1265,12 @@ til::point TextBuffer::GetWordEnd2(til::point pos, const std::wstring_view wordD
|
||||
// So the heuristic we use is:
|
||||
// 1. move to the end of the delimiter class run
|
||||
// 2. (includeWhitespace) if the next delimiter class run is a ControlChar, go forward one more delimiter class run
|
||||
pos = _GetDelimiterClassRunEnd(pos, wordDelimiters);
|
||||
if (!includeWhitespace || pos.x == bufferSize.RightExclusive())
|
||||
pos = _GetDelimiterClassRunEnd(pos, wordDelimiters, includeWhitespace);
|
||||
if (pos >= limit)
|
||||
{
|
||||
return limit;
|
||||
}
|
||||
else if (!includeWhitespace || pos.x == bufferSize.RightExclusive())
|
||||
{
|
||||
// Special case:
|
||||
// we're at the right boundary (and end of a delimiter class run),
|
||||
@@ -1235,7 +1281,8 @@ til::point TextBuffer::GetWordEnd2(til::point pos, const std::wstring_view wordD
|
||||
if (const auto nextDelimClass = bufferSize.IsInBounds(pos) ? _GetDelimiterClassAt(pos, wordDelimiters) : DelimiterClass::ControlChar;
|
||||
nextDelimClass == DelimiterClass::ControlChar)
|
||||
{
|
||||
return _GetDelimiterClassRunEnd(pos, wordDelimiters);
|
||||
pos = _GetDelimiterClassRunEnd(pos, wordDelimiters, includeWhitespace);
|
||||
return std::min(pos, limit);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
@@ -1288,29 +1335,48 @@ bool TextBuffer::IsWordBoundary(const til::point pos, const std::wstring_view wo
|
||||
return prevDelimiterClass != currentDelimiterClass && currentDelimiterClass != DelimiterClass::ControlChar;
|
||||
}
|
||||
|
||||
til::point TextBuffer::_GetDelimiterClassRunStart(til::point pos, const std::wstring_view wordDelimiters) const
|
||||
// Method Description:
|
||||
// - Get the start position for the current delimiter class run, scanning backward
|
||||
// - Stops when the delimiter class changes or a row boundary is reached
|
||||
// - When accessibilityMode is true, freely crosses non-wrapped row boundaries
|
||||
// - When accessibilityMode is false, only crosses wrap-forced row boundaries
|
||||
// Arguments:
|
||||
// - pos - the buffer position to start scanning from
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - accessibilityMode - when true, cross non-wrapped row boundaries freely
|
||||
// Return Value:
|
||||
// - The position of the first character in the current delimiter class run (inclusive)
|
||||
til::point TextBuffer::_GetDelimiterClassRunStart(til::point pos, const std::wstring_view wordDelimiters, const bool accessibilityMode) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
const auto initialDelimClass = bufferSize.IsInBounds(pos) ? _GetDelimiterClassAt(pos, wordDelimiters) : DelimiterClass::ControlChar;
|
||||
for (auto nextPos = pos; nextPos != bufferSize.Origin(); pos = nextPos)
|
||||
auto nextPos = pos;
|
||||
while (nextPos != bufferSize.Origin())
|
||||
{
|
||||
bufferSize.DecrementInExclusiveBounds(nextPos);
|
||||
|
||||
if (nextPos.x == bufferSize.RightExclusive())
|
||||
{
|
||||
// wrapped onto previous line,
|
||||
// check if it was forced to wrap
|
||||
// wrapped onto previous line
|
||||
const auto& row = GetRowByOffset(nextPos.y);
|
||||
if (!row.WasWrapForced())
|
||||
if (!row.WasWrapForced() && !accessibilityMode)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
// In accessibility mode (or if row was wrap-forced), continue
|
||||
// across the row boundary. The actual last character of the
|
||||
// previous row will be checked on the next iteration.
|
||||
// Don't update pos to avoid storing a transient position
|
||||
}
|
||||
else if (_GetDelimiterClassAt(nextPos, wordDelimiters) != initialDelimClass)
|
||||
{
|
||||
// if we changed delim class, we're done (don't apply move)
|
||||
return pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = nextPos;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
@@ -1320,7 +1386,8 @@ til::point TextBuffer::_GetDelimiterClassRunStart(til::point pos, const std::wst
|
||||
// Arguments:
|
||||
// - pos - the buffer position being within the current delimiter class
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
til::point TextBuffer::_GetDelimiterClassRunEnd(til::point pos, const std::wstring_view wordDelimiters) const
|
||||
// - accessibilityMode - when true, cross non-wrapped row boundaries freely
|
||||
til::point TextBuffer::_GetDelimiterClassRunEnd(til::point pos, const std::wstring_view wordDelimiters, const bool accessibilityMode) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
const auto initialDelimClass = bufferSize.IsInBounds(pos) ? _GetDelimiterClassAt(pos, wordDelimiters) : DelimiterClass::ControlChar;
|
||||
@@ -1333,7 +1400,16 @@ til::point TextBuffer::_GetDelimiterClassRunEnd(til::point pos, const std::wstri
|
||||
// wrapped onto next line,
|
||||
// check if it was forced to wrap or switched delimiter class
|
||||
const auto& row = GetRowByOffset(pos.y);
|
||||
if (!row.WasWrapForced() || _GetDelimiterClassAt(nextPos, wordDelimiters) != initialDelimClass)
|
||||
if (accessibilityMode)
|
||||
{
|
||||
// In accessibility mode, always cross row boundaries,
|
||||
// but still stop if the delimiter class changes
|
||||
if (_GetDelimiterClassAt(nextPos, wordDelimiters) != initialDelimClass)
|
||||
{
|
||||
return nextPos;
|
||||
}
|
||||
}
|
||||
else if (!row.WasWrapForced() || _GetDelimiterClassAt(nextPos, wordDelimiters) != initialDelimClass)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
@@ -1348,283 +1424,6 @@ til::point TextBuffer::_GetDelimiterClassRunEnd(til::point pos, const std::wstri
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the til::point for the beginning of the word you are on
|
||||
// Arguments:
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - accessibilityMode - when enabled, we continue expanding left until we are at the beginning of a readable word.
|
||||
// Otherwise, expand left until a character of a new delimiter class is found
|
||||
// (or a row boundary is encountered)
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - The til::point for the first character on the "word" (inclusive)
|
||||
til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// Consider a buffer with this text in it:
|
||||
// " word other "
|
||||
// In selection (accessibilityMode = false),
|
||||
// a "word" is defined as the range between two delimiters
|
||||
// so the words in the example include [" ", "word", " ", "other", " "]
|
||||
// In accessibility (accessibilityMode = true),
|
||||
// a "word" includes the delimiters after a range of readable characters
|
||||
// so the words in the example include ["word ", "other "]
|
||||
// NOTE: the start anchor (this one) is inclusive, whereas the end anchor (GetWordEnd) is exclusive
|
||||
|
||||
#pragma warning(suppress : 26496)
|
||||
auto copy{ target };
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
if (target == bufferSize.Origin())
|
||||
{
|
||||
// can't expand left
|
||||
return target;
|
||||
}
|
||||
else if (target == bufferSize.EndExclusive())
|
||||
{
|
||||
// GH#7664: Treat EndExclusive as EndInclusive so
|
||||
// that it actually points to a space in the buffer
|
||||
copy = bufferSize.BottomRightInclusive();
|
||||
}
|
||||
else if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||
{
|
||||
// if at/past the limit --> clamp to limit
|
||||
copy = limitOptional.value_or(bufferSize.BottomRightInclusive());
|
||||
}
|
||||
|
||||
if (accessibilityMode)
|
||||
{
|
||||
return _GetWordStartForAccessibility(copy, wordDelimiters);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _GetWordStartForSelection(copy, wordDelimiters);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (accessibility definition) you are on
|
||||
// Arguments:
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The til::point for the first character on the current/previous READABLE "word" (inclusive)
|
||||
til::point TextBuffer::_GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
auto result = target;
|
||||
const auto bufferSize = GetSize();
|
||||
|
||||
// ignore left boundary. Continue until readable text found
|
||||
while (_GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
|
||||
{
|
||||
if (result == bufferSize.Origin())
|
||||
{
|
||||
//looped around and hit origin (no word between origin and target)
|
||||
return result;
|
||||
}
|
||||
bufferSize.DecrementInBounds(result);
|
||||
}
|
||||
|
||||
// make sure we expand to the left boundary or the beginning of the word
|
||||
while (_GetDelimiterClassAt(result, wordDelimiters) == DelimiterClass::RegularChar)
|
||||
{
|
||||
if (result == bufferSize.Origin())
|
||||
{
|
||||
// first char in buffer is a RegularChar
|
||||
// we can't move any further back
|
||||
return result;
|
||||
}
|
||||
bufferSize.DecrementInBounds(result);
|
||||
}
|
||||
|
||||
// move off of delimiter
|
||||
bufferSize.IncrementInBounds(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (selection definition) you are on
|
||||
// Arguments:
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The til::point for the first character on the current word or delimiter run (stopped by the left margin)
|
||||
til::point TextBuffer::_GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
auto result = target;
|
||||
const auto bufferSize = GetSize();
|
||||
|
||||
const auto initialDelimiter = _GetDelimiterClassAt(result, wordDelimiters);
|
||||
const bool isControlChar = initialDelimiter == DelimiterClass::ControlChar;
|
||||
|
||||
// expand left until we hit the left boundary or a different delimiter class
|
||||
while (result != bufferSize.Origin() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
||||
{
|
||||
if (result.x == bufferSize.Left())
|
||||
{
|
||||
// Prevent wrapping to the previous line if the selection begins on whitespace
|
||||
if (isControlChar)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.y > 0)
|
||||
{
|
||||
// Prevent wrapping to the previous line if it was hard-wrapped (e.g. not forced by us to wrap)
|
||||
const auto& priorRow = GetRowByOffset(result.y - 1);
|
||||
if (!priorRow.WasWrapForced())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bufferSize.DecrementInBounds(result);
|
||||
}
|
||||
|
||||
if (_GetDelimiterClassAt(result, wordDelimiters) != initialDelimiter)
|
||||
{
|
||||
// move off of delimiter
|
||||
bufferSize.IncrementInBounds(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the til::point for the beginning of the NEXT word
|
||||
// Arguments:
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - accessibilityMode - when enabled, we continue expanding right until we are at the beginning of the next READABLE word
|
||||
// Otherwise, expand right until a character of a new delimiter class is found
|
||||
// (or a row boundary is encountered)
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - The til::point for the last character on the "word" (inclusive)
|
||||
til::point TextBuffer::GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// Consider a buffer with this text in it:
|
||||
// " word other "
|
||||
// In selection (accessibilityMode = false),
|
||||
// a "word" is defined as the range between two delimiters
|
||||
// so the words in the example include [" ", "word", " ", "other", " "]
|
||||
// In accessibility (accessibilityMode = true),
|
||||
// a "word" includes the delimiters after a range of readable characters
|
||||
// so the words in the example include ["word ", "other "]
|
||||
// NOTE: the end anchor (this one) is exclusive, whereas the start anchor (GetWordStart) is inclusive
|
||||
|
||||
// Already at/past the limit. Can't move forward.
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
if (accessibilityMode)
|
||||
{
|
||||
return _GetWordEndForAccessibility(target, wordDelimiters, limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _GetWordEndForSelection(target, wordDelimiters);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the next READABLE word
|
||||
// Arguments:
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - limit - the last "valid" position in the text buffer (to improve performance)
|
||||
// Return Value:
|
||||
// - The til::point for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
||||
til::point TextBuffer::_GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const
|
||||
{
|
||||
const auto bufferSize{ GetSize() };
|
||||
auto result{ target };
|
||||
|
||||
if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||
{
|
||||
// if we're already on/past the last RegularChar,
|
||||
// clamp result to that position
|
||||
result = limit;
|
||||
|
||||
// make the result exclusive
|
||||
bufferSize.IncrementInBounds(result, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (result != limit && result != bufferSize.BottomRightInclusive() && _GetDelimiterClassAt(result, wordDelimiters) == DelimiterClass::RegularChar)
|
||||
{
|
||||
// Iterate through readable text
|
||||
bufferSize.IncrementInBounds(result);
|
||||
}
|
||||
|
||||
while (result != limit && result != bufferSize.BottomRightInclusive() && _GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
|
||||
{
|
||||
// expand to the beginning of the NEXT word
|
||||
bufferSize.IncrementInBounds(result);
|
||||
}
|
||||
|
||||
// Special case: we tried to move one past the end of the buffer
|
||||
// Manually increment onto the EndExclusive point.
|
||||
if (result == bufferSize.BottomRightInclusive())
|
||||
{
|
||||
bufferSize.IncrementInBounds(result, true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the NEXT word
|
||||
// Arguments:
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The til::point for the last character of the current word or delimiter run (stopped by right margin)
|
||||
til::point TextBuffer::_GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
|
||||
auto result = target;
|
||||
const auto initialDelimiter = _GetDelimiterClassAt(result, wordDelimiters);
|
||||
const bool isControlChar = initialDelimiter == DelimiterClass::ControlChar;
|
||||
|
||||
// expand right until we hit the right boundary as a ControlChar or a different delimiter class
|
||||
while (result != bufferSize.BottomRightInclusive() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
||||
{
|
||||
if (result.x == bufferSize.RightInclusive())
|
||||
{
|
||||
// Prevent wrapping to the next line if the selection begins on whitespace
|
||||
if (isControlChar)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Prevent wrapping to the next line if this one was hard-wrapped (e.g. not forced by us to wrap)
|
||||
const auto& row = GetRowByOffset(result.y);
|
||||
if (!row.WasWrapForced())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bufferSize.IncrementInBounds(result);
|
||||
}
|
||||
|
||||
if (_GetDelimiterClassAt(result, wordDelimiters) != initialDelimiter)
|
||||
{
|
||||
// move off of delimiter
|
||||
bufferSize.DecrementInBounds(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void TextBuffer::_PruneHyperlinks()
|
||||
{
|
||||
// Check the old first row for hyperlink references
|
||||
@@ -1671,57 +1470,6 @@ void TextBuffer::_PruneHyperlinks()
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update pos to be the position of the first character of the next word. This is used for accessibility
|
||||
// Arguments:
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The til::point for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// move to the beginning of the next word
|
||||
// NOTE: _GetWordEnd...() returns the exclusive position of the "end of the word"
|
||||
// This is also the inclusive start of the next word.
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit) };
|
||||
|
||||
if (bufferSize.CompareInBounds(copy, limit, true) >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pos = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update pos to be the position of the first character of the previous word. This is used for accessibility
|
||||
// Arguments:
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The til::point for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToPreviousWord(til::point& pos, std::wstring_view wordDelimiters) const
|
||||
{
|
||||
// move to the beginning of the current word
|
||||
auto copy{ GetWordStart(pos, wordDelimiters, true) };
|
||||
|
||||
if (!GetSize().DecrementInBounds(copy, true))
|
||||
{
|
||||
// can't move behind current word
|
||||
return false;
|
||||
}
|
||||
|
||||
// move to the beginning of the previous word
|
||||
pos = GetWordStart(copy, wordDelimiters, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update pos to be the beginning of the current glyph/character. This is used for accessibility
|
||||
// Arguments:
|
||||
@@ -3779,3 +3527,34 @@ void TextBuffer::ManuallyMarkRowAsPrompt(til::CoordType y)
|
||||
attr.SetMarkAttributes(MarkKind::Prompt);
|
||||
}
|
||||
}
|
||||
|
||||
// This is an optimization used by the renderer to avoid scheduling a timer if not necessary;
|
||||
// unlike the renderer, we know the committed range of our own buffer.
|
||||
bool TextBuffer::ContainsBlinkAttributeInRegion(const Microsoft::Console::Types::Viewport& region) const
|
||||
{
|
||||
const auto top = region.Top();
|
||||
auto bottom = std::min(region.BottomInclusive(), _estimateOffsetOfLastCommittedRow());
|
||||
|
||||
for (auto row = top; row < bottom; ++row)
|
||||
{
|
||||
const auto& r = GetRowByOffset(row);
|
||||
for (const auto& attr : r.Attributes())
|
||||
{
|
||||
if (attr.IsBlinking())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextBuffer::IsGlyphDoubleWidthAt(const til::point at) const
|
||||
{
|
||||
if (!_isRowCommitted(at.y)) [[unlikely]]
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return _getRow(at.y).DbcsAttrAt(at.x) != DbcsAttribute::Single;
|
||||
}
|
||||
|
||||
@@ -172,15 +172,10 @@ public:
|
||||
void TriggerNewTextNotification(const std::wstring_view newText);
|
||||
void TriggerSelection();
|
||||
|
||||
til::point GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
|
||||
til::point GetWordStart2(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetWordEnd2(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetWordStart(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetWordEnd(til::point pos, const std::wstring_view wordDelimiters, bool includeWhitespace, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
|
||||
bool IsWordBoundary(const til::point pos, const std::wstring_view wordDelimiters) const;
|
||||
bool MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToPreviousWord(til::point& pos, const std::wstring_view wordDelimiters) const;
|
||||
|
||||
til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
@@ -315,6 +310,9 @@ public:
|
||||
void SetScrollbarData(ScrollbarData mark, til::CoordType y);
|
||||
void ManuallyMarkRowAsPrompt(til::CoordType y);
|
||||
|
||||
bool ContainsBlinkAttributeInRegion(const Microsoft::Console::Types::Viewport& region) const;
|
||||
bool IsGlyphDoubleWidthAt(const til::point at) const;
|
||||
|
||||
private:
|
||||
void _reserve(til::size screenBufferSize, const TextAttribute& defaultAttributes);
|
||||
void _commit(const std::byte* row);
|
||||
@@ -324,16 +322,13 @@ private:
|
||||
ROW& _getRowByOffsetDirect(size_t offset);
|
||||
ROW& _getRow(til::CoordType y) const;
|
||||
til::CoordType _estimateOffsetOfLastCommittedRow() const noexcept;
|
||||
bool _isRowCommitted(til::CoordType y) const noexcept;
|
||||
|
||||
void _SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept;
|
||||
void _ExpandTextRow(til::inclusive_rect& selectionRow) const;
|
||||
DelimiterClass _GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetDelimiterClassRunStart(til::point pos, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetDelimiterClassRunEnd(til::point pos, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const;
|
||||
til::point _GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetDelimiterClassRunStart(til::point pos, const std::wstring_view wordDelimiters, const bool accessibilityMode = false) const;
|
||||
til::point _GetDelimiterClassRunEnd(til::point pos, const std::wstring_view wordDelimiters, const bool accessibilityMode = false) const;
|
||||
void _PruneHyperlinks();
|
||||
|
||||
std::wstring _commandForRow(const til::CoordType rowOffset, const til::CoordType bottomInclusive, const bool clipAtCursor = false) const;
|
||||
|
||||
@@ -34,6 +34,16 @@ class UTextAdapterTests
|
||||
{
|
||||
TEST_CLASS(UTextAdapterTests);
|
||||
|
||||
TEST_CLASS_SETUP(ClassSetup)
|
||||
{
|
||||
wil::unique_hmodule icu{ LoadLibraryExW(L"icu.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) };
|
||||
if (!icu)
|
||||
{
|
||||
WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ICU is not present");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_METHOD(Unicode)
|
||||
{
|
||||
DummyRenderer renderer;
|
||||
|
||||
@@ -26,6 +26,9 @@ TARGETLIBS = \
|
||||
$(CONSOLE_OBJ_PATH)\types\lib\$(O)\ConTypes.lib \
|
||||
$(TARGETLIBS) \
|
||||
|
||||
DELAYLOAD = \
|
||||
icu.dll \
|
||||
|
||||
# -------------------------------------
|
||||
# Localization
|
||||
# -------------------------------------
|
||||
|
||||
@@ -237,7 +237,6 @@
|
||||
<Capability Name="internetClient" />
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<rescap:Capability Name="unvirtualizedResources" />
|
||||
<rescap:Capability Name="appLicensing" />
|
||||
</Capabilities>
|
||||
|
||||
<Extensions>
|
||||
|
||||
@@ -237,7 +237,6 @@
|
||||
<Capability Name="internetClient" />
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<rescap:Capability Name="unvirtualizedResources" />
|
||||
<rescap:Capability Name="appLicensing" />
|
||||
</Capabilities>
|
||||
|
||||
<Extensions>
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
ResourceKey="TabViewBackground" />
|
||||
|
||||
<SolidColorBrush x:Key="SettingsUiTabBrush"
|
||||
Color="#0c0c0c" />
|
||||
Color="#282828" />
|
||||
|
||||
<SolidColorBrush x:Key="BroadcastPaneBorderColor"
|
||||
Color="{StaticResource SystemAccentColorDark2}" />
|
||||
@@ -211,7 +211,7 @@
|
||||
ResourceKey="TabViewBackground" />
|
||||
|
||||
<SolidColorBrush x:Key="SettingsUiTabBrush"
|
||||
Color="#ffffff" />
|
||||
Color="#F9F9F9" />
|
||||
|
||||
<SolidColorBrush x:Key="BroadcastPaneBorderColor"
|
||||
Color="{StaticResource SystemAccentColorLight2}" />
|
||||
@@ -234,7 +234,7 @@
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsUiTabBrush"
|
||||
ResourceKey="SystemControlBackgroundBaseLowBrush" />
|
||||
ResourceKey="SystemColorWindowBrush" />
|
||||
|
||||
<SolidColorBrush x:Key="BroadcastPaneBorderColor"
|
||||
Color="{StaticResource SystemColorHighlightColor}" />
|
||||
|
||||
@@ -499,8 +499,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto resizeSucceeded = _ResizePane(realArgs.ResizeDirection());
|
||||
args.Handled(resizeSucceeded);
|
||||
_ResizePane(realArgs.ResizeDirection());
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -801,7 +801,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_RemoveTabs(tabsToRemove);
|
||||
|
||||
actionArgs.Handled(true);
|
||||
actionArgs.Handled(!tabsToRemove.empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,7 +837,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// tab row, until you mouse over them. Probably has something to do
|
||||
// with tabs not resizing down until there's a mouse exit event.
|
||||
|
||||
actionArgs.Handled(true);
|
||||
actionArgs.Handled(!tabsToRemove.empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1475,7 +1475,7 @@ namespace winrt::TerminalApp::implementation
|
||||
WI_IsAnyFlagSet(source, SuggestionsSource::CommandHistory | SuggestionsSource::QuickFixes);
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
currentWorkingDirectory = control.CurrentWorkingDirectory();
|
||||
currentWorkingDirectory = control.WorkingDirectory();
|
||||
|
||||
if (shouldGetContext)
|
||||
{
|
||||
|
||||
@@ -1068,6 +1068,15 @@ int AppCommandlineArgs::ParseArgs(winrt::array_view<const winrt::hstring> args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When a toast notification is clicked, Windows may launch a new instance
|
||||
// with "__fromToast" as the argument. This is a no-op sentinel — the
|
||||
// in-process Activated handler on the toast already handled activation.
|
||||
// See DesktopNotification.cpp for more details.
|
||||
if (args.size() == 2 && args[1] == L"__fromToast")
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto commands = ::TerminalApp::AppCommandlineArgs::BuildCommands(args);
|
||||
|
||||
for (auto& cmdBlob : commands)
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<IPaneContent> TaskbarProgressChanged;
|
||||
til::typed_event<IPaneContent> ReadOnlyChanged;
|
||||
til::typed_event<IPaneContent> FocusRequested;
|
||||
til::typed_event<IPaneContent, winrt::TerminalApp::NotificationEventArgs> NotificationRequested;
|
||||
|
||||
til::typed_event<winrt::Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command> DispatchCommandRequested;
|
||||
};
|
||||
|
||||
129
src/cascadia/TerminalApp/DesktopNotification.cpp
Normal file
129
src/cascadia/TerminalApp/DesktopNotification.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "DesktopNotification.h"
|
||||
|
||||
#include <WtExeUtils.h>
|
||||
|
||||
using namespace winrt::Windows::UI::Notifications;
|
||||
using namespace winrt::Windows::Data::Xml::Dom;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
std::atomic<int64_t> DesktopNotification::_lastNotificationTime{ 0 };
|
||||
|
||||
// Method Description:
|
||||
// - Rate-limits toast notifications so we don't spam the user.
|
||||
// Return Value:
|
||||
// - Returns true if a notification is allowed, false if too recent.
|
||||
bool DesktopNotification::ShouldSendNotification()
|
||||
{
|
||||
FILETIME ft{};
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
const auto now = (static_cast<int64_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
|
||||
auto last = _lastNotificationTime.load(std::memory_order_relaxed);
|
||||
|
||||
if (now - last < MinNotificationIntervalTicks)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to update; if another thread beat us, that's fine — we'll skip this one.
|
||||
return _lastNotificationTime.compare_exchange_strong(last, now, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sends a toast notification with the given title and message.
|
||||
// - When the user clicks the toast, the `Activated` callback fires
|
||||
// with the tabIndex that was passed in, so the caller can switch
|
||||
// to the correct tab and summon the window.
|
||||
// Arguments:
|
||||
// - args: The title, message, and tab index to include in the notification.
|
||||
// - activated: A callback invoked on the background thread when the
|
||||
// toast is clicked. The uint32_t parameter is the tab index.
|
||||
void DesktopNotification::SendNotification(const DesktopNotificationArgs& args, std::function<void()> activatedFunc)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldSendNotification())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the toast XML. We use a simple template with a title and body text.
|
||||
//
|
||||
// <toast launch="__fromToast">
|
||||
// <visual>
|
||||
// <binding template="ToastGeneric">
|
||||
// <text>Title</text>
|
||||
// <text>Message</text>
|
||||
// </binding>
|
||||
// </visual>
|
||||
// </toast>
|
||||
auto toastXml = ToastNotificationManager::GetTemplateContent(ToastTemplateType::ToastText02);
|
||||
auto textNodes = toastXml.GetElementsByTagName(L"text");
|
||||
|
||||
// First <text> is the title
|
||||
textNodes.Item(0).InnerText(args.Title);
|
||||
// Second <text> is the body
|
||||
textNodes.Item(1).InnerText(args.Message);
|
||||
|
||||
auto toastElement = toastXml.DocumentElement();
|
||||
|
||||
// When a toast is clicked, Windows launches a new instance of the app
|
||||
// with the "launch" attribute as command-line arguments. We handle
|
||||
// toast activation in-process via the Activated event below, so the
|
||||
// new instance should do nothing. "__fromToast" is recognized by
|
||||
// AppCommandlineArgs::ParseArgs as a no-op sentinel.
|
||||
toastElement.SetAttribute(L"launch", L"__fromToast");
|
||||
|
||||
toastElement.SetAttribute(L"scenario", L"default");
|
||||
|
||||
auto toast = ToastNotification{ toastXml };
|
||||
|
||||
// Set the tag and group to enable notification replacement.
|
||||
// Repeated notifications with the same tag replace the previous one
|
||||
// rather than stacking in the notification center.
|
||||
toast.Tag(args.Tag);
|
||||
toast.Group(L"WindowsTerminal");
|
||||
|
||||
// When the user activates (clicks) the toast, fire the callback.
|
||||
if (activatedFunc)
|
||||
{
|
||||
toast.Activated([activatedFunc](const auto& /*sender*/, const auto& /*eventArgs*/) {
|
||||
activatedFunc();
|
||||
});
|
||||
}
|
||||
|
||||
// For packaged apps, CreateToastNotifier() uses the package identity automatically.
|
||||
// For unpackaged apps, we must pass the explicit AUMID that was registered
|
||||
// at startup via SetCurrentProcessExplicitAppUserModelID.
|
||||
winrt::Windows::UI::Notifications::ToastNotifier notifier{ nullptr };
|
||||
if (IsPackaged())
|
||||
{
|
||||
notifier = ToastNotificationManager::CreateToastNotifier();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Retrieve the AUMID that was set by WindowEmperor at startup.
|
||||
wil::unique_cotaskmem_string aumid;
|
||||
if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&aumid)))
|
||||
{
|
||||
notifier = ToastNotificationManager::CreateToastNotifier(aumid.get());
|
||||
}
|
||||
}
|
||||
if (notifier)
|
||||
{
|
||||
notifier.Show(toast);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Toast notification is a best-effort feature. If it fails (e.g., notifications
|
||||
// are disabled, or the app is unpackaged without proper AUMID setup), we silently
|
||||
// ignore the error.
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/cascadia/TerminalApp/DesktopNotification.h
Normal file
38
src/cascadia/TerminalApp/DesktopNotification.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- DesktopNotification.h
|
||||
|
||||
Module Description:
|
||||
- Helper for sending Windows desktop toast notifications. Used to surface
|
||||
terminal activity events to the user via the Windows notification center.
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct DesktopNotificationArgs
|
||||
{
|
||||
winrt::hstring Title;
|
||||
winrt::hstring Message;
|
||||
winrt::hstring Tag;
|
||||
};
|
||||
|
||||
class DesktopNotification
|
||||
{
|
||||
public:
|
||||
static bool ShouldSendNotification();
|
||||
static void SendNotification(const DesktopNotificationArgs& args, std::function<void()> activatedFunc);
|
||||
|
||||
private:
|
||||
static std::atomic<int64_t> _lastNotificationTime;
|
||||
|
||||
// Minimum interval between notifications, in 100ns ticks (FILETIME units).
|
||||
// 5 seconds = 5 * 10,000,000
|
||||
static constexpr int64_t MinNotificationIntervalTicks = 50'000'000LL;
|
||||
};
|
||||
}
|
||||
@@ -14,6 +14,15 @@ namespace TerminalApp
|
||||
runtimeclass BellEventArgs
|
||||
{
|
||||
Boolean FlashTaskbar { get; };
|
||||
Boolean SendNotification { get; };
|
||||
};
|
||||
|
||||
runtimeclass NotificationEventArgs
|
||||
{
|
||||
Microsoft.Terminal.Control.OutputNotificationStyle Style { get; };
|
||||
Boolean OnlyWhenInactive { get; };
|
||||
String Title { get; };
|
||||
String Body { get; };
|
||||
};
|
||||
|
||||
interface IPaneContent
|
||||
@@ -46,6 +55,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> TaskbarProgressChanged;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> ReadOnlyChanged;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> FocusRequested;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, NotificationEventArgs> NotificationRequested;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,10 +31,14 @@ Pane::Pane(IPaneContent content, const bool lastFocused) :
|
||||
_lastActive{ lastFocused }
|
||||
{
|
||||
_setPaneContent(std::move(content));
|
||||
_root.Children().Append(_borderFirst);
|
||||
_CreatePaneHeader();
|
||||
|
||||
const auto& control{ _content.GetRoot() };
|
||||
_borderFirst.Child(control);
|
||||
|
||||
// Set up leaf layout: header in _root row 0, content in _borderFirst row 1.
|
||||
// The TermControl stays as the direct child of _borderFirst (no Grid wrapper)
|
||||
// so the SwapChainPanel renders correctly.
|
||||
_SetupLeafLayout(control);
|
||||
|
||||
// Register an event with the control to have it inform us when it gains focus.
|
||||
if (control)
|
||||
@@ -1228,6 +1232,12 @@ void Pane::UpdateVisuals()
|
||||
const auto& brush{ _ComputeBorderColor() };
|
||||
_borderFirst.BorderBrush(brush);
|
||||
_borderSecond.BorderBrush(brush);
|
||||
|
||||
// Update pane header color to match focus state
|
||||
if (_paneHeaderBorder && _paneHeaderBorder.Visibility() == winrt::Windows::UI::Xaml::Visibility::Visible)
|
||||
{
|
||||
_paneHeaderBorder.Background(brush);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1450,9 +1460,9 @@ void Pane::_CloseChild(const bool closeFirst)
|
||||
_root.RowDefinitions().Clear();
|
||||
|
||||
// Reattach the TermControl to our grid.
|
||||
_root.Children().Append(_borderFirst);
|
||||
_CreatePaneHeader();
|
||||
const auto& control{ _content.GetRoot() };
|
||||
_borderFirst.Child(control);
|
||||
_SetupLeafLayout(control);
|
||||
|
||||
// Make sure to set our _splitState before focusing the control. If you
|
||||
// fail to do this, when the tab handles the GotFocus event and asks us
|
||||
@@ -1755,7 +1765,92 @@ void Pane::_setPaneContent(IPaneContent content)
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up row/column definitions for this pane. There are three total
|
||||
// - Creates the pane header UI elements (title bar shown above the content).
|
||||
// The header is initially collapsed and only shown via ShowPaneHeaders().
|
||||
void Pane::_CreatePaneHeader()
|
||||
{
|
||||
namespace WUX = winrt::Windows::UI::Xaml;
|
||||
|
||||
_paneHeaderText = Controls::TextBlock{};
|
||||
_paneHeaderText.FontSize(12);
|
||||
_paneHeaderText.Padding({ 8, 2, 8, 2 });
|
||||
_paneHeaderText.IsTextSelectionEnabled(false);
|
||||
_paneHeaderText.TextTrimming(WUX::TextTrimming::CharacterEllipsis);
|
||||
if (_content)
|
||||
{
|
||||
_paneHeaderText.Text(_content.Title());
|
||||
_titleChangedRevoker = _content.TitleChanged(winrt::auto_revoke, [this](auto&&, auto&&) {
|
||||
_paneHeaderBorder.Dispatcher().RunAsync(
|
||||
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
[this]() {
|
||||
if (_content && _paneHeaderText)
|
||||
{
|
||||
_paneHeaderText.Text(_content.Title());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_paneHeaderBorder = Controls::Border{};
|
||||
_paneHeaderBorder.Padding({ 0, 0, 0, 0 });
|
||||
_paneHeaderBorder.Child(_paneHeaderText);
|
||||
_paneHeaderBorder.Visibility(WUX::Visibility::Collapsed);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up the leaf pane layout in _root: a header row (auto-sized) and a
|
||||
// content row (star-sized). The TermControl stays as the direct child of
|
||||
// _borderFirst so the SwapChainPanel renders correctly.
|
||||
void Pane::_SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control)
|
||||
{
|
||||
auto headerRow = Controls::RowDefinition{};
|
||||
headerRow.Height(GridLengthHelper::Auto());
|
||||
auto contentRow = Controls::RowDefinition{};
|
||||
contentRow.Height(GridLengthHelper::FromValueAndType(1, GridUnitType::Star));
|
||||
_root.RowDefinitions().Append(headerRow);
|
||||
_root.RowDefinitions().Append(contentRow);
|
||||
|
||||
Controls::Grid::SetRow(_paneHeaderBorder, 0);
|
||||
Controls::Grid::SetRow(_borderFirst, 1);
|
||||
|
||||
_root.Children().Append(_paneHeaderBorder);
|
||||
_root.Children().Append(_borderFirst);
|
||||
|
||||
if (control)
|
||||
{
|
||||
_borderFirst.Child(control);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Show or hide the pane header title bar on all leaf panes in the tree.
|
||||
// Called by Tab when the number of panes changes.
|
||||
void Pane::ShowPaneHeaders(bool show)
|
||||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
if (_paneHeaderBorder)
|
||||
{
|
||||
namespace WUX = winrt::Windows::UI::Xaml;
|
||||
_paneHeaderBorder.Visibility(show ? WUX::Visibility::Visible : WUX::Visibility::Collapsed);
|
||||
|
||||
if (show)
|
||||
{
|
||||
const auto& brush = _ComputeBorderColor();
|
||||
_paneHeaderBorder.Background(brush);
|
||||
_paneHeaderText.Foreground(winrt::Windows::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::White()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_firstChild->ShowPaneHeaders(show);
|
||||
_secondChild->ShowPaneHeaders(show);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up row/column definitions for this pane.There are three total
|
||||
// row/cols. The middle one is for the separator. The first and third are for
|
||||
// each of the child panes, and are given a size in pixels, based off the
|
||||
// available space, and the percent of the space they respectively consume,
|
||||
@@ -2321,6 +2416,10 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
|
||||
_root.RowDefinitions().Clear();
|
||||
_CreateRowColDefinitions();
|
||||
|
||||
// Reset Grid.Row on _borderFirst — it may have been set to row 1 in the
|
||||
// leaf layout (header=row0, content=row1).
|
||||
Controls::Grid::SetRow(_borderFirst, 0);
|
||||
|
||||
_borderFirst.Child(_firstChild->GetRootElement());
|
||||
_borderSecond.Child(_secondChild->GetRootElement());
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ public:
|
||||
bool ContainsReadOnly() const;
|
||||
|
||||
void EnableBroadcast(bool enabled);
|
||||
void ShowPaneHeaders(bool show);
|
||||
void BroadcastKey(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool keyDown);
|
||||
void BroadcastChar(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const wchar_t vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers);
|
||||
void BroadcastString(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const winrt::hstring& text);
|
||||
@@ -235,6 +236,11 @@ private:
|
||||
winrt::Windows::UI::Xaml::Controls::Border _borderFirst{};
|
||||
winrt::Windows::UI::Xaml::Controls::Border _borderSecond{};
|
||||
|
||||
// Per-pane title header (visible when there are split panes)
|
||||
winrt::Windows::UI::Xaml::Controls::Border _paneHeaderBorder{ nullptr };
|
||||
winrt::Windows::UI::Xaml::Controls::TextBlock _paneHeaderText{ nullptr };
|
||||
winrt::TerminalApp::IPaneContent::TitleChanged_revoker _titleChangedRevoker;
|
||||
|
||||
PaneResources _themeResources;
|
||||
|
||||
#pragma region Properties that need to be transferred between child / parent panes upon splitting / closing
|
||||
@@ -266,6 +272,8 @@ private:
|
||||
void _SetupChildCloseHandlers();
|
||||
winrt::TerminalApp::IPaneContent _takePaneContent();
|
||||
void _setPaneContent(winrt::TerminalApp::IPaneContent content);
|
||||
void _CreatePaneHeader();
|
||||
void _SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control);
|
||||
bool _HasChild(const std::shared_ptr<Pane> child);
|
||||
winrt::TerminalApp::TerminalPaneContent _getTerminalContent() const;
|
||||
|
||||
|
||||
@@ -672,15 +672,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Dieser Linktyp wird derzeit nicht unterstützt:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Abbrechen</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Dieser Link kann zu einem unsicheren Speicherort führen. Links können ihren Computer und Ihre Daten beschädigen. Klicken Sie zum Schutz Des Computers nur auf Links aus vertrauenswürdigen Quellen.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Trotzdem öffnen</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Einstellungen</value>
|
||||
</data>
|
||||
@@ -854,11 +848,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>Der aktive Bereich wurde auf die Registerkarte „{0}“ verschoben</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>Registerkarte „{0}“ wurde in das Fenster „{1}“ verschoben</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Registerkarte „{0}“ in neues Fenster verschoben</value>
|
||||
@@ -870,7 +864,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Der aktive Bereich wurde in das Fenster "{0}" verschoben</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Aktiver Bereich in neues Fenster verschoben</value>
|
||||
|
||||
@@ -496,24 +496,48 @@
|
||||
<value>Third-Party notices</value>
|
||||
<comment>A hyperlink name for the Terminal's third-party notices</comment>
|
||||
</data>
|
||||
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Close all</value>
|
||||
</data>
|
||||
<data name="QuitDialog.Title" xml:space="preserve">
|
||||
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
|
||||
<value>Do you want to close all windows?</value>
|
||||
</data>
|
||||
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
|
||||
<value>Close all</value>
|
||||
</data>
|
||||
<data name="CloseAllDialog.Title" xml:space="preserve">
|
||||
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
|
||||
<value>Do you want to close all tabs?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
|
||||
<value>Close all</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
|
||||
<value>Do you want to close this tab?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
|
||||
<value>Close tab</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
|
||||
<value>Do you want to close this pane?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
|
||||
<value>Close pane</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
|
||||
<value>Do you want to close these tabs?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
|
||||
<value>Close tabs</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
|
||||
<value>Do you want to close these panes?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
|
||||
<value>Close panes</value>
|
||||
</data>
|
||||
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
|
||||
<value>Don't ask me again</value>
|
||||
</data>
|
||||
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
@@ -745,6 +769,14 @@
|
||||
<value>Windows</value>
|
||||
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
|
||||
</data>
|
||||
<data name="NotificationMessage_TabActivity" xml:space="preserve">
|
||||
<value>Activity in tab "{0}"</value>
|
||||
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
|
||||
</data>
|
||||
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
|
||||
<value>Activity in tab "{0}" (window "{1}")</value>
|
||||
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
|
||||
</data>
|
||||
<data name="DropPathTabRun.Text" xml:space="preserve">
|
||||
<value>Open a new tab in given starting directory</value>
|
||||
</data>
|
||||
@@ -881,10 +913,10 @@
|
||||
<value>If set, the command will be appended to the profile's default command instead of replacing it.</value>
|
||||
</data>
|
||||
<data name="RestartConnectionText" xml:space="preserve">
|
||||
<value>Restart connection</value>
|
||||
<value>Restart session</value>
|
||||
</data>
|
||||
<data name="RestartConnectionToolTip" xml:space="preserve">
|
||||
<value>Restart the active pane connection</value>
|
||||
<value>Restart the active pane session</value>
|
||||
</data>
|
||||
<data name="SnippetPaneTitle.Text" xml:space="preserve">
|
||||
<value>Snippets</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Este tipo de vínculo no se admite actualmente:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Cancelar</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Este vínculo puede dar lugar a una ubicación no segura. Los hipervínculos pueden ser perjudiciales para el equipo y los datos. Para proteger el equipo, haga clic solo en vínculos de orígenes de confianza.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Abrir de todas formas</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Configuración</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>Panel activo movido a la pestaña "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>La pestaña "{0}" se ha movido a la ventana "{1}"</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>La pestaña "{0}" se ha movido a la nueva ventana</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Panel activo movido a la ventana "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Panel activo movido a nueva ventana</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ce type de lien n’est actuellement pas pris en charge :</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Annuler</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ce lien peut entraîner un emplacement non sécurisé. Les liens hypertexte peuvent endommager votre ordinateur et vos données. Pour protéger votre ordinateur, cliquez uniquement sur des liens provenant de sources fiables.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Ouvrir quand même</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Paramètres</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>Volet actif déplacé vers l’onglet « {0} »</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>Onglet « {0} » déplacé vers la fenêtre « {1} »</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Onglet « {0} » déplacé vers une nouvelle fenêtre</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Volet actif déplacé vers l’onglet « {0} »</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Volet actif déplacé vers une nouvelle fenêtre</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Questo tipo di collegamento non è al momento supportato:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Annulla</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Questo collegamento potrebbe causare un percorso non sicuro. I collegamenti ipertestuali possono essere dannosi per il computer e i dati. Per proteggere il computer, fare clic solo su collegamenti da origini attendibili.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Apri comunque</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Impostazioni</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>Riquadro attivo spostato nella scheda "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>Scheda "{0}" spostata nella finestra "{1}"</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Scheda "{0}" spostata in una nuova finestra</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Riquadro attivo spostato nella finestra "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Riquadro attivo spostato in una nuova finestra</value>
|
||||
|
||||
@@ -670,15 +670,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>このリンクの種類は現在サポートされていません:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>キャンセル</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>このリンクは安全でない可能性があります。ハイパーリンクは、コンピューターやデータに問題を起こす可能性があります。コンピューターを保護するには、信頼できるソースからのリンクのみをクリックしてください。</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>開く</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
@@ -852,11 +846,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>アクティブなペインを [{0}] タブに移動しました</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>[{0}] タブを "{1}" ウィンドウに移動しました</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>[{0}] タブを新しいウィンドウに移動しました</value>
|
||||
@@ -868,7 +862,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>アクティブなペインを "{0}" ウィンドウに移動しました</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>アクティブなペインを新しいウィンドウに移動しました</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>이 링크 형식은 현재 지원되지 않습니다.</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>취소</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>이 링크로 인해 안전하지 않은 위치가 발생할 수 있습니다. 하이퍼링크는 컴퓨터와 데이터를 손상시킬 수 있습니다. 컴퓨터를 보호하려면 신뢰할 수 있는 원본의 링크만 클릭하세요.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>열기</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>설정</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>활성 창이 "{0}" 탭으로 이동됨</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>"{0}" 탭이 "{1}" 창으로 이동됨</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>"{0}" 탭이 새 창으로 이동됨</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>활성 창이 "{0}" 창으로 이동됨</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>활성 창이 새 창으로 이동됨</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Não há suporte para este tipo de link no momento:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Cancelar</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Este link pode levar a um local não seguro. Hiperlinks podem ser prejudiciais ao computador e aos dados. Para proteger o computador, clique somente em links de fontes confiáveis.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Abrir mesmo assim</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Configurações</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>Painel ativo movido para a guia "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>Guia "{0}" movida para janela "{1}"</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Guia "{0}" movida para nova janela</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Painel ativo movido para a janela "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Painel ativo movido para nova janela</value>
|
||||
|
||||
@@ -669,14 +669,8 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ťђïś łϊηќ ŧурē ιş çũґѓзⁿτľÿ ñστ şΰρρоŕŧĕđ: !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Çдπсёľ !</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ŧђīś ℓîŋќ мαў ľêãδ τб áń úʼnšàƒé ℓоćάŧίоñ. Ĥўрзŗℓĭŋķѕ çâⁿ ъέ ђąřмƒúļ τό ўôця ċómφύŧèґ аňδ ðáťǻ. Ţб ρгøťėçŧ ўòύг ςömφùţĕŕ, ŏŋľỳ čℓΐςķ łίŋκѕ ƒřöм ťŗμѕŧєđ śόυяčêś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Őρέй ǻпŷŵãγ !!!</value>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Сąñс℮ł !</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Śëţťĩпğś !!</value>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>∆çťíνĕ рåⁿэ мôνеð ťб "{0}" ţав !!! !!! !!!</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>"{0}" ťāъ мōνęđ τŏ "{1}" шΐπδŏẅ !!! !!! !!!</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>"{0}" тąь mǿνєđ ŧσ ήèώ ẅĩŋďøẃ !!! !!! !!!</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Λςťìνє рáиė mόνéð ťб "{0}" ŵîńđθω !!! !!! !!! </value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Αĉťįνέ ρªņз mσνёđ τǿ ήёẃ ẃîпďǿω !!! !!! !!!</value>
|
||||
|
||||
@@ -669,14 +669,8 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ťђïś łϊηќ ŧурē ιş çũґѓзⁿτľÿ ñστ şΰρρоŕŧĕđ: !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Çдπсёľ !</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ŧђīś ℓîŋќ мαў ľêãδ τб áń úʼnšàƒé ℓоćάŧίоñ. Ĥўрзŗℓĭŋķѕ çâⁿ ъέ ђąřмƒúļ τό ўôця ċómφύŧèґ аňδ ðáťǻ. Ţб ρгøťėçŧ ўòύг ςömφùţĕŕ, ŏŋľỳ čℓΐςķ łίŋκѕ ƒřöм ťŗμѕŧєđ śόυяčêś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Őρέй ǻпŷŵãγ !!!</value>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Сąñс℮ł !</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Śëţťĩпğś !!</value>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>∆çťíνĕ рåⁿэ мôνеð ťб "{0}" ţав !!! !!! !!!</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>"{0}" ťāъ мōνęđ τŏ "{1}" шΐπδŏẅ !!! !!! !!!</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>"{0}" тąь mǿνєđ ŧσ ήèώ ẅĩŋďøẃ !!! !!! !!!</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Λςťìνє рáиė mόνéð ťб "{0}" ŵîńđθω !!! !!! !!! </value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Αĉťįνέ ρªņз mσνёđ τǿ ήёẃ ẃîпďǿω !!! !!! !!!</value>
|
||||
|
||||
@@ -669,14 +669,8 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ťђïś łϊηќ ŧурē ιş çũґѓзⁿτľÿ ñστ şΰρρоŕŧĕđ: !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Çдπсёľ !</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ŧђīś ℓîŋќ мαў ľêãδ τб áń úʼnšàƒé ℓоćάŧίоñ. Ĥўрзŗℓĭŋķѕ çâⁿ ъέ ђąřмƒúļ τό ўôця ċómφύŧèґ аňδ ðáťǻ. Ţб ρгøťėçŧ ўòύг ςömφùţĕŕ, ŏŋľỳ čℓΐςķ łίŋκѕ ƒřöм ťŗμѕŧєđ śόυяčêś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Őρέй ǻпŷŵãγ !!!</value>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Сąñс℮ł !</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Śëţťĩпğś !!</value>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>∆çťíνĕ рåⁿэ мôνеð ťб "{0}" ţав !!! !!! !!!</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>"{0}" ťāъ мōνęđ τŏ "{1}" шΐπδŏẅ !!! !!! !!!</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>"{0}" тąь mǿνєđ ŧσ ήèώ ẅĩŋďøẃ !!! !!! !!!</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Λςťìνє рáиė mόνéð ťб "{0}" ŵîńđθω !!! !!! !!! </value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Αĉťįνέ ρªņз mσνёđ τǿ ήёẃ ẃîпďǿω !!! !!! !!!</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Этот тип связи в настоящее время не поддерживается:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Отмена</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Эта ссылка может привести к небезопасному расположению. Гиперссылки могут нанести вред компьютеру и данным. Чтобы защитить компьютер, щелкните ссылки только из надежных источников.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Все равно открыть</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Параметры</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>Активная область перемещена на вкладку "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>Вкладка "{0}" перемещена в окно "{1}"</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Вкладка "{0}" перемещена в новое окно</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>Активная область перемещена в окно "{0}"</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>Активная область перемещена в новое окно</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>当前不支持此链接类型:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>此链接可能会导致不安全的位置。超链接可能对你的计算机和数据有害。若要保护你的计算机,请仅单击来自受信任源的链接。</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>仍然打开</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>设置</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>活动窗格已移动到“{0}”选项卡</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>“{0}”选项卡已移动到“{1}”窗口</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>“{0}”选项卡已移动到新窗口</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>活动窗格已移动到“{0}”选项卡</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>活动窗格已移动到新窗口</value>
|
||||
|
||||
@@ -669,15 +669,9 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>目前不支援此連結類型:</value>
|
||||
</data>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>此連結可能通往不安全地點。超連結可能對你的電腦和資料造成傷害。為了保護你的電腦,只點擊來自可信來源的連結。</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>一律開啟</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
@@ -851,11 +845,11 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
|
||||
<value>活動窗格已移動至「{0}」索引標籤</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_Default" xml:space="preserve">
|
||||
<value>「{0}」索引標籤已移至「{1}」視窗</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window to which the tab was moved.</comment>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the name of the window the tab was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_TabMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>「{0}」索引標籤已移至新視窗</value>
|
||||
@@ -867,7 +861,7 @@
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
|
||||
<value>活動窗格已移動至「{0}」視窗</value>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window to which the pane was moved.</comment>
|
||||
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>
|
||||
</data>
|
||||
<data name="TerminalPage_PaneMovedAnnouncement_NewWindow" xml:space="preserve">
|
||||
<value>活動窗格已移至新視窗</value>
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_activePane = nullptr;
|
||||
|
||||
_closePaneMenuItem.Visibility(WUX::Visibility::Collapsed);
|
||||
_restartConnectionMenuItem.Visibility(WUX::Visibility::Collapsed);
|
||||
|
||||
auto firstId = _nextPaneId;
|
||||
|
||||
@@ -86,6 +85,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_MakeTabViewItem();
|
||||
_CreateContextMenu();
|
||||
_UpdateMenuItemStates();
|
||||
|
||||
_headerControl.TabStatus(_tabStatus);
|
||||
|
||||
@@ -123,6 +123,12 @@ namespace winrt::TerminalApp::implementation
|
||||
_bellIndicatorTimer.Stop();
|
||||
}
|
||||
|
||||
void Tab::_ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& /*sender*/, const Windows::Foundation::IInspectable& /*e*/)
|
||||
{
|
||||
ShowActivityIndicator(false);
|
||||
_activityIndicatorTimer.Stop();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initializes a TabViewItem for this Tab instance.
|
||||
// Arguments:
|
||||
@@ -329,6 +335,10 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
ShowBellIndicator(false);
|
||||
}
|
||||
if (_tabStatus.ActivityIndicator())
|
||||
{
|
||||
ShowActivityIndicator(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,6 +371,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// The tabWidthMode may have changed, update the header control accordingly
|
||||
_UpdateHeaderControlMaxWidth();
|
||||
|
||||
// Refresh pane header visibility based on the current setting
|
||||
const auto showHeaders = settings.GlobalSettings().ShowPaneHeaders() && _rootPane->GetLeafPaneCount() > 1;
|
||||
_rootPane->ShowPaneHeaders(showHeaders);
|
||||
|
||||
// Update the settings on all our panes.
|
||||
_rootPane->WalkTree([&](const auto& pane) {
|
||||
pane->UpdateSettings(settings);
|
||||
@@ -459,6 +473,26 @@ namespace winrt::TerminalApp::implementation
|
||||
_bellIndicatorTimer.Start();
|
||||
}
|
||||
|
||||
void Tab::ShowActivityIndicator(const bool show)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_tabStatus.ActivityIndicator(show);
|
||||
}
|
||||
|
||||
void Tab::ActivateActivityIndicatorTimer()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
if (!_activityIndicatorTimer)
|
||||
{
|
||||
_activityIndicatorTimer.Interval(std::chrono::milliseconds(2000));
|
||||
_activityIndicatorTimer.Tick({ get_weak(), &Tab::_ActivityIndicatorTimerTick });
|
||||
}
|
||||
|
||||
_activityIndicatorTimer.Start();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the title string of the last focused terminal control in our tree.
|
||||
// Returns the empty string if there is no such control.
|
||||
@@ -646,6 +680,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// After split, Close Pane Menu Item should be visible
|
||||
_closePaneMenuItem.Visibility(WUX::Visibility::Visible);
|
||||
|
||||
// Show pane headers now that we have multiple panes (if the setting is enabled)
|
||||
try
|
||||
{
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
_rootPane->ShowPaneHeaders(settings.GlobalSettings().ShowPaneHeaders());
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// The active pane has an id if it is a leaf
|
||||
if (activePaneId)
|
||||
{
|
||||
@@ -844,14 +886,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - direction: The direction to move the separator in.
|
||||
// Return Value:
|
||||
// - whether a pane was resized
|
||||
bool Tab::ResizePane(const ResizeDirection& direction)
|
||||
// - <none>
|
||||
void Tab::ResizePane(const ResizeDirection& direction)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// NOTE: This _must_ be called on the root pane, so that it can propagate
|
||||
// throughout the entire tree.
|
||||
return _rootPane->ResizePane(direction);
|
||||
_rootPane->ResizePane(direction);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1068,6 +1110,7 @@ namespace winrt::TerminalApp::implementation
|
||||
dispatcher,
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 200 },
|
||||
.leading = true,
|
||||
.trailing = true,
|
||||
},
|
||||
[weakThis]() {
|
||||
@@ -1148,6 +1191,14 @@ namespace winrt::TerminalApp::implementation
|
||||
tab->TabRaiseVisualBell.raise();
|
||||
}
|
||||
|
||||
// Send a desktop toast notification if requested, but only if
|
||||
// the pane isn't already in the belled state. This prevents
|
||||
// sending repeated toasts for repeated BEL characters.
|
||||
if (bellArgs.SendNotification() && !tab->_tabStatus.BellIndicator())
|
||||
{
|
||||
tab->TabToastNotificationRequested.raise(tab->Title(), L"");
|
||||
}
|
||||
|
||||
// Show the bell indicator in the tab header
|
||||
tab->ShowBellIndicator(true);
|
||||
|
||||
@@ -1166,6 +1217,55 @@ namespace winrt::TerminalApp::implementation
|
||||
events.RestartTerminalRequested = terminal.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &Tab::_bubbleRestartTerminalRequested });
|
||||
}
|
||||
|
||||
events.NotificationRequested = content.NotificationRequested(
|
||||
winrt::auto_revoke,
|
||||
[dispatcher, weakThis](TerminalApp::IPaneContent sender, auto notifArgs) -> safe_void_coroutine {
|
||||
const auto weakThisCopy = weakThis;
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
if (const auto tab{ weakThisCopy.get() })
|
||||
{
|
||||
const auto activeContent = tab->GetActiveContent();
|
||||
const auto isActivePaneContent = activeContent && activeContent == sender;
|
||||
|
||||
if (notifArgs.OnlyWhenInactive() && isActivePaneContent &&
|
||||
tab->_focusState != WUX::FocusState::Unfocused)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
const auto style = notifArgs.Style();
|
||||
|
||||
if (WI_IsFlagSet(style, OutputNotificationStyle::Taskbar))
|
||||
{
|
||||
tab->TabRaiseVisualBell.raise();
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Audible))
|
||||
{
|
||||
if (const auto termContent{ sender.try_as<TerminalApp::TerminalPaneContent>() })
|
||||
{
|
||||
termContent.PlayNotificationSound();
|
||||
}
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Tab))
|
||||
{
|
||||
tab->ShowActivityIndicator(true);
|
||||
|
||||
if (tab->_focusState != WUX::FocusState::Unfocused)
|
||||
{
|
||||
tab->ActivateActivityIndicatorTimer();
|
||||
}
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Notification))
|
||||
{
|
||||
const auto title = notifArgs.Title().empty() ? tab->Title() : notifArgs.Title();
|
||||
tab->TabToastNotificationRequested.raise(title, notifArgs.Body());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (_tabStatus.IsInputBroadcastActive())
|
||||
{
|
||||
if (const auto& termContent{ content.try_as<TerminalApp::TerminalPaneContent>() })
|
||||
@@ -1254,7 +1354,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Method Description:
|
||||
// - Set an indicator on the tab if any pane is in a closed connection state.
|
||||
// - Show/hide the Restart Connection context menu entry depending on active pane's state.
|
||||
// - Show/hide the Restart Session context menu entry depending on active pane's state.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
@@ -1271,13 +1371,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_tabStatus.IsConnectionClosed(isClosed);
|
||||
}
|
||||
|
||||
if (_activePane)
|
||||
{
|
||||
_restartConnectionMenuItem.Visibility(_activePane->IsConnectionClosed() ?
|
||||
WUX::Visibility::Visible :
|
||||
WUX::Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::_RestartActivePaneConnection()
|
||||
@@ -1324,6 +1417,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_rootPane->GetLeafPaneCount() == 1)
|
||||
{
|
||||
_closePaneMenuItem.Visibility(WUX::Visibility::Collapsed);
|
||||
_rootPane->ShowPaneHeaders(false);
|
||||
}
|
||||
|
||||
_RecalculateAndApplyReadOnly();
|
||||
@@ -1348,6 +1442,22 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_UpdateMenuItemStates();
|
||||
}
|
||||
|
||||
void Tab::_UpdateMenuItemStates()
|
||||
{
|
||||
// Terminal-specific menu items
|
||||
const auto content = _activePane ? _activePane->GetContent() : nullptr;
|
||||
const auto isTerm = content && content.try_as<winrt::TerminalApp::TerminalPaneContent>() != nullptr;
|
||||
_duplicateTabMenuItem.IsEnabled(isTerm);
|
||||
_exportTabMenuItem.IsEnabled(isTerm);
|
||||
_findMenuItem.IsEnabled(isTerm);
|
||||
_restartConnectionMenuItem.IsEnabled(isTerm);
|
||||
|
||||
// Snippets Pane can technically be split
|
||||
_splitTabMenuItem.IsEnabled(isTerm || (content && content.try_as<winrt::TerminalApp::SnippetsPaneContent>() != nullptr));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1393,6 +1503,10 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
tab->ShowBellIndicator(false);
|
||||
}
|
||||
if (tab->_tabStatus.ActivityIndicator())
|
||||
{
|
||||
tab->ShowActivityIndicator(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1652,106 +1766,100 @@ namespace winrt::TerminalApp::implementation
|
||||
Automation::AutomationProperties::SetHelpText(renameTabMenuItem, renameTabToolTip);
|
||||
}
|
||||
|
||||
Controls::MenuFlyoutItem duplicateTabMenuItem;
|
||||
{
|
||||
// "Duplicate tab"
|
||||
Controls::FontIcon duplicateTabSymbol;
|
||||
duplicateTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
duplicateTabSymbol.Glyph(L"\xF5ED");
|
||||
|
||||
duplicateTabMenuItem.Click({ get_weak(), &Tab::_duplicateTabClicked });
|
||||
duplicateTabMenuItem.Text(RS_(L"DuplicateTabText"));
|
||||
duplicateTabMenuItem.Icon(duplicateTabSymbol);
|
||||
_duplicateTabMenuItem.Click({ get_weak(), &Tab::_duplicateTabClicked });
|
||||
_duplicateTabMenuItem.Text(RS_(L"DuplicateTabText"));
|
||||
_duplicateTabMenuItem.Icon(duplicateTabSymbol);
|
||||
|
||||
const auto duplicateTabToolTip = RS_(L"DuplicateTabToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(duplicateTabMenuItem, box_value(duplicateTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(duplicateTabMenuItem, duplicateTabToolTip);
|
||||
WUX::Controls::ToolTipService::SetToolTip(_duplicateTabMenuItem, box_value(duplicateTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_duplicateTabMenuItem, duplicateTabToolTip);
|
||||
}
|
||||
|
||||
Controls::MenuFlyoutItem splitTabMenuItem;
|
||||
{
|
||||
// "Split tab"
|
||||
Controls::FontIcon splitTabSymbol;
|
||||
splitTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
splitTabSymbol.Glyph(L"\xF246"); // ViewDashboard
|
||||
|
||||
splitTabMenuItem.Click({ get_weak(), &Tab::_splitTabClicked });
|
||||
splitTabMenuItem.Text(RS_(L"SplitTabText"));
|
||||
splitTabMenuItem.Icon(splitTabSymbol);
|
||||
_splitTabMenuItem.Click({ get_weak(), &Tab::_splitTabClicked });
|
||||
_splitTabMenuItem.Text(RS_(L"SplitTabText"));
|
||||
_splitTabMenuItem.Icon(splitTabSymbol);
|
||||
|
||||
const auto splitTabToolTip = RS_(L"SplitTabToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(splitTabMenuItem, box_value(splitTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(splitTabMenuItem, splitTabToolTip);
|
||||
WUX::Controls::ToolTipService::SetToolTip(_splitTabMenuItem, box_value(splitTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_splitTabMenuItem, splitTabToolTip);
|
||||
}
|
||||
|
||||
Controls::MenuFlyoutItem closePaneMenuItem = _closePaneMenuItem;
|
||||
{
|
||||
// "Close pane"
|
||||
closePaneMenuItem.Click({ get_weak(), &Tab::_closePaneClicked });
|
||||
closePaneMenuItem.Text(RS_(L"ClosePaneText"));
|
||||
_closePaneMenuItem.Click({ get_weak(), &Tab::_closePaneClicked });
|
||||
_closePaneMenuItem.Text(RS_(L"ClosePaneText"));
|
||||
|
||||
const auto closePaneToolTip = RS_(L"ClosePaneToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(closePaneMenuItem, box_value(closePaneToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(closePaneMenuItem, closePaneToolTip);
|
||||
WUX::Controls::ToolTipService::SetToolTip(_closePaneMenuItem, box_value(closePaneToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_closePaneMenuItem, closePaneToolTip);
|
||||
}
|
||||
|
||||
Controls::MenuFlyoutItem exportTabMenuItem;
|
||||
{
|
||||
// "Export tab"
|
||||
Controls::FontIcon exportTabSymbol;
|
||||
exportTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
exportTabSymbol.Glyph(L"\xE74E"); // Save
|
||||
|
||||
exportTabMenuItem.Click({ get_weak(), &Tab::_exportTextClicked });
|
||||
exportTabMenuItem.Text(RS_(L"ExportTabText"));
|
||||
exportTabMenuItem.Icon(exportTabSymbol);
|
||||
_exportTabMenuItem.Click({ get_weak(), &Tab::_exportTextClicked });
|
||||
_exportTabMenuItem.Text(RS_(L"ExportTabText"));
|
||||
_exportTabMenuItem.Icon(exportTabSymbol);
|
||||
|
||||
const auto exportTabToolTip = RS_(L"ExportTabToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(exportTabMenuItem, box_value(exportTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(exportTabMenuItem, exportTabToolTip);
|
||||
WUX::Controls::ToolTipService::SetToolTip(_exportTabMenuItem, box_value(exportTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_exportTabMenuItem, exportTabToolTip);
|
||||
}
|
||||
|
||||
Controls::MenuFlyoutItem findMenuItem;
|
||||
{
|
||||
// "Find"
|
||||
Controls::FontIcon findSymbol;
|
||||
findSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
findSymbol.Glyph(L"\xF78B"); // SearchMedium
|
||||
|
||||
findMenuItem.Click({ get_weak(), &Tab::_findClicked });
|
||||
findMenuItem.Text(RS_(L"FindText"));
|
||||
findMenuItem.Icon(findSymbol);
|
||||
_findMenuItem.Click({ get_weak(), &Tab::_findClicked });
|
||||
_findMenuItem.Text(RS_(L"FindText"));
|
||||
_findMenuItem.Icon(findSymbol);
|
||||
|
||||
const auto findToolTip = RS_(L"FindToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(findMenuItem, box_value(findToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(findMenuItem, findToolTip);
|
||||
WUX::Controls::ToolTipService::SetToolTip(_findMenuItem, box_value(findToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_findMenuItem, findToolTip);
|
||||
}
|
||||
|
||||
Controls::MenuFlyoutItem restartConnectionMenuItem = _restartConnectionMenuItem;
|
||||
{
|
||||
// "Restart connection"
|
||||
// "Restart session"
|
||||
Controls::FontIcon restartConnectionSymbol;
|
||||
restartConnectionSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
restartConnectionSymbol.Glyph(L"\xE72C");
|
||||
|
||||
restartConnectionMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
_restartConnectionMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_RestartActivePaneConnection();
|
||||
}
|
||||
});
|
||||
restartConnectionMenuItem.Text(RS_(L"RestartConnectionText"));
|
||||
restartConnectionMenuItem.Icon(restartConnectionSymbol);
|
||||
_restartConnectionMenuItem.Text(RS_(L"RestartConnectionText"));
|
||||
_restartConnectionMenuItem.Icon(restartConnectionSymbol);
|
||||
|
||||
const auto restartConnectionToolTip = RS_(L"RestartConnectionToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(restartConnectionMenuItem, box_value(restartConnectionToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(restartConnectionMenuItem, restartConnectionToolTip);
|
||||
WUX::Controls::ToolTipService::SetToolTip(_restartConnectionMenuItem, box_value(restartConnectionToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_restartConnectionMenuItem, restartConnectionToolTip);
|
||||
}
|
||||
|
||||
// Build the menu
|
||||
@@ -1759,16 +1867,16 @@ namespace winrt::TerminalApp::implementation
|
||||
Controls::MenuFlyoutSeparator menuSeparator;
|
||||
contextMenuFlyout.Items().Append(chooseColorMenuItem);
|
||||
contextMenuFlyout.Items().Append(renameTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(duplicateTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(splitTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(_duplicateTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(_splitTabMenuItem);
|
||||
_AppendMoveMenuItems(contextMenuFlyout);
|
||||
contextMenuFlyout.Items().Append(exportTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(findMenuItem);
|
||||
contextMenuFlyout.Items().Append(restartConnectionMenuItem);
|
||||
contextMenuFlyout.Items().Append(_exportTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(_findMenuItem);
|
||||
contextMenuFlyout.Items().Append(_restartConnectionMenuItem);
|
||||
contextMenuFlyout.Items().Append(menuSeparator);
|
||||
|
||||
auto closeSubMenu = _AppendCloseMenuItems(contextMenuFlyout);
|
||||
closeSubMenu.Items().Append(closePaneMenuItem);
|
||||
closeSubMenu.Items().Append(_closePaneMenuItem);
|
||||
|
||||
// GH#5750 - When the context menu is dismissed with ESC, toss the focus
|
||||
// back to our control.
|
||||
|
||||
@@ -48,12 +48,15 @@ namespace winrt::TerminalApp::implementation
|
||||
void ShowBellIndicator(const bool show);
|
||||
void ActivateBellIndicatorTimer();
|
||||
|
||||
void ShowActivityIndicator(const bool show);
|
||||
void ActivateActivityIndicatorTimer();
|
||||
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateCanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
const float splitSize,
|
||||
winrt::Windows::Foundation::Size availableSpace) const;
|
||||
|
||||
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
||||
void ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
||||
bool NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
bool SwapPane(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
bool FocusPane(const uint32_t id);
|
||||
@@ -121,6 +124,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
til::typed_event<TerminalApp::Tab, IInspectable> ActivePaneChanged;
|
||||
til::event<winrt::delegate<>> TabRaiseVisualBell;
|
||||
til::event<winrt::delegate<winrt::hstring /*title*/, winrt::hstring /*body*/>> TabToastNotificationRequested;
|
||||
til::typed_event<IInspectable, IInspectable> TaskbarProgressChanged;
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
@@ -140,11 +144,17 @@ namespace winrt::TerminalApp::implementation
|
||||
static constexpr double HeaderRenameBoxWidthTitleLength{ std::numeric_limits<double>::infinity() };
|
||||
|
||||
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _duplicateTabMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _splitTabMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveToNewWindowMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveRightMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveLeftMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _exportTabMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _findMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _restartConnectionMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closePaneMenuItem{};
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
Microsoft::Terminal::Settings::Model::IActionMapView _actionMap{ nullptr };
|
||||
winrt::hstring _keyChord{};
|
||||
@@ -159,9 +169,6 @@ namespace winrt::TerminalApp::implementation
|
||||
std::shared_ptr<Pane> _activePane{ nullptr };
|
||||
std::shared_ptr<Pane> _zoomedPane{ nullptr };
|
||||
|
||||
Windows::UI::Xaml::Controls::MenuFlyoutItem _closePaneMenuItem;
|
||||
Windows::UI::Xaml::Controls::MenuFlyoutItem _restartConnectionMenuItem;
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::IconStyle _lastIconStyle;
|
||||
winrt::hstring _lastIconPath{};
|
||||
std::optional<winrt::Windows::UI::Color> _runtimeTabColor{};
|
||||
@@ -182,6 +189,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::TerminalApp::IPaneContent::ConnectionStateChanged_revoker ConnectionStateChanged;
|
||||
winrt::TerminalApp::IPaneContent::ReadOnlyChanged_revoker ReadOnlyChanged;
|
||||
winrt::TerminalApp::IPaneContent::FocusRequested_revoker FocusRequested;
|
||||
winrt::TerminalApp::IPaneContent::NotificationRequested_revoker NotificationRequested;
|
||||
|
||||
// These events literally only apply if the content is a TermControl.
|
||||
winrt::Microsoft::Terminal::Control::TermControl::KeySent_revoker KeySent;
|
||||
@@ -210,6 +218,9 @@ namespace winrt::TerminalApp::implementation
|
||||
SafeDispatcherTimer _bellIndicatorTimer;
|
||||
void _BellIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
SafeDispatcherTimer _activityIndicatorTimer;
|
||||
void _ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _UpdateHeaderControlMaxWidth();
|
||||
|
||||
void _CreateContextMenu();
|
||||
@@ -220,6 +231,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _AttachEventHandlersToPane(std::shared_ptr<Pane> pane);
|
||||
|
||||
void _UpdateActivePane(std::shared_ptr<Pane> pane);
|
||||
void _UpdateMenuItemStates();
|
||||
|
||||
winrt::hstring _GetActiveTitle() const;
|
||||
|
||||
@@ -230,8 +242,6 @@ namespace winrt::TerminalApp::implementation
|
||||
void _UpdateConnectionClosedState();
|
||||
void _RestartActivePaneConnection();
|
||||
|
||||
void _DuplicateTab();
|
||||
|
||||
winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush();
|
||||
|
||||
void _MakeTabViewItem();
|
||||
|
||||
@@ -32,6 +32,12 @@
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.BellIndicator, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderActivityIndicator"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="8"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.ActivityIndicator, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderZoomIcon"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "TabRowControl.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "DesktopNotification.h"
|
||||
#include "..\TerminalSettingsModel\FileUtils.h"
|
||||
#include "../TerminalSettingsAppAdapterLib/TerminalSettings.h"
|
||||
|
||||
@@ -150,6 +151,18 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
|
||||
// When a tab requests a desktop toast notification, send the toast
|
||||
// and handle activation by summoning this window and switching to the tab.
|
||||
newTabImpl->TabToastNotificationRequested([weakThis{ get_weak() }, weakTab{ newTabImpl->get_weak() }](const winrt::hstring& title, const winrt::hstring& body) {
|
||||
if (const auto page{ weakThis.get() })
|
||||
{
|
||||
if (const auto tab{ weakTab.get() })
|
||||
{
|
||||
page->_SendDesktopNotification(title, body, tab);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
auto tabViewItem = newTabImpl->TabViewItem();
|
||||
_tabView.TabItems().InsertAt(insertPosition, tabViewItem);
|
||||
|
||||
@@ -394,7 +407,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Removes the tab (both TerminalControl and XAML) after prompting for approval
|
||||
// Arguments:
|
||||
// - tab: the tab to remove
|
||||
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::Tab tab)
|
||||
// - skipConfirmClose: if true, skip the confirmOnClose check. Used when
|
||||
// an aggregate confirmation has already been shown (i.e. close other tabs)
|
||||
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::Tab tab, bool skipConfirmClose)
|
||||
{
|
||||
winrt::com_ptr<TerminalPage> strong;
|
||||
|
||||
@@ -413,6 +428,24 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Skip the per-tab confirmOnClose check when the caller has already
|
||||
// shown an aggregate confirmation dialog (e.g. _RemoveTabs).
|
||||
if (!skipConfirmClose)
|
||||
{
|
||||
const auto tabImpl = _GetTabImpl(tab);
|
||||
if (tabImpl && _ShouldWarnOnCloseTab(tabImpl))
|
||||
{
|
||||
const auto weak = get_weak();
|
||||
|
||||
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::Tab);
|
||||
strong = weak.get();
|
||||
if (!strong || warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto t = winrt::get_self<implementation::Tab>(tab);
|
||||
auto actions = t->BuildStartupActions(BuildStartupKind::None);
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(actions));
|
||||
@@ -782,6 +815,22 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto pane{ activeTab->GetActivePane() })
|
||||
{
|
||||
const auto weak = get_weak();
|
||||
|
||||
// Check if we should warn before closing a single pane
|
||||
// (only triggers on Always — Automatic doesn't warn for single pane)
|
||||
const auto setting = _settings.GlobalSettings().ConfirmOnClose();
|
||||
if (setting == ConfirmOnClose::Always)
|
||||
{
|
||||
// If this is the last pane, closing it closes the tab,
|
||||
// so use the tab dialog text instead.
|
||||
const auto kind = activeTab->GetLeafPaneCount() == 1 ? ConfirmCloseDialogKind::Tab : ConfirmCloseDialogKind::Pane;
|
||||
auto warningResult = co_await _ShowConfirmCloseDialog(kind);
|
||||
if (!weak.get() || warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
||||
if (co_await _PaneConfirmCloseReadOnly(pane))
|
||||
{
|
||||
if (const auto strong = weak.get())
|
||||
@@ -795,10 +844,33 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Method Description:
|
||||
// - Close all panes with the given IDs sequentially.
|
||||
// - Shows a single aggregate confirmation dialog upfront if the confirmOnClose setting warrants it.
|
||||
// Arguments:
|
||||
// - weakTab: weak reference to the tab that the pane belongs to.
|
||||
// - weakTab: weak reference to the tab that the panes belong to.
|
||||
// - paneIds: collection of the IDs of the panes that are marked for removal.
|
||||
void TerminalPage::_ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
|
||||
safe_void_coroutine TerminalPage::_ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
|
||||
{
|
||||
// Show a single aggregate confirmation for closing multiple panes.
|
||||
if (_settings.GlobalSettings().ConfirmOnClose() != ConfirmOnClose::Never)
|
||||
{
|
||||
const auto weak = get_weak();
|
||||
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::MultiplePanes);
|
||||
if (!weak.get() || warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
_CloseRemainingPanes(weakTab, std::move(paneIds));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Recursively closes panes by ID, chaining each close via the
|
||||
// ClosedByParent callback. Called after confirmation has already
|
||||
// been handled by _ClosePanes.
|
||||
// Arguments:
|
||||
// - weakTab: weak reference to the tab that the panes belong to
|
||||
// - paneIds: remaining pane IDs to close
|
||||
void TerminalPage::_CloseRemainingPanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
|
||||
{
|
||||
if (auto strongTab{ weakTab.get() })
|
||||
{
|
||||
@@ -813,10 +885,9 @@ namespace winrt::TerminalApp::implementation
|
||||
pane->ClosedByParent([ids{ std::move(paneIds) }, weakThis{ get_weak() }, weakTab]() {
|
||||
if (auto strongThis{ weakThis.get() })
|
||||
{
|
||||
strongThis->_ClosePanes(weakTab, std::move(ids));
|
||||
strongThis->_CloseRemainingPanes(weakTab, std::move(ids));
|
||||
}
|
||||
});
|
||||
|
||||
// Close the pane which will eventually trigger the closed by parent event
|
||||
_HandleClosePaneRequested(pane);
|
||||
break;
|
||||
@@ -841,18 +912,33 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Method Description:
|
||||
// - Closes provided tabs one by one
|
||||
// - Shows a single aggregate confirmation dialog upfront if the confirmOnClose setting warrants it.
|
||||
// Arguments:
|
||||
// - tabs - tabs to remove
|
||||
safe_void_coroutine TerminalPage::_RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs)
|
||||
{
|
||||
if (tabs.empty())
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Show a single aggregate confirmation instead of per-tab dialogs.
|
||||
const auto weak = get_weak();
|
||||
if (_settings.GlobalSettings().ConfirmOnClose() != ConfirmOnClose::Never)
|
||||
{
|
||||
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::MultipleTabs);
|
||||
if (!weak.get() || warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& tab : tabs)
|
||||
{
|
||||
winrt::Windows::Foundation::IAsyncAction action{ nullptr };
|
||||
if (const auto strong = weak.get())
|
||||
{
|
||||
action = _HandleCloseTabRequested(tab);
|
||||
action = _HandleCloseTabRequested(tab, /*skipConfirmClose*/ true);
|
||||
}
|
||||
|
||||
if (!action)
|
||||
@@ -1185,4 +1271,103 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
return _tabs.Size() > 1;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempts to find and focus the given tab in this window.
|
||||
// Arguments:
|
||||
// - tab: The tab to focus.
|
||||
// Return Value:
|
||||
// - true if the tab was found and focused, false otherwise.
|
||||
bool TerminalPage::FocusTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
if (const auto tabIndex{ _GetTabIndex(tab) })
|
||||
{
|
||||
_SelectTab(tabIndex.value());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sends a desktop toast notification with the given title and body.
|
||||
// When the toast is activated (clicked), the window is summoned and
|
||||
// the originating tab is focused.
|
||||
// Arguments:
|
||||
// - tabTitle: The title to display in the notification.
|
||||
// - body: The body text. If empty, a standard tab-activity message is built.
|
||||
// - tab: The tab to switch to when the toast is activated.
|
||||
void TerminalPage::_SendDesktopNotification(const winrt::hstring& tabTitle, const winrt::hstring& body, const winrt::com_ptr<Tab>& tab)
|
||||
{
|
||||
// Build the notification message.
|
||||
// If a custom body is provided (e.g. from OSC 777), use the title/body directly.
|
||||
// Otherwise, build the standard tab-activity notification message.
|
||||
winrt::hstring notificationTitle;
|
||||
winrt::hstring message;
|
||||
if (!body.empty())
|
||||
{
|
||||
notificationTitle = tabTitle;
|
||||
message = body;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the window name if available for context; otherwise just use the tab title.
|
||||
// Use the raw WindowName (not WindowNameForDisplay) so we don't include
|
||||
// the "<unnamed window>" placeholder in the notification body.
|
||||
const auto windowName = _WindowProperties ? _WindowProperties.WindowName() : winrt::hstring{};
|
||||
if (!windowName.empty())
|
||||
{
|
||||
message = RS_fmt(L"NotificationMessage_TabActivityInWindow", std::wstring_view{ tabTitle }, std::wstring_view{ windowName });
|
||||
}
|
||||
else
|
||||
{
|
||||
message = RS_fmt(L"NotificationMessage_TabActivity", std::wstring_view{ tabTitle });
|
||||
}
|
||||
notificationTitle = CascadiaSettings::ApplicationDisplayName();
|
||||
}
|
||||
|
||||
// Use the Tab object's identity hash as a stable toast tag.
|
||||
// This survives tab reordering and cross-window moves.
|
||||
const auto tabHash = std::hash<winrt::Windows::Foundation::IUnknown>{}(*tab);
|
||||
const hstring tabTag{ fmt::format(FMT_COMPILE(L"wt-tab-{:016x}"), tabHash) };
|
||||
|
||||
const implementation::DesktopNotificationArgs args{
|
||||
.Title = notificationTitle,
|
||||
.Message = message,
|
||||
.Tag = tabTag
|
||||
};
|
||||
|
||||
implementation::DesktopNotification::SendNotification(args, [weakThis{ get_weak() }, weakTab{ tab->get_weak() }]() {
|
||||
if (const auto page{ weakThis.get() })
|
||||
{
|
||||
// The toast Activated callback runs on a background thread.
|
||||
// Marshal to the UI thread for tab focus and window summon.
|
||||
page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis, weakTab]() {
|
||||
if (const auto p{ weakThis.get() })
|
||||
{
|
||||
if (const auto t{ weakTab.get() })
|
||||
{
|
||||
// Try to find and focus the tab in this window first.
|
||||
if (const auto tabIndex{ p->_GetTabIndex(*t) })
|
||||
{
|
||||
p->SummonWindowRequested.raise(nullptr, nullptr);
|
||||
p->_SelectTab(tabIndex.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// The tab may have moved to another window.
|
||||
// Raise FocusTabRequested so the emperor can
|
||||
// search all windows for it.
|
||||
p->FocusTabRequested.raise(nullptr, *t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tab was closed. Just summon this window.
|
||||
p->SummonWindowRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Toast.h" />
|
||||
<ClInclude Include="DesktopNotification.h" />
|
||||
<ClInclude Include="TerminalSettingsCache.h" />
|
||||
<ClInclude Include="SuggestionsControl.h">
|
||||
<DependentUpon>SuggestionsControl.xaml</DependentUpon>
|
||||
@@ -287,6 +288,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="Toast.cpp" />
|
||||
<ClCompile Include="DesktopNotification.cpp" />
|
||||
<ClCompile Include="TerminalSettingsCache.cpp" />
|
||||
<ClCompile Include="SuggestionsControl.cpp">
|
||||
<DependentUpon>SuggestionsControl.xaml</DependentUpon>
|
||||
|
||||
@@ -884,26 +884,63 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Displays a dialog to warn the user that they are about to close all open windows.
|
||||
// Once the user clicks the OK button, shut down the application.
|
||||
// If cancel is clicked, the dialog will close.
|
||||
// - Displays the unified close confirmation dialog configured for the
|
||||
// given scenario. Resets the "don't ask me again" checkbox before showing.
|
||||
// If the user confirms and checked "don't ask me again", sets
|
||||
// confirmOnClose to Never and writes settings to disk.
|
||||
// - Only one dialog can be visible at a time. If another dialog is visible
|
||||
// when this is called, nothing happens. See _ShowDialog for details
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowQuitDialog()
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowConfirmCloseDialog(ConfirmCloseDialogKind kind)
|
||||
{
|
||||
return _ShowDialogHelper(L"QuitDialog");
|
||||
}
|
||||
// Load the dialog (triggers x:Load) and configure its strings.
|
||||
const auto dialog = FindName(L"ConfirmCloseDialog").as<ContentDialog>();
|
||||
switch (kind)
|
||||
{
|
||||
case ConfirmCloseDialogKind::CloseAll:
|
||||
dialog.Title(winrt::box_value(RS_(L"ConfirmCloseDialog_CloseAllTitle")));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmCloseDialog_CloseAllPrimary"));
|
||||
break;
|
||||
case ConfirmCloseDialogKind::Window:
|
||||
dialog.Title(winrt::box_value(RS_(L"ConfirmCloseDialog_WindowTitle")));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmCloseDialog_WindowPrimary"));
|
||||
break;
|
||||
case ConfirmCloseDialogKind::Tab:
|
||||
dialog.Title(winrt::box_value(RS_(L"ConfirmCloseDialog_TabTitle")));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmCloseDialog_TabPrimary"));
|
||||
break;
|
||||
case ConfirmCloseDialogKind::MultiplePanes:
|
||||
dialog.Title(winrt::box_value(RS_(L"ConfirmCloseDialog_MultiplePanesTitle")));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmCloseDialog_MultiplePanesPrimary"));
|
||||
break;
|
||||
case ConfirmCloseDialogKind::MultipleTabs:
|
||||
dialog.Title(winrt::box_value(RS_(L"ConfirmCloseDialog_MultipleTabsTitle")));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmCloseDialog_MultipleTabsPrimary"));
|
||||
break;
|
||||
case ConfirmCloseDialogKind::Pane:
|
||||
dialog.Title(winrt::box_value(RS_(L"ConfirmCloseDialog_PaneTitle")));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmCloseDialog_PanePrimary"));
|
||||
break;
|
||||
}
|
||||
dialog.CloseButtonText(RS_(L"ConfirmCloseDialog_Cancel"));
|
||||
|
||||
// Method Description:
|
||||
// - Displays a dialog for warnings found while closing the terminal app using
|
||||
// key binding with multiple tabs opened. Display messages to warn user
|
||||
// that more than 1 tab is opened, and once the user clicks the OK button, remove
|
||||
// all the tabs and shut down and app. If cancel is clicked, the dialog will close
|
||||
// - Only one dialog can be visible at a time. If another dialog is visible
|
||||
// when this is called, nothing happens. See _ShowDialog for details
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowCloseWarningDialog()
|
||||
{
|
||||
return _ShowDialogHelper(L"CloseAllDialog");
|
||||
// BODGY: After a ContentDialog is dismissed, FindName() can no longer
|
||||
// resolve children inside it. Use Content() to get the checkbox directly.
|
||||
const auto checkbox = dialog.Content().as<CheckBox>();
|
||||
checkbox.IsChecked(false);
|
||||
|
||||
auto result = ContentDialogResult::None;
|
||||
if (auto presenter{ _dialogPresenter.get() })
|
||||
{
|
||||
result = co_await presenter.ShowDialog(dialog);
|
||||
}
|
||||
|
||||
if (result == ContentDialogResult::Primary && checkbox.IsChecked().Value())
|
||||
{
|
||||
_settings.GlobalSettings().ConfirmOnClose(ConfirmOnClose::Never);
|
||||
_settings.WriteSettingsToDisk();
|
||||
}
|
||||
|
||||
co_return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1600,8 +1637,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Replace the Starting directory with the CWD, if given
|
||||
const auto workingDirectory = control.WorkingDirectory();
|
||||
const auto validWorkingDirectory = !workingDirectory.empty();
|
||||
if (validWorkingDirectory)
|
||||
if (Utils::IsValidDirectory(workingDirectory.c_str()))
|
||||
{
|
||||
controlSettings.DefaultSettings()->StartingDirectory(workingDirectory);
|
||||
}
|
||||
@@ -2210,12 +2246,13 @@ namespace winrt::TerminalApp::implementation
|
||||
// signal that we want to close everything.
|
||||
safe_void_coroutine TerminalPage::RequestQuit()
|
||||
{
|
||||
if (!_displayingCloseDialog)
|
||||
const auto setting = _settings.GlobalSettings().ConfirmOnClose();
|
||||
if (setting != ConfirmOnClose::Never && !_displayingCloseDialog)
|
||||
{
|
||||
_displayingCloseDialog = true;
|
||||
|
||||
const auto weak = get_weak();
|
||||
auto warningResult = co_await _ShowQuitDialog();
|
||||
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::CloseAll);
|
||||
const auto strong = weak.get();
|
||||
if (!strong)
|
||||
{
|
||||
@@ -2228,9 +2265,9 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
QuitRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
|
||||
QuitRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPage::PersistState()
|
||||
@@ -2308,12 +2345,69 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Close the terminal app. If there is more
|
||||
// than one tab opened, show a warning dialog.
|
||||
// - Determines whether a close-window action should show a confirmation
|
||||
// dialog, based on the confirmOnClose setting and the current window state.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - true, if a warning dialog should be shown before closing the window
|
||||
bool TerminalPage::_ShouldWarnOnClose() const
|
||||
{
|
||||
const auto setting = _settings.GlobalSettings().ConfirmOnClose();
|
||||
switch (setting)
|
||||
{
|
||||
case ConfirmOnClose::Always:
|
||||
return true;
|
||||
case ConfirmOnClose::Automatic:
|
||||
{
|
||||
// Warn if there's more than one tab.
|
||||
if (_HasMultipleTabs())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Warn if the one tab has more than one pane.
|
||||
if (_GetTabImpl(_tabs.GetAt(0))->GetLeafPaneCount() > 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case ConfirmOnClose::Never:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Determines whether closing a specific tab should show a confirmation
|
||||
// dialog, based on the confirmOnClose setting and the tab's state.
|
||||
// Arguments:
|
||||
// - tab: The tab being closed
|
||||
// Return Value:
|
||||
// - true, if a warning dialog should be shown before closing the tab
|
||||
bool TerminalPage::_ShouldWarnOnCloseTab(const winrt::com_ptr<Tab>& tab) const
|
||||
{
|
||||
const auto setting = _settings.GlobalSettings().ConfirmOnClose();
|
||||
switch (setting)
|
||||
{
|
||||
case ConfirmOnClose::Always:
|
||||
return true;
|
||||
case ConfirmOnClose::Automatic:
|
||||
// Warn if this tab has more than one pane.
|
||||
return tab->GetLeafPaneCount() > 1;
|
||||
case ConfirmOnClose::Never:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Close the terminal app. If the confirmOnClose setting indicates we should
|
||||
// warn for the current window state, show a warning dialog.
|
||||
safe_void_coroutine TerminalPage::CloseWindow()
|
||||
{
|
||||
if (_HasMultipleTabs() &&
|
||||
_settings.GlobalSettings().ConfirmCloseAllTabs() &&
|
||||
if (_ShouldWarnOnClose() &&
|
||||
!_displayingCloseDialog)
|
||||
{
|
||||
if (_newTabButton && _newTabButton.Flyout())
|
||||
@@ -2322,7 +2416,14 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
_DismissTabContextMenus();
|
||||
_displayingCloseDialog = true;
|
||||
auto warningResult = co_await _ShowCloseWarningDialog();
|
||||
|
||||
const auto weak = get_weak();
|
||||
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::Window);
|
||||
if (!weak.get())
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
_displayingCloseDialog = false;
|
||||
|
||||
if (warningResult != ContentDialogResult::Primary)
|
||||
@@ -2791,15 +2892,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - direction: The direction to move the separator in.
|
||||
// Return Value:
|
||||
// - whether a pane was resized
|
||||
bool TerminalPage::_ResizePane(const ResizeDirection& direction)
|
||||
// - <none>
|
||||
void TerminalPage::_ResizePane(const ResizeDirection& direction)
|
||||
{
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
return tabImpl->ResizePane(direction);
|
||||
tabImpl->ResizePane(direction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -3198,15 +3298,13 @@ namespace winrt::TerminalApp::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const
|
||||
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri)
|
||||
{
|
||||
const auto& schemeName = parsedUri.SchemeName();
|
||||
|
||||
if (schemeName == L"http" || schemeName == L"https")
|
||||
if (parsedUri.SchemeName() == L"http" || parsedUri.SchemeName() == L"https")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (schemeName == L"file")
|
||||
if (parsedUri.SchemeName() == L"file")
|
||||
{
|
||||
static const auto pathext{ wil::TryGetEnvironmentVariableW<std::wstring>(L"PATHEXT") };
|
||||
const auto filename = parsedUri.Path();
|
||||
@@ -3220,16 +3318,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
return true;
|
||||
}
|
||||
if (const auto& safeSchemes = _settings.GlobalSettings().SafeUriSchemes())
|
||||
{
|
||||
for (const auto& scheme : safeSchemes)
|
||||
{
|
||||
if (til::equals_insensitive_ascii(schemeName, scheme))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -3621,8 +3709,7 @@ namespace winrt::TerminalApp::implementation
|
||||
profile = GetClosestProfileForDuplicationOfProfile(profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile);
|
||||
const auto workingDirectory = tabImpl->GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto validWorkingDirectory = !workingDirectory.empty();
|
||||
if (validWorkingDirectory)
|
||||
if (Utils::IsValidDirectory(workingDirectory.c_str()))
|
||||
{
|
||||
controlSettings.DefaultSettings()->StartingDirectory(workingDirectory);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,16 @@ namespace winrt::TerminalApp::implementation
|
||||
ScrollDown = 1
|
||||
};
|
||||
|
||||
enum class ConfirmCloseDialogKind
|
||||
{
|
||||
Pane,
|
||||
Tab,
|
||||
MultiplePanes,
|
||||
MultipleTabs,
|
||||
Window,
|
||||
CloseAll
|
||||
};
|
||||
|
||||
struct RenameWindowRequestedArgs : RenameWindowRequestedArgsT<RenameWindowRequestedArgs>
|
||||
{
|
||||
WINRT_PROPERTY(winrt::hstring, ProposedName);
|
||||
@@ -168,6 +178,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void OpenSettingsUI();
|
||||
void WindowActivated(const bool activated);
|
||||
bool FocusTab(const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down);
|
||||
|
||||
@@ -192,6 +203,7 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<IInspectable, IInspectable> IdentifyWindowsRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
til::typed_event<IInspectable, IInspectable> SummonWindowRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::Tab> FocusTabRequested;
|
||||
til::typed_event<IInspectable, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
til::typed_event<IInspectable, IInspectable> OpenSystemMenu;
|
||||
@@ -301,8 +313,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowDialogHelper(const std::wstring_view& name);
|
||||
|
||||
void _ShowAboutDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowQuitDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowConfirmCloseDialog(ConfirmCloseDialogKind kind);
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseReadOnlyDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowMultiLinePasteWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowLargePasteWarningDialog();
|
||||
@@ -349,7 +360,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
safe_void_coroutine _ExportTab(const Tab& tab, winrt::hstring filepath);
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::Tab tab);
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::Tab tab, bool skipConfirmClose = false);
|
||||
void _CloseTabAtIndex(uint32_t index);
|
||||
void _RemoveTab(const winrt::TerminalApp::Tab& tab);
|
||||
safe_void_coroutine _RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs);
|
||||
@@ -400,9 +411,12 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalApp::Tab _GetTabByTabViewItem(const IInspectable& tabViewItem) const noexcept;
|
||||
|
||||
void _HandleClosePaneRequested(std::shared_ptr<Pane> pane);
|
||||
bool _ShouldWarnOnClose() const;
|
||||
bool _ShouldWarnOnCloseTab(const winrt::com_ptr<Tab>& tab) const;
|
||||
safe_void_coroutine _SetFocusedTab(const winrt::TerminalApp::Tab tab);
|
||||
safe_void_coroutine _CloseFocusedPane();
|
||||
void _ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds);
|
||||
safe_void_coroutine _ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds);
|
||||
void _CloseRemainingPanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds);
|
||||
winrt::Windows::Foundation::IAsyncOperation<bool> _PaneConfirmCloseReadOnly(std::shared_ptr<Pane> pane);
|
||||
void _AddPreviouslyClosedPaneOrTab(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>&& args);
|
||||
|
||||
@@ -412,7 +426,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
const float splitSize,
|
||||
std::shared_ptr<Pane> newPane);
|
||||
bool _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
||||
void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
||||
void _ToggleSplitOrientation();
|
||||
|
||||
void _ScrollPage(ScrollDirection scrollDirection);
|
||||
@@ -424,7 +438,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
safe_void_coroutine _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs);
|
||||
static bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const;
|
||||
static bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
|
||||
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
|
||||
bool _CopyText(bool dismissSelection, bool singleLine, bool withControlSequences, Microsoft::Terminal::Control::CopyFormat formats);
|
||||
@@ -571,6 +585,8 @@ namespace winrt::TerminalApp::implementation
|
||||
void _activePaneChanged(winrt::TerminalApp::Tab tab, Windows::Foundation::IInspectable args);
|
||||
safe_void_coroutine _doHandleSuggestions(Microsoft::Terminal::Settings::Model::SuggestionsArgs realArgs);
|
||||
|
||||
void _SendDesktopNotification(const winrt::hstring& tabTitle, const winrt::hstring& body, const winrt::com_ptr<Tab>& tab);
|
||||
|
||||
#pragma region ActionHandlers
|
||||
// These are all defined in AppActionHandlers.cpp
|
||||
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
|
||||
|
||||
@@ -86,17 +86,12 @@
|
||||
Grid.Row="2"
|
||||
x:Load="False" />
|
||||
|
||||
<ContentDialog x:Name="QuitDialog"
|
||||
x:Uid="QuitDialog"
|
||||
<ContentDialog x:Name="ConfirmCloseDialog"
|
||||
Grid.Row="2"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary" />
|
||||
|
||||
<ContentDialog x:Name="CloseAllDialog"
|
||||
x:Uid="CloseAllDialog"
|
||||
Grid.Row="2"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary" />
|
||||
DefaultButton="Primary">
|
||||
<CheckBox x:Uid="DontAskAgainCheckBox" />
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="CloseReadOnlyDialog"
|
||||
x:Uid="CloseReadOnlyDialog"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include "BellEventArgs.g.cpp"
|
||||
#include "NotificationEventArgs.g.cpp"
|
||||
#include "TerminalPaneContent.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
@@ -34,6 +35,8 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
_controlEvents._ConnectionStateChanged = _control.ConnectionStateChanged(winrt::auto_revoke, { this, &TerminalPaneContent::_controlConnectionStateChangedHandler });
|
||||
_controlEvents._WarningBell = _control.WarningBell(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlWarningBellHandler });
|
||||
_controlEvents._PromptStarted = _control.PromptStarted(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlPromptStartedHandler });
|
||||
_controlEvents._OutputStarted = _control.OutputStarted(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlOutputStartedHandler });
|
||||
_controlEvents._CloseTerminalRequested = _control.CloseTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_closeTerminalRequestedHandler });
|
||||
_controlEvents._RestartTerminalRequested = _control.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_restartTerminalRequestedHandler });
|
||||
|
||||
@@ -42,6 +45,8 @@ namespace winrt::TerminalApp::implementation
|
||||
_controlEvents._SetTaskbarProgress = _control.SetTaskbarProgress(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlSetTaskbarProgress });
|
||||
_controlEvents._ReadOnlyChanged = _control.ReadOnlyChanged(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlReadOnlyChanged });
|
||||
_controlEvents._FocusFollowMouseRequested = _control.FocusFollowMouseRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlFocusFollowMouseRequested });
|
||||
_controlEvents._OutputIdle = _control.OutputIdle(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlOutputIdleHandler });
|
||||
_controlEvents._ShowNotification = _control.ShowNotification(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlShowNotification });
|
||||
}
|
||||
void TerminalPaneContent::_removeControlEvents()
|
||||
{
|
||||
@@ -102,7 +107,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
args.Profile(::Microsoft::Console::Utils::GuidToString(_profile.Guid()));
|
||||
// If we know the user's working directory use it instead of the profile.
|
||||
if (const auto dir = _control.WorkingDirectory(); !dir.empty())
|
||||
if (const auto dir = _control.WorkingDirectory(); ::Microsoft::Console::Utils::IsValidDirectory(dir.c_str()))
|
||||
{
|
||||
args.StartingDirectory(dir);
|
||||
}
|
||||
@@ -173,6 +178,30 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
uint64_t TerminalPaneContent::TaskbarState()
|
||||
{
|
||||
const auto vtState = _control.TaskbarState();
|
||||
if (vtState != 0)
|
||||
{
|
||||
return vtState;
|
||||
}
|
||||
if (_autoDetectActive)
|
||||
{
|
||||
return 3; // Indeterminate
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t TerminalPaneContent::TaskbarProgress()
|
||||
{
|
||||
const auto vtState = _control.TaskbarState();
|
||||
if (vtState != 0)
|
||||
{
|
||||
return _control.TaskbarProgress();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void TerminalPaneContent::_controlReadOnlyChanged(const IInspectable&, const IInspectable&)
|
||||
{
|
||||
ReadOnlyChanged.raise(*this, nullptr);
|
||||
@@ -182,6 +211,11 @@ namespace winrt::TerminalApp::implementation
|
||||
FocusRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlShowNotification(const IInspectable& /*sender*/, const ShowNotificationEventArgs& args)
|
||||
{
|
||||
NotificationRequested.raise(*this, winrt::make<implementation::NotificationEventArgs>(winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Notification, false, args.Title(), args.Body()));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when our attached control is closed. Triggers listeners to our close
|
||||
// event, if we're a leaf pane.
|
||||
@@ -261,6 +295,25 @@ namespace winrt::TerminalApp::implementation
|
||||
// has the 'visual' flag set
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
void TerminalPaneContent::PlayNotificationSound()
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
auto sounds{ _profile.BellSound() };
|
||||
if (sounds && sounds.Size() > 0)
|
||||
{
|
||||
winrt::hstring soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
|
||||
winrt::Windows::Foundation::Uri uri{ soundPath };
|
||||
_playBellSound(uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
|
||||
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
@@ -272,18 +325,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
|
||||
{
|
||||
// Audible is set, play the sound
|
||||
auto sounds{ _profile.BellSound() };
|
||||
if (sounds && sounds.Size() > 0)
|
||||
{
|
||||
winrt::hstring soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
|
||||
winrt::Windows::Foundation::Uri uri{ soundPath };
|
||||
_playBellSound(uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
|
||||
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
||||
}
|
||||
PlayNotificationSound();
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
|
||||
@@ -291,9 +333,60 @@ namespace winrt::TerminalApp::implementation
|
||||
_control.BellLightOn();
|
||||
}
|
||||
|
||||
// raise the event with the bool value corresponding to the taskbar flag
|
||||
// raise the event with the bool values corresponding to the taskbar and notification flags
|
||||
BellRequested.raise(*this,
|
||||
*winrt::make_self<TerminalApp::implementation::BellEventArgs>(WI_IsFlagSet(_profile.BellStyle(), BellStyle::Taskbar)));
|
||||
*winrt::make_self<TerminalApp::implementation::BellEventArgs>(
|
||||
WI_IsFlagSet(_profile.BellStyle(), BellStyle::Taskbar),
|
||||
WI_IsFlagSet(_profile.BellStyle(), BellStyle::Notification)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlPromptStartedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
const auto notifyStyle = _profile.NotifyOnNextPrompt();
|
||||
if (static_cast<int>(notifyStyle) != 0)
|
||||
{
|
||||
NotificationRequested.raise(*this,
|
||||
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle, true));
|
||||
}
|
||||
|
||||
const auto autoDetect = _profile.AutoDetectRunningCommand();
|
||||
if (autoDetect != AutoDetectRunningCommand::Disabled && _autoDetectActive)
|
||||
{
|
||||
_autoDetectActive = false;
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlOutputStartedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
const auto autoDetect = _profile.AutoDetectRunningCommand();
|
||||
if (autoDetect != AutoDetectRunningCommand::Disabled && !_autoDetectActive)
|
||||
{
|
||||
_autoDetectActive = true;
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlOutputIdleHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
const auto notifyStyle = _profile.NotifyOnInactiveOutput();
|
||||
if (static_cast<int>(notifyStyle) != 0)
|
||||
{
|
||||
NotificationRequested.raise(*this,
|
||||
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
#include "TerminalPaneContent.g.h"
|
||||
#include "BellEventArgs.g.h"
|
||||
#include "NotificationEventArgs.g.h"
|
||||
#include "BasicPaneEvents.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
@@ -13,10 +14,23 @@ namespace winrt::TerminalApp::implementation
|
||||
struct BellEventArgs : public BellEventArgsT<BellEventArgs>
|
||||
{
|
||||
public:
|
||||
BellEventArgs(bool flashTaskbar) :
|
||||
FlashTaskbar(flashTaskbar) {}
|
||||
BellEventArgs(bool flashTaskbar, bool sendNotification) :
|
||||
FlashTaskbar(flashTaskbar), SendNotification(sendNotification) {}
|
||||
|
||||
til::property<bool> FlashTaskbar;
|
||||
til::property<bool> SendNotification;
|
||||
};
|
||||
|
||||
struct NotificationEventArgs : public NotificationEventArgsT<NotificationEventArgs>
|
||||
{
|
||||
public:
|
||||
NotificationEventArgs(winrt::Microsoft::Terminal::Control::OutputNotificationStyle style, bool onlyWhenInactive = false, const winrt::hstring& title = {}, const winrt::hstring& body = {}) :
|
||||
Style(style), OnlyWhenInactive(onlyWhenInactive), Title(title), Body(body) {}
|
||||
|
||||
til::property<winrt::Microsoft::Terminal::Control::OutputNotificationStyle> Style;
|
||||
til::property<bool> OnlyWhenInactive;
|
||||
til::property<winrt::hstring> Title;
|
||||
til::property<winrt::hstring> Body;
|
||||
};
|
||||
|
||||
struct TerminalPaneContent : TerminalPaneContentT<TerminalPaneContent>, BasicPaneEvents
|
||||
@@ -36,6 +50,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
|
||||
void MarkAsDefterm();
|
||||
void PlayNotificationSound();
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const
|
||||
{
|
||||
@@ -43,8 +58,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
winrt::hstring Title() { return _control.Title(); }
|
||||
uint64_t TaskbarState() { return _control.TaskbarState(); }
|
||||
uint64_t TaskbarProgress() { return _control.TaskbarProgress(); }
|
||||
uint64_t TaskbarState();
|
||||
uint64_t TaskbarProgress();
|
||||
bool ReadOnly() { return _control.ReadOnly(); }
|
||||
winrt::hstring Icon() const;
|
||||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() const noexcept;
|
||||
@@ -66,11 +81,15 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
|
||||
bool _bellPlayerCreated{ false };
|
||||
std::atomic<bool> _autoDetectActive{ false };
|
||||
|
||||
struct ControlEventTokens
|
||||
{
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ConnectionStateChanged_revoker _ConnectionStateChanged;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::WarningBell_revoker _WarningBell;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::PromptStarted_revoker _PromptStarted;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::OutputStarted_revoker _OutputStarted;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::OutputIdle_revoker _OutputIdle;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::CloseTerminalRequested_revoker _CloseTerminalRequested;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::RestartTerminalRequested_revoker _RestartTerminalRequested;
|
||||
|
||||
@@ -79,6 +98,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Control::TermControl::SetTaskbarProgress_revoker _SetTaskbarProgress;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ReadOnlyChanged_revoker _ReadOnlyChanged;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::FocusFollowMouseRequested_revoker _FocusFollowMouseRequested;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ShowNotification_revoker _ShowNotification;
|
||||
|
||||
} _controlEvents;
|
||||
void _setupControlEvents();
|
||||
@@ -89,6 +109,9 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine _controlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
void _controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& e);
|
||||
void _controlPromptStartedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
|
||||
void _controlOutputStartedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
|
||||
void _controlOutputIdleHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
|
||||
void _controlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _controlTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
@@ -96,6 +119,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _controlSetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlReadOnlyChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlFocusFollowMouseRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlShowNotification(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::Control::ShowNotificationEventArgs& args);
|
||||
|
||||
void _closeTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
void _restartTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace TerminalApp
|
||||
Microsoft.Terminal.Control.TermControl GetTermControl();
|
||||
|
||||
void MarkAsDefterm();
|
||||
void PlayNotificationSound();
|
||||
|
||||
Microsoft.Terminal.Settings.Model.Profile GetProfile();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace winrt::TerminalApp::implementation
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingActive, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingIndeterminate, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, BellIndicator, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ActivityIndicator, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsReadOnlyActive, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(uint32_t, ProgressValue, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsInputBroadcastActive, PropertyChanged.raise);
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace TerminalApp
|
||||
Boolean IsProgressRingActive { get; set; };
|
||||
Boolean IsProgressRingIndeterminate { get; set; };
|
||||
Boolean BellIndicator { get; set; };
|
||||
Boolean ActivityIndicator { get; set; };
|
||||
UInt32 ProgressValue { get; set; };
|
||||
Boolean IsReadOnlyActive { get; set; };
|
||||
Boolean IsInputBroadcastActive { get; set; };
|
||||
|
||||
@@ -1205,6 +1205,15 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
bool TerminalWindow::FocusTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
return _root->FocusTab(tab);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TerminalWindow::WindowName(const winrt::hstring& name)
|
||||
{
|
||||
const auto oldIsQuakeMode = _WindowProperties->IsQuakeWindow();
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace winrt::TerminalApp::implementation
|
||||
bool ShowTabsFullscreen() const;
|
||||
bool AutoHideWindow();
|
||||
void IdentifyWindow();
|
||||
bool FocusTab(const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
std::optional<uint32_t> LoadPersistedLayoutIdx() const;
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowLayout LoadPersistedLayout();
|
||||
@@ -221,6 +222,7 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
|
||||
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
||||
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
|
||||
FORWARDED_TYPED_EVENT(FocusTabRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::Tab, _root, FocusTabRequested);
|
||||
FORWARDED_TYPED_EVENT(OpenSystemMenu, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, OpenSystemMenu);
|
||||
FORWARDED_TYPED_EVENT(QuitRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, QuitRequested);
|
||||
FORWARDED_TYPED_EVENT(ShowWindowChanged, Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Control::ShowWindowArgs, _root, ShowWindowChanged);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import "IPaneContent.idl";
|
||||
import "TerminalPage.idl";
|
||||
import "ShortcutActionDispatch.idl";
|
||||
import "Tab.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
@@ -74,6 +75,7 @@ namespace TerminalApp
|
||||
Boolean ShowTabsFullscreen { get; };
|
||||
|
||||
void IdentifyWindow();
|
||||
Boolean FocusTab(TerminalApp.Tab tab);
|
||||
void SetPersistedLayoutIdx(UInt32 idx);
|
||||
void RequestExitFullscreen();
|
||||
|
||||
@@ -126,6 +128,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.Tab> FocusTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.SystemMenuChangeArgs> SystemMenuChangeRequested;
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
#include <winrt/Windows.Media.Playback.h>
|
||||
#include <winrt/Windows.Management.Deployment.h>
|
||||
|
||||
#include <winrt/Windows.UI.Notifications.h>
|
||||
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
|
||||
|
||||
@@ -139,6 +139,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnSearchMissingCommand = [this](auto&& PH1, auto&& PH2) { _terminalSearchMissingCommand(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
|
||||
_terminal->SetSearchMissingCommandCallback(pfnSearchMissingCommand);
|
||||
|
||||
auto pfnPromptStarted = [this] { _terminalPromptStarted(); };
|
||||
_terminal->SetPromptStartedCallback(pfnPromptStarted);
|
||||
|
||||
auto pfnOutputStarted = [this] { _terminalOutputStarted(); };
|
||||
_terminal->SetOutputStartedCallback(pfnOutputStarted);
|
||||
|
||||
auto pfnShowNotification = [this](auto&& PH1, auto&& PH2) { _terminalShowNotification(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
|
||||
_terminal->SetShowNotificationCallback(pfnShowNotification);
|
||||
|
||||
auto pfnClearQuickFix = [this] { ClearQuickFix(); };
|
||||
_terminal->SetClearQuickFixCallback(pfnClearQuickFix);
|
||||
|
||||
@@ -1596,9 +1605,31 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Since this can only ever be triggered by output from the connection,
|
||||
// then the Terminal already has the write lock when calling this
|
||||
// callback.
|
||||
if (_restoring)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WarningBell.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::_terminalPromptStarted()
|
||||
{
|
||||
if (_restoring)
|
||||
{
|
||||
return;
|
||||
}
|
||||
PromptStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::_terminalOutputStarted()
|
||||
{
|
||||
if (_restoring)
|
||||
{
|
||||
return;
|
||||
}
|
||||
OutputStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called for the Terminal's TitleChanged callback. This will re-raise
|
||||
// a new winrt TypedEvent that can be listened to.
|
||||
@@ -1656,6 +1687,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void ControlCore::_terminalTaskbarProgressChanged()
|
||||
{
|
||||
if (_restoring)
|
||||
{
|
||||
return;
|
||||
}
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
@@ -1673,6 +1708,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - duration - How long the note should be sustained (in microseconds).
|
||||
void ControlCore::_terminalPlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration)
|
||||
{
|
||||
if (_restoring)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// The UI thread might try to acquire the console lock from time to time.
|
||||
// --> Unlock it, so the UI doesn't hang while we're busy.
|
||||
const auto suspension = _terminal->SuspendLock();
|
||||
@@ -1691,6 +1730,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
SearchMissingCommand.raise(*this, make<implementation::SearchMissingCommandEventArgs>(hstring{ missingCommand }, bufferRow));
|
||||
}
|
||||
|
||||
void ControlCore::_terminalShowNotification(std::wstring_view title, std::wstring_view body)
|
||||
{
|
||||
ShowNotification.raise(*this, make<implementation::ShowNotificationEventArgs>(hstring{ title }, hstring{ body }));
|
||||
}
|
||||
|
||||
void ControlCore::OpenCWD()
|
||||
{
|
||||
const auto workingDirectory = WorkingDirectory();
|
||||
@@ -1845,8 +1889,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_terminal->SerializeMainBuffer(handle);
|
||||
}
|
||||
|
||||
void ControlCore::RestoreFromPath(const wchar_t* path) const
|
||||
void ControlCore::RestoreFromPath(const wchar_t* path)
|
||||
{
|
||||
_restoring = true;
|
||||
const auto restoreComplete = wil::scope_exit([&] { _restoring = false; });
|
||||
wil::unique_handle file{ CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr) };
|
||||
|
||||
// This block of code exists temporarily to fix buffer dumps that were
|
||||
@@ -2426,11 +2472,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return *context;
|
||||
}
|
||||
|
||||
winrt::hstring ControlCore::CurrentWorkingDirectory() const
|
||||
{
|
||||
return winrt::hstring{ _terminal->GetWorkingDirectory() };
|
||||
}
|
||||
|
||||
bool ControlCore::QuickFixesAvailable() const noexcept
|
||||
{
|
||||
return _cachedQuickFixes && _cachedQuickFixes.Size() > 0;
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void Close();
|
||||
void PersistTo(HANDLE handle) const;
|
||||
void RestoreFromPath(const wchar_t* path) const;
|
||||
void RestoreFromPath(const wchar_t* path);
|
||||
|
||||
void ClearQuickFix();
|
||||
|
||||
@@ -191,8 +191,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void ContextMenuSelectCommand();
|
||||
void ContextMenuSelectOutput();
|
||||
|
||||
winrt::hstring CurrentWorkingDirectory() const;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ITerminalInput
|
||||
@@ -277,6 +275,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::TitleChangedEventArgs> TitleChanged;
|
||||
til::typed_event<IInspectable, Control::WriteToClipboardEventArgs> WriteToClipboard;
|
||||
til::typed_event<> WarningBell;
|
||||
til::typed_event<> PromptStarted;
|
||||
til::typed_event<> OutputStarted;
|
||||
til::typed_event<> TabColorChanged;
|
||||
til::typed_event<> BackgroundColorChanged;
|
||||
til::typed_event<IInspectable, Control::ScrollPositionChangedArgs> ScrollPositionChanged;
|
||||
@@ -294,6 +294,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
til::typed_event<IInspectable, Control::CompletionsChangedEventArgs> CompletionsChanged;
|
||||
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
til::typed_event<IInspectable, Control::ShowNotificationEventArgs> ShowNotification;
|
||||
til::typed_event<> RefreshQuickFixUI;
|
||||
til::typed_event<IInspectable, Control::WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
@@ -325,6 +326,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
#pragma region TerminalCoreCallbacks
|
||||
void _terminalWarningBell();
|
||||
void _terminalPromptStarted();
|
||||
void _terminalOutputStarted();
|
||||
void _terminalTitleChanged(std::wstring_view wstr);
|
||||
void _terminalScrollPositionChanged(const int viewTop,
|
||||
const int viewHeight,
|
||||
@@ -335,6 +338,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const int velocity,
|
||||
const std::chrono::microseconds duration);
|
||||
void _terminalSearchMissingCommand(std::wstring_view missingCommand, const til::CoordType& bufferRow);
|
||||
void _terminalShowNotification(std::wstring_view title, std::wstring_view body);
|
||||
void _terminalWindowSizeChanged(int32_t width, int32_t height);
|
||||
|
||||
void _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
|
||||
@@ -421,6 +425,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
std::optional<til::point> _lastHoveredCell;
|
||||
uint16_t _lastHoveredId{ 0 };
|
||||
std::atomic<bool> _initializedTerminal{ false };
|
||||
std::atomic<bool> _restoring{ false };
|
||||
bool _isReadOnly{ false };
|
||||
bool _closing{ false };
|
||||
|
||||
|
||||
@@ -192,12 +192,15 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> PromptStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OutputStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> BackgroundColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TaskbarProgressChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RendererEnteredErrorState;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RefreshQuickFixUI;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
|
||||
@@ -169,6 +169,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void ControlInteractivity::GotFocus()
|
||||
{
|
||||
_focused = true;
|
||||
|
||||
if (_uiaEngine.get())
|
||||
{
|
||||
THROW_IF_FAILED(_uiaEngine->Enable());
|
||||
@@ -181,6 +183,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void ControlInteractivity::LostFocus()
|
||||
{
|
||||
_focused = false;
|
||||
|
||||
if (_uiaEngine.get())
|
||||
{
|
||||
THROW_IF_FAILED(_uiaEngine->Disable());
|
||||
@@ -248,7 +252,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
PasteFromClipboard.raise(*this, std::move(args));
|
||||
}
|
||||
|
||||
void ControlInteractivity::PointerPressed(Control::MouseButtonState buttonState,
|
||||
void ControlInteractivity::PointerPressed(const uint32_t /*pointerId*/,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const uint64_t timestamp,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
@@ -261,6 +266,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const auto shiftEnabled = modifiers.IsShiftPressed();
|
||||
const auto ctrlEnabled = modifiers.IsCtrlPressed();
|
||||
|
||||
// Mark that this pointer event actually started within our bounds.
|
||||
// We'll need this later, for PointerMoved events.
|
||||
_pointerPressedInBounds = true;
|
||||
|
||||
// GH#9396: we prioritize hyper-link over VT mouse events
|
||||
auto hyperlink = _core->GetHyperlink(terminalPosition.to_core_point());
|
||||
if (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown) &&
|
||||
@@ -357,24 +366,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInteractivity::TouchPressed(const winrt::Windows::Foundation::Point contactPoint)
|
||||
void ControlInteractivity::TouchPressed(const Core::Point contactPoint)
|
||||
{
|
||||
_touchAnchor = contactPoint;
|
||||
}
|
||||
|
||||
bool ControlInteractivity::PointerMoved(Control::MouseButtonState buttonState,
|
||||
bool ControlInteractivity::PointerMoved(const uint32_t /*pointerId*/,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
const bool focused,
|
||||
const Core::Point pixelPosition,
|
||||
const bool pointerPressedInBounds)
|
||||
const Core::Point pixelPosition)
|
||||
{
|
||||
const auto terminalPosition = _getTerminalPosition(til::point{ pixelPosition }, false);
|
||||
// Returning true from this function indicates that the caller should do no further processing of this movement.
|
||||
bool handledCompletely = false;
|
||||
|
||||
// Short-circuit isReadOnly check to avoid warning dialog
|
||||
if (focused && !_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
|
||||
if (_focused && !_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
|
||||
{
|
||||
_sendMouseEventHelper(terminalPosition, pointerUpdateKind, modifiers, 0, buttonState);
|
||||
handledCompletely = true;
|
||||
@@ -383,7 +391,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// actually start _in_ the control bounds. Case in point - someone drags
|
||||
// a file into the bounds of the control. That shouldn't send the
|
||||
// selection into space.
|
||||
else if (focused && pointerPressedInBounds && WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown))
|
||||
else if (_focused && _pointerPressedInBounds && WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown))
|
||||
{
|
||||
if (_singleClickTouchdownPos)
|
||||
{
|
||||
@@ -429,10 +437,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return handledCompletely;
|
||||
}
|
||||
|
||||
void ControlInteractivity::TouchMoved(const winrt::Windows::Foundation::Point newTouchPoint,
|
||||
const bool focused)
|
||||
void ControlInteractivity::TouchMoved(const Core::Point newTouchPoint)
|
||||
{
|
||||
if (focused &&
|
||||
if (_focused &&
|
||||
_touchAnchor)
|
||||
{
|
||||
const auto anchor = _touchAnchor.value();
|
||||
@@ -466,11 +473,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInteractivity::PointerReleased(Control::MouseButtonState buttonState,
|
||||
void ControlInteractivity::PointerReleased(const uint32_t /*pointerId*/,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
const Core::Point pixelPosition)
|
||||
{
|
||||
_pointerPressedInBounds = false;
|
||||
|
||||
const auto terminalPosition = _getTerminalPosition(til::point{ pixelPosition }, false);
|
||||
// Short-circuit isReadOnly check to avoid warning dialog
|
||||
if (!_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
|
||||
|
||||
@@ -51,23 +51,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
::Microsoft::Console::Render::IRenderData* GetRenderData() const;
|
||||
|
||||
#pragma region Input Methods
|
||||
void PointerPressed(Control::MouseButtonState buttonState,
|
||||
void PointerPressed(const uint32_t pointerId,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const uint64_t timestamp,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
const Core::Point pixelPosition);
|
||||
void TouchPressed(const winrt::Windows::Foundation::Point contactPoint);
|
||||
void TouchPressed(const Core::Point contactPoint);
|
||||
|
||||
bool PointerMoved(Control::MouseButtonState buttonState,
|
||||
bool PointerMoved(const uint32_t pointerId,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
const bool focused,
|
||||
const Core::Point pixelPosition,
|
||||
const bool pointerPressedInBounds);
|
||||
void TouchMoved(const winrt::Windows::Foundation::Point newTouchPoint,
|
||||
const bool focused);
|
||||
const Core::Point pixelPosition);
|
||||
void TouchMoved(const Core::Point newTouchPoint);
|
||||
|
||||
void PointerReleased(Control::MouseButtonState buttonState,
|
||||
void PointerReleased(const uint32_t pointerId,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
const Core::Point pixelPosition);
|
||||
@@ -115,7 +115,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
// If this is set, then we assume we are in the middle of panning the
|
||||
// viewport via touch input.
|
||||
std::optional<winrt::Windows::Foundation::Point> _touchAnchor;
|
||||
std::optional<Core::Point> _touchAnchor;
|
||||
|
||||
using Timestamp = uint64_t;
|
||||
|
||||
@@ -142,6 +142,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
uint64_t _id;
|
||||
static std::atomic<uint64_t> _nextId;
|
||||
|
||||
bool _focused{ false };
|
||||
bool _pointerPressedInBounds{ false };
|
||||
|
||||
unsigned int _numberOfClicks(Core::Point clickPos, Timestamp clickTime);
|
||||
void _updateSystemParameterSettings() noexcept;
|
||||
|
||||
|
||||
@@ -36,24 +36,24 @@ namespace Microsoft.Terminal.Control
|
||||
void RequestPasteTextFromClipboard();
|
||||
void SetEndSelectionPoint(Microsoft.Terminal.Core.Point point);
|
||||
|
||||
void PointerPressed(MouseButtonState buttonState,
|
||||
void PointerPressed(UInt32 pointerId,
|
||||
MouseButtonState buttonState,
|
||||
UInt32 pointerUpdateKind,
|
||||
UInt64 timestamp,
|
||||
Microsoft.Terminal.Core.ControlKeyStates modifiers,
|
||||
Microsoft.Terminal.Core.Point pixelPosition);
|
||||
void TouchPressed(Windows.Foundation.Point contactPoint);
|
||||
void TouchPressed(Microsoft.Terminal.Core.Point contactPoint);
|
||||
|
||||
Boolean PointerMoved(MouseButtonState buttonState,
|
||||
Boolean PointerMoved(UInt32 pointerId,
|
||||
MouseButtonState buttonState,
|
||||
UInt32 pointerUpdateKind,
|
||||
Microsoft.Terminal.Core.ControlKeyStates modifiers,
|
||||
Boolean focused,
|
||||
Microsoft.Terminal.Core.Point pixelPosition,
|
||||
Boolean pointerPressedInBounds);
|
||||
Microsoft.Terminal.Core.Point pixelPosition);
|
||||
|
||||
void TouchMoved(Windows.Foundation.Point newTouchPoint,
|
||||
Boolean focused);
|
||||
void TouchMoved(Microsoft.Terminal.Core.Point newTouchPoint);
|
||||
|
||||
void PointerReleased(MouseButtonState buttonState,
|
||||
void PointerReleased(UInt32 pointerId,
|
||||
MouseButtonState buttonState,
|
||||
UInt32 pointerUpdateKind,
|
||||
Microsoft.Terminal.Core.ControlKeyStates modifiers,
|
||||
Microsoft.Terminal.Core.Point pixelPosition);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "CharSentEventArgs.g.h"
|
||||
#include "StringSentEventArgs.g.h"
|
||||
#include "SearchMissingCommandEventArgs.g.h"
|
||||
#include "ShowNotificationEventArgs.g.h"
|
||||
#include "WindowSizeChangedEventArgs.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
@@ -252,6 +253,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::property<til::CoordType> BufferRow;
|
||||
};
|
||||
|
||||
struct ShowNotificationEventArgs : public ShowNotificationEventArgsT<ShowNotificationEventArgs>
|
||||
{
|
||||
public:
|
||||
ShowNotificationEventArgs(const winrt::hstring& title, const winrt::hstring& body) :
|
||||
Title(title),
|
||||
Body(body) {}
|
||||
|
||||
til::property<winrt::hstring> Title;
|
||||
til::property<winrt::hstring> Body;
|
||||
};
|
||||
|
||||
struct WindowSizeChangedEventArgs : public WindowSizeChangedEventArgsT<WindowSizeChangedEventArgs>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -160,6 +160,12 @@ namespace Microsoft.Terminal.Control
|
||||
Int32 BufferRow { get; };
|
||||
}
|
||||
|
||||
runtimeclass ShowNotificationEventArgs
|
||||
{
|
||||
String Title { get; };
|
||||
String Body { get; };
|
||||
}
|
||||
|
||||
runtimeclass WindowSizeChangedEventArgs
|
||||
{
|
||||
Int32 Width;
|
||||
|
||||
@@ -29,6 +29,23 @@ namespace Microsoft.Terminal.Control
|
||||
MinGW,
|
||||
};
|
||||
|
||||
[flags]
|
||||
enum OutputNotificationStyle
|
||||
{
|
||||
Taskbar = 0x1,
|
||||
Audible = 0x2,
|
||||
Tab = 0x4,
|
||||
Notification = 0x8,
|
||||
All = 0xffffffff
|
||||
};
|
||||
|
||||
enum AutoDetectRunningCommand
|
||||
{
|
||||
Disabled,
|
||||
Automatic,
|
||||
Progress
|
||||
};
|
||||
|
||||
// Class Description:
|
||||
// TerminalSettings encapsulates all settings that control the
|
||||
// TermControl's behavior. In these settings there is both the entirety
|
||||
@@ -76,6 +93,11 @@ namespace Microsoft.Terminal.Control
|
||||
Boolean RepositionCursorWithMouse { get; };
|
||||
|
||||
PathTranslationStyle PathTranslationStyle { get; };
|
||||
String DragDropDelimiter { get; };
|
||||
|
||||
OutputNotificationStyle NotifyOnInactiveOutput { get; };
|
||||
OutputNotificationStyle NotifyOnNextPrompt { get; };
|
||||
AutoDetectRunningCommand AutoDetectRunningCommand { get; };
|
||||
|
||||
// NOTE! When adding something here, make sure to update ControlProperties.h too!
|
||||
};
|
||||
|
||||
@@ -60,7 +60,5 @@ namespace Microsoft.Terminal.Control
|
||||
void SelectOutput(Boolean goUp);
|
||||
IVector<ScrollMark> ScrollMarks { get; };
|
||||
|
||||
String CurrentWorkingDirectory { get; };
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -328,6 +328,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_revokers.CompletionsChanged = _core.CompletionsChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleCompletionsChanged });
|
||||
_revokers.RestartTerminalRequested = _core.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleRestartTerminalRequested });
|
||||
_revokers.SearchMissingCommand = _core.SearchMissingCommand(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleSearchMissingCommand });
|
||||
_revokers.ShowNotification = _core.ShowNotification(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleShowNotification });
|
||||
_revokers.WindowSizeChanged = _core.WindowSizeChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWindowSizeChanged });
|
||||
_revokers.WriteToClipboard = _core.WriteToClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWriteToClipboard });
|
||||
|
||||
@@ -393,6 +394,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// attached content before we set up the throttled func, and that'll A/V
|
||||
_revokers.coreScrollPositionChanged = _core.ScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_ScrollPositionChanged });
|
||||
_revokers.WarningBell = _core.WarningBell(winrt::auto_revoke, { get_weak(), &TermControl::_coreWarningBell });
|
||||
_revokers.PromptStarted = _core.PromptStarted(winrt::auto_revoke, { get_weak(), &TermControl::_corePromptStarted });
|
||||
_revokers.OutputStarted = _core.OutputStarted(winrt::auto_revoke, { get_weak(), &TermControl::_coreOutputStarted });
|
||||
|
||||
static constexpr auto AutoScrollUpdateInterval = std::chrono::microseconds(static_cast<int>(1.0 / 30.0 * 1000000));
|
||||
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
|
||||
@@ -1988,12 +1991,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// NB: I don't think this is correct because the touch should be in the center of the rect.
|
||||
// I suspect the point.Position() would be correct.
|
||||
const auto contactRect = point.Properties().ContactRect();
|
||||
_interactivity.TouchPressed({ contactRect.X, contactRect.Y });
|
||||
til::point newTouchPoint{ til::math::rounding, contactRect.X, contactRect.Y };
|
||||
_interactivity.TouchPressed(newTouchPoint.to_core_point());
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto cursorPosition = point.Position();
|
||||
_interactivity.PointerPressed(TermControl::GetPressedMouseButtons(point),
|
||||
_interactivity.PointerPressed(point.PointerId(),
|
||||
TermControl::GetPressedMouseButtons(point),
|
||||
TermControl::GetPointerUpdateKind(point),
|
||||
point.Timestamp(),
|
||||
ControlKeyStates{ args.KeyModifiers() },
|
||||
@@ -2032,12 +2037,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
|
||||
type == Windows::Devices::Input::PointerDeviceType::Pen)
|
||||
{
|
||||
auto suppressFurtherHandling = _interactivity.PointerMoved(TermControl::GetPressedMouseButtons(point),
|
||||
auto suppressFurtherHandling = _interactivity.PointerMoved(point.PointerId(),
|
||||
TermControl::GetPressedMouseButtons(point),
|
||||
TermControl::GetPointerUpdateKind(point),
|
||||
ControlKeyStates(args.KeyModifiers()),
|
||||
_focused,
|
||||
pixelPosition,
|
||||
_pointerPressedInBounds);
|
||||
pixelPosition);
|
||||
|
||||
// GH#9109 - Only start an auto-scroll when the drag actually
|
||||
// started within our bounds. Otherwise, someone could start a drag
|
||||
@@ -2076,7 +2080,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
else if (type == Windows::Devices::Input::PointerDeviceType::Touch)
|
||||
{
|
||||
const auto contactRect = point.Properties().ContactRect();
|
||||
_interactivity.TouchMoved({ contactRect.X, contactRect.Y }, _focused);
|
||||
til::point newTouchPoint{ til::math::rounding, contactRect.X, contactRect.Y };
|
||||
|
||||
_interactivity.TouchMoved(newTouchPoint.to_core_point());
|
||||
}
|
||||
|
||||
args.Handled(true);
|
||||
@@ -2109,7 +2115,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
|
||||
type == Windows::Devices::Input::PointerDeviceType::Pen)
|
||||
{
|
||||
_interactivity.PointerReleased(TermControl::GetPressedMouseButtons(point),
|
||||
_interactivity.PointerReleased(point.PointerId(),
|
||||
TermControl::GetPressedMouseButtons(point),
|
||||
TermControl::GetPointerUpdateKind(point),
|
||||
ControlKeyStates(args.KeyModifiers()),
|
||||
pixelPosition);
|
||||
@@ -3073,7 +3080,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// the full path of the file to our terminal connection. Like conhost, if
|
||||
// the path contains a space, we'll wrap the path in quotes.
|
||||
// - Unlike conhost, if multiple files are dropped onto the terminal, we'll
|
||||
// write all the paths to the terminal, separated by spaces.
|
||||
// write all the paths to the terminal, separated by the configured delimiter.
|
||||
// Arguments:
|
||||
// - e: The DragEventArgs from the Drop event
|
||||
// Return Value:
|
||||
@@ -3194,12 +3201,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
std::wstring allPathsString;
|
||||
const auto delimiter{ _core.Settings().DragDropDelimiter() };
|
||||
for (auto& fullPath : fullPaths)
|
||||
{
|
||||
// Join the paths with spaces
|
||||
// Join the paths with the delimiter
|
||||
if (!allPathsString.empty())
|
||||
{
|
||||
allPathsString += L" ";
|
||||
allPathsString += delimiter;
|
||||
}
|
||||
|
||||
const auto translationStyle{ _core.Settings().PathTranslationStyle() };
|
||||
@@ -3723,6 +3731,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_playWarningBell->Run();
|
||||
}
|
||||
|
||||
void TermControl::_corePromptStarted(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
PromptStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TermControl::_coreOutputStarted(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
OutputStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
hstring TermControl::ReadEntireBuffer() const
|
||||
{
|
||||
return _core.ReadEntireBuffer();
|
||||
@@ -3731,10 +3749,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
return _core.CommandHistory();
|
||||
}
|
||||
winrt::hstring TermControl::CurrentWorkingDirectory() const
|
||||
{
|
||||
return _core.CurrentWorkingDirectory();
|
||||
}
|
||||
|
||||
void TermControl::UpdateWinGetSuggestions(Windows::Foundation::Collections::IVector<hstring> suggestions)
|
||||
{
|
||||
@@ -3844,6 +3858,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void TermControl::_coreOutputIdle(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
_refreshSearch();
|
||||
OutputIdle.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TermControl::OwningHwnd(uint64_t owner)
|
||||
|
||||
@@ -117,8 +117,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
|
||||
void SelectCommand(const bool goUp);
|
||||
void SelectOutput(const bool goUp);
|
||||
|
||||
winrt::hstring CurrentWorkingDirectory() const;
|
||||
#pragma endregion
|
||||
|
||||
void ScrollViewport(int viewTop);
|
||||
@@ -213,6 +211,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, IInspectable> FocusFollowMouseRequested;
|
||||
til::typed_event<Control::TermControl, Windows::UI::Xaml::RoutedEventArgs> Initialized;
|
||||
til::typed_event<> WarningBell;
|
||||
til::typed_event<> PromptStarted;
|
||||
til::typed_event<> OutputStarted;
|
||||
til::typed_event<> OutputIdle;
|
||||
til::typed_event<IInspectable, Control::KeySentEventArgs> KeySent;
|
||||
til::typed_event<IInspectable, Control::CharSentEventArgs> CharSent;
|
||||
til::typed_event<IInspectable, Control::StringSentEventArgs> StringSent;
|
||||
@@ -232,6 +233,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(RestartTerminalRequested, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(WriteToClipboard, IInspectable, Control::WriteToClipboardEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(ShowNotification, IInspectable, Control::ShowNotificationEventArgs);
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -426,6 +428,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args);
|
||||
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
|
||||
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
|
||||
void _corePromptStarted(const IInspectable& sender, const IInspectable& args);
|
||||
void _coreOutputStarted(const IInspectable& sender, const IInspectable& args);
|
||||
void _coreOutputIdle(const IInspectable& sender, const IInspectable& args);
|
||||
|
||||
winrt::Windows::Foundation::Point _toPosInDips(const Core::Point terminalCellPos);
|
||||
@@ -451,6 +455,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
Control::ControlCore::ScrollPositionChanged_revoker coreScrollPositionChanged;
|
||||
Control::ControlCore::WarningBell_revoker WarningBell;
|
||||
Control::ControlCore::PromptStarted_revoker PromptStarted;
|
||||
Control::ControlCore::OutputStarted_revoker OutputStarted;
|
||||
Control::ControlCore::RendererEnteredErrorState_revoker RendererEnteredErrorState;
|
||||
Control::ControlCore::BackgroundColorChanged_revoker BackgroundColorChanged;
|
||||
Control::ControlCore::FontSizeChanged_revoker FontSizeChanged;
|
||||
@@ -470,6 +476,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Control::ControlCore::CompletionsChanged_revoker CompletionsChanged;
|
||||
Control::ControlCore::RestartTerminalRequested_revoker RestartTerminalRequested;
|
||||
Control::ControlCore::SearchMissingCommand_revoker SearchMissingCommand;
|
||||
Control::ControlCore::ShowNotification_revoker ShowNotification;
|
||||
Control::ControlCore::RefreshQuickFixUI_revoker RefreshQuickFixUI;
|
||||
Control::ControlCore::WindowSizeChanged_revoker WindowSizeChanged;
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
event Windows.Foundation.TypedEventHandler<Object, NoticeEventArgs> RaiseNotice;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> PromptStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OutputStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OutputIdle;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> HidePointerCursor;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RestorePointerCursor;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
@@ -82,6 +85,7 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, CharSentEventArgs> CharSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, StringSentEventArgs> StringSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
|
||||
|
||||
|
||||
Microsoft.UI.Xaml.Controls.CommandBarFlyout ContextMenu { get; };
|
||||
|
||||
@@ -124,6 +124,7 @@ namespace Microsoft.Terminal.Core
|
||||
Boolean AllowKittyKeyboardMode { get; };
|
||||
Boolean AllowVtChecksumReport { get; };
|
||||
Boolean AllowVtClipboardWrite { get; };
|
||||
Boolean AllowOscNotifications { get; };
|
||||
Boolean TrimBlockSelection { get; };
|
||||
Boolean DetectURLs { get; };
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
_answerbackMessage = settings.AnswerbackMessage();
|
||||
_wordDelimiters = settings.WordDelimiters();
|
||||
_suppressApplicationTitle = settings.SuppressApplicationTitle();
|
||||
_startingTitle = settings.StartingTitle();
|
||||
_trimBlockSelection = settings.TrimBlockSelection();
|
||||
_autoMarkPrompts = settings.AutoMarkPrompts();
|
||||
_rainbowSuggestions = settings.RainbowSuggestions();
|
||||
@@ -123,11 +124,6 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
// Save the changes made above and in UpdateAppearance as the new default render settings.
|
||||
GetRenderSettings().SaveDefaultSettings();
|
||||
|
||||
if (!_startingTitle)
|
||||
{
|
||||
_startingTitle = settings.StartingTitle();
|
||||
}
|
||||
|
||||
if (!_startingTabColor && settings.StartingTabColor())
|
||||
{
|
||||
_startingTabColor = settings.StartingTabColor().Value();
|
||||
@@ -267,6 +263,7 @@ void Terminal::SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettin
|
||||
auto features = til::enumset<ITermDispatch::OptionalFeature>{};
|
||||
features.set(ITermDispatch::OptionalFeature::ChecksumReport, settings.AllowVtChecksumReport());
|
||||
features.set(ITermDispatch::OptionalFeature::ClipboardWrite, settings.AllowVtClipboardWrite());
|
||||
features.set(ITermDispatch::OptionalFeature::DesktopNotification, settings.AllowOscNotifications());
|
||||
engine.Dispatch().SetOptionalFeatures(features);
|
||||
}
|
||||
|
||||
@@ -767,6 +764,11 @@ TerminalInput::OutputType Terminal::SendCharEvent(const wchar_t ch, const WORD s
|
||||
// This changed the scrollbar marks - raise a notification to update them
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
// regardless, notify that we started command output
|
||||
if (_pfnOutputStarted)
|
||||
{
|
||||
_pfnOutputStarted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1276,11 +1278,26 @@ void Microsoft::Terminal::Core::Terminal::SetSearchMissingCommandCallback(std::f
|
||||
_pfnSearchMissingCommand.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept
|
||||
{
|
||||
_pfnShowNotification.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetClearQuickFixCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnClearQuickFix.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetPromptStartedCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnPromptStarted.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetOutputStartedCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnOutputStarted.swap(pfn);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Stores the search highlighted regions in the terminal
|
||||
void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept
|
||||
|
||||
@@ -159,12 +159,14 @@ public:
|
||||
|
||||
bool IsVtInputEnabled() const noexcept override;
|
||||
void NotifyBufferRotation(const int delta) override;
|
||||
void NotifyShellIntegrationMark() override;
|
||||
void NotifyShellIntegrationMark(ShellIntegrationMark mark) override;
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
void SearchMissingCommand(const std::wstring_view command) override;
|
||||
|
||||
void ShowNotification(const std::wstring_view title, const std::wstring_view body) override;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void ClearMark();
|
||||
@@ -233,8 +235,11 @@ public:
|
||||
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
|
||||
void CompletionsChangedCallback(std::function<void(std::wstring_view, unsigned int)> pfn) noexcept;
|
||||
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view, const til::CoordType)> pfn) noexcept;
|
||||
void SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept;
|
||||
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
|
||||
void SetWindowSizeChangedCallback(std::function<void(int32_t, int32_t)> pfn) noexcept;
|
||||
void SetPromptStartedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetOutputStartedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
|
||||
void SetSearchHighlightFocused(size_t focusedIdx) noexcept;
|
||||
void ScrollToSearchHighlight(til::CoordType searchScrollOffset);
|
||||
@@ -341,15 +346,18 @@ private:
|
||||
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
|
||||
std::function<void(std::wstring_view, unsigned int)> _pfnCompletionsChanged;
|
||||
std::function<void(std::wstring_view, const til::CoordType)> _pfnSearchMissingCommand;
|
||||
std::function<void(std::wstring_view, std::wstring_view)> _pfnShowNotification;
|
||||
std::function<void()> _pfnClearQuickFix;
|
||||
std::function<void(int32_t, int32_t)> _pfnWindowSizeChanged;
|
||||
std::function<void()> _pfnPromptStarted;
|
||||
std::function<void()> _pfnOutputStarted;
|
||||
|
||||
RenderSettings _renderSettings;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
||||
::Microsoft::Console::VirtualTerminal::TerminalInput _terminalInput;
|
||||
|
||||
std::optional<std::wstring> _title;
|
||||
std::optional<std::wstring> _startingTitle;
|
||||
std::wstring _startingTitle;
|
||||
std::optional<til::color> _startingTabColor;
|
||||
|
||||
std::vector<til::point_span> _searchHighlights;
|
||||
|
||||
@@ -91,12 +91,8 @@ void Terminal::SetWindowTitle(const std::wstring_view title)
|
||||
_assertLocked();
|
||||
if (!_suppressApplicationTitle)
|
||||
{
|
||||
_title.reset();
|
||||
if (!title.empty())
|
||||
{
|
||||
_title.emplace(title);
|
||||
}
|
||||
_pfnTitleChanged(GetConsoleTitle());
|
||||
_title.emplace(title.empty() ? _startingTitle : title);
|
||||
_pfnTitleChanged(_title.value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,13 +112,6 @@ bool Terminal::ResizeWindow(const til::CoordType width, const til::CoordType hei
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto currentDimensions = _GetMutableViewport().Dimensions();
|
||||
|
||||
if (width == currentDimensions.width && height == currentDimensions.height)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_pfnWindowSizeChanged)
|
||||
{
|
||||
_pfnWindowSizeChanged(width, height);
|
||||
@@ -380,6 +369,14 @@ void Terminal::SearchMissingCommand(const std::wstring_view command)
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::ShowNotification(const std::wstring_view title, const std::wstring_view body)
|
||||
{
|
||||
if (_pfnShowNotification)
|
||||
{
|
||||
_pfnShowNotification(title, body);
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyBufferRotation(const int delta)
|
||||
{
|
||||
// Update our selection, so it doesn't move as the buffer is cycled
|
||||
@@ -416,8 +413,26 @@ void Terminal::NotifyBufferRotation(const int delta)
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyShellIntegrationMark()
|
||||
void Terminal::NotifyShellIntegrationMark(ShellIntegrationMark mark)
|
||||
{
|
||||
// Notify the scrollbar that marks have been added so it can refresh the mark indicators
|
||||
_NotifyScrollEvent();
|
||||
|
||||
switch (mark)
|
||||
{
|
||||
case ShellIntegrationMark::Prompt:
|
||||
if (_pfnPromptStarted)
|
||||
{
|
||||
_pfnPromptStarted();
|
||||
}
|
||||
break;
|
||||
case ShellIntegrationMark::Output:
|
||||
if (_pfnOutputStarted)
|
||||
{
|
||||
_pfnOutputStarted();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ std::pair<til::point, til::point> Terminal::_ExpandSelectionAnchors(std::pair<ti
|
||||
break;
|
||||
case SelectionExpansion::Word:
|
||||
{
|
||||
start = buffer.GetWordStart2(start, _wordDelimiters, false);
|
||||
start = buffer.GetWordStart(start, _wordDelimiters, false);
|
||||
|
||||
// GH#5099: We round to the nearest cell boundary,
|
||||
// so we would normally prematurely expand to the next word
|
||||
@@ -325,7 +325,7 @@ std::pair<til::point, til::point> Terminal::_ExpandSelectionAnchors(std::pair<ti
|
||||
{
|
||||
bufferSize.DecrementInExclusiveBounds(end);
|
||||
}
|
||||
end = buffer.GetWordEnd2(end, _wordDelimiters, false);
|
||||
end = buffer.GetWordEnd(end, _wordDelimiters, false);
|
||||
break;
|
||||
}
|
||||
case SelectionExpansion::Char:
|
||||
@@ -435,9 +435,9 @@ void Terminal::ExpandSelectionToWord()
|
||||
const auto& buffer = _activeBuffer();
|
||||
auto selection{ _selection.write() };
|
||||
wil::hide_name _selection;
|
||||
selection->start = buffer.GetWordStart2(selection->start, _wordDelimiters, false);
|
||||
selection->start = buffer.GetWordStart(selection->start, _wordDelimiters, false);
|
||||
selection->pivot = selection->start;
|
||||
selection->end = buffer.GetWordEnd2(selection->end, _wordDelimiters, false);
|
||||
selection->end = buffer.GetWordEnd(selection->end, _wordDelimiters, false);
|
||||
|
||||
// if we're targeting both endpoints, instead just target "end"
|
||||
if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start) && WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
|
||||
@@ -826,13 +826,13 @@ void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
|
||||
case SelectionDirection::Left:
|
||||
{
|
||||
auto nextPos = pos;
|
||||
nextPos = buffer.GetWordStart2(nextPos, _wordDelimiters, true);
|
||||
nextPos = buffer.GetWordStart(nextPos, _wordDelimiters, true);
|
||||
if (nextPos == pos)
|
||||
{
|
||||
// didn't move because we're already at the beginning of a word,
|
||||
// so move to the beginning of the previous word
|
||||
buffer.GetSize().DecrementInExclusiveBounds(nextPos);
|
||||
nextPos = buffer.GetWordStart2(nextPos, _wordDelimiters, true);
|
||||
nextPos = buffer.GetWordStart(nextPos, _wordDelimiters, true);
|
||||
}
|
||||
pos = nextPos;
|
||||
break;
|
||||
@@ -841,24 +841,24 @@ void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
|
||||
{
|
||||
const auto mutableViewportEndExclusive = _GetMutableViewport().BottomInclusiveRightExclusive();
|
||||
auto nextPos = pos;
|
||||
nextPos = buffer.GetWordEnd2(nextPos, _wordDelimiters, true, mutableViewportEndExclusive);
|
||||
nextPos = buffer.GetWordEnd(nextPos, _wordDelimiters, true, mutableViewportEndExclusive);
|
||||
if (nextPos == pos)
|
||||
{
|
||||
// didn't move because we're already at the end of a word,
|
||||
// so move to the end of the next word
|
||||
buffer.GetSize().IncrementInExclusiveBounds(nextPos);
|
||||
nextPos = buffer.GetWordEnd2(nextPos, _wordDelimiters, true, mutableViewportEndExclusive);
|
||||
nextPos = buffer.GetWordEnd(nextPos, _wordDelimiters, true, mutableViewportEndExclusive);
|
||||
}
|
||||
pos = nextPos;
|
||||
break;
|
||||
}
|
||||
case SelectionDirection::Up:
|
||||
_MoveByChar(direction, pos);
|
||||
pos = buffer.GetWordStart2(pos, _wordDelimiters, true);
|
||||
pos = buffer.GetWordStart(pos, _wordDelimiters, true);
|
||||
break;
|
||||
case SelectionDirection::Down:
|
||||
_MoveByChar(direction, pos);
|
||||
pos = buffer.GetWordEnd2(pos, _wordDelimiters, true);
|
||||
pos = buffer.GetWordEnd(pos, _wordDelimiters, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,18 +184,11 @@ void Terminal::SelectNewRegion(const til::point coordStart, const til::point coo
|
||||
std::wstring_view Terminal::GetConsoleTitle() const noexcept
|
||||
{
|
||||
_assertLocked();
|
||||
|
||||
if (_title)
|
||||
if (_title.has_value())
|
||||
{
|
||||
return *_title;
|
||||
}
|
||||
|
||||
if (_startingTitle)
|
||||
{
|
||||
return *_startingTitle;
|
||||
}
|
||||
|
||||
return {};
|
||||
return _startingTitle;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -352,7 +352,12 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
_AllowKittyKeyboardMode = profile.AllowKittyKeyboardMode();
|
||||
_AllowVtChecksumReport = profile.AllowVtChecksumReport();
|
||||
_AllowVtClipboardWrite = profile.AllowVtClipboardWrite();
|
||||
_AllowOscNotifications = profile.AllowOscNotifications();
|
||||
_PathTranslationStyle = profile.PathTranslationStyle();
|
||||
_DragDropDelimiter = profile.DragDropDelimiter();
|
||||
_NotifyOnInactiveOutput = profile.NotifyOnInactiveOutput();
|
||||
_NotifyOnNextPrompt = profile.NotifyOnNextPrompt();
|
||||
_AutoDetectRunningCommand = profile.AutoDetectRunningCommand();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user