Compare commits

...

27 Commits

Author SHA1 Message Date
Ethan Balakumar
0252c78997 Terminal receives focus on drag n drop (#20003)
### Summary
Updates terminal to gain foreground focus when a user drags and drops a
file into the terminal.

### Changes
Updates the `DragDropHandler` to call `SetForegroundWindow`.

### Validation
* Built and deployed locally
* Manually verified terminal gains focus when dragging and dropping

Closes #19934

(cherry picked from commit a1a43a4ff5)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgpBND8
Service-Version: 1.25
2026-04-02 19:21:54 -05:00
Theodore Tsirpanis
82d5e0cad3 Use vs-pwsh icons if applicable. (#19990)
## Summary of the Pull Request
This PR updates `VsDevShellGenerator` to use the `vs-pwsh` icon in
generated profiles, if modern PowerShell has been detected.

## References and Relevant Issues
The icons were added in #17706, but are not used anywhere.

## Detailed Description of the Pull Request / Additional comments
* Updated `VsDevShellGenerator::GetProfileCommandLine` to accept a
`bool& isPwsh` parameter, which is set to whether the generated profile
command line is using modern PowerShell. This value gets passed to
`VsDevShellGenerator::GetProfileIconPath`'s new parameter, which
determines whether to return the icon for `powershell` or `pwsh`.

(cherry picked from commit e0400150d0)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgpBNIk
Service-Version: 1.25
2026-04-02 19:21:52 -05:00
Leonard Hecker
d960f4a05a Make disabling the Kitty Keyboard Protocol possible (#19995)
Avoid translating W32IM sequences to KKP.

Closes #19977

## Validation Steps Performed
* Use French Bepo keyboard layout
* Disable KKP
* Use fish shell
* `AltGr+Y` produces `{` 

(cherry picked from commit 0f5d883c59)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgpBMwc
Service-Version: 1.25
2026-04-02 19:21:51 -05:00
Dustin L. Howett
2c9277cbb4 Only honor Ctrl+Z during ReadFile if the console is in PROCESSED mode (#19940)
This restores the behavior of ReadFile to that of Windows 7.

Closes #4958

(cherry picked from commit 80e4b3c947)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgpBM28
Service-Version: 1.25
2026-04-02 19:21:49 -05:00
Carlos Zamora
e382d328b2 Improve UX for selection during VTMM (#19973)
Selection in VT mouse mode has been feeling a little weird. I've made a
few changes in this space to improve the overall experience when in vt
mouse mode:
- don't round selection positions: this means that you now highlight the
cell you're on if you're going right, and the adjacent cell if you're
going left
- fix drag-left excluding the current cell
- #9608: shift+click now clears any existing selection instead of
extending it. This feels more intuitive since Shift already works as the
override modifier

Somewhat related to #18106

## Validation
 alt selections feel consistent
 selecting in VTMM feels accurate (selects the cell we started on)
 creating new selections (aka clearing old selection) in VTMM feels
intuitive (forwards and backwards)

Closes #9608

(cherry picked from commit 2e33056fd8)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgna3V8
Service-Version: 1.25
2026-04-02 19:14:34 -05:00
Carlos Zamora
2bd369939c Update 'restart connection' action to reset internal state (#19971)
## Summary of the Pull Request
I was becoming frustrated with getting in a state where a CLI app (i.e.
Copilot CLI) enters some VT state (like mouse mode) then doesn't unset
it when it accidentally exits. I normally use "Restart connection" to
keep the buffer and connect again. Problem is, "restart connection"
didn't actually reset the internal state! So I would type and get a
bunch of lingering VT escape sequences. This bug is tracked over in
#18425 in a more generic way.

This fixes that bug by doing the following:
- update `ITermDispatch::HardReset()` -->`HardReset(bool erase)`
   - `erase=true` does what `HardReset()` already did
- `erase=false` skips over clearing the screen and resetting the cursor
position
- expose `HardReset(false)` as `HardResetWithoutErase()` by piping it up
through `Terminal` --> `ControlCore` --> `TermControl`
-  update the restart connection handler
- `TerminalPage::_restartPaneConnection()` now calls
`HardResetWithoutErase()` before setting the new connection
- this is also the same route for the "Enter to restart connection"
scenario (text displayed when connection ends)

Relevant notes from PR discussion:
- `PSEUDOCONSOLE_INHERIT_CURSOR` is passed into the new connection via
`_restartPaneConnection()` --> `_duplicateConnectionForRestart()` -->
`_CreateConnectionFromSettings(profile,
*controlSettings.DefaultSettings(), true)`

## Validation Steps Performed
- Used this to enter mouse tracking mode: `Write-Host -NoNewline
"`e[?1003h`e[?1006h"`
- mouse selection doesn't work as usual (expected)
- invoke "restart connection" action
- mouse selection works as usual

Closes #18425

(cherry picked from commit ec939aabda)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgpBL5s
Service-Version: 1.25
2026-04-02 19:14:13 -05:00
Leonard Hecker
7f5185eb06 Implement OSC 7 for setting the CWD (#20019)
This adds support for OSC 7 which is the same as OSC 9;9 but using
file URIs. As per the previous discussion in #8214, the problem is
that WSL shells emit URIs that can't work because the hostname in
the URI translates to an UNC path with an non-existing hostname.
In my opinion this doesn't deter the fact though that OSC 7 works
just fine for a native Windows application.

In the future we should consider trying to detect WSL file URIs
and translating it to the `--cd` argument for `wsl.exe`.

All of the heavy lifting for parsing the URI is done by
`PathCreateFromUrlW`. It just had to be plugged into the OSC 9;9 code.

Closes #3158

## Validation Steps Performed
* Launch fish-shell in WSL
* Duplicate tab works 
* (And because it doesn't work without using
  `IsValidDirectory` I know that OSC 7 works )

(cherry picked from commit 4ce79d7289)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgpBLe8
Service-Version: 1.25
2026-04-02 19:14:12 -05:00
Leonard Hecker
0291d97503 Send a CPR request on every unknown sequence (#20009)
This PR is 90% wiring up OOP interfaces.

Closes #19926

## Validation Steps Performed
* Run `github.com/xtermjs/vtc`
* Observed `UnknownSequence` calls under a debugger

(cherry picked from commit da0446a7d1)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgpBLzY
Service-Version: 1.25
2026-04-02 19:14:10 -05:00
Carlos Zamora
f7a5515cf7 Fix selection markers appearing on scroll (#20045)
## Summary of the Pull Request
Updates the scroll handler to check the selection mode before updating
the markers.

Introduced in #19974

## Validation Steps Performed
`ls` --> create selection --> scroll away and back
 keyboard selection: markers are present both times
 mouse selection: markers are missing both times

(cherry picked from commit 3104c8feb2)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgo0IB8
Service-Version: 1.25
2026-03-31 18:19:19 -05:00
Carlos Zamora
2219739391 Fix search dropdown theming (#19987)
## Summary of the Pull Request
Popups are in their own separate tree, so we had to find it and set the
theme ourselves.

## Validation Steps Performed
Prereq: Windows theme = light + terminal theme = dark
 settings search dropdown is dark theme

Closes #19927

(cherry picked from commit c562dad15d)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgnsPtk
Service-Version: 1.25
2026-03-31 18:19:17 -05:00
jason
7cff119b34 Fix Korean IME arrow key inserting character at wrong position (#20039)
Fix a regression introduced in v1.24 where pressing an arrow key during
Korean IME composition caused the committed character to be inserted at
the wrong cursor position.

Before #19738, the Korean IME activated through IMM32 (excluded from TSF
by `TF_TMAE_UIELEMENTENABLEDONLY`) and was not affected by
`TermControl::_KeyHandler` forwarding keys to the PTY during
composition. After #19738, the Korean IME activates through TSF, making
a missing composition guard in `_KeyHandler` visible as a bug.

The sequence of events that causes the bug:

1. User presses Left arrow during active Korean IME composition (e.g.
composing `가`).
2. `_KeyHandler` calls `_TrySendKeyEvent(VK_LEFT)` which enqueues
`\x1b[D` to the PTY input queue. The cursor moves.
3. TSF processes the key. The Korean IME sees the arrow and ends the
composition.
4. `OnEndComposition` schedules `_doCompositionUpdate` with
`TF_ES_ASYNC`.
5. The async session fires, reads finalized text `가`, calls
`HandleOutput("가")`.
6. PTY processes `[\x1b[D, "가"]`: cursor moves left first, then `가` is
inserted at the wrong (already-moved) position.

The fix adds a guard before `_TrySendKeyEvent`, which mirrors the
existing behavior in conhost (windowio.cpp). When TSF has an active
composition, key events are not converted into input. The Korean IME
re-injects navigation and confirmation keys after the composition ends,
at which point `HasActiveComposition()` returns false and they are
forwarded normally.

**Historical note:** This guard was not needed before PR #17067 (v1.22)
because the old implementation used WinRT `CoreTextServices` via XAML
(`TSFInputControl.xaml`). The XAML framework intercepted composition key
events before `_KeyHandler`. The new custom Win32 TSF context in #17067
no longer does this. The bug was latent from v1.22 but only became
visible for Korean in v1.24 when #19738 removed
`TF_TMAE_UIELEMENTENABLEDONLY`.

## Validation Steps Performed

1. Open Windows Terminal with Korean IME (Dubeolsik layout).
2. Type `rk` to begin composing `가` (composition active, syllable not
yet committed).
3. Press the Left arrow key.
4. Before fix: `가` is inserted one cell to the left of the intended
position.
5. After fix: `가` is inserted at the correct position, then cursor moves
left.

Also verified:
- Normal Korean text input (typing without arrow keys) still works
correctly.
- Arrow key navigation when no composition is active still works
correctly.
- English and other IME input is not affected.

Closes #20038
Refs #19738

(cherry picked from commit 14f4271954)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgo0JpM
Service-Version: 1.25
2026-03-31 17:44:28 -05:00
Dustin L. Howett
58414c542f conpty: remove accidental bool; use BOOL instead (#20035)
Closes #19102

(cherry picked from commit 01f8a4031d)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgoyJIE
Service-Version: 1.25
2026-03-31 17:44:26 -05:00
Dustin L. Howett
bf77086b60 Reinstate the (apparently) load-bearing empty bracketed paste (#20037)
Some applications have come to rely on an "empty" bracketed paste packet
to indicate that the clipboard was _requested,_ but not sent. Some
agentic CLI tools use this to guess whether the clipboard contained e.g.
an image or otherwise unserializable data.

Apparently, gnome-terminal and VS Code do this; others as well (I tested
xterm, konsole, gnome-terminal and I can't remember which ones did and
which ones did not.)

Refs #19517

(cherry picked from commit 2870a702f4)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgotgA4
Service-Version: 1.25
2026-03-31 17:44:25 -05:00
gcrtnst
2644ca0a8a Fix MSB4019 error in ConPTY nupkg (#20029)
This commit fixes the following error that occurs when attempting to use the
`Microsoft.Windows.Console.ConPTY` nupkg in a Visual C++ project:

    MSB4019: The imported project "C:\Microsoft.Windows.Console.ConPTY.props" was not found.

Based on the list of reserved and well-known properties, the property
`MSBuildThisProjectDirectory` does not appear to exist.  This PR
replaces it with the correct property, `MSBuildThisFileDirectory`.

(cherry picked from commit be5dcf8e7a)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgotQIk
Service-Version: 1.25
2026-03-30 17:46:06 -05:00
Sagar
1ad9a2e932 Fix copyOnSelect right-click overwriting clipboard with stale selection (#19943)
## Summary of the Pull Request
Fix `copyOnSelect` right-click paste overwriting the clipboard with a
stale selection instead of pasting the current clipboard contents.

## Detailed Description of the Pull Request / Additional comments
When `copyOnSelect` is enabled, the selected text is already copied to
the clipboard on left mouse button release in `PointerReleased`. The
selection is intentionally left visible as a visual reference (the
`_selectionNeedsToBeCopied` flag is set to `false` to track that the
copy already happened).

However, the right-click handler in `PointerPressed` unconditionally
called `CopySelectionToClipboard()` before pasting, ignoring both the
`copyOnSelect` setting and the `_selectionNeedsToBeCopied` flag. This
caused any still-visible selection to be re-copied to the clipboard,
overwriting whatever the user may have copied from another application
(or another terminal tab) in the meantime.

This change splits the right-click behavior based on the `copyOnSelect`
setting:
- **`copyOnSelect: true`** — Skip the redundant copy, clear the
selection, and paste directly. The text was already copied on mouse-up.
- **`copyOnSelect: false`** — Preserve existing behavior: copy the
selection (if any), clear it, and paste only if there was no selection
to copy.

## Validation Steps Performed
1. Set `"copyOnSelect": true` in `settings.json`.
2. Selected text in a terminal pane - verified it was copied to
clipboard on mouse-up.
3. Switched to Notepad, copied different text ("NEW TEXT").
4. Switched back to Terminal (selection still visible), right-clicked —
verified "NEW TEXT" was pasted, not the old selection.
5. Verified right-click with no active selection still pastes clipboard
contents.
6. Verified right-click immediately after selecting (no app switch)
pastes the just-selected text.
7. Set `"copyOnSelect": false` — verified right-click still copies
selection first, then pastes only when no selection exists (original
behavior unchanged).
8. Verified tab-switching with an active selection does not cause stale
clipboard overwrites on right-click.

## PR Checklist
Closes #14465 (dupe of #19942)

---------

Co-authored-by: Sagar Bhure <sagarbhure@microsoft.com>
(cherry picked from commit ad7b34e55f)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgn30Ls
Service-Version: 1.25
2026-03-30 17:46:05 -05:00
Leonard Hecker
74f3bb42e1 Fix a deadlock during cooked reads (#19994)
Closes #19922

## Validation Steps Performed
* The repro now works as expected 
  (`CreatePseudoConsole({1,20})` + `WriteFile("キ")`)

(cherry picked from commit ddf514e99e)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgn2sRU
Service-Version: 1.25
2026-03-30 17:46:03 -05:00
Carlos Zamora
c0ca78c3ee Fix selection markers disappearing after scrolling out of view (#19974)
## Summary of the Pull Request
Pretty straightforward

## Validation Steps Performed
 Selection markers are present after scrolling them out of view and
scrolling back

Closes #17135

(cherry picked from commit 14ee19fc27)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgna-WM
Service-Version: 1.25
2026-03-30 17:46:02 -05:00
Dustin L. Howett
37dc437e65 Suppress the invalid media error in Stable (#19969)
It's creating a lot of noise for folks, and it is not particularly
_helpful_ since it does not specify a location or even name which
resource failed to load or parse.

On stable, let's just silently ignore them.

Refs #19964

(cherry picked from commit 6d7fac999a)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgnTk_s
Service-Version: 1.25
2026-03-12 17:14:58 -05:00
Artem Lytkin
4a782b062c control: focus terminal on click-drag while search is open (#19931)
## Summary
- Fix inability to copy terminal text via Ctrl+C when the search dialog
is open
- Root cause: click-and-drag doesn't call `Focus()` because `_focused`
is already `true` (set by the search box's bubbling GotFocus)
- Fix: also focus the terminal when the search box contains keyboard
focus

## Detailed Description of the Pull Request / Additional comments
When the search dialog is open and the user click-drags in the terminal
to select text, `_PointerPressedHandler` skips
`Focus(FocusState::Pointer)` because `_focused` is `true`. The
`_focused` flag is `true` because the `SearchBoxControl` is a child of
`TermControl` in the XAML visual tree, so `TermControl`'s
`_GotFocusHandler` fires (via bubbling `GotFocus`) when the search box's
`TextBox` gains focus, setting `_focused = true`.

The fix adds a `ContainsFocus()` check so that focus is explicitly moved
to the terminal when the search box has keyboard focus. This makes
click-drag behavior consistent with tap behavior (`_TappedHandler`
already focuses unconditionally) and uses the same `ContainsFocus()`
pattern already established at lines 1569 and 2366 in the same file.

## Validation Steps Performed
- Verified click-drag + Ctrl+C copies selected text when search dialog
is open
- Verified simple click (tap) in terminal while search is open still
works
- Verified clicking in the search box retains focus in the search box
- Verified typing in search box still works when it has focus
- Verified Escape still closes the search box
- Verified Ctrl+C with no selection while search is open doesn't break
- Code formatted with clang-format

## PR Checklist
 Closes #19908

(cherry picked from commit e2d51636cd)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgnOgZ8
Service-Version: 1.25
2026-03-12 17:14:56 -05:00
Carlos Zamora
4701843082 Fix memory leaks with UIA (#19950)
## Summary of the Pull Request
This includes the memory leak fixes that @lhecker and I investigated as
a part of #19710.

The `ITextRangeProvider`s (namely `UiaTextRange`s) weren't being
destroyed after they were done being used by the screen reader.

## Validation Steps Performed
In my own testing, I set a breakpoint on the destructor for
`UiaTextRangeBase`. Prior to this change, that destructor would mainly
be called when the terminal control was closed, which would result in us
leaking these objects. With this change, I've confirmed that these text
ranges are being destroyed immediately after they are done being used
(without needing to close the terminal control).

## PR Checklist
Closes #19710

(cherry picked from commit e2110e716c)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgnOhC8
Service-Version: 1.25
2026-03-12 17:14:55 -05:00
Leonard Hecker
efe9f27c00 Make TSF initialization fully fallible (#19958)
Apparently, on some (internal) variants of Windows `TF_CategoryMgr`
can exist while `TF_DisplayAttributeMgr` is absent. This is likely
a variant configuration error, but we shouldn't crash anyway.

Closes MSFT-61309810

(cherry picked from commit 30b1456ffe)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgnOg_4
Service-Version: 1.25
2026-03-12 17:14:53 -05:00
sagarbhure-dev
008e293205 Fix GenerateSettingsIndex using element name instead of x:Name (#19945)
Use GetAttribute('x:Name') instead of .Name in GenerateSettingsIndex.ps1
to avoid PowerShell's XML integration returning the element tag name
(e.g. 'local:SettingContainer') when x:Name is absent.

Also add missing x:Name attributes to:
- Compatibility.xaml: AmbiguousWidth SettingContainer
- NewTabMenu.xaml: AddRemainingProfiles and CurrentFolderIcon containers

## Summary of the Pull Request
Fix GenerateSettingsIndex.ps1 emitting "local:SettingContainer" as the
element name in the generated index when a SettingContainer has no
x:Name attribute.

## References and Relevant Issues
Per DHowett's comment - the root cause is PowerShell's XML integration:
$element.Name returns the XML element tag name (e.g.
local:SettingContainer) when no x:Name attribute exists.

## Detailed Description of the Pull Request / Additional comments
Two changes:

- GenerateSettingsIndex.ps1: Replace $settingContainer.Name with
$settingContainer.GetAttribute("x:Name"), which correctly returns an
empty string when the attribute is absent instead of the element tag
name.

- Add missing x:Name attributes to three SettingContainer elements:
    - Compatibility.xaml: AmbiguousWidth (Globals_AmbiguousWidth)
- NewTabMenu.xaml: AddRemainingProfiles
(NewTabMenu_AddRemainingProfiles)
    - NewTabMenu.xaml: CurrentFolderIcon (NewTabMenu_CurrentFolderIcon)
- This fixes four incorrect IndexEntry lines in the generated output
that previously contained L"local:SettingContainer" as the element name.

## Validation Steps Performed
Ran GenerateSettingsIndex.ps1 before and after - confirmed the four
incorrect entries with L"local:SettingContainer" are now generated with
the correct x:Name values (or empty string where appropriate).

## PR Checklist
Closes #19929

Co-authored-by: Sagar Bhure <sagarbhure@microsoft.com>
(cherry picked from commit 8cad67020f)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgnOg9Q
Service-Version: 1.25
2026-03-12 17:14:51 -05:00
Dustin L. Howett
7adb2157a5 vpack: actually, we have to use a 3-segment version number (#19939)
Our last build failed because it tried to pass "10621.0" off as a
uint64. I didn't know it had to be a single number... so let's use the
3-component equivalent (which would have been 1.24.260303001)

(cherry picked from commit 5828fb5ce5)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgms2-E
Service-Version: 1.25
2026-03-12 17:14:50 -05:00
Dustin L. Howett
9ae724aa5b build: make sure the AnyCPU build sets BuildPlatform properly (#19925)
This caused the WPF-only build (packaging phase, really) to fail.

Fixes d6714f3ca9 (#19328)

(cherry picked from commit 0f6ee4ad2e)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgmftD0
Service-Version: 1.25
2026-03-02 14:45:41 -06:00
Windows Console Service Bot
d6da2555f5 Localization Updates - main - 03/02/2026 (#19914)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
(cherry picked from commit 59c7e3b73c)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgmfcKA
Service-Version: 1.25
2026-03-02 14:45:40 -06:00
Dustin L. Howett
f740350283 build: reset version year so 1.25 preview starts over from 2026 2026-02-27 17:48:25 -06:00
Dustin L. Howett
62512eb116 pgo: train 1.25 separately 2026-02-27 17:48:09 -06:00
81 changed files with 676 additions and 155 deletions

View File

@@ -572,6 +572,7 @@ FGHIJ
fgidx
FGs
FILEDESCRIPTION
filehops
FILESUBTYPE
FILESYSPATH
FILEW
@@ -1772,6 +1773,7 @@ uldash
uldb
ULONGLONG
ulwave
Unaccess
Unadvise
unattend
UNCPRIORITY

View File

@@ -56,11 +56,12 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ą ωћόĺé ņέш ∑×τзńşĩōиŝ ρâģε τђат šнòωş ωħąт нǻś ъеēñ įηšтǻľĺéδ ĭʼnтο ўбμŗ Ţзřmĭňāŀ !!! !!! !!! !!! !!! !!! !!! !!!
- €όммаήδ Рдĺēтţĕ пŏẅ şĥŏшś üρ ϊñ ỳоũѓ йαťïνє ļäŋģµаġέ άś ŵєŀľ åś Σиĝℓĭŝђ !!! !!! !!! !!! !!! !!! !!!
- ∏еẅ VΤ ƒэåŧύґέŝ şűçн ăŝ ѕỳňсĥŗǿйìźėð гēŋďзříⁿğ, ηĕш ćôĺõг şĉћěмєѕ, çóńƒіĝџŗáτїöπ ƒοг qũī¢ķ möűšë ąćŧϊόņŝ ľîķє žøōmίйğ, ǻⁿđ мόřε !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- ₣ïňάĺĺў, ŧне âъΐŀίťŷ ţø şēаґсђ ƒбг ăиÿ şēťτіήġ! !!! !!! !!! !!! !!!
- Á ŋеώ ñăŧїνе ěðíτōг ƒοѓ ќэÿ вїñďĭňğş, дčтιθήѕ дñð çθmmãήδ ρàľěţťę ёñтгĩέś. !!! !!! !!! !!! !!! !!! !!! !
- Пėώ čоmmμñìтў ŀό¢àłįżåţίòйš ŧō Šэґъιäñ åηδ Ůκŗăįлīăπ !!! !!! !!! !!! !!! !
- Ѕυррòŗт ƒòŗ ťĥё "Kitty" ĸ℮ŷъøàŗď ρřŏťô¢õℓ ƒŏґ нįģћ-ƒíđёℓïтÿ îńрüť êńсøďíлğ !!! !!! !!! !!! !!! !!! !!! !
Ρĺęąŝэ ѕєě õμя ĞĭтΗύв řєĺэдšέŝ рάġě ƒοґ àďđϊтїõлаℓ ðêţǻїłş. !!! !!! !!! !!! !!! !!!
Ρŀ℮âѕē şєё όûя ĜîтΗūь ŕεĺĕǻŝёš раġĕ ƒŏґ ãδđϊŧïбπåľ δеτáΐłś. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,11 +56,12 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ą ωћόĺé ņέш ∑×τзńşĩōиŝ ρâģε τђат šнòωş ωħąт нǻś ъеēñ įηšтǻľĺéδ ĭʼnтο ўбμŗ Ţзřmĭňāŀ !!! !!! !!! !!! !!! !!! !!! !!!
- €όммаήδ Рдĺēтţĕ пŏẅ şĥŏшś üρ ϊñ ỳоũѓ йαťïνє ļäŋģµаġέ άś ŵєŀľ åś Σиĝℓĭŝђ !!! !!! !!! !!! !!! !!! !!!
- ∏еẅ VΤ ƒэåŧύґέŝ şűçн ăŝ ѕỳňсĥŗǿйìźėð гēŋďзříⁿğ, ηĕш ćôĺõг şĉћěмєѕ, çóńƒіĝџŗáτїöπ ƒοг qũī¢ķ möűšë ąćŧϊόņŝ ľîķє žøōmίйğ, ǻⁿđ мόřε !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- ₣ïňάĺĺў, ŧне âъΐŀίťŷ ţø şēаґсђ ƒбг ăиÿ şēťτіήġ! !!! !!! !!! !!! !!!
- Á ŋеώ ñăŧїνе ěðíτōг ƒοѓ ќэÿ вїñďĭňğş, дčтιθήѕ дñð çθmmãήδ ρàľěţťę ёñтгĩέś. !!! !!! !!! !!! !!! !!! !!! !
- Пėώ čоmmμñìтў ŀό¢àłįżåţίòйš ŧō Šэґъιäñ åηδ Ůκŗăįлīăπ !!! !!! !!! !!! !!! !
- Ѕυррòŗт ƒòŗ ťĥё "Kitty" ĸ℮ŷъøàŗď ρřŏťô¢õℓ ƒŏґ нįģћ-ƒíđёℓïтÿ îńрüť êńсøďíлğ !!! !!! !!! !!! !!! !!! !!! !
Ρĺęąŝэ ѕєě õμя ĞĭтΗύв řєĺэдšέŝ рάġě ƒοґ àďđϊтїõлаℓ ðêţǻїłş. !!! !!! !!! !!! !!! !!!
Ρŀ℮âѕē şєё όûя ĜîтΗūь ŕεĺĕǻŝёš раġĕ ƒŏґ ãδđϊŧïбπåľ δеτáΐłś. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

@@ -56,11 +56,12 @@
<ReleaseNotes>
Vėѓѕіöй __VERSION_NUMBER__ !!! !!! !
- Ą ωћόĺé ņέш ∑×τзńşĩōиŝ ρâģε τђат šнòωş ωħąт нǻś ъеēñ įηšтǻľĺéδ ĭʼnтο ўбμŗ Ţзřmĭňāŀ !!! !!! !!! !!! !!! !!! !!! !!!
- €όммаήδ Рдĺēтţĕ пŏẅ şĥŏшś üρ ϊñ ỳоũѓ йαťïνє ļäŋģµаġέ άś ŵєŀľ åś Σиĝℓĭŝђ !!! !!! !!! !!! !!! !!! !!!
- ∏еẅ VΤ ƒэåŧύґέŝ şűçн ăŝ ѕỳňсĥŗǿйìźėð гēŋďзříⁿğ, ηĕш ćôĺõг şĉћěмєѕ, çóńƒіĝџŗáτїöπ ƒοг qũī¢ķ möűšë ąćŧϊόņŝ ľîķє žøōmίйğ, ǻⁿđ мόřε !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
- ₣ïňάĺĺў, ŧне âъΐŀίťŷ ţø şēаґсђ ƒбг ăиÿ şēťτіήġ! !!! !!! !!! !!! !!!
- Á ŋеώ ñăŧїνе ěðíτōг ƒοѓ ќэÿ вїñďĭňğş, дčтιθήѕ дñð çθmmãήδ ρàľěţťę ёñтгĩέś. !!! !!! !!! !!! !!! !!! !!! !
- Пėώ čоmmμñìтў ŀό¢àłįżåţίòйš ŧō Šэґъιäñ åηδ Ůκŗăįлīăπ !!! !!! !!! !!! !!! !
- Ѕυррòŗт ƒòŗ ťĥё "Kitty" ĸ℮ŷъøàŗď ρřŏťô¢õℓ ƒŏґ нįģћ-ƒíđёℓïтÿ îńрüť êńсøďíлğ !!! !!! !!! !!! !!! !!! !!! !
Ρĺęąŝэ ѕєě õμя ĞĭтΗύв řєĺэдšέŝ рάġě ƒοґ àďđϊтїõлаℓ ðêţǻїłş. !!! !!! !!! !!! !!! !!!
Ρŀ℮âѕē şєё όûя ĜîтΗūь ŕεĺĕǻŝёš раġĕ ƒŏґ ãδđϊŧïбπåľ δеτáΐłś. !!! !!! !!! !!! !!! !!!
</ReleaseNotes>
<ScreenshotCaptions>
<!-- Valid length: 200 character limit, up to 9 elements per platform -->

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@
<PropertyGroup>
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
<PGOBranch>main</PGOBranch>
<PGOBranch>release-1.25</PGOBranch>
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>

View File

@@ -46,6 +46,7 @@ jobs:
BuildConfiguration: ${{ config }}
dependsOn: ${{ parameters.dependsOn }}
variables:
BuildPlatform: Any CPU
OutputBuildPlatform: AnyCPU
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
JobOutputDirectory: $(Build.ArtifactStagingDirectory)\nupkg

View File

@@ -211,7 +211,7 @@ extends:
ob_createvpack_verbose: true
ob_createvpack_vpackdirectory: '$(JobOutputDirectory)\vpack'
ob_createvpack_versionAs: string
ob_createvpack_version: '$(XES_APPXMANIFESTVERSION)'
ob_createvpack_version: '$(XES_PACKAGEVERSIONNUMBER)'
ob_updateOSManifest_gitcheckinConfigPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
# We're skipping the 'fetch' part of the OneBranch rules, but that doesn't mean
# that it doesn't expect to have downloaded a manifest directly to some 'destination'

View File

@@ -3,7 +3,7 @@
<!-- This file is read by XES, which we use in our Release builds. -->
<PropertyGroup Label="Version">
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2025</XesBaseYearForStoreVersion>
<XesBaseYearForStoreVersion>2026</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>25</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>

View File

@@ -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)
{

View File

@@ -1600,8 +1600,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);
}
@@ -2973,7 +2972,11 @@ namespace winrt::TerminalApp::implementation
text = winrt::hstring{ Utils::TrimPaste(text) };
}
if (text.empty())
// LOAD BEARING: Send an empty bracketed paste even if the clipboard was empty.
// Bracketed Paste provides an application a way to know whether the
// user pasted, even if there was no applicable content on it. This
// behavior is observed in GNOME Terminal, among others.
if (!bracketedPaste && text.empty())
{
co_return;
}
@@ -3555,8 +3558,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);
}
@@ -3742,7 +3744,13 @@ namespace winrt::TerminalApp::implementation
// for nulls
if (const auto& connection{ _duplicateConnectionForRestart(paneContent) })
{
paneContent.GetTermControl().Connection(connection);
// Reset the terminal's VT state before attaching the new connection.
// The previous client may have left dirty modes (e.g., bracketed
// paste, mouse tracking, alternate buffer, kitty keyboard) that
// would corrupt input/output for the new shell process.
const auto& termControl = paneContent.GetTermControl();
termControl.HardResetWithoutErase();
termControl.Connection(connection);
connection.Start();
}
}

View File

@@ -102,7 +102,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);
}

View File

@@ -355,6 +355,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
void ControlCore::HardResetWithoutErase()
{
const auto lock = _terminal->LockForWriting();
_terminal->HardResetWithoutErase();
}
bool ControlCore::Initialize(const float actualWidth,
const float actualHeight,
const float compositionScale)
@@ -2075,7 +2081,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// the selection (we need to reset selection on double-click or
// triple-click, so it captures the word or the line, rather than
// extending the selection)
if (_terminal->IsSelectionActive() && (!shiftEnabled || isOnOriginalPosition))
// - GH#9608: VT mouse mode is enabled. In this mode, Shift is used
// to override mouse input, so Shift+Click should start a fresh
// selection rather than extending the previous one.
if (_terminal->IsSelectionActive() && (!shiftEnabled || isOnOriginalPosition || _terminal->IsTrackingMouseInput()))
{
// Reset the selection
_terminal->ClearSelection();
@@ -2417,11 +2426,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;

View File

@@ -191,8 +191,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ContextMenuSelectCommand();
void ContextMenuSelectOutput();
winrt::hstring CurrentWorkingDirectory() const;
#pragma endregion
#pragma region ITerminalInput
@@ -257,6 +255,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TerminalConnection::ITerminalConnection Connection();
void Connection(const TerminalConnection::ITerminalConnection& connection);
void HardResetWithoutErase();
void AnchorContextMenu(til::point viewportRelativeCharacterPosition);

View File

@@ -98,6 +98,7 @@ namespace Microsoft.Terminal.Control
void ApplyAppearance(Boolean focused);
Microsoft.Terminal.TerminalConnection.ITerminalConnection Connection;
void HardResetWithoutErase();
IControlSettings Settings { get; };
IControlAppearance FocusedAppearance { get; };

View File

@@ -54,6 +54,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
self->Attached.raise(*self, nullptr);
}
});
// GH#14464: Mark mode and quick-edit (shift+arrow) selections update
// the selection through ControlCore, bypassing SetEndSelectionPoint.
// Listen for selection changes so _selectionNeedsToBeCopied is set
// for ALL selection types, not just mouse drag.
_core->UpdateSelectionMarkers([weakThis = get_weak()](auto&&, auto&&) {
if (auto self{ weakThis.get() })
{
if (self->_core->HasSelection())
{
self->_selectionNeedsToBeCopied = true;
}
}
});
}
uint64_t ControlInteractivity::Id()
@@ -285,8 +299,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
const auto isOnOriginalPosition = _lastMouseClickPosNoSelection == pixelPosition;
// Rounded coordinates for text selection
_core->LeftClickOnTerminal(_getTerminalPosition(til::point{ pixelPosition }, true),
// Rounded coordinates for text selection.
// Don't round in VT mouse mode; cell-level precision matters more
const auto round = !_core->IsVtMouseModeEnabled();
_core->LeftClickOnTerminal(_getTerminalPosition(til::point{ pixelPosition }, round),
multiClickMapper,
altEnabled,
shiftEnabled,
@@ -296,8 +312,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
if (_core->HasSelection())
{
// GH#9787: if selection is active we don't want to track the touchdown position
// so that dragging the mouse will extend the selection rather than starting the new one
_singleClickTouchdownPos = std::nullopt;
// so that dragging the mouse will extend the selection rather than starting the new one.
// In VT mouse mode, keep tracking the touchdown point so that PointerMoved
// can re-anchor the selection based on drag direction (the dx < 0 adjustment).
// Without this, dragging left wouldn't include the initially clicked cell
// because floored coordinates place the anchor on the cell's left edge.
if (!_core->IsVtMouseModeEnabled())
{
_singleClickTouchdownPos = std::nullopt;
}
}
}
else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown))
@@ -314,13 +337,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else
{
// Try to copy the text and clear the selection
const auto successfulCopy = CopySelectionToClipboard(shiftEnabled, false, _core->Settings().CopyFormatting());
// GH#19942, GH#14464: Don't re-copy a selection that was
// already copied via copyOnSelect on mouse-up. But DO copy
// if the selection was made via mark mode or modified with
// quick-edit keys (shift+arrow), since those paths never
// triggered an automatic copy.
const auto copied = (_selectionNeedsToBeCopied || !_core->CopyOnSelect()) &&
CopySelectionToClipboard(shiftEnabled, false, _core->Settings().CopyFormatting());
_core->ClearSelection();
if (_core->CopyOnSelect() || !successfulCopy)
if (_core->CopyOnSelect() || !copied)
{
// CopyOnSelect: right click always pastes!
// Otherwise: no selection --> paste
// CopyOnSelect: right-click always pastes.
// Otherwise: no selection paste.
RequestPasteTextFromClipboard();
}
}
@@ -682,7 +710,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - cursorPosition: in pixels, relative to the origin of the control
void ControlInteractivity::SetEndSelectionPoint(const Core::Point pixelPosition)
{
_core->SetEndSelectionPoint(_getTerminalPosition(til::point{ pixelPosition }, true));
// Don't round in VT mouse mode; cell-level precision matters more
const auto round = !_core->IsVtMouseModeEnabled();
_core->SetEndSelectionPoint(_getTerminalPosition(til::point{ pixelPosition }, round));
_selectionNeedsToBeCopied = true;
}

View File

@@ -60,7 +60,5 @@ namespace Microsoft.Terminal.Control
void SelectOutput(Boolean goUp);
IVector<ScrollMark> ScrollMarks { get; };
String CurrentWorkingDirectory { get; };
};
}

View File

@@ -49,7 +49,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void InteractivityAutomationPeer::ParentProvider(AutomationPeer parentProvider)
{
_parentProvider = parentProvider;
// LOAD-BEARING: use _parentProvider->ProviderFromPeer(_parentProvider) instead of this->ProviderFromPeer(*this).
// Since we split the automation peer into TermControlAutomationPeer and InteractivityAutomationPeer,
// using "this" returns null. This can cause issues with some UIA Client scenarios like any navigation in Narrator.
_parentProvider = parentProvider ? parentProvider.as<IAutomationPeerProtected>().ProviderFromPeer(parentProvider) : nullptr;
}
// Method Description:
@@ -181,15 +184,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::_CreateXamlUiaTextRange(UIA::ITextRangeProvider* returnVal) const
{
// LOAD-BEARING: use _parentProvider->ProviderFromPeer(_parentProvider) instead of this->ProviderFromPeer(*this).
// Since we split the automation peer into TermControlAutomationPeer and InteractivityAutomationPeer,
// using "this" returns null. This can cause issues with some UIA Client scenarios like any navigation in Narrator.
const auto parent{ _parentProvider.get() };
if (!parent)
if (!_parentProvider)
{
return nullptr;
}
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parent.as<IAutomationPeerProtected>().ProviderFromPeer(parent));
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, _parentProvider);
return xutr.as<XamlAutomation::ITextRangeProvider>();
};
@@ -201,22 +200,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - com_array of Xaml Wrapped UiaTextRange (ITextRangeProviders)
com_array<XamlAutomation::ITextRangeProvider> InteractivityAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
{
if (!_parentProvider)
{
return {};
}
// transfer ownership of UiaTextRanges to this new vector
auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::TermControlUiaTextRange>(textRanges);
auto count = gsl::narrow<int>(providers.size());
const auto len = gsl::narrow<uint32_t>(providers.size());
com_array<XamlAutomation::ITextRangeProvider> result{ len };
std::vector<XamlAutomation::ITextRangeProvider> vec;
vec.reserve(count);
for (auto i = 0; i < count; i++)
for (uint32_t i = 0; i < len; ++i)
{
if (auto xutr = _CreateXamlUiaTextRange(providers[i].detach()))
{
vec.emplace_back(std::move(xutr));
result[i] = std::move(xutr);
}
}
com_array<XamlAutomation::ITextRangeProvider> result{ vec };
return result;
}
}

View File

@@ -80,7 +80,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity;
weak_ref<Windows::UI::Xaml::Automation::Peers::AutomationPeer> _parentProvider;
winrt::Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple _parentProvider{ nullptr };
til::rect _controlBounds{};
til::rect _controlPadding{};

View File

@@ -3,7 +3,7 @@
namespace Microsoft.Terminal.Control
{
[default_interface] runtimeclass InteractivityAutomationPeer :
Windows.UI.Xaml.Automation.Peers.AutomationPeer,
Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer,
Windows.UI.Xaml.Automation.Provider.ITextProvider
{

View File

@@ -532,6 +532,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_core.Connection(newConnection);
}
void TermControl::HardResetWithoutErase()
{
_core.HardResetWithoutErase();
}
void TermControl::_throttledUpdateScrollbar(const ScrollBarUpdate& update)
{
if (!_initializedTerminal)
@@ -1790,6 +1795,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return true;
}
// While TSF has an active composition, key events must not be forwarded
// to the PTY directly. The IME re-injects navigation/confirmation keys
// after composition ends, at which point HasActiveComposition() == false
// and they are forwarded normally. This mirrors conhost v1 behavior in
// src/interactivity/win32/windowio.cpp.
if (GetTSFHandle().HasActiveComposition())
{
return true;
}
if (_TrySendKeyEvent(vkey, scanCode, modifiers, keyDown))
{
return true;
@@ -1955,7 +1970,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto point = args.GetCurrentPoint(*this);
const auto type = ptr.PointerDeviceType();
if (!_focused)
// GH#19908: _focused can be true even when the search box has
// keyboard focus, because GotFocus bubbles from the search box
// child and _GotFocusHandler sets _focused=true. If the user
// click-drags in the terminal while the search box is focused,
// we need to explicitly call Focus() to move keyboard focus back
// to the terminal so that Ctrl+C copies the selection.
if (!_focused || (_searchBox && _searchBox->ContainsFocus()))
{
Focus(FocusState::Pointer);
}
@@ -2501,9 +2522,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_updateScrollBar->Run(update);
// if a selection marker is already visible,
// update the position of those markers
if (SelectionStartMarker().Visibility() == Visibility::Visible || SelectionEndMarker().Visibility() == Visibility::Visible)
// If we have a selection with markers (exposed via selection mode),
// update the position of the markers
if (_core.HasSelection() && _core.SelectionMode() >= SelectionInteractionMode::Keyboard)
{
_updateSelectionMarkers(nullptr, winrt::make<UpdateSelectionMarkersEventArgs>(false));
}
@@ -3067,6 +3088,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
co_return;
}
if (const auto hwnd = reinterpret_cast<HWND>(OwningHwnd()))
{
SetForegroundWindow(hwnd);
}
const auto weak = get_weak();
if (e.DataView().Contains(StandardDataFormats::ApplicationLink()))
@@ -3707,10 +3733,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)
{

View File

@@ -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);
@@ -192,6 +190,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TerminalConnection::ITerminalConnection Connection();
void Connection(const TerminalConnection::ITerminalConnection& connection);
void HardResetWithoutErase();
Control::CursorDisplayState CursorVisibility() const noexcept;
void CursorVisibility(Control::CursorDisplayState cursorVisibility);

View File

@@ -53,6 +53,7 @@ namespace Microsoft.Terminal.Control
void SetOverrideColorScheme(Microsoft.Terminal.Core.ICoreScheme scheme);
Microsoft.Terminal.TerminalConnection.ITerminalConnection Connection;
void HardResetWithoutErase();
UInt64 ContentId{ get; };

View File

@@ -121,6 +121,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// GH#13978: If the TermControl has already been removed from the UI tree, XAML might run into weird bugs.
// This will prevent the `dispatcher.RunAsync` calls below from raising UIA events on the main thread.
_termControl = {};
// Solve the circular reference between us and the content automation peer.
_contentAutomationPeer.ParentProvider(nullptr);
}
// Method Description:

View File

@@ -55,6 +55,18 @@ void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Re
_stateMachine = std::make_unique<StateMachine>(std::move(engine));
}
// Method Description:
// - Resets all VT state to defaults without clearing the buffer content.
// Called when a connection is restarted so that any dirty modes left
// behind by a crashed application don't affect the new connection.
void Terminal::HardResetWithoutErase()
{
_assertLocked();
_stateMachine->ResetState();
auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
engine.Dispatch().HardReset(false);
}
// Method Description:
// - Initializes the Terminal from the given set of settings.
// Arguments:
@@ -1522,6 +1534,10 @@ void Terminal::SerializeMainBuffer(HANDLE handle) const
_mainBuffer->SerializeTo(handle);
}
void Terminal::UnknownSequence() noexcept
{
}
void Terminal::ColorSelection(const TextAttribute& attr, winrt::Microsoft::Terminal::Core::MatchMode matchMode)
{
const auto colorSelection = [this](const til::point coordStartInclusive, const til::point coordEndExclusive, const TextAttribute& attr) {

View File

@@ -85,6 +85,7 @@ public:
void Create(til::size viewportSize,
til::CoordType scrollbackLines,
Microsoft::Console::Render::Renderer& renderer);
void HardResetWithoutErase();
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
Microsoft::Console::Render::Renderer& renderer);
@@ -131,7 +132,9 @@ public:
#pragma region ITerminalApi
// These methods are defined in TerminalApi.cpp
void UnknownSequence() noexcept override;
void ReturnResponse(const std::wstring_view response) override;
bool IsConPTY() const noexcept override;
Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() noexcept override;
BufferState GetBufferAndViewport() noexcept override;
void SetViewportPosition(const til::point position) noexcept override;

View File

@@ -28,6 +28,11 @@ void Terminal::ReturnResponse(const std::wstring_view response)
}
}
bool Terminal::IsConPTY() const noexcept
{
return false;
}
Microsoft::Console::VirtualTerminal::StateMachine& Terminal::GetStateMachine() noexcept
{
return *_stateMachine;

View File

@@ -43,7 +43,8 @@
</local:SettingContainer>
<!-- Ambiguous Width -->
<local:SettingContainer x:Uid="Globals_AmbiguousWidth">
<local:SettingContainer x:Name="AmbiguousWidth"
x:Uid="Globals_AmbiguousWidth">
<ComboBox AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind ViewModel.AmbiguousWidthList}"

View File

@@ -44,6 +44,28 @@ using namespace winrt::Windows::Foundation::Collections;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
// GH#19927 - Walk the visual tree of the given element to find any
// Popups and set the theme on their Child element. In XAML Islands,
// popup children render in the PopupRoot (separate from the content
// tree), so they don't inherit our page's RequestedTheme
static void _setThemeOnPopups(const winrt::Windows::UI::Xaml::DependencyObject& element,
const winrt::Windows::UI::Xaml::ElementTheme theme)
{
const auto childCount = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetChildrenCount(element);
for (int32_t i = 0; i < childCount; i++)
{
const auto child = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetChild(element, i);
if (const auto popup = child.try_as<winrt::Windows::UI::Xaml::Controls::Primitives::Popup>())
{
if (const auto popupChild = popup.Child().try_as<winrt::Windows::UI::Xaml::FrameworkElement>())
{
popupChild.RequestedTheme(theme);
}
}
_setThemeOnPopups(child, theme);
}
}
static WUX::Controls::FontIcon _fontIconForNavTag(const std::wstring_view navTag)
{
WUX::Controls::FontIcon icon{};
@@ -350,6 +372,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_Navigate(tag, BreadcrumbSubPage::None);
}
}
// GH#19927 - Theme the search box's internal popup now that the
// visual tree is ready and control templates are applied
const auto theme = _settingsSource.GlobalSettings().CurrentTheme();
const auto hasThemeForSettings{ theme.Settings() != nullptr };
const auto requestedTheme = hasThemeForSettings ? theme.Settings().RequestedTheme() : theme.RequestedTheme();
_setThemeOnPopups(SettingsSearchBox(), requestedTheme);
}
// Function Description:
@@ -1098,13 +1127,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
const auto& theme = _settingsSource.GlobalSettings().CurrentTheme();
const bool hasThemeForSettings{ theme.Settings() != nullptr };
const auto& appTheme = theme.RequestedTheme();
const auto& requestedTheme = (hasThemeForSettings) ? theme.Settings().RequestedTheme() : appTheme;
const auto theme = _settingsSource.GlobalSettings().CurrentTheme();
const auto hasThemeForSettings{ theme.Settings() != nullptr };
const auto appTheme = theme.RequestedTheme();
const auto requestedTheme = (hasThemeForSettings) ? theme.Settings().RequestedTheme() : appTheme;
RequestedTheme(requestedTheme);
// GH#19927 - Theme the search box's internal popup so its
// dropdown matches the app theme instead of the system theme
_setThemeOnPopups(SettingsSearchBox(), requestedTheme);
// Mica gets it's appearance from the app's theme, not necessarily the
// Page's theme. In the case of dark app, light settings, mica will be a
// dark color, and the text will also be dark, making the UI _very_ hard

View File

@@ -329,7 +329,8 @@
</local:SettingContainer>
<!-- Icon -->
<local:SettingContainer x:Uid="NewTabMenu_CurrentFolderIcon"
<local:SettingContainer x:Name="CurrentFolderIcon"
x:Uid="NewTabMenu_CurrentFolderIcon"
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValue>
@@ -497,7 +498,8 @@
</local:SettingContainer>
<!-- Add Remaining Profiles -->
<local:SettingContainer x:Uid="NewTabMenu_AddRemainingProfiles"
<local:SettingContainer x:Name="AddRemainingProfiles"
x:Uid="NewTabMenu_AddRemainingProfiles"
FontIconGlyph="&#xE902;"
Style="{StaticResource SettingContainerWithIcon}">
<Button x:Name="AddRemainingProfilesButton"

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Windows-Konsole</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Breite von mehrdeutigen Zeichen</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Legt die Breite fest, die für ostasiatische mehrdeutige Zeichen verwendet wird. „Eng“ (Standard) priorisiert die Kompatibilität, während „Weit“ die Lesbarkeit mit vielen CJK-Schriftarten priorisiert. Im Modus „Breit“ funktionieren einige Anwendungen möglicherweise nicht ordnungsgemäß und verursachen eine erratische Cursorbewegung. Das Ändern dieser Einstellung erfordert einen Neustart von Windows-Terminal und gilt nur für Anwendungen, die von dort aus gestartet werden.</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Schmal</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Breit</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Spalten</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Consola de Windows</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Ancho de caracteres ambiguos</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Establece el ancho usado para los caracteres ambiguos de Asia Oriental. "Estrecho" (valor predeterminado) da prioridad a la compatibilidad, mientras que "Ancho" da prioridad a la legibilidad con muchas fuentes CJK. En el modo "Ancho", es posible que algunas aplicaciones no funcionen correctamente y provoquen un movimiento errático del cursor. Cambiar esta configuración requiere un reinicio de Terminal Windows y solo se aplica a las aplicaciones que se inician desde dentro de ella.</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Estrecho</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Anchura</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Columnas</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Console Windows</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Largeur des caractères ambigus dAsie de lEst</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Définit la largeur utilisée pour les caractères ambigus dAsie de lEst. « Narrow » (par défaut) privilégie la compatibilité, tandis que « Wide » favorise la lisibilité avec de nombreuses polices CJK. En mode « Wide », certaines applications peuvent ne pas fonctionner correctement et provoquer un déplacement erratique du curseur. La modification de ce paramètre nécessite le redémarrage du Terminal Windows et ne sapplique quaux applications lancées à partir de celui-ci.</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Étroites</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Larges</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Colonnes</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Windows Console</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Larghezza dei caratteri ambigui</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Imposta la larghezza usata per i caratteri ambigui dell'Asia orientale. "Narrow" (impostazione predefinita) privilegia la compatibilità, mentre "Wide" privilegia la leggibilità con molti tipi di carattere CJK. In modalità "Wide", alcune applicazioni potrebbero non funzionare correttamente e causare movimenti irregolari del cursore. Per applicare questa modifica è necessario riavviare Terminale Windows e si applica solo alle applicazioni avviate all'interno.</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Stretti</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Ampiezza</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Colonne</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Windows コンソール</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>あいまいな文字の幅</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>東アジアのあいまいな文字に使用する幅を設定します。[幅を狭くする] (既定) は互換性を優先し、[幅を広くする] は多くの CJK フォントでの読みやすさを優先します。[幅を広くする] モードでは、一部のアプリケーションが正しく動作せず、カーソルの動きが不安定になることがあります。この設定を変更するには、Windows ターミナルの再起動が必要で、Windows ターミナル内から起動したアプリケーションにのみ適用されます。</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>狭い</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>広い</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>列</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Windows 콘솔</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>모호한 문자 너비</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>동아시아의 모호한 문자에 사용되는 너비를 설정하세요. "좁게"(기본값)는 호환성을 우선시하고, "넓게"는 많은 CJK 글꼴에서 가독성을 우선시합니다. "넓게" 모드에서는 일부 애플리케이션이 제대로 작동하지 않아 커서가 이상하게 움직일 수 있습니다. 이 설정을 변경하려면 Windows 터미널을 다시 시작해야 하며, 이 설정은 Windows 터미널 내에서 실행된 애플리케이션에만 적용됩니다.</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>좁게</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>넓게</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>열</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Console do Windows</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Largura de caracteres ambíguos</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Define a largura usada para caracteres ambíguos do Leste Asiático. "Estreito" (padrão) prioriza a compatibilidade, enquanto "Amplo" prioriza a legibilidade com muitas fontes CJK. No modo "Amplo", alguns aplicativos podem não funcionar corretamente e provocar movimento irregular do cursor. Alterar essa configuração exige reiniciar o Terminal do Windows e vale só para aplicativos iniciados dentro dele.</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Estreita</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Largo</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Colunas</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Щіŋďŏшś Ĉǿʼnşöℓę !!! !</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Ẅίďτħ οƒ àmъïġũõŭś ¢ћäřаčτëŕś !!! !!! !!!</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Šеŧѕ тĥé ẃίďтн цšеď ƒθŕ Ёāѕť Дѕїāπ Δmъìĝůόųş ¢ĥǻŕǻćτєŗş. "Νǻяѓòш" (đéƒåųĺţ) ρґΐõѓіŧīźéѕ ċǿmραťĭвĭľΐτŷ, ẃђίļė "Ẁîδ℮" рŕīόŕïтϊźĕş гèáðàвіℓīτў ẁìτн мâйý ČЈК ƒблťś. Ĩл "Шϊďε" mőδє, şõmе áρφļĭĉªτιόņś мąу ⁿõт ẃóѓк çθřŕзçτłў αŋδ čäűѕє ℮ŗѓāŧíć ςŭѓşοґ mòνėmĕŋť. Ċђªŋĝϊйġ тнϊş śэттĩņģ ŕêqůįŗëš å ř℮ŝţâгŧ ōƒ Ẁίήďôωş Ţёŕмĭиàĺ ąηδ îт öʼnłý ãφрŀįέѕ τő ąρрļĭсатįŏлŝ ℓаϋⁿćћ℮ð ƒřом шìтħїή îť. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Ŋǻŕґŏш !</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Шĭðе !</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Ċσŀùмñѕ !!</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Щіŋďŏшś Ĉǿʼnşöℓę !!! !</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Ẅίďτħ οƒ àmъïġũõŭś ¢ћäřаčτëŕś !!! !!! !!!</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Šеŧѕ тĥé ẃίďтн цšеď ƒθŕ Ёāѕť Дѕїāπ Δmъìĝůόųş ¢ĥǻŕǻćτєŗş. "Νǻяѓòш" (đéƒåųĺţ) ρґΐõѓіŧīźéѕ ċǿmραťĭвĭľΐτŷ, ẃђίļė "Ẁîδ℮" рŕīόŕïтϊźĕş гèáðàвіℓīτў ẁìτн мâйý ČЈК ƒблťś. Ĩл "Шϊďε" mőδє, şõmе áρφļĭĉªτιόņś мąу ⁿõт ẃóѓк çθřŕзçτłў αŋδ čäűѕє ℮ŗѓāŧíć ςŭѓşοґ mòνėmĕŋť. Ċђªŋĝϊйġ тнϊş śэттĩņģ ŕêqůįŗëš å ř℮ŝţâгŧ ōƒ Ẁίήďôωş Ţёŕмĭиàĺ ąηδ îт öʼnłý ãφрŀįέѕ τő ąρрļĭсатįŏлŝ ℓаϋⁿćћ℮ð ƒřом шìтħїή îť. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Ŋǻŕґŏш !</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Шĭðе !</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Ċσŀùмñѕ !!</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Щіŋďŏшś Ĉǿʼnşöℓę !!! !</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Ẅίďτħ οƒ àmъïġũõŭś ¢ћäřаčτëŕś !!! !!! !!!</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Šеŧѕ тĥé ẃίďтн цšеď ƒθŕ Ёāѕť Дѕїāπ Δmъìĝůόųş ¢ĥǻŕǻćτєŗş. "Νǻяѓòш" (đéƒåųĺţ) ρґΐõѓіŧīźéѕ ċǿmραťĭвĭľΐτŷ, ẃђίļė "Ẁîδ℮" рŕīόŕïтϊźĕş гèáðàвіℓīτў ẁìτн мâйý ČЈК ƒблťś. Ĩл "Шϊďε" mőδє, şõmе áρφļĭĉªτιόņś мąу ⁿõт ẃóѓк çθřŕзçτłў αŋδ čäűѕє ℮ŗѓāŧíć ςŭѓşοґ mòνėmĕŋť. Ċђªŋĝϊйġ тнϊş śэттĩņģ ŕêqůįŗëš å ř℮ŝţâгŧ ōƒ Ẁίήďôωş Ţёŕмĭиàĺ ąηδ îт öʼnłý ãφрŀįέѕ τő ąρрļĭсатįŏлŝ ℓаϋⁿćћ℮ð ƒřом шìтħїή îť. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Ŋǻŕґŏш !</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Шĭðе !</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Ċσŀùмñѕ !!</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Консоль Windows</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>Ширина символов в пропорциональных шрифтах</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>Задает ширину для символов восточноазиатских шрифтов. Значение "Узкая" (по умолчанию) обеспечивает совместимость, а "Широкая" улучшает читаемость большинства шрифтов CJK. В режиме "Широкая" некоторые приложения могут работать неправильно, что приводит к беспорядочному движению курсора. Изменение этого параметра требует перезапуска Терминала Windows и применяется только к приложениям, запущенным из него.</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>Узкие</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>Широкие</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Столбцы</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Windows 控制台</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>模糊字符的宽度</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>设置东亚模糊字符的宽度。"窄"模式(默认)优先考虑兼容性,而"宽"模式优先考虑很多中日韩字体的可读性。在"宽"模式下,某些应用程序可能无法正常工作,并导致光标不规则移动。更改此设置需要重启 Windows 终端,而且仅适用于从终端中启动的应用程序。</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>窄</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>宽</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>列</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -371,6 +371,21 @@
<data name="Globals_TextMeasurement_Console.Text" xml:space="preserve">
<value>Windows 主控台</value>
</data>
<data name="Globals_AmbiguousWidth.Header" xml:space="preserve">
<value>模糊字元寬度</value>
<comment>A label for a drop down selector, referring to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth.HelpText" xml:space="preserve">
<value>設定東亞模糊字元的寬度。「窄」(預設) 以相容性為優先,而「寬」則以多數中日韓字型的可讀性為優先。在「寬」模式下,部分應用程式可能無法正常運作,導致游標移動異常。變更此設定後,需重新啟動 Windows 終端機,且僅適用於從 Windows 終端機內啟動的應用程式。</value>
</data>
<data name="Globals_AmbiguousWidth_Narrow.Text" xml:space="preserve">
<value>窄</value>
<comment>As in "narrow width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_AmbiguousWidth_Wide.Text" xml:space="preserve">
<value>寬</value>
<comment>As in "wide width". Refers to the East Asian Ambiguous Width Unicode specification.</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>欄</value>
<comment>Header for a control to choose the number of columns in the terminal's text grid.</comment>

View File

@@ -647,9 +647,12 @@ void CascadiaSettings::_validateMediaResources()
_globals->ResolveMediaResources(mediaResourceResolver);
if (_foundInvalidUserResources)
if (Feature_WarnOnInvalidSettingsMediaResources::IsEnabled())
{
_warnings.Append(SettingsLoadWarnings::InvalidMediaResource);
if (_foundInvalidUserResources)
{
_warnings.Append(SettingsLoadWarnings::InvalidMediaResource);
}
}
}

View File

@@ -8,6 +8,16 @@
using namespace winrt::Microsoft::Terminal::Settings::Model;
static bool _IsPwshAvailable()
{
// Try to detect if `pwsh.exe` is available in the PATH, if so we want to use that
// Allow some extra space in case user put it somewhere odd
// We do need to allocate space for the full path even if we don't want to paste the whole thing in
wchar_t pwshPath[MAX_PATH] = { 0 };
const auto pwshExeName = L"pwsh.exe";
return SearchPathW(nullptr, pwshExeName, nullptr, MAX_PATH, pwshPath, nullptr);
}
void VsDevShellGenerator::GenerateProfiles(const VsSetupConfiguration::VsSetupInstance& instance, bool hidden, std::vector<winrt::com_ptr<implementation::Profile>>& profiles) const
{
try
@@ -21,9 +31,10 @@ void VsDevShellGenerator::GenerateProfiles(const VsSetupConfiguration::VsSetupIn
const winrt::guid profileGuid{ ::Microsoft::Console::Utils::CreateV5Uuid(TERMINAL_PROFILE_NAMESPACE_GUID, std::as_bytes(std::span{ seed })) };
auto profile = winrt::make_self<implementation::Profile>(profileGuid);
profile->Name(winrt::hstring{ GetProfileName(instance) });
profile->Commandline(winrt::hstring{ GetProfileCommandLine(instance) });
auto isPwsh = _IsPwshAvailable();
profile->Commandline(winrt::hstring{ GetProfileCommandLine(instance, isPwsh) });
profile->StartingDirectory(winrt::hstring{ instance.GetInstallationPath() });
profile->Icon(winrt::hstring{ GetProfileIconPath() });
profile->Icon(winrt::hstring{ GetProfileIconPath(isPwsh) });
profile->Hidden(hidden);
profiles.emplace_back(std::move(profile));
}
@@ -37,20 +48,15 @@ std::wstring VsDevShellGenerator::GetProfileName(const VsSetupConfiguration::VsS
return name;
}
std::wstring VsDevShellGenerator::GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance& instance) const
std::wstring VsDevShellGenerator::GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance& instance, bool isPwsh) const
{
// Build this in stages, so reserve space now
std::wstring commandLine;
commandLine.reserve(256);
// Try to detect if `pwsh.exe` is available in the PATH, if so we want to use that
// Allow some extra space in case user put it somewhere odd
// We do need to allocate space for the full path even if we don't want to paste the whole thing in
wchar_t pwshPath[MAX_PATH] = { 0 };
const auto pwshExeName = L"pwsh.exe";
if (SearchPathW(nullptr, pwshExeName, nullptr, MAX_PATH, pwshPath, nullptr))
if (isPwsh)
{
commandLine.append(pwshExeName);
commandLine.append(L"pwsh.exe");
}
else
{

View File

@@ -37,13 +37,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model
return L"VsDevShell" + instance.GetInstanceId();
}
std::wstring GetProfileIconPath() const
std::wstring GetProfileIconPath(bool isPwsh) const
{
return L"ms-appx:///ProfileIcons/vs-powershell.png";
return isPwsh ? L"ms-appx:///ProfileIcons/vs-pwsh.png" :
L"ms-appx:///ProfileIcons/vs-powershell.png";
}
std::wstring GetProfileName(const VsSetupConfiguration::VsSetupInstance& instance) const;
std::wstring GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance& instance) const;
std::wstring GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance& instance, bool isPwsh) const;
std::wstring GetDevShellModulePath(const VsSetupConfiguration::VsSetupInstance& instance) const;
};
};

