When calculating the initial terminal window size, we weren't taking
into account the line height and cell width settings, so the resulting
number of rows and columns didn't match the requested launch size.
Verification:
Manually verified that the window is now correctly sized when using a
custom line height and cell width.
Closes#18582
This PR fixes two cases where image content wasn't correctly erased when
overwritten.
1. When legacy console APIs fill an area of the buffer using a starting
coordinate and a length, the affected area could potentially wrap over
multiple rows, but we were only erasing the overwritten image content on
the first affected row.
2. When copying an area of the buffer with text content over another
area that contained image content, the image in the target area would
sometimes not be erased, because we ignored the `_eraseCells` return
value which indicated that the image slice needed to be removed.
## References and Relevant Issues
The original code was from the Sixel implementation in PR #17421.
## Validation Steps Performed
I've manually verified that these two cases are now working as expected.
## PR Checklist
- [x] Closes#18568
This requires us to delay-sign the assembly with a public key (the snk
file), and then later submit it for strong naming. This is separate from
code signing, and has to take place before it.
The snk file does not contain any private key material.
This cannot merge until we are approved to use this new signing "key
code".
We used to cherry-pick every commit that had even one card in "To Cherry
Pick", even if it was also referenced by a card in "Rejected" or even
"To Consider".
Now we will warn and skip those commits.
I took this opportunity to add a bit of an object model for servicing
cards as well as prettify the output.
That allowed us to add a list of cards that were ignored due to having
no commits, and display little icons for each type of card.
`RenderSettings` already stores `DECSCNM` (reversed screen),
so it only makes sense to also store DECSET 2026 there.
## Validation Steps Performed
* Same as in #18826✅
Wanted to learn how the bot works, so I went ahead cleaned up the bot
rules a bit. List of changes:
- added a description for each rule (and move it to the top of the rule)
- added all the "Area-" labels and sorted
The conhost v2 rewrite from a decade ago introduced a race condition:
Previously, we would acquire and hold the global console lock while
servicing
a console API call. If the call cannot be completed a wait task is
enqueued,
while the lock is held. The v2 rewrite then split the project up into a
"server" and "host" component (which remain to this day). The "host"
would
hold the console lock, while the "server" was responsible for enqueueing
wait
tasks _outside of the console lock_. Without any form of
synchronization,
any operations on the waiter list would then of course introduce a race
condition. In conhost this primarily meant keyboard/mouse input, because
that
runs on the separate Win32 window thread. For Windows Terminal it
primarily
meant the VT input thread.
I do not know why this issue is so extremely noticeable specifically
when we
respond to DSC CPR requests, but I'm also not surprised: I suspect that
the
overall performance issues that conhost had for a long time, meant that
most
things it did were slower than allocating the wait task.
Now that both conhost and Windows Terminal became orders of magnitudes
faster
over the last few years, it probably just so happens that the DSC CPR
request
takes almost exactly as many cycles to complete as allocating the wait
task
does, hence perfectly reproducing the race condition.
There's also a slight chance that this is actually a regression from my
ConPTY
rewrite #17510, but I fail to see what that would be. Regardless of
that,
I'm 100% certain though, that this is a bug that has existed in v0.1.
Closes#18117Closes#18800
## Validation Steps Performed
* See repro in #18800. In other words:
* Continuously emit DSC CPR sequences
* ...read the response from stdin
* ...and print the response to stdout
* Doesn't deadlock randomly anymore ✅
* Feature & Unit tests ✅
The "open JSON" button in the settings UI wasn't working when invoked
via accessibility tools (specifically Narrator in scan mode and Voice
Access). For some reason, in those scenarios, neither the `Tapped` or
`KeyDown` event were hit!
This PR adds the logic to open the json file via the `ItemInvoked` event
instead. The `Tapped` and `KeyDown` handlers were removed to prevent a
redundant `OpenJson` event being raised.
Additionally, `SelectsOnInvoked` was set to `False` on the "open JSON"
nav item. This prevents the selection pill from moving to the nav item,
which feels more correct.
## Validation Steps Performed
The following scenarios are confirmed to open the JSON
✅ Mouse click
✅ Keyboard (Spacebar and Enter)
✅ Voice Access
✅ Narrator in scan mode
For all of these (except Voice Access), I've confirmed that holding the
Alt button while invoking the JSON button opens defaults.json.
Closes#18770Closes#12003
This PR adds a new policy definition to the ADMX templates for settings
the default Terminal application in Windows.
> [!Note]
> This PR does not change any code of Windows, Console Host or Windows
Terminal. It only adds the definition for a new policy to the templates.
I got the registry values form the documentation and by testing the
values.
The policy is only available as user policy because the registry values
have to be in HKCU.
The Policy is implemented as preference (not inside the Policy key) and
therefore keeps it's value on removing (not configured) it. You can see
this in `gpedit.msc` on the policy symbol and the hint in the
description.
Closes#18302
Refs #18303
We can't do the `pos.x != 0` check. Instead, I replaced it with
a CR check to avoid redundant CRs during CRLF translation.
Closes#18735
## Validation Steps Performed
* Run the repro in the linked issue
Use DECSC/DECRC and XTPUSHSGR/XTPOPSGR while redrawing
popups, since they're drawn using the current popup colors.
I wish we could just use the reverse video rendition...
Closes#18742
## Validation Steps Performed
* Run `color 3f` and then press F7
* Works fine in conhost (VtPipeTerm) ✅
* Works as expected (black background) in VS Code ✅
Add additional information to 2 error scenarios when launching a
different profile in the `ConptyConnection.cpp` file.
- Requires Elevation
- File Not Found
Created a profile that required elevation and verified the error
message. Created profile that passed a made up command and verified the
error message.
Closes#7186
When we overwrite the attributes during the fill,
we must retain the lead/trail byte attributes.
Closes#18746
## Validation Steps Performed
* Added a unit test ✅
## Summary of the Pull Request
Support drag-n-drop path translation in the style used by MinGW
programs. In particular for usage with shells like `ash` from busybox
(https://frippery.org/busybox/).
## Detailed Description of the Pull Request / Additional comments
Provides a new option "mingw" for "pathTranslationStyle".
Shown as "MinGW" with translation documented as `(C:\ -> C:/)` in the
UI.
As per the other modes, this translates `\` to `/` but stops there.
There is no prefix/drive translation.
## Validation Steps Performed
Run using `busybox ash` shell. Dragged directories and files from both
local disks and network shares onto terminal. All were appropriately
single quoted and had their backslashes replaced with forward slashes.
They were directly usable by the `ash` shell.
Language files containing the other options have been updated to include
the new one.
## PR Checklist
- [ ] Closes #xxx
- [ ] Tests added/passed
- [x] Documentation updated
- [Docs PR #849](https://github.com/MicrosoftDocs/terminal/pull/849)
- [ ] Schema updated (if necessary)
Co-authored-by: Adam Butcher <adam@jessamine.uk>
This pull request adds support for resetting the various color table
entries and xterm resource values back to their defaults.
Building on the default color table James introduced in #17879, it was
relatively straightforward to add support for resetting specific
entries.
This implementation cleaves tightly to observed behavior in xterm(379)
rather than observed behavior in libvte(0.70.6). They differ in the
following ways:
- xterm rejects any OSC [110..119] with any number of parameters; libvte
accepts it but only resets the first color.
- When passed a list of color indices to reset in 104, xterm resets any
colors up until the first one which fails to parse as an integer and
does _not_ reset the rest; libvte resets all parseable color indices.
I was unable to verify how these reset commands interact with colors set
via `DECAC Assign Color` so I went with the implementation that made the
most sense:
- Resetting the background color with `110` also restores the background
color alias entry to its pre-`DECAC` value; this results in the
perceived background color returning to e.g. index 0 in conhost and the
`background` color in Terminal.
- _ibid._ for the foreground color
Refs #18695
Refs #17879Closes#3719
This required removing connections during the build to `nuget.org` and
`powershellgallery.com`.
The NuGet Tool task was downloading nuget from `nuget.org`
unconditionally.
The `AzureFileCopy` task was downloading `Az.Accounts` from
`powershellgallery.com` unconditionally.
Both of these tasks have better options nowadays.
Tested and passed in OneBranch on 2025-04-01.
This pull request brings us up to fmt 11.1.4 and enables `FMT_PEDANTIC`.
`FMT_PEDANTIC` turns on `/W3`, which is required by our local feudal
lords who will automatically file bugs on us if we don't build with
enough warnings enabled.
PR adds a WinGet configuration file to install the necessary
dependencies in order to build terminal locally. The configuration file
enables developer mode, installs PowerShell 7, Visual Studio 2022 & all
the required workloads from the .vsconfig file (in accordance with
the dependencies listed in the README).
## Validation Steps Performed
Tested the configuration file by spinning up a clean Win11 Pro VM in
azure and then doing the following:
1. Install latest WinGet on the VM using WinGet sandbox script.
Install git and clone the repo
2. Run `winget configure .config/configuration.winget` (this should work
by just double-clicking the file in explorer too)
3. After the configuration is completed, open the solution in the now
installed Visual Studio and build. The build is successful and I could
start terminal with F5
Co-authored-by: Demitrius Nelon <denelon@microsoft.com>
After taking in 1.22, our CodeQL process caught a few locations where we
weren't following the right guidance:
- Performing integer comparisons of different sizes which could lead to
an infinite loop if the larger integer goes out of range of the smaller
integer
- Not checking HResult of a called method
Co-authored-by: aphistra <102989060+aphistra@users.noreply.github.com>
Allow users to preview color schemes by hovering over them with the
mouse pointer in the Command Palette.
- This PR handles issue #18238.
- This extends the previously closed issue #6689, which allowed the `UP`
and `DOWN` arrows to trigger a preview of color schemes in the Command
Palette.
This works by attaching event handlers for `PointerEntered` and
`PointerExited` to `ListViewItem` containers. When the mouse pointer
moves into the item's bounding area, the `PreviewAction` handler is
triggered to showcase the hovered color scheme. Conversely, when the
mouse pointer leaves the item's area, the `PreviewAction` is executed on
the selected item (generally from the `UP` and `DOWN` arrows).
**Important note:**
- This also provides previews for the other features that the
`ActionPreviewHandler` handles, such as the background opacity of the
terminal.
## Validation Steps Performed
- Hover a color scheme, and it becomes the active one.
- Pressing `ESC` at any point to dismiss the command palette, and the
scheme returns to the previous one.
- I did not add any additional test, though all existing ColorScheme
tests passed.
Closes#18238
I found multiple issues while investigating this:
* Render thread shutdown is racy, because it doesn't actually stop the
render thread.
* Lifetime management in `ControlCore` failed to account for the
circular dependency of render thread --> renderer --> render data -->
terminal --> renderer --> render thread. Fixed by reordering the
`ControlCore` members to ensure their correct destruction.
* Ensured that the connection setter calls close on the previous
connection.
(Hopefully) Closes#18598
## Validation Steps Performed
* Can't repro the original failure ❌
* Opening and closing tabs as fast as possible doesn't crash anymore ✅
* Detaching and reattaching a tab producing continuous output ✅
It turns out that we *can* support language overrides--fairly easily, in
fact!--by simply changing the default Language qualifier.
I elected not to change how packaged language override works until we
are certain this works properly everywhere. Consider it a healthy
distrust of the Windows App Platform.
Closes#18419Closes#18336Closes#17619
Since `WaitForDA1` would wait until `_deviceAttributes` is non-zero,
we must ensure it's actually non-zero at the end of this handler,
even if there are no parameters.
## Validation Steps Performed
* Mod the Terminal DA1 to be `\x1b[?6c`. No hang ✅
* Mod the Terminal DA1 to be `\x1b[?61c`. No hang ✅
I've received a dump from an affected user, and it showed that the
layout event in TerminalPage was raised synchronously. This meant that
during page initialization, the handoff listener was started while still
being stuck inside the handoff listener. This resulted in a deadlock.
This PR fixes the issue by not holding the lock across handoff callback
calls.
Closes#18634
## Validation Steps Performed
* Can't repro ❌
This can be considered "part 1" of fixing #18599: It prevents crashes
(due to unhandled exceptions) by ensuring we only create 1 content
dialog across all windows at a time. Sounds bad, but I tried it and it's
not actually _that_ bad in practice (it's still really gross though).
The bad news is that I don't have a "part 2", because I can't figure out
what's going on:
* Create 2 windows
* Open the About dialog in window 1
and right click the text
* Close the About dialog
* Open the About dialog in window 2
and right click the text
* WinUI will simply toss the focus to window 1
It appears as if context menus are permanently associated with the first
window that uses them. It has nothing to do with whether a ContentDialog
instance is reused (I tested that).
## Validation Steps Performed
* Open 2 windows with 2 tabs each
* Attempt to close window 1, dialog appears ✅
* Attempt to close window 2, dialog moves to window 2 ✅
The logic didn't work when persistence was enabled and you had 2 windows
and closed the 2nd one, or when dragging the last tab out of the only
window.
## Validation Steps Performed
* 2 windows, close the 2nd one, app doesn't exit ✅
* 1 window, 1 tab, drag the tab out of the window, app doesn't exit ✅
I don't actually know why this is happening, because it doesn't
happen with startup actions specified in the settings file.
In any case, it's fixed with more delays.
Closes#18572
## Validation Steps Performed
* Create a tab with 2 panes
* Tear it off into a new window
* New window has 1 tab with 2 panes ✅
Missed a few `_getTerminalPosition()` on the first run. Disabled
rounding for pointer movements and mouse wheel events (which are used
for hyperlink hover detection and vt mouse mode). The only time we round
now is...
- `SetEndSelectionPoint()` --> because we're updating a selection
- `ControlCore->LeftClickOnTerminal()` --> where all paths are used for
selection*
*the only path that doesn't is `RepositionCursorWithMouse` being
enabled, which also makes sense based on clicking around Notepad with a
large font size.
## References and Relevant Issues
Follow-up for #18486Closes#18595
## Validation Steps Performed
In large font size, play around with midnight commander and hover over
hyperlink edges.
* `_ApplyLanguageSettingChange` calls `PrimaryLanguageOverride`
(the WinRT API function) and we would call it every time a new
window is created. Now it's only called on settings load.
* `_RegisterTabEvents` would listen for "Content" changes which can
be null. `IVector::Append` throws if a null object is given.
In our case, it's null if the content got erased with nothing.
Additionally, this fixes a bug where we wouldn't call
`_ProcessLazySettingsChanges` on startup. This is important if the
settings file was changed while Windows Terminal wasn't running.
Lastly, there's a lifetime fix in this PR, which is a one-line change
and I didn't want to make a separate PR for that.
When the server handle gets closed on conhost (= terminal is gone),
and e.g. PowerShell is used, we would previously log 6 error messages.
This PR reduces it to zero, by removing the 3 biggest offenders.
## Summary of the Pull Request
There's already logic to tab to a hyperlink when we're in mark mode. We
do this by looking at the automatically detected hyperlinks and finding
the next one of interest. This adds an extra step afterwards to find any
embedded hyperlinks and tab to them too.
Since embedded hyperlinks are stored as text attributes, we need to
iterate through the buffer to find the hyperlink and it's buffer
boundaries. This PR tries to reduce the workload of that by first
finding the automatically detected hyperlinks (since that's a fairly
quick process), then using the reduced search area to find the embedded
hyperlink (if one exists).
## Validation Steps Performed
In PowerShell, add an embedded hyperlink as such:
```powershell
${ESC}=[char]27
Write-Host "${ESC}]8;;https://github.com/microsoft/terminal${ESC}\This is a link!${ESC}]8;;${ESC}\"
```
Enter mark mode (ctrl+shift+m) then shift+tab to it.
✅ The "This is a link!" is selected
✅ Verified that this works when searching forwards and backwards
Closes#18310Closes#15194
Follow-up from #13405
OSC 8 support added in #7251
WinUI asynchronously updates its tab view items, so it may happen that
we're given a `TabViewItem` that still contains a `TabBase` which has
actually already been removed. Regressed in #15924.
Closes#18581
## Validation Steps Performed
* Close tabs rapidly with middle click
* No crash ✅
This is a theoretical fix for #18584 as I cannot reproduce the issue
anymore. It did happen briefly on one of my devices though, and at the
time I observed that it would persist a window with no startup actions.
Found this one completely randomly.
## Validation Steps Performed
* Open 2 windows with 1 tab each
* Click the X button on the tab in the 1st window
* OpenConsole/etc. is cleaned up ✅
---------
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
During startup we relinquish ownership of the console lock to wait for
the DA1 response of the hosting terminal. The problem occurs if the
hosting terminal disconnects during that time. The broken pipe will
cause `VtIo` to send out `CTRL_CLOSE_EVENT` messages, but those won't
achieve anything, because the first and only client hasn't even finished
connecting yet. What we need to do instead is to return an error code.
In order to not use a bunch of booleans to control this behavior, I gave
`VtIo` a state enum. This however required restructuring the calling
code in order to not have a dozen states.
## Validation Steps Performed
* Launch cmd.exe with ConPTY
* ...but leave the stdin pipe unbound (which will hang the DA1 request)
* Immediately kill the ConPTY session
* cmd.exe exits after clicking away the error message ✅
Before we had a Settings UI, we added support for a setting called
`startOnUserLogin`. It was a boolean, and on startup we would try to
yeet the value of that setting into the Windows API responsible for
registering us as a startup task.
Unfortunately, we failed to take into account a few things.
- Startup tasks can be independently controlled by the user in Windows
Settings or by an enterprise using enterprise policy
- This control is not limited to *disabling* the task; it also supports
enabling it!
Users could enable our startup task outside the settings file and we
would never know it. We would load up, see that `startOnUserLogin` was
`false`, and go disable the task again. 🤦
Conversely, if the user disables our task outside the app _we can never
enable it from inside the app._ If an enterprise has configured it
either direction, we can't change it either.
The best way forward is to remove it from our settings model and only
ever interact with the Windows API.
This pull request replaces `startOnUserLogin` with a rich settings
experience that will reflect the current and final state of the task as
configured through Windows. Terminal will enable it if it can and
display a message if it can't.
My first attempt at this PR (which you can read in the commit history)
made us try harder to sync the state between the settings model and the
OS; we would propagate the disabled state back to the user setting when
the task was disabled in the OS or if we failed to enable it when the
user asked for it. That was fragile and didn't support reporting the
state in the settings UI, and it seems like it would be confusing for a
setting to silently turn itself back off anyway...
Closes#12564