View File

@@ -324,9 +324,11 @@ std::vector<wil::com_ptr<T>> SafeArrayToOwningVector(SAFEARRAY* safeArray)
std::vector<wil::com_ptr<T>> result{ gsl::narrow<std::size_t>(count) };
for (int i = 0; i < count; i++)
{
result[i].attach(pVals[i]);
result[i] = pVals[i];
}
THROW_IF_FAILED(SafeArrayUnaccessData(safeArray));
THROW_IF_FAILED(SafeArrayDestroy(safeArray));
return result;
}

View File

@@ -187,4 +187,11 @@
<alwaysDisabledReleaseTokens/>
</feature>
<feature>
<name>Feature_WarnOnInvalidSettingsMediaResources</name>
<description>Controls whether Terminal should display a warning dialog when icon, backgroundImage, shader, etc. could not be found.</description>
<stage>AlwaysEnabled</stage>
<alwaysDisabledReleaseTokens/>
</feature>
</featureStaging>

View File

@@ -670,7 +670,7 @@ void FileTests::TestReadFileBasicEmpty()
const auto hIn = GetStdInputHandle();
VERIFY_IS_NOT_NULL(hIn, L"Verify we have the standard input handle.");
DWORD dwMode = 0;
DWORD dwMode = ENABLE_PROCESSED_INPUT; // ^Z is only handled when processed input is enabled.
VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hIn, dwMode), L"Set input mode for test.");
VERIFY_WIN32_BOOL_SUCCEEDED(FlushConsoleInputBuffer(hIn), L"Flush input buffer in preparation for test.");

View File

@@ -24,6 +24,22 @@ ConhostInternalGetSet::ConhostInternalGetSet(_In_ IIoProvider& io) :
{
}
void ConhostInternalGetSet::UnknownSequence() noexcept
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
// VT sequences unknown to us may cause the cursor position to change in a way that
// we don't know about. In this case, we need to mark the cursor position as "dirty".
//
// The worst offender is likely PowerShell. It uses VT sequences but also calls
// GetConsoleScreenBufferInfoEx for *every single line of output* (!!!). This prevents
// us from using a more conservative solution (e.g. always fetching the cursor position).
if (gci.IsInVtIoMode())
{
gci.GetActiveOutputBuffer().SetConptyCursorPositionMayBeWrong();
}
}
// - Sends a string response to the input stream of the console.
// - Used by various commands where the program attached would like a reply to one of the commands issued.
// - This will generate two "key presses" (one down, one up) for every character in the string and place them into the head of the console's input stream.
@@ -48,6 +64,12 @@ void ConhostInternalGetSet::ReturnResponse(const std::wstring_view response)
_io.GetActiveInputBuffer()->WriteString(response);
}
bool ConhostInternalGetSet::IsConPTY() const noexcept
{
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
return gci.IsInVtIoMode();
}
// Routine Description:
// - Retrieves the state machine for the active output buffer.
// Arguments:

View File

@@ -29,8 +29,10 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::
public:
ConhostInternalGetSet(_In_ Microsoft::Console::IIoProvider& io);
void UnknownSequence() noexcept override;
void ReturnResponse(const std::wstring_view response) override;
bool IsConPTY() const noexcept override;
Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() override;
BufferState GetBufferAndViewport() override;
void SetViewportPosition(const til::point position) override;

View File

@@ -1313,6 +1313,15 @@ COOKED_READ_DATA::LayoutResult COOKED_READ_DATA::_layoutLine(std::wstring& outpu
til::CoordType cols = 0;
const auto len = textBuffer.FitTextIntoColumns(text, columnLimit - column, cols);
// GH#19922: We need to account for terminals that are just 1 column wide, as we may deadlock otherwise.
// `columnLimit - column == 1` will then prevent `FitTextIntoColumns` from fitting any wide glyphs.
// We can detect this by checking for `len == 0`, skip the offending glyph and break out of the deadlock.
if (len == 0) [[unlikely]]
{
it += textBuffer.GraphemeNext(text, 0);
break;
}
output.append(text, 0, len);
column += cols;
it += len;

View File

@@ -42,7 +42,7 @@ CONPTY_EXPORT HRESULT WINAPI ConptyCreatePseudoConsoleAsUser(HANDLE hToken, COOR
CONPTY_EXPORT HRESULT WINAPI ConptyResizePseudoConsole(HPCON hPC, COORD size);
CONPTY_EXPORT HRESULT WINAPI ConptyClearPseudoConsole(HPCON hPC, BOOL keepCursorRow);
CONPTY_EXPORT HRESULT WINAPI ConptyShowHidePseudoConsole(HPCON hPC, bool show);
CONPTY_EXPORT HRESULT WINAPI ConptyShowHidePseudoConsole(HPCON hPC, BOOL show);
CONPTY_EXPORT HRESULT WINAPI ConptyReparentPseudoConsole(HPCON hPC, HWND newParent);
CONPTY_EXPORT HRESULT WINAPI ConptyReleasePseudoConsole(HPCON hPC);

View File

@@ -951,6 +951,11 @@ LRESULT Window::_HandleGetDpiScaledSize(UINT dpiNew, _Inout_ SIZE* pSizeNew) con
// - <none>
void Window::_HandleDrop(const WPARAM wParam) const
{
if (const auto hwnd = GetWindowHandle())
{
SetForegroundWindow(hwnd);
}
const auto drop = reinterpret_cast<HDROP>(wParam);
Clipboard::Instance().PasteDrop(drop);
DragFinish(drop);

View File

@@ -270,6 +270,16 @@ constexpr T saturate(auto val)
}
CATCH_RETURN();
if (a->ProcessControlZ)
{
// ProcessControlZ is only set for CONSOLE_IO_RAW_READ. To restore
// the behavior from Windows 7 (see filehops.c:123) we need to honor
// ^Z only if PROCESSED_INPUT is enabled.
ULONG InputMode{ 0 };
m->_pApiRoutines->GetConsoleInputModeImpl(*pInputBuffer, InputMode);
a->ProcessControlZ = (InputMode & ENABLE_PROCESSED_INPUT) != 0;
}
TraceConsoleAPICallWithOrigin(
"ReadConsole",
TraceLoggingBoolean(a->Unicode, "Unicode"),

View File

@@ -35,6 +35,7 @@ public:
#pragma warning(disable : 26432) // suppress rule of 5 violation on interface because tampering with this is fraught with peril
virtual ~ITermDispatch() = 0;
virtual void UnknownSequence() noexcept = 0;
virtual void Print(const wchar_t wchPrintable) = 0;
virtual void PrintString(const std::wstring_view string) = 0;
@@ -81,6 +82,7 @@ public:
virtual void BackIndex() = 0; // DECBI
virtual void ForwardIndex() = 0; // DECFI
virtual void SetWindowTitle(std::wstring_view title) = 0; // DECSWT, OscWindowTitle
virtual void SetCurrentWorkingDirectory(const std::wstring_view uri) = 0; // OSC 7
virtual void HorizontalTabSet() = 0; // HTS
virtual void ForwardTab(const VTInt numTabs) = 0; // CHT, HT
virtual void BackwardsTab(const VTInt numTabs) = 0; // CBT
@@ -139,7 +141,7 @@ public:
virtual void AnnounceCodeStructure(const VTInt ansiLevel) = 0; // ACS
virtual void SoftReset() = 0; // DECSTR
virtual void HardReset() = 0; // RIS
virtual void HardReset(bool erase) = 0; // RIS
virtual void ScreenAlignmentPattern() = 0; // DECALN
virtual void SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR
@@ -155,13 +157,9 @@ public:
virtual void EndHyperlink() = 0;
virtual void DoConEmuAction(const std::wstring_view string) = 0;
virtual void DoITerm2Action(const std::wstring_view string) = 0;
virtual void DoFinalTermAction(const std::wstring_view string) = 0;
virtual void DoVsCodeAction(const std::wstring_view string) = 0;
virtual void DoWTAction(const std::wstring_view string) = 0;
virtual StringHandler DefineSixelImage(const VTInt macroParameter,

View File

@@ -37,6 +37,7 @@ namespace Microsoft::Console::VirtualTerminal
ITerminalApi& operator=(const ITerminalApi&) = delete;
ITerminalApi& operator=(ITerminalApi&&) = delete;
virtual void UnknownSequence() noexcept = 0;
virtual void ReturnResponse(const std::wstring_view response) = 0;
struct BufferState
@@ -46,6 +47,7 @@ namespace Microsoft::Console::VirtualTerminal
bool isMainBuffer;
};
virtual bool IsConPTY() const noexcept = 0;
virtual StateMachine& GetStateMachine() = 0;
virtual BufferState GetBufferAndViewport() = 0;
virtual void SetViewportPosition(const til::point position) = 0;

View File

@@ -48,6 +48,11 @@ AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettin
{
}
void AdaptDispatch::UnknownSequence() noexcept
{
_api.UnknownSequence();
}
// Routine Description:
// - Translates and displays a single character
// Arguments:
@@ -2073,6 +2078,13 @@ void AdaptDispatch::SetAnsiMode(const bool ansiMode)
// CSI = flags ; mode u - Sets kitty keyboard protocol flags
void AdaptDispatch::SetKittyKeyboardProtocol(const VTParameter flags, const VTParameter mode) noexcept
{
// Avoid setting KKP flags in `_terminalInput` when we're ConPTY. Otherwise, we'd be translating
// W32IM to KKP, even when KKP is not supported by the hosting terminal (possibly intentionally).
if (_api.IsConPTY())
{
return;
}
const auto kittyFlags = gsl::narrow_cast<uint8_t>(flags.value_or(0));
const auto KittyKeyboardProtocol = static_cast<TerminalInput::KittyKeyboardProtocolMode>(mode.value_or(1));
_terminalInput.SetKittyKeyboardProtocol(kittyFlags, KittyKeyboardProtocol);
@@ -2081,6 +2093,11 @@ void AdaptDispatch::SetKittyKeyboardProtocol(const VTParameter flags, const VTPa
// CSI ? u - Queries current kitty keyboard protocol flags
void AdaptDispatch::QueryKittyKeyboardProtocol()
{
if (_api.IsConPTY())
{
return;
}
const auto flags = static_cast<VTInt>(_terminalInput.GetKittyFlags());
_ReturnCsiResponse(fmt::format(FMT_COMPILE(L"?{}u"), flags));
}
@@ -2088,6 +2105,11 @@ void AdaptDispatch::QueryKittyKeyboardProtocol()
// CSI > flags u - Pushes current kitty keyboard flags onto the stack and sets new flags
void AdaptDispatch::PushKittyKeyboardProtocol(const VTParameter flags)
{
if (_api.IsConPTY())
{
return;
}
const auto kittyFlags = gsl::narrow_cast<uint8_t>(flags.value_or(0));
_terminalInput.PushKittyFlags(kittyFlags);
}
@@ -2095,6 +2117,11 @@ void AdaptDispatch::PushKittyKeyboardProtocol(const VTParameter flags)
// CSI < count u - Pops one or more entries from the kitty keyboard stack
void AdaptDispatch::PopKittyKeyboardProtocol(const VTParameter count)
{
if (_api.IsConPTY())
{
return;
}
const auto popCount = static_cast<size_t>(count.value_or(1));
_terminalInput.PopKittyFlags(popCount);
}
@@ -2588,6 +2615,27 @@ void AdaptDispatch::SetWindowTitle(std::wstring_view title)
_api.SetWindowTitle(title);
}
// OSC 7 - Set Current Working Directory
// While ConEmu's OSC 9;9 works well for native Windows paths,
// OSC 7 uses file URIs, which may not always work.
void AdaptDispatch::SetCurrentWorkingDirectory(std::wstring_view uri)
{
// Ensure that the URI has a null terminator.
std::wstring path{ uri };
// PathCreateFromUrlW supports writing to the input pointer,
// and the resulting path can never be longer than the URI.
const auto ptr = path.data();
auto len = gsl::narrow<DWORD>(path.size());
THROW_IF_FAILED(PathCreateFromUrlW(ptr, ptr, &len, 0));
path.resize(len);
if (til::is_legal_path(path))
{
_api.SetWorkingDirectory(path);
}
}
//Routine Description:
// HTS - sets a VT tab stop in the cursor's current column.
//Arguments:
@@ -2982,7 +3030,7 @@ void AdaptDispatch::SoftReset()
// - Clears UDKs.
// - Clears a down-line-loaded character set.
// * The soft font is reset in the renderer and the font buffer is deleted.
// - Clears the screen.
// - Clears the screen. (if erase=true)
// * This is like Erase in Display (3), also clearing scrollback, as well as ED(2)
// - Returns the cursor to the upper-left corner of the screen.
// * CUP(1;1)
@@ -2992,8 +3040,8 @@ void AdaptDispatch::SoftReset()
// - Sets all character sets to the default.
// * G0(USASCII)
//Arguments:
// <none>
void AdaptDispatch::HardReset()
// - erase: if true, erase the screen and scrollback
void AdaptDispatch::HardReset(bool erase)
{
// If in the alt buffer, switch back to main before doing anything else.
if (_usingAltBuffer)
@@ -3020,9 +3068,12 @@ void AdaptDispatch::HardReset()
// to ensure that it clears with the default background color.
SoftReset();
// Clears the screen - Needs to be done in two operations.
EraseInDisplay(DispatchTypes::EraseType::All);
EraseInDisplay(DispatchTypes::EraseType::Scrollback);
if (erase)
{
// Clears the screen - Needs to be done in two operations.
EraseInDisplay(DispatchTypes::EraseType::All);
EraseInDisplay(DispatchTypes::EraseType::Scrollback);
}
// Set the color table and render modes back to their initial startup values.
_renderSettings.RestoreDefaultSettings();
@@ -3033,8 +3084,14 @@ void AdaptDispatch::HardReset()
_renderer->SynchronizedOutputChanged();
}
// Cursor to 1,1 - the Soft Reset guarantees this is absolute
CursorPosition(1, 1);
if (erase)
{
// Cursor to 1,1 - the Soft Reset guarantees this is absolute.
// Only done when clearing buffers, because when preserving content
// the cursor should stay where the previous shell left it so the
// new shell prompt appears in the right place.
CursorPosition(1, 1);
}
// We only reset the system line feed mode if the input mode is set. If it
// isn't set, that either means they're both reset, and there's nothing for
@@ -3585,6 +3642,10 @@ void AdaptDispatch::DoConEmuAction(const std::wstring_view string)
_pages.ActivePage().Buffer().StartCommand();
_api.NotifyShellIntegrationMark();
}
else
{
_api.UnknownSequence();
}
}
// Method Description:
@@ -3616,6 +3677,10 @@ void AdaptDispatch::DoITerm2Action(const std::wstring_view string)
_pages.ActivePage().Buffer().StartPrompt();
_api.NotifyShellIntegrationMark();
}
else
{
_api.UnknownSequence();
}
}
// Method Description:
@@ -3686,9 +3751,14 @@ void AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
break;
}
default:
_api.UnknownSequence();
break;
}
}
else
{
_api.UnknownSequence();
}
// When we add the rest of the FTCS sequences (GH#11000), we should add a
// simple state machine here to track the most recently emitted mark from
@@ -3763,6 +3833,10 @@ void AdaptDispatch::DoVsCodeAction(const std::wstring_view string)
// If it's poorly formatted, just eat it
}
else
{
_api.UnknownSequence();
}
}
// Method Description:

View File

@@ -38,6 +38,7 @@ namespace Microsoft::Console::VirtualTerminal
public:
AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept;
void UnknownSequence() noexcept override;
void Print(const wchar_t wchPrintable) override;
void PrintString(const std::wstring_view string) override;
@@ -113,6 +114,7 @@ namespace Microsoft::Console::VirtualTerminal
void BackIndex() override; // DECBI
void ForwardIndex() override; // DECFI
void SetWindowTitle(const std::wstring_view title) override; // DECSWT, OSCWindowTitle
void SetCurrentWorkingDirectory(std::wstring_view uri) override; // OSC 7
void HorizontalTabSet() override; // HTS
void ForwardTab(const VTInt numTabs) override; // CHT, HT
void BackwardsTab(const VTInt numTabs) override; // CBT
@@ -128,7 +130,7 @@ namespace Microsoft::Console::VirtualTerminal
void SendC1Controls(const bool enabled) override; // S8C1T, S7C1T
void AnnounceCodeStructure(const VTInt ansiLevel) override; // ACS
void SoftReset() override; // DECSTR
void HardReset() override; // RIS
void HardReset(bool erase) override; // RIS
void ScreenAlignmentPattern() override; // DECALN
void SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR

View File

@@ -13,7 +13,8 @@ Abstract:
// This includes support libraries from the CRT, STL, WIL, and GSL
#include "LibraryIncludes.h"
#include <cmath>
#include <Shlwapi.h>
#define ENABLE_INTSAFE_SIGNED_FUNCTIONS
#include <intsafe.h>

View File

@@ -22,6 +22,7 @@ namespace Microsoft::Console::VirtualTerminal
class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Console::VirtualTerminal::ITermDispatch
{
public:
void UnknownSequence() noexcept override {}
void Print(const wchar_t wchPrintable) override = 0;
void PrintString(const std::wstring_view string) override = 0;
@@ -68,6 +69,7 @@ public:
void BackIndex() override {} // DECBI
void ForwardIndex() override {} // DECFI
void SetWindowTitle(std::wstring_view /*title*/) override {} // DECSWT, OscWindowTitle
void SetCurrentWorkingDirectory(std::wstring_view /*uri*/) override {} // OSC 7
void HorizontalTabSet() override {} // HTS
void ForwardTab(const VTInt /*numTabs*/) override {} // CHT, HT
void BackwardsTab(const VTInt /*numTabs*/) override {} // CBT
@@ -126,7 +128,7 @@ public:
void AnnounceCodeStructure(const VTInt /*ansiLevel*/) override {} // ACS
void SoftReset() override {} // DECSTR
void HardReset() override {} // RIS
void HardReset(bool /*erase*/) override {} // RIS
void ScreenAlignmentPattern() override {} // DECALN
void SetCursorStyle(const DispatchTypes::CursorStyle /*cursorStyle*/) override {} // DECSCUSR

View File

@@ -60,6 +60,10 @@ using namespace Microsoft::Console::VirtualTerminal;
class TestGetSet final : public ITerminalApi
{
public:
void UnknownSequence() noexcept override
{
}
void ReturnResponse(const std::wstring_view response) override
{
Log::Comment(L"ReturnResponse MOCK called...");
@@ -76,6 +80,11 @@ public:
}
}
bool IsConPTY() const noexcept override
{
return false;
}
StateMachine& GetStateMachine() override
{
return *_stateMachine;
@@ -1651,7 +1660,7 @@ public:
Log::Comment(L"Test 3: Verify space reset");
_testGetSet->PrepData();
_pDispatch->HardReset();
_pDispatch->HardReset(true);
_pDispatch->DeviceStatusReport(DispatchTypes::StatusType::MacroSpaceReport, {});
swprintf_s(pwszBuffer, ARRAYSIZE(pwszBuffer), L"\x1b[%zu*{", availableSpace);
@@ -1683,7 +1692,7 @@ public:
Log::Comment(L"Test 3: Verify checksum resets to 0");
_testGetSet->PrepData();
_pDispatch->HardReset();
_pDispatch->HardReset(true);
_pDispatch->DeviceStatusReport(DispatchTypes::StatusType::MemoryChecksum, 56);
_testGetSet->ValidateInputEvent(L"\033P56!~0000\033\\");

View File

@@ -228,7 +228,8 @@ TerminalInput::OutputType TerminalInput::HandleKey(const INPUT_RECORD& event)
// GH#4999 - If we're in win32-input mode, skip straight to doing that.
// Since this mode handles all types of key events, do nothing else.
//
// The kitty keyboard protocol takes precedence, because it's cross-platform.
// ConPTY assumes that W32IM always remains enabled. We have to prefer
// the kitty keyboard protocol, because otherwise it would never be used.
if (_inputMode.test(Mode::Win32) && !_forceDisableWin32InputMode && !_kittyFlags)
{
return _makeWin32Output(event.Event.KeyEvent);

View File

@@ -28,6 +28,7 @@ namespace Microsoft::Console::VirtualTerminal
IStateMachineEngine& operator=(const IStateMachineEngine&) = default;
IStateMachineEngine& operator=(IStateMachineEngine&&) = default;
virtual void UnknownSequence() noexcept = 0;
virtual bool EncounteredWin32InputModeSequence() const noexcept = 0;
virtual bool ActionExecute(const wchar_t wch) = 0;

View File

@@ -129,6 +129,10 @@ til::enumset<DeviceAttribute, uint64_t> InputStateMachineEngine::WaitUntilDA1(DW
return til::enumset<DeviceAttribute, uint64_t>::from_bits(val);
}
void InputStateMachineEngine::UnknownSequence() noexcept
{
}
bool InputStateMachineEngine::EncounteredWin32InputModeSequence() const noexcept
{
return _encounteredWin32InputModeSequence;

View File

@@ -166,6 +166,7 @@ namespace Microsoft::Console::VirtualTerminal
void CaptureNextCursorPositionReport() noexcept;
til::enumset<DeviceAttribute, uint64_t> WaitUntilDA1(DWORD timeout) noexcept;
void UnknownSequence() noexcept override;
bool EncounteredWin32InputModeSequence() const noexcept override;
bool ActionExecute(const wchar_t wch) override;

View File

@@ -24,6 +24,11 @@ OutputStateMachineEngine::OutputStateMachineEngine(std::unique_ptr<ITermDispatch
THROW_HR_IF_NULL(E_INVALIDARG, _dispatch.get());
}
void OutputStateMachineEngine::UnknownSequence() noexcept
{
_dispatch->UnknownSequence();
}
bool OutputStateMachineEngine::EncounteredWin32InputModeSequence() const noexcept
{
return false;
@@ -230,7 +235,7 @@ bool OutputStateMachineEngine::ActionEscDispatch(const VTID id)
_dispatch->DeviceAttributes();
break;
case EscActionCodes::RIS_ResetToInitialState:
_dispatch->HardReset();
_dispatch->HardReset(true);
break;
case EscActionCodes::SS2_SingleShift:
_dispatch->SingleShift(2);
@@ -683,6 +688,7 @@ bool OutputStateMachineEngine::ActionCsiDispatch(const VTID id, const VTParamete
_dispatch->PopKittyKeyboardProtocol(parameters.at(0));
break;
default:
_dispatch->UnknownSequence();
break;
}
@@ -737,7 +743,7 @@ IStateMachineEngine::StringHandler OutputStateMachineEngine::ActionDcsDispatch(c
handler = _dispatch->RestorePresentationState(parameters.at(0));
break;
default:
handler = nullptr;
_dispatch->UnknownSequence();
break;
}
@@ -858,6 +864,9 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
}
break;
}
case OscActionCodes::CurrentWorkingDirectory:
_dispatch->SetCurrentWorkingDirectory(string);
break;
case OscActionCodes::Hyperlink:
{
std::wstring params;
@@ -901,6 +910,7 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
break;
}
default:
_dispatch->UnknownSequence();
break;
}
@@ -921,6 +931,7 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
bool OutputStateMachineEngine::ActionSs3Dispatch(const wchar_t /*wch*/, const VTParameters /*parameters*/) noexcept
{
// The output engine doesn't handle any SS3 sequences.
_dispatch->UnknownSequence();
_ClearLastChar();
return true;
}

View File

@@ -24,6 +24,7 @@ namespace Microsoft::Console::VirtualTerminal
OutputStateMachineEngine(std::unique_ptr<ITermDispatch> pDispatch);
void UnknownSequence() noexcept override;
bool EncounteredWin32InputModeSequence() const noexcept override;
bool ActionExecute(const wchar_t wch) override;
@@ -203,13 +204,14 @@ namespace Microsoft::Console::VirtualTerminal
ExitVt52Mode = VTID("<")
};
enum OscActionCodes : unsigned int
enum OscActionCodes : size_t
{
SetIconAndWindowTitle = 0,
SetWindowIcon = 1,
SetWindowTitle = 2,
SetWindowProperty = 3, // Not implemented
SetColor = 4,
CurrentWorkingDirectory = 7,
Hyperlink = 8,
ConEmuAction = 9,
SetForegroundColor = 10,

View File

@@ -1044,6 +1044,7 @@ void StateMachine::_EnterSosPmApcString() noexcept
{
_state = VTStates::SosPmApcString;
_cachedSequence.reset();
_engine->UnknownSequence();
_trace.TraceStateChange(L"SosPmApcString");
}

View File

@@ -40,6 +40,10 @@ public:
dcsDataString.clear();
}
void UnknownSequence() noexcept override
{
}
bool EncounteredWin32InputModeSequence() const noexcept override
{
return false;

View File

@@ -12,7 +12,7 @@ Handle Handle::Create()
{
Handle handle;
handle._impl = new Implementation();
if (!handle._impl->Initialize())
if (FAILED(handle._impl->Initialize()))
{
delete handle._impl;
handle._impl = nullptr;

View File

@@ -71,33 +71,27 @@ void Implementation::SetDefaultScopeAlphanumericHalfWidth(bool enable) noexcept
s_wantsAnsiInputScope.store(enable, std::memory_order_relaxed);
}
bool Implementation::Initialize()
HRESULT Implementation::Initialize()
{
_categoryMgr = wil::CoCreateInstanceNoThrow<ITfCategoryMgr>(CLSID_TF_CategoryMgr);
if (!_categoryMgr)
{
return false;
}
_displayAttributeMgr = wil::CoCreateInstance<ITfDisplayAttributeMgr>(CLSID_TF_DisplayAttributeMgr);
RETURN_IF_FAILED_EXPECTED(CoCreateInstance(CLSID_TF_CategoryMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(_categoryMgr.addressof())));
RETURN_IF_FAILED_EXPECTED(CoCreateInstance(CLSID_TF_DisplayAttributeMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(_displayAttributeMgr.addressof())));
// There's no point in calling TF_GetThreadMgr. ITfThreadMgr is a per-thread singleton.
_threadMgrEx = wil::CoCreateInstance<ITfThreadMgrEx>(CLSID_TF_ThreadMgr, CLSCTX_INPROC_SERVER);
RETURN_IF_FAILED_EXPECTED(CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(_threadMgrEx.addressof())));
THROW_IF_FAILED(_threadMgrEx->ActivateEx(&_clientId, s_activationFlags.load(std::memory_order_relaxed)));
THROW_IF_FAILED(_threadMgrEx->CreateDocumentMgr(_documentMgr.addressof()));
RETURN_IF_FAILED(_threadMgrEx->ActivateEx(&_clientId, s_activationFlags.load(std::memory_order_relaxed)));
RETURN_IF_FAILED(_threadMgrEx->CreateDocumentMgr(_documentMgr.addressof()));
TfEditCookie ecTextStore;
THROW_IF_FAILED(_documentMgr->CreateContext(_clientId, 0, static_cast<ITfContextOwnerCompositionSink*>(this), _context.addressof(), &ecTextStore));
RETURN_IF_FAILED(_documentMgr->CreateContext(_clientId, 0, static_cast<ITfContextOwnerCompositionSink*>(this), _context.addressof(), &ecTextStore));
_ownerCompositionServices = _context.try_query<ITfContextOwnerCompositionServices>();
_contextSource = _context.query<ITfSource>();
THROW_IF_FAILED(_contextSource->AdviseSink(IID_ITfContextOwner, static_cast<ITfContextOwner*>(this), &_cookieContextOwner));
THROW_IF_FAILED(_contextSource->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink*>(this), &_cookieTextEditSink));
RETURN_IF_FAILED(_contextSource->AdviseSink(IID_ITfContextOwner, static_cast<ITfContextOwner*>(this), &_cookieContextOwner));
RETURN_IF_FAILED(_contextSource->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink*>(this), &_cookieTextEditSink));
THROW_IF_FAILED(_documentMgr->Push(_context.get()));
return true;
RETURN_IF_FAILED(_documentMgr->Push(_context.get()));
return S_OK;
}
void Implementation::Uninitialize() noexcept

View File

@@ -21,7 +21,7 @@ namespace Microsoft::Console::TSF
virtual ~Implementation() = default;
bool Initialize();
HRESULT Initialize();
void Uninitialize() noexcept;
HWND FindWindowOfActiveTSF() noexcept;
void AssociateFocus(IDataProvider* provider);

View File

@@ -234,7 +234,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
UiaTracing::TextProvider::GetSelection(*this, *range.Get());
LONG currentIndex = 0;
hr = SafeArrayPutElement(*ppRetVal, &currentIndex, range.Detach());
hr = SafeArrayPutElement(*ppRetVal, &currentIndex, range.Get());
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);
@@ -278,7 +278,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
UiaTracing::TextProvider::GetVisibleRanges(*this, *range.Get());
LONG currentIndex = 0;
hr = SafeArrayPutElement(*ppRetVal, &currentIndex, range.Detach());
hr = SafeArrayPutElement(*ppRetVal, &currentIndex, range.Get());
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);

View File

@@ -128,6 +128,8 @@ namespace Microsoft::Console::Utils
const wchar_t* FindActionableControlCharacter(const wchar_t* beg, const size_t len) noexcept;
bool IsValidDirectory(const wchar_t* path) noexcept;
// Same deal, but in TerminalPage::_evaluatePathForCwd
std::wstring EvaluateStartingDirectory(std::wstring_view cwd, std::wstring_view startingDirectory);

View File

@@ -1237,6 +1237,19 @@ plainSearch:
return it;
}
// Returns true if it's a valid path to a directory.
bool Utils::IsValidDirectory(const wchar_t* path) noexcept
{
if (path == nullptr || *path == L'\0')
{
return false;
}
WIN32_FILE_ATTRIBUTE_DATA data;
const auto ok = GetFileAttributesExW(path, GetFileExInfoStandard, &data);
return ok && (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
#pragma warning(pop)
std::wstring Utils::EvaluateStartingDirectory(

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisProjectDirectory)\..\Microsoft.Windows.Console.ConPTY.props" />
<Import Project="$(MSBuildThisFileDirectory)..\Microsoft.Windows.Console.ConPTY.props" />
</Project>

View File

@@ -332,7 +332,7 @@ static HRESULT _ClearPseudoConsole(_In_ const PseudoConsole* const pPty, BOOL ke
// Return Value:
// - S_OK if the call succeeded, else an appropriate HRESULT for failing to
// write the clear message to the pty.
HRESULT _ShowHidePseudoConsole(_In_ const PseudoConsole* const pPty, const bool show)
HRESULT _ShowHidePseudoConsole(_In_ const PseudoConsole* const pPty, const BOOL show) noexcept
{
if (pPty == nullptr)
{
@@ -340,7 +340,7 @@ HRESULT _ShowHidePseudoConsole(_In_ const PseudoConsole* const pPty, const bool
}
unsigned short signalPacket[2];
signalPacket[0] = PTY_SIGNAL_SHOWHIDE_WINDOW;
signalPacket[1] = show;
signalPacket[1] = show ? 1 : 0;
const BOOL fSuccess = WriteFile(pPty->hSignal, signalPacket, sizeof(signalPacket), nullptr, nullptr);
return fSuccess ? S_OK : HRESULT_FROM_WIN32(GetLastError());
@@ -539,7 +539,7 @@ extern "C" HRESULT WINAPI ConptyClearPseudoConsole(_In_ HPCON hPC, BOOL keepCurs
// to keep ConPTY's internal HWND state in sync with the state of whatever the
// hosting window is.
// - For more information, refer to GH#12515.
extern "C" HRESULT WINAPI ConptyShowHidePseudoConsole(_In_ HPCON hPC, bool show)
extern "C" HRESULT WINAPI ConptyShowHidePseudoConsole(_In_ HPCON hPC, BOOL show)
{
// _ShowHidePseudoConsole will return E_INVALIDARG for us if the hPC is nullptr.
return _ShowHidePseudoConsole((PseudoConsole*)hPC, show);

View File

@@ -207,8 +207,13 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
continue
}
# Extract Name (prefer x:Name over Name)
$name = $null -ne $settingContainer.Name ? $settingContainer.Name : ""
# Extract Name via GetAttribute to avoid PowerShell's XML integration
# returning the element name (e.g. "local:SettingContainer") when x:Name is absent.
$name = $settingContainer.GetAttribute("x:Name")
if ([string]::IsNullOrEmpty($name))
{
$name = ""
}
if ($filename -eq "Appearances.xaml")
{
# Profile.Appearance settings need a special prefix for the ElementName.