Compare commits

..

138 Commits

Author SHA1 Message Date
Dustin L. Howett
9d9db8bdcc Fix backport in 2df8845d9 2025-11-24 13:30:54 -06:00
Leonard Hecker
2df8845d99 Fix a WPF<>TSF crash by avoiding TF_TMAE_CONSOLE (#19584)
As explained in detail in the diff.

Closes #19562

(cherry picked from commit 1ca0c76bc7)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzghp8j8
Service-Version: 1.22
2025-11-24 12:40:44 -06:00
PankajBhojwani
94f4eb315f Only do "keys" fixups for non-nested, non-iterable commands (#19408)
## Summary of the Pull Request
When we introduced action IDs, we separated "commands" from
"keybindings", and introduced fixup logic to rewrite the legacy-style
command blocks into the new version. However we don't do any ID logic
for nested and iterable commands, so make sure we don't inform the
loader for fixups in those cases.

## Validation Steps Performed
We no longer repeatedly attempt to fixup the settings file when we see a
`"keys"` entry in a nested/iterable command block

## PR Checklist
- [x] Closes #18736

(cherry picked from commit 04676bd31a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgfjxUQ
Service-Version: 1.22
2025-11-24 12:40:30 -06:00
Dustin L. Howett
c3e97dd39e build: remove the forced vpack submission; let us do it on our own time (#19271)
(cherry picked from commit 4f391c5e42)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgd_3-Q
Service-Version: 1.22
2025-11-24 12:40:29 -06:00
Carlos Zamora
cbffa59756 Fix names and types of a few telemetry events (#19257)
Fixes a few issues with some telemetry events:
- The macro is organized as such: `TraceLoggingX(value, argName,
[argDescription])`. A few args had a description set on the spot where
the name should be. I added a name for a few of these.
- `TraceLoggingBool` --> `TraceLoggingInt32` for `themeChoice` (we
shouldn't be casting the evaluated int as a bool; it loses some of the
data we care about)
- improves the description for `themeChoice` to include information
about the legacy values

Checked through all our telemetry events and all of the args have a
proper name set. We tend to use `TraceLoggingValue` too which
automatically figures out the type that's being used, so that's also
handled.

(cherry picked from commit 7055b99acc)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgdzQco
Service-Version: 1.22
2025-11-24 12:40:23 -06:00
Dustin L. Howett
81b763a4ee Switch to the @Local view on TerminalDependencies (#19243)
Due to an unexpected decision on behalf of the Azure Artifacts folks,
the default view for a feed with upstream sources reports all packages,
even if they are not actually populated into the feed.

This results in (uncontrolled) 401 errors whenever a new package appears
upstream, because the feed tells our users and our build system that it
is available, but fails when the download actually begins because it is
not allowed to "write" the upstream version to the feed.

(cherry picked from commit abaa9488d9)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgdnCV0
Service-Version: 1.22
2025-11-24 12:40:22 -06:00
Leonard Hecker
f259e20c53 Fix a output marks performance regression (#19242)
An alternative approach for #18291. Improves perf by ~7%.

(cherry picked from commit 6b19d21845)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgdm49Y
Service-Version: 1.22
2025-11-24 12:39:58 -06:00
Dustin L. Howett
22af7736bb Fix hot reload for icon, bell, close on exit; regressed in #16172 (#19217)
In #16172, we removed the propagation of the profile down into the
Terminal Pane Content.

It was holding on to the profile from the _old_ settings model (😱).

This also broke background image hot reload.

(cherry picked from commit 666a75bc70)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgdVVHE
Service-Version: 1.22
2025-11-24 12:39:56 -06:00
Leonard Hecker
40c6ff49bb Fix use-after-free when disabling the ASB (#19186)
Closes #17515

## Validation Steps Performed
* Disable the ASB while there's a pending cooked read
* Type some text
* No crash 

(cherry picked from commit dfcc8f3c62)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgdFoBQ
Service-Version: 1.22
2025-08-01 17:48:03 -05:00
Dustin L. Howett
62445ae3d0 Fix backport of 0512af571 2025-07-29 19:56:32 -05:00
Carlos Zamora
cf76a95eaf Add telemetry for new tab menu traffic (#19142)
## Summary of the Pull Request
Adds new telemetry events to track traffic through the new tab menu.
Specifically, the following events are added:
- `NewTabMenuDefaultButtonClicked`: Event emitted when the default
button from the new tab split button is invoked
- `NewTabMenuOpened`: Event emitted when the new tab menu is opened
- `NewTabMenuClosed`: Event emitted when the new tab menu is closed
- `NewTabMenuItemClicked`: Event emitted when an item from the new tab
menu is invoked
- Has an `ItemType` parameter that can be set to `Settings`,
`CommandPalette`, `About, `Profile`, `Action`
- Has a `TabCount` parameter that keeps tracked of the number of tabs in
the window before changing the state
- `NewTabMenuCreatedNewTerminalSession`: Event emitted when a new
terminal was created via the new tab menu
- Has a `SessionType` parameter that can be set to `ElevatedWindow`,
`Window`, `Pane`, `Tab`
- Instead of `TabCount`, has a `NewTabCount` that keeps track of the
_new_ number of tabs after the session has been created
- `NewTabMenuItemElevateSubmenuItemClicked`: Event emitted when the
elevate submenu item from the new tab menu is invoked

## Validation Steps Performed
Used TVPP to see events generated from interacting with the new tab
menu.

(cherry picked from commit 8c20d2052d)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgc0Dww
Service-Version: 1.22
2025-07-29 12:54:03 -05:00
Dustin L. Howett
d626c07bca Re-enable web-source icons in Stable and Preview builds (#19137)
Disables a controversial part of #19044.

Refs #19075

(cherry picked from commit 7b841628df)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgcqq7E
Service-Version: 1.22
2025-07-29 12:54:01 -05:00
Leonard Hecker
da0571497a Improve TSF color filtering logic (re: QQPinyin) (#19117)
If an IME provider sets both `crText` and `crBk` we should respect this,
but the previous logic would incorrectly assert for `crLine !=
TF_CT_NONE`.

## Validation Steps Performed
 I'm not aware which TSF even sets these colors in a
way that's compatible with us in the first place...

(cherry picked from commit f2b30b4e1e)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgck4T8
Service-Version: 1.22
2025-07-29 12:53:59 -05:00
Dustin L. Howett
e4eb33873a version: fix the LCID in our VERSIONINFO, add descriptions to each file (#19114)
Closes #19106

(cherry picked from commit f14718f738)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgcbOIs
Service-Version: 1.22
2025-07-29 12:53:58 -05:00
Dustin L. Howett
e1a1b805c6 During session save, use the profile's GUID rather than its Name (#19113)
This will prevent Terminal from erroneously selecting a hidden (deleted,
disabled or otherwise) profile of the same name during restoration and
subsequently using the wrong settings.

I am not certain why we used the name at all!

Closes #19105

(cherry picked from commit c4fbb58f69)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgcbMe4
Service-Version: 1.22
2025-07-29 12:53:43 -05:00
Leonard Hecker
0512af571b Fix another VT input double-encoding issue (#19083)
Closes #17264
Closes https://github.com/microsoft/edit/issues/182

Long shot, but probably also...
Closes #18579
Closes #19082

(cherry picked from commit 97f0a06fbe)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWZBNU
Service-Version: 1.22
2025-07-29 12:53:41 -05:00
Leonard Hecker
fcc75d9862 Preserve the cursor row during Clear Buffer (#18976)
Introduces an ABI change to the ConptyClearPseudoConsole signal.
Otherwise, we have to make it so that the API call always retains
the row the cursor is on, but I feel like that makes it worse.

Closes #18732
Closes #18878

* Launch `ConsoleMonitor.exe`
* Create some text above & below the cursor in PowerShell
* Clear Buffer
* Buffer is cleared except for the cursor row 
* ...same in ConPTY 

(cherry picked from commit fc0a06c3b6)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzga5M7I
Service-Version: 1.22
2025-07-29 12:50:41 -05:00
Carlos Zamora
8feed98edf Fix crash when closing multiple panes simultaneously (#19023)
Fixes a crash when multiple panes were closed simultaneously (i.e. using
broadcast input).

The root cause of this crash was that we would get a null pointer
exception when trying to access a member/function off of a null
`_content`. This is because `Pane::_CloseChild()` would always pass over
the content from the non-closed pane and attempt to hook everything up
to it.

The fix was to operate similarly to `Pane::Close()` and raise a `Closed`
event and return early. Since there's no alternative content to attach
to, might as well just close the entire pane. This propagates up the
stack of listeners to update the UI appropriately and close the parent
pane and eventually the entire tab, if necessary.
 
Closes #18071
Closes #17432

## Validation Steps Performed
1. Open 2 panes
2. Use broadcast input to send "exit" to both panes
3.  Terminal doesn't crash and the tab closes gracefully

(cherry picked from commit 6bf315a4c9)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgb3LNo
Service-Version: 1.22
2025-07-29 12:48:27 -05:00
Dustin L. Howett
7394807212 Revert "Add branding and unpackaged metadata to a few telemetry events (#18926)"
This reverts commit e21b2c6643.
2025-06-24 17:17:27 -05:00
Dustin L. Howett
54a7f2fd63 Port the context menu positioning logic from 8bbf00e 2025-06-24 17:04:53 -05:00
Dustin L. Howett
ede606b837 Try to get the client name during DefTerm handoff (#19014)
(cherry picked from commit cf95460a26)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbO1vA
Service-Version: 1.22
2025-06-24 16:46:42 -05:00
Carlos Zamora
92daa011bd Display a warning if SUI is unable to write to the settings file (#19027)
Adds logic to display a warning popup if the settings.json is marked as
read-only and we try to write to the settings.json file. Previously,
this scenario would crash, which definitely isn't right. However, a
simple fix of "not-crashing" wouldn't feel right either.

This leverages the existing infrastructure to display a warning dialog
when we failed to write to the settings file. The main annoyance here is
that that popup dialog is located in `TerminalWindow` and is normally
triggered from a failed `SettingsLoadEventArgs`. To get around this,
`CascadiaSettings::WriteSettingsToDisk()` now returns a boolean to
signal if the write was successful; whereas if it fails, a warning is
added to the settings object. If we fail to write to disk, the function
will return false and we'll raise an event with the settings' warnings
to `TerminalPage` which passes it along to `TerminalWindow`.

Additionally, this uses `IVectorView<SettingsLoadWarnings>` as opposed
to `IVector<SettingsLoadWarnings>` throughout the relevant code. It's
more correct as the list of warnings shouldn't be mutable and the
warnings from the `CascadiaSettings` object are retrieved in that
format.

-  Using SUI, save settings when the settings.json is set to read-only

Closes #18913

(cherry picked from commit 218c9fbe3e)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgb3QSg
Service-Version: 1.22
2025-06-24 16:46:41 -05:00
Carlos Zamora
e21b2c6643 Add branding and unpackaged metadata to a few telemetry events (#18926)
Adds branding and distribution metadata to the following telemetry
events:
- ActionDispatched (branding only)
- JsonSettingsChanged
- UISettingsChanged
- SessionBecameInteractive

Also removes the settings logger output from the debugger and some
leftover debugging functions.
Adds a label to the XSettingsChanged settings value to make it easier to
read on the backend.

(cherry picked from commit b50eaa19e0)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgaj8x8
Service-Version: 1.22
2025-06-24 10:13:43 -05:00
James Holderness
32e69d7163 Indicate support for OSC 52 in the DA1 report (#19034)
Some applications that make use of the `OSC 52` clipboard sequence will
only do so if they can be certain that the terminal actually has that
functionality. Indicating our support for `OSC 52` in the `DA1` report
will give them an easy way to detect that.

`OSC 52` support was added to Windows Terminal in issue #5823, and to
ConHost in issue #18949.

Support for writing to the clipboard is indicated in the primary device
attributes report by the extension parameter `52`. This is obviously not
a standard DEC extension, but it's one that's been agreed upon by a
number of modern terminals. The extension is only reported when writing
to the clipboard is actually permitted (Windows Terminal has an option
to disable that).

I've updated the Device Attributes unit test to check that we're
reporting extension `52` when clipboard access is enabled, and not
reporting it when disabled.

- [x] Closes #19017
- [x] Tests added/passed

(cherry picked from commit 00ee88400a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbpe4k
Service-Version: 1.22
2025-06-24 10:07:28 -05:00
Dustin L. Howett
43f800d043 build: adjust for changes in the Az.Accounts module (#19020)
(cherry picked from commit 4cf492e36b)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbYQ_g
Service-Version: 1.22
2025-06-24 10:05:54 -05:00
Leonard Hecker
7c9841604d Fix support for the Tencent QQPinyin IME (#19046)
(cherry picked from commit b47fdfc7e6)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbjZ8E
Service-Version: 1.22
2025-06-17 15:05:09 -05:00
Dustin L. Howett
5dbae6b362 Gently rework icon and background image validation (#19044)
Right now, image validation accepts web-sourced icons (boo) and rejects
images whose paths begin with `\\?\`. In addition, it will warn the user
for things out of their control like images set by fragments.

This pull request adds a filesystem path validator (which accepts images
with fully-qualified paths and UNC paths), makes the URI validator
reject any web-origin URIs (only `file` and `ms-*` are allowable), and
suppresses warnings for any images that were not _directly_ set by the
user.

Since we want to avoid using fragment images that fail validation, we no
longer `Clear` each image property but rather set it to the blank or
fallback value.

This does **not** actually add support for images at absolute paths
beginning with `\\?\`. Such images are still rejected by `Image` and the
other XAML fixtures we use for images. It's better than a warning,
though.

Closes #18703
Closes #14143
Refs #18710
Refs #5204
Related to #18922 (http-origin icons will be blank everywhere and not
just the jump list ;))

(cherry picked from commit f28bb42979)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbjZlQ
Service-Version: 1.22
2025-06-17 15:04:49 -05:00
Carlos Zamora
fa8520e581 Manually focus panes after swapping them (#19024)
(cherry picked from commit bd7e3179ff)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbeR18
Service-Version: 1.22
2025-06-17 15:04:48 -05:00
Katherine Reynolds
65d3a281c2 Improve VS profile generation (#19025)
* Make PowerShell profile generation try to find `pwsh.exe` before
falling back to legacy powershell
* Make profiles generated on an `arm64` host work properly

## Validation Steps Performed

* Local build ran
* Verified the new `arm64` profile works
* Verified `pwsh.exe` is used if present
* Verified `powershell.exe` is used if `pwsh` is not present in path
* Verified we don't attempt to create `arm64` host cmd/pwsh profiles if
VS is not >= 17.4

(cherry picked from commit bb62ce9345)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbeRwk
Service-Version: 1.22
2025-06-17 15:04:47 -05:00
Dustin L. Howett
218e3e132f build: try even harder to find a working VC tools version (#18996)
I can't explain this, but VS 17.14 ships with VisualCpp.Tools.Core
version 14.44.35208 but the files say 14.44.35207.

(cherry picked from commit 9dbcf4b9dd)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbDfzQ
Service-Version: 1.22
2025-06-17 15:04:46 -05:00
Carlos Zamora
1752816f7f Fix some build errors from updated VS build agents (#18927)
Looks like there's a new VS version on the build agents. This just goes
through and fixes any issues they found.

There's still a COMPILER CRASH though.

(cherry picked from commit 2d64a3a4ab)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgakG1w
Service-Version: 1.22
2025-06-17 15:04:45 -05:00
Mitch Capper (they, them)
34c530c2a3 Fix Microsoft.Windows.Console.ConPTY package runtime identifiers #18387
win10-* is no longer a valid rid

https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/8.0/rid-graph

This package would fail to install the dependencies to the correct
location in .net 8 and later by default. win-x64 is a valid runtime id
in prior .net versions so I think this should be back compat.

Without this the package fails to do its job on newer builds unless `
<UseRidGraph>true</UseRidGraph>` and the user sets `win10-x64` as their
RID in their project file.

(cherry picked from commit c6e7f3244b)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgap6WE
Service-Version: 1.22
2025-06-17 15:03:43 -05:00
Dustin L. Howett
5e3a53cb2d wpf: force builtin glyphs (#18906)
They're much prettier, but some users may not be 100% happy.

(cherry picked from commit 696dac2c6a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgaWoFg
Service-Version: 1.22
2025-05-13 18:18:54 -05:00
Dustin L. Howett
fdd32278bc wpf: allow OSC 52 to write the clipboard (#18905)
We never hooked up this callback!

This allows a CLI application to emit text directly to the clipboard.

(cherry picked from commit c64a9d2a32)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgaWn6g
Service-Version: 1.22
2025-05-13 18:18:53 -05:00
Dustin L. Howett
8d5ebd5cff build: fix the tsa config yet again (#18901)
We ship the org chart, baby!

(cherry picked from commit f08321a0b2)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgaT5FY
Service-Version: 1.22
2025-05-13 11:56:58 -05:00
Carlos Zamora
c02376acaa [1.22] Fix teardown when 'allowHeadless' is enabled (#18869)
Fixes a bug where `Monarch::_peasants` would not be updated when the
last window was closed and `compatibility.allowHeadless` was enabled.

## Detailed Description of the Pull Request / Additional comments
The bug was originally caused by `Monarch::_peasants` still holding on
to a reference to itself in the list. Normally, a `Peasant` was removed
from the list via the `WindowManager::SignalClose()` (aka
`Monarch::SignalClose()`) function. However,
`AppHost::_CloseRequested()` would omit that call when the last window
was closing.

Normally, that makes sense. It's the last window, so let's call
`AppHost::_quit()` --> `WindowManager::QuitAll()` -->
`Monarch::QuitAll()`, where we just call `Peasant::Quit()` on all the
peasants and the monarch and we call it a day. Everything should be
cleaned up and if we need a new session, we'll create a new `Monarch`
anyways.

Problem is, when `compatibility.allowHeadless` is enabled, the
`WindowEmperor` doesn't actually close! We want the `WindowEmperor` to
stick around because that's the "headless" part we're allowing. See
`WindowEmperor::_decrementWindowCount()`:
bbd6427b08/src/cascadia/WindowsTerminal/WindowEmperor.cpp (L296-L308)

The fix here was to avoid the `QuitAll()` code path mentioned above if
`compatibility.allowHeadless` is enabled. Just treat this as a normal
teardown otherwise so that the `WindowEmperor` creates a new `Monarch`
when we need it.

## Validation Steps Performed
 The scenario from the bug works:
- enable `compatibility.allowHeadless`
- set `windowingBehavior` to `useExisting`
- Open Terminal
- Close the only open window
- Attempting to open Terminal again should open a new window
 when all windows are closed, we still have the background process

Closes #18827
2025-05-08 11:20:19 -07:00
Leonard Hecker
ea0ba567fd Fix a major stdin wakeup race condition (#18816)
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 #18117
Closes #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 

(cherry picked from commit 2992421761)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgUXwj0 PVTI_lADOAF3p4s4AmhmQzgZiUlw
Service-Version: 1.22
2025-05-07 12:17:24 -05:00
Leonard Hecker
66feae0eb0 Properly implement WaitForData for ReadConsoleInput (#18228)
There were two bugs:
* Ever since the conhost v1 -> v2 rewrite the `readDataDirect.cpp`
  implementation incorrectly passed `false` as the wait flag.
  The unintentional mistake is obvious in hindsight as the
  check for `CONSOLE_STATUS_WAIT` makes no sense in this case.
* The ConPTY integration into `InputBuffer` was done incorrectly,
  as it would unconditionally wake up the readers/waiters without
  checking if the buffer is now actually non-empty.

Closes #15859

## Validation Steps Performed
Test code:
```cpp
#include <Windows.h>
#include <stdio.h>

int main() {
    HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
    INPUT_RECORD buf[128];
    DWORD read;

    SetConsoleMode(
        in,
        ENABLE_PROCESSED_INPUT | ENABLE_VIRTUAL_TERMINAL_INPUT
    );

    for (int i = 0; ReadConsoleInputW(in, buf, 128, &read); ++i) {
        printf("%d read=%lu\n", i, read);
    }

    return 0;
}
```
Run it under Windows Terminal and type any input. >50% of all
inputs will result in `read=0`. This is fixed after this PR.

(cherry picked from commit 5c55144c28)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgaHLrQ
Service-Version: 1.22
2025-05-07 12:17:23 -05:00
Dustin L. Howett
6498aa6457 wpf: use the new TSF implementation (#18861)
This fixes two issues in the WPF terminal control:
- The emoji picker and other IME candidate windows didn't show up in the
right place
- Submitting an emoji via the emoji picker would result in two win32
input mode events with a VK of 65535 and the surrogate pair halves.

I am not sure I did the right thing with the thread TSF handle...

(cherry picked from commit 06f736bebe)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZ-Sw4
Service-Version: 1.22
2025-05-05 11:24:43 -05:00
James Holderness
111e10ade8 Fix SGR mouse movement reports (#18864)
According to the documentation, the final character of an SGR mouse
report is meant to be `M` for a button press and `m` for a button
release. However it isn't clear what the final character should be for
motion events, and we were using an `m` if there weren't any buttons
held down at the time, while all other terminals used an `M`, regardless
of the button state.

This PR updates our implementation to match what everyone else is doing,
since our interpretation of the spec was causing problems for some apps.

I've manually tested the new behavior in Vttest, and confirmed that our
mouse reports now match Xterm more closely, and I've tested with v0.42.0
of Zellij, which was previous glitching badly in Windows Terminal, but
now works correctly.

I've also updated our unit tests for the SGR mouse mode to reflect the
correct report format.

Closes #18712

(cherry picked from commit 865f5e5239)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZ9_E0
Service-Version: 1.22
2025-05-05 11:24:41 -05:00
James Holderness
a0d15b5e23 Fix two image erasure bugs (#18855)
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

(cherry picked from commit 08e76da3a1)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZ3XUA
Service-Version: 1.22
2025-05-05 11:21:43 -05:00
Dustin L. Howett
bbd6427b08 wpf: strong-name sign Microsoft.Terminal.Wpf (#18836)
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".

(cherry picked from commit 0568173aba)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZuEzY
Service-Version: 1.22
2025-04-29 15:58:09 -05:00
Dustin L. Howett
b08a414791 release-engineering: package (during build) and upload GPO templates (#18841)
I've been doing this manually. It is time for me to do it not-manually.

(cherry picked from commit 21f3179326)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZwVgk
Service-Version: 1.22
2025-04-28 13:17:49 -05:00
Dustin L. Howett
8fad47d9c7 build: run official builds with the R1 network isolation policy (#18753)
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.

(cherry picked from commit 22c509f426)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZ0dVU
Service-Version: 1.22
2025-04-28 13:17:47 -05:00
James Holderness
26875ff09f Improve quality of GDI image scaling (#18495)
When Sixel images are rendered, they're automatically scaled to match
the 10x20 cell size of the original hardware terminals. If this requires
the image to be scaled down, the default GDI stretching mode can produce
ugly visual artefacts, particularly for color images. This PR changes
the stretching mode to `COLORONCOLOR`, which looks considerably better,
but without impacting performance.

The initial Sixel implementation was added in PR #17421.

## Validation Steps Performed

I've tested with a number of different images using a small font size to
trigger the downscaling, and I think the results are generally better,
although simple black on white images are still better with the default
mode (i.e. `BLACKONWHITE`), which is understandable.

I've also checked the performance with a variation of the [sixel-bench]
test, and confirmed that the new mode is no worse than the default.

[sixel-bench]: https://github.com/jerch/sixel-bench

(cherry picked from commit b243fb6189)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZ0dHI
Service-Version: 1.22
2025-04-28 13:17:46 -05:00
Dustin L. Howett
6ffde34897 ServicingPipeline: make a bunch of quality of life improvements (#18830)
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.

(cherry picked from commit 8e94983170)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZtprA
Service-Version: 1.22
2025-04-24 13:26:12 -05:00
Leonard Hecker
d43bc22997 Fix til string to integer routines (#18276)
(cherry picked from commit 89bc36c021)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZtkWk
Service-Version: 1.22
2025-04-24 12:39:06 -05:00
Leonard Hecker
fa65a29bcc New tokenization & integer parsing helpers (#17962)
Reading through our existing patterns for integer parsing, I noticed
that we'd be better off returning them as optionals.
This also allowed me to improve the implementation to support integers
all the way up to their absolute maximum/minimum.

Furthermore, I noticed that `prefix_split` was unsound:
If the last needle character was the last character in the remaining
text, the remaining text would be updated to an empty string view.
The caller would then have no idea if there's 1 more token left
or if the string is truly empty.
To solve this, this PR introduces an iterator class. This will allow
it to be used in our VT parser code.

(cherry picked from commit fa8273065f)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZtkTk
Service-Version: 1.22
2025-04-24 12:39:04 -05:00
Carlos Zamora
0892689fbb [SUI] Improve accessibility to open json (#18828)
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.

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 #18770
Closes #12003

(cherry picked from commit a8a47b9367)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZrDt4
Service-Version: 1.22
2025-04-23 15:51:27 -05:00
Dustin L. Howett
246e1d5770 Add support for OSC 104, 110, 111, 112 and 117 (resets) (#18767)
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 #17879
Closes #3719

(cherry picked from commit 5f311506dc)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZOWsU
Service-Version: 1.22
2025-04-21 17:40:21 -05:00
Heiko
180a52e925 [Enterprise, GPO] Add "Default Terminal app" policy to definition template (#18363)
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

(cherry picked from commit 68d9e0d038)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZlw44
Service-Version: 1.22
2025-04-21 17:37:15 -05:00
Windows Console Service Bot
2b6f437671 Localization Updates - main - 04/16/2025 21:02:38 (#18807)
(cherry picked from commit 712ce5fa2f)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZlxKI
Service-Version: 1.22
2025-04-21 17:37:13 -05:00
Leonard Hecker
7d15e2d600 Backup and restore attributes during cooked reads (#18797)
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 

(cherry picked from commit 8b01f546cb)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZd3bw
Service-Version: 1.22
2025-04-21 17:36:20 -05:00
Dustin Hall
2977892e98 Add 2 additional error messages (#18462)
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

(cherry picked from commit f7e853cd9f)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZlxJc
Service-Version: 1.22
2025-04-21 17:36:19 -05:00
Leonard Hecker
2375c1b005 Fix CRLF translation when DISABLE_NEWLINE_AUTO_RETURN is reset (#18781)
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

(cherry picked from commit 354e05d713)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZRM3c
Service-Version: 1.22
2025-04-16 15:53:33 -05:00
Leonard Hecker
ed1ddd2aeb Fix wide char support for WriteConsoleOutputAttribute (#18796)
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 

(cherry picked from commit 90c312f7da)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZX2Dk
Service-Version: 1.22
2025-04-16 15:53:31 -05:00
Vamsi Krishna Kanjeevaram
747b3a4ffc Add a right margin to the suggestion description textblock (#18780)
This ensures that the vertical scrollbar will not cover the description text.
Closes #18545

(cherry picked from commit f83b98e100)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgZX-v8
Service-Version: 1.22
2025-04-16 15:53:30 -05:00
Vamsi Krishna Kanjeevaram
7b79b73ea4 Display local time instead of UTC while restoring previous session (#18775)
Closes #18727

(cherry picked from commit ad19d2c967)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYvbLY
Service-Version: 1.22
2025-04-16 15:53:28 -05:00
Dustin L. Howett
26eb5f84de vcpkg: add an overlay port for fmt 11.1.4; enable /W3 (#18729)
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.

(cherry picked from commit f34dbbf3ac)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYvOpA
Service-Version: 1.22
2025-03-26 17:37:53 -05:00
Windows Console Service Bot
39ffa65d7f Localization Updates - main - startOnUserLogin (#18609)
(cherry picked from commit 4bcdd7a844)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYvO2I
Service-Version: 1.22
2025-03-26 15:18:55 -05:00
Dustin L. Howett
572f804007 Remove startOnUserLogin from the settings; use OS APIs only (#18530)
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

(cherry picked from commit a46fac25d3)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYvOug
Service-Version: 1.22
2025-03-26 15:17:07 -05:00
Dustin L. Howett
72849610ad Add support for language override to unpackaged/portable builds (#18684)
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 #18419
Closes #18336
Closes #17619

(cherry picked from commit 7d8f7eb429)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYVTtg
Service-Version: 1.22
2025-03-25 13:13:59 -05:00
Dustin L. Howett
cb3fb42a63 Delay-load icu so that we don't fail to start up on Windows <1903 (#18707)
(cherry picked from commit 75d8fc29f5)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYi9uU
Service-Version: 1.22
2025-03-25 13:12:53 -05:00
aphistra
bd49b19c1a Remove unused MUXCustomBuildTasks package (#18683)
It has a Component Governance alert (and no license), plus we aren't using it.

(cherry picked from commit f023b3bfd2)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYf3c0
Service-Version: 1.22
2025-03-19 12:48:36 -05:00
Javier
dec00afc3b Multiple fixes to address DD CodeQL requirements (#18451)
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>
(cherry picked from commit 6e89242373)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWmd4s
Service-Version: 1.22
2025-03-18 13:27:13 -05:00
Leonard Hecker
f465275bc5 Fix a shutdown race condition in ControlCore (#18632)
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 

(cherry picked from commit 70f85a4a35)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgXhFbo
Service-Version: 1.22
2025-03-18 13:27:10 -05:00
Leonard Hecker
ccdfd4d0e5 Fix a ConPTY startup hang with 0-param DA1 responses (#18681)
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 

(cherry picked from commit 32ae00f71a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYO0bA
Service-Version: 1.22
2025-03-12 18:29:58 -05:00
Leonard Hecker
a3d285000d Fix a handoff deadlock if layout completes synchronously (#18676)
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 

(cherry picked from commit 2693210ead)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgYLZvQ
Service-Version: 1.22
2025-03-12 18:29:33 -05:00
Leonard Hecker
cb29bed3d6 ConPTY: Fix shutdown if killed during startup (#18588)
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 

(cherry picked from commit 733a5e7bec)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgXjzIk
Service-Version: 1.22
2025-02-26 13:07:40 -06:00
Windows Console Service Bot
990da6cad0 Localization Updates - main - 02/13/2025 03:05:04 (#18569)
(cherry picked from commit 13e7c9314d)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgXeZ1M
Service-Version: 1.22
2025-02-26 13:07:39 -06:00
Leonard Hecker
18d7231ef2 Add Oklab based color scheme "Ottosson" (#18502)
Campbell has been the default color scheme for a long time now,
but it has quite some issues with hue and chroma.

This PR introduces a new scheme which was created using the Oklab
color space to find colors with maximal distance to each other
and well distributed and consistent hue and chroma.
Because of this, I've named the scheme after the creator of Oklab.
 
Closes #17818

(cherry picked from commit e60acbc12a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgW-IDA
Service-Version: 1.22
2025-02-03 17:12:52 -06:00
Éléa Dufresne
1951f93ad4 Fix Ctrl+Insert does not copy the selected text from Command Palette (#18483)
Fixes an issue where pressing `CTRL` + `Insert` does not copy text
selected in the Command Palette. Instead, it closes it, and any text
selected in the pane is copied to the clipboard.

Since `Insert` is a virtual key, I address the issue by adding a
conditional check for `CTRL` with either `Insert` or `C` (previously, it
only checked for `CTRL` with `C`) for the copy action in the Command
Palette.

## Validation Steps Performed

I followed the reproduction steps and verified that the actual behaviour
matched the expected behaviour. All existing tests passed, but no new
test was added.

Closes #9520

(cherry picked from commit 2e92a15464)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgW9xcY
Service-Version: 1.22
2025-02-03 15:21:13 -06:00
Dustin L. Howett
14a7cf3ad3 Update Cascadia Code to 2407.24 (#18499)
This update fixes a hinting issue in Arabic glyphs.

See microsoft/cascadia-code#746 for more details.

(cherry picked from commit bf074f3e40)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgW99S0
Service-Version: 1.22
2025-02-03 15:21:12 -06:00
Tsukasa OI
f9e962c298 Escape single quotes while translating dropped Win32 paths (#18007)
When file/folder is dropped to the terminal, its path is translated and
quoted with a pair of single quotes if necessary.

However, the terminal control does not escape single quotes (allowed in
the Win32 subsystem) that need escapes when translated.

On the translation styles other than `"none"` (note: all other
translation styles are currently intended for the POSIX shell), it
causes incorrect path to be pasted when the path contains one or more
single quotes (see #18006 for an example).

With this commit, the terminal control escapes a single quote with a
valid escape sequence `'\''` (finish quote, print a single quote then
begin quote again) when the path translation is required.

* Changed escape sequence from `'"'"'` to much shorter `'\''`.
* Reflected comments by the reviewer.

* Overhaul after addition of multiple path translation styles (not just
WSL but Cygwin and MSYS).
* More clarification both in the code and in the commit message.

* Minor clarification both in the code and in the commit message.

* #18006
* #16214
* #18195

This is a follow-up of #16214 and #18195, fixing #18006.

Closes #18006

Supersedes 7878728752

(cherry picked from commit ae90d52bb1)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVEvdU
Service-Version: 1.22
2025-02-03 13:08:47 -06:00
Windows Console Service Bot
3af8a05697 Localization Updates - main - Orphaned and Path Translation (#18208)
(cherry picked from commit 84d6b0fba0)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgW9l4E
Service-Version: 1.22
2025-02-03 13:08:47 -06:00
Dustin L. Howett
9a262e947c Add a new (advanced) profile setting, pathTranslationStyle (#18195)
`pathTranslationStyle` has four options:

- `none`: Do no translation
- `wsl`: Translate `C:\` to `/mnt/c` and `\\wsl$\Foo\bar` to `/bar`
- `cygwin`: Translate `C:\` to `/cygdrive/c`
- `msys2`: Translate `C:\` to `/c`

It is intended as a broadly-supported replacement for us checking the
source every time the user drops a path.

We no longer need to push the source name all the way down to the
control.

I am hesitant to commit to using other folks' product names in our
settings model,
however, these are almost certainly more recognizable than whatever
other weird
names we could come up with.

The Git Bash fragment extension profile could conceivably use
`pathTranslationStyle`
`msys2` to make sure drag/dropped paths look right.

(cherry picked from commit 068906714f)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgW9l6A
Service-Version: 1.22
2025-02-03 13:08:47 -06:00
Windows Console Service Bot
1b5381b37f OSC 52 Localization Updates - main - 01/24/2025 03:05:35 (#18456)
(cherry picked from commit d6b56ae818)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgW9i6c
Service-Version: 1.22
2025-02-03 13:08:47 -06:00
Dustin L. Howett
db7a50a80b Let folks disable OSC 52 (#18449)
This pull request introduces a new profile setting,
`compatibility.allowOSC52`, which defaults to `true`. When disabled, it
will not allow applications to write to the clipboard.

Security-minded folks may choose to disable it.

(cherry picked from commit 33556fb631)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWpodA
Service-Version: 1.22
2025-02-03 13:08:46 -06:00
Carlos Zamora
6debbc3d13 Add a Compatibility and Terminal page to the Settings UI (#17895)
Adds a global Compatibility page to the settings UI. This page exposes
several existing settings and introduces a few new settings:
- compatibility.allowHeadless
- compatibility.isolatedMode
- compatibility.textMeasurement
- debugFeatures

This also adds a Terminal subpage for profiles in the settings UI. This
page includes:
- suppressApplicationTitle
- compatibility.input.forceVT
- compatibility.allowDECRQCRA
- answerbackMessage

Several smaller changes were accomplished as a part of this PR:
- `experimental.input.forceVT` was renamed to
`compatibility.input.forceVT`
- introduced the `compatibility.allowDECRQCRA` setting
- updated the schema for these new settings and
`compatibility.allowHeadless` (which was missing)
- add `Feature_DebugModeUI` feature flag to control if debug features
should be shown in the SUI

Verified accessible via Accessibility Insights

A part of #10000
Closes #16672

(cherry picked from commit 18d86bca09)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgW9kBM
Service-Version: 1.22
2025-02-03 12:15:36 -06:00
Leonard Hecker
5148c0cf0d Add 10.0.26100.0 to MaxVersionTested (#18252)
As it turns out, you cannot use `<uap17:UpdateWhileInUse>`
(or any other newer namespace) unless you declare a corresponding
`MaxVersionTested` in your package manifest.
It does not appear that there's a reason for this, it just is.
`MaxVersionTested` is not to be confused with the `maxversiontested`,
which is something else entirely, but I updated it for safe measure.
Since `maxversiontested` is not a "max", but rather a list
of tested versions, it gets appended to the end of the list.

Closes #18119

(cherry picked from commit 32eeefd89e)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVXHVQ
Service-Version: 1.22
2025-02-03 11:55:32 -06:00
Leonard Hecker
a5dc395c03 Fix order and robustness of CTRL_*_EVENTs (#18233)
* This fixes a regression in 391abafc, which caused attached clients
  to receive CTRL_CLOSE_EVENTs, etc., in oldest-to-newest order,
  while historically the opposite is expected.
* It also changes the behavior of `ProcessCtrlEvents` to dispatch
  these events no matter whether a client is already dead.
  This restores the Windows XP to Windows 8.1 behavior.

Both of these fixes would address the issue on their own.

Closes #15373

## Validation Steps Performed
* CloseTest from our repository shows newest-to-oldest order again.
* node gets killed when run under npm and closing the tab.

(cherry picked from commit 09d8ac44ad)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVBZ1o
Service-Version: 1.22
2025-02-03 11:55:30 -06:00
Leonard Hecker
938b2190e5 Revert "Dedup command history by default (#17852)" (#18229)
This reverts commit 5fdfd51209,
because 3 people complained about this change VS 1 person
requesting the change to be made in the first place.

Closes #18138
Reopens #17797 for discussion

(cherry picked from commit 220c7cd92e)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgUeWb8
Service-Version: 1.22
2025-02-03 11:55:29 -06:00
Dustin L. Howett
e571e4fa22 build: change how we find the latest VC tools version (#18468)
Apparently, we were using the package containing the CRT _source code_
to determine the version of the tools.

Also apparently, VS does not guarantee that that package has the same
version as the tools package.

We should use the version of the tools package instead.

(cherry picked from commit 8e4da6e938)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWyLAQ
Service-Version: 1.22
2025-01-28 17:03:18 -06:00
Leonard Hecker
26f82608b3 Reduce likelihood of races between stdout and cooked stdin reads (#18326)
As explained in the comment on `_getViewportCursorPosition`, printing
to stdout after initiating a cooked stdin reads is a race condition
between the application and the terminal. But we can significantly
reduce the likelihood of this being obvious with this change.

Related to #18265
Possibly related to #18081

## Validation Steps Performed

Execute the following Go code and start typing:
```go
package main

import (
	"fmt"
	"time"
)

func main() {
	go func() {
		time.Sleep(50 * time.Millisecond)
		fmt.Printf("Here is a prompt! >")
	}()

	var text string
	fmt.Scanln(&text)
}
```

Without this change the prompt will disappear,
and with this change in place, it'll work as expected. 

(cherry picked from commit 1040035b55)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWppag
Service-Version: 1.22
2025-01-28 17:03:17 -06:00
Carlos Zamora
e435c1670f Fix 'closeWindow' ignoring confirmation (#18434)
Reroutes the `closeWindow` action to use the `CloseWindow()` method like
the window's X button does. This includes logic to display the
confirmation dialog.

Also removes `CloseRequested` as it was only used by this action
handler. We already have `CloseWindowRequested` so we're just using that
instead.

## Validation Steps Performed
 `closeWindow` action while multiple tabs opened brings up the
confirmation dialog

Closes #17613

(cherry picked from commit fb7b0e1218)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWkUeU
Service-Version: 1.22
2025-01-28 17:03:16 -06:00
Javier
91086f6706 propsheet: add a CodeQL supression comment (#18431)
CodeQL is raising errors when building Visual Studio since they have a
dependency on Windows Terminal for our integrated terminal. The issue
raised by CodeQL refers to a non-constant string format, but in this
case the string comes from a resource file and should be considered
constant.

(cherry picked from commit 25392ea604)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWYgYU
Service-Version: 1.22
2025-01-15 15:00:06 -06:00
Carlos Zamora
795077cb25 Fix tag for SessionBecameInteractive event (#18426)
Adds a description and keyword for the `SessionBecameInteractive` event

Follow-up from #17682

(cherry picked from commit 3772fc3fc5)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmszgWWlDk
Service-Version: 1.21
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWWlDg
Service-Version: 1.22
2025-01-14 20:06:27 -06:00
Dustin L. Howett
0e5fbad0f6 Teach ServicingPipeline to paginate project board items (#18328)
Oops, it didn't support more than 100 items!

(cherry picked from commit 3e6690290f)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWLtrU
Service-Version: 1.22
2025-01-08 15:41:19 -06:00
Dustin L. Howett
8ed73b1473 build: add a couple more signing variables to ESRP (#18411)
This is in support of some identity changes we need to make.

(cherry picked from commit a3a4464667)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWLo5Y
Service-Version: 1.22
2025-01-08 15:41:17 -06:00
Leonard Hecker
b4207403ea Reduce malloc churn for console calls <=128KiB (#18287)
This increases the console IO buffer size to retain at least 128KiB as
this matches the default buffer size of `cat`. This avoids allocator
churn due to constantly freeing and reallocating buffers. In the future
this should ideally use a better suited, cheap allocator.

Closes #18286

(cherry picked from commit aa5459df4a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgWLtjY
Service-Version: 1.22
2025-01-08 15:41:16 -06:00
Carlos Zamora
dc807db593 Add "Windows.Terminal.VisualStudio" to schema (#18322)
Closes #18037

(cherry picked from commit 8598ed78d5)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVq2uw
Service-Version: 1.22
2024-12-13 14:41:25 -06:00
Javier
f78bf09336 Add CodeQL suppression comment to propsheet (#18315)
CodeQL is raising errors when building Visual Studio since we have a
dependency on Windows Terminal for our integrated terminal. The issue
raised is not applicable to this case and therefore requires a
suppression comment to ignore the raised error.

(cherry picked from commit 19460f98e0)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVqzyA
Service-Version: 1.22
2024-12-13 14:38:15 -06:00
Leonard Hecker
a24d3a9ce4 Update settings schema for compatibility.textMeasurement (#18277)
It seems I forgot to add this in #16916.

(cherry picked from commit c0d40c9768)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVUrMM
Service-Version: 1.22
2024-12-13 14:38:14 -06:00
Leonard Hecker
6b8c04ad71 Fix infinite recursion in TSF (#18248)
The current `FindWindowOfActiveTSF` implementation can
result in infinite recursion which we must guard again.
This change is not tested as I don't know how to trigger
the issue to begin with (a missing CoreInput thread).

(cherry picked from commit 924310481a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVIDNA
Service-Version: 1.22
2024-11-26 13:21:48 -06:00
Tsukasa OI
7878728752 Escape single quotes while translating dropped Win32 paths (#18007)
When file/folder is dropped to the terminal, its path is translated and
quoted with a pair of single quotes if necessary.

However, the terminal control does not escape single quotes (allowed in
the Win32 subsystem) that need escapes when translated.

On the translation styles other than `"none"` (note: all other
translation styles are currently intended for the POSIX shell), it
causes incorrect path to be pasted when the path contains one or more
single quotes (see #18006 for an example).

With this commit, the terminal control escapes a single quote with a
valid escape sequence `'\''` (finish quote, print a single quote then
begin quote again) when the path translation is required.

* Changed escape sequence from `'"'"'` to much shorter `'\''`.
* Reflected comments by the reviewer.

* Overhaul after addition of multiple path translation styles (not just
WSL but Cygwin and MSYS).
* More clarification both in the code and in the commit message.

* Minor clarification both in the code and in the commit message.

* #18006
* #16214
* #18195

This is a follow-up of #16214 and #18195, fixing #18006.

Closes #18006

(cherry picked from commit ae90d52bb1)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVEvdU
Service-Version: 1.22
2024-11-25 14:57:44 -06:00
Dustin L. Howett
ede23a5a18 build: fix arm64 vcpkg triplet selection error (#18239)
microsoft/vcpkg-tool#1474 now validates that the target triplet is
valid. Unfortunately, `ARM64` is not valid... despite VS defaulting to
it.

VS 17.12 moved to the newer version of the vcpkg tool.

Given that we still want to build on VS 17.12, this commit adds a local
workaround.

See DD-2302065 for the internal tracking bug.
 
See microsoft/vcpkg#42182 for the upstream fix.

(cherry picked from commit 6047f37e84)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgVEH-w
Service-Version: 1.22
2024-11-25 14:54:02 -06:00
Windows Console Service Bot
03f050559c Localization Updates - main - 11/01/2024 03:05:38 (#18135)
(cherry picked from commit 52262b05fa)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgU6Zlw
Service-Version: 1.22
2024-11-18 16:02:35 -06:00
Leonard Hecker
819628a185 AtlasEngine: Better builtin glyphs (#18179)
This slightly modifies the builtin glyph width and corner radius to
more closely match Cascadia Mono. Previously, at low DPI (100% scale),
the corner radius was barely noticeable which looked kind of bad.

(cherry picked from commit a8e83c1c0f)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgU6YuY
Service-Version: 1.22
2024-11-18 16:00:45 -06:00
Carlos Zamora
ef0a6b76bd Add 'Move Tab' submenu to tab context menu (#18107)
## Summary of the Pull Request
Adds a "Move tab" submenu to the tab's context menu. This submenu includes "move tab to new window", "move left", and "move right".

The new "move left/right" items are disabled if the tab can't be moved in a certain direction.'

Closes #17900

(cherry picked from commit d8089e903e)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgU6Yu8
Service-Version: 1.22
2024-11-18 16:00:43 -06:00
Dustin L. Howett
2143ca1c92 [<= 1.22] Retain (BUT DON'T INDICATE) orphaned dynamic profiles (#18206)
The original intent with dynamic profiles was that they could be
uninstalled but that Terminal would remember your settings in case they
ever came back.

After we implemented dynamic profile _deletion_, however, we
accidentally made it so that saving your settings after a dynamic
profile disappeared scoured it from the planet _forever_ (since we
remembered that we generated it, but now it was no longer in the
settings file).

This pull request implements:

- Tracking for orphaned dynamic profiles

Closes #14061
Closes #11510
Refs #13916
Refs #9997

Modified for 1.22. I am not including any of the UI affordances.

(cherry picked from commit 90866c7c93)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgU1-p4
Service-Version: 1.22
2024-11-18 15:52:44 -06:00
Dustin L. Howett
e476dd2b9c [<= 1.22] Do path translation for multiple types of WSL (#18205)
In #18195, we introduced a real `pathTranslationStyle` setting.

I'm not backporting that whole thing.
2024-11-18 08:36:45 -08:00
Dustin L. Howett
b97f3c1cd7 wsl: skip distributions that indicate they are "Modern" (#18183)
(cherry picked from commit 00ff803ace)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgUu4sg
Service-Version: 1.22
2024-11-15 10:50:08 -06:00
Carlos Zamora
c1890c4a99 Fix High Contrast mode in Settings UI (#18130)
"HighContrast" is not a possible requested theme. So `_UpdateBackgroundForMica()` would force the settings UI to be light or dark. To fix this, we just check if we're in high contrast mode and, if so, we don't bother setting the requested theme.

(cherry picked from commit d04381ec05)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgUZ6Mc
Service-Version: 1.22
2024-11-15 10:50:05 -06:00
Carlos Zamora
5f614bc1a0 Fix High Contrast mode in Command Palette (#18132)
Turns out that having the styles for the KeyChordText and ParsedCommandLineText be empty for high contrast mode caused the issue. Since we're already using theme resources for the colors, we automatically adjust properly to whatever the high contrast theme is (Thanks XAML!).

Bonus points:
- we didn't need the theme dictionaries anymore, so I just moved them to the ResourceDictionary directly
- ParsedCommandLineTextBlockStyle isn't used. So I removed it altogether.

Validated command palette with multiple high contrast themes. See PR thread for demo.

Closes #17914

(cherry picked from commit e83434ff7e)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgUZ6Mo
Service-Version: 1.22
2024-11-15 10:50:02 -06:00
Windows Console Service Bot
0a9ed2bfda Localization Updates - 10/22/2024 03:06:53 (#18031)
Closes #17752

(cherry picked from commit b58aa26e7a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgUIJdU
Service-Version: 1.22
2024-11-15 10:49:56 -06:00
Leonard Hecker
3ace5785cd Add a policy for profile sources (#18009)
This adds a basic policy check for DisabledProfileSources, so that
organizations can easily disable certain profiles like the Azure one.

Closes #17964

## Validation Steps Performed
* Add a policy to disable Azure under HKCU. Disabled 
* Add a policy to disable nothing under HKLM. Enabled 
  (...because it overrides the HKCU setting.)

(cherry picked from commit 3a06826915)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgT6i0c
Service-Version: 1.22
2024-10-17 16:47:51 -05:00
Carlos Zamora
8fa98f62bc Fix hiding the icon when it's set to "none" (#18030)
The settings UI and settings model allow you to set the icon to "none"
to hide the icon (you can actually see this effect in the settings UI
when changing the value of the profile icon). However, during settings
validation, "none" is considered a file path, which is then failed to be
parsed, resulting in the icon being marked as invalid and immediately
clearing the value.

This PR fixes this issue by considering "none" to be an accepted value
during validation.

Related to #15843
Closes #17943

## Validation Steps Performed
When an icon is set to "none", ...
 no more warning
 the icon is hidden

(cherry picked from commit 36f064cfc8)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTyV8E
Service-Version: 1.22
2024-10-17 16:47:49 -05:00
Leonard Hecker
b947d1a8be Avoid focus loops in ConPTY (#17829)
This fixes a lot of subtle issues:
* Avoid emitting another de-/iconify VT sequence when
  we encounter a (de)iconify VT sequence during parsing.
* Avoid emitting a de-/iconify VT sequence when
  a focus event is received on the signal pipe.
* Avoid emitting such sequences on startup.
* Avoid emitting multiple such sequences
  when rapidly un-/focusing the window.

It's also a minor cleanup, because the `GA_ROOTOWNER` is not security
relevant. It was added because there was concern that someone can just
spawn a ConPTY session, tell it that it's focused, and spawn a child
which is now focused. But why would someone do that, when the console
IOCTLs to do so are not just publicly available but also documented?

I also disabled the IME window.

## Validation Steps Performed
* First:
  ```cpp
  int main() {
      for (bool show = false;; show = !show) {
          printf(show ? "Show in 3s...\n" : "Hide in 3s...\n");
          Sleep(3000);
          ShowWindow(GetConsoleWindow(), show ? SW_SHOW : SW_HIDE);
      }
  }
  ```
* PowerShell 5's `Get-Credential` gains focus 
* `sleep 5; Get-Credential` and focus another app. WT should start
  blinking in the taskbar. Restore it. The popup has focus 
* Run `:hardcopy` in vim: Window is shown centered at (0,0) ✖️
  But that's okay because it does that already anyway 
* `Connect-AzAccount` doesn't crash PowerShell 

(cherry picked from commit 4386bf07fd)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTs61k
Service-Version: 1.22
2024-10-08 17:43:51 -05:00
Dustin L. Howett
a0987c22c8 Revert "Stop updating AutoSuggestBox on selection" (#17989)
Reverts microsoft/terminal#17961
Closes #17987
Reopens #17916

(cherry picked from commit b715008de3)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTiWbQ
Service-Version: 1.22
2024-10-08 17:43:50 -05:00
Leonard Hecker
24475acba8 Add input scope startup setting (#17953)
This adds a "defaultInputScope" setting, hooks it up to our TSF,
and exposes it as a setting in the UI under the startup page.
In order to stay close with the other language setting, I moved that
one from the appearance to the startup page as well.
20 out of the 26 files in this PR are boilerplate unfortunately.

Closes #17816

## Validation Steps Performed
* Install and use the Chinese IME
* Launch WT
* Chinese input 
* Change setting to `alphanumericHalfWidth`
* Restart WT
* English input 

(cherry picked from commit fc606d2bae)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTTKAI
Service-Version: 1.22
2024-09-26 14:58:14 -05:00
James Holderness
2a8dee286e Add support for resetting the color scheme with RIS (#17879)
## Summary of the Pull Request

This improves our `RIS` (hard reset) implementation, so it now also
resets any changes that are made to the color table and color aliases,
which is one of the things it's supposed to be doing.

## References and Relevant Issues

This is also a small step towards implementing the `OSC` sequences that
reset individual color table entries (issue #3719).

## Detailed Description of the Pull Request / Additional comments

The way this works is by having a second copy of the color table and
alias indices to hold the default values in the `RenderSettings` class.
This default set is initially populated at startup with the user's
chosen color scheme, but can also potentially be updated if the user
changes their settings while a session is already in progress.

When we receive an `RIS` request, we just copy the default values back
over the active settings, and refresh the renderer.

## Validation Steps Performed

I've manually tested both OpenConsole and Windows Terminal by changing
my color scheme programmatically, and then confirming that the original
colors are restored when an `RIS` sequence is received.

I've also added some basic unit tests that check both the color aliases
and color table are restored by `RIS`.

## PR Checklist
- [x] Tests added/passed

(cherry picked from commit 5e8e10fdc0)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTTOyY
Service-Version: 1.22
2024-09-26 14:58:13 -05:00
Windows Console Service Bot
181448908e Localization Updates - main - 09/26/2024 19:14:21 (#17958)
Closes #17752
Closes #17764
Closes #17830

(cherry picked from commit 59dc5eff42)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTX8OU
Service-Version: 1.22
2024-09-26 14:23:01 -05:00
Leonard Hecker
e5f0af22d7 Stop updating AutoSuggestBox on selection (#17961)
`AutoSuggestBox` has a `SuggestionChosen` event and any reasonable
person would assume that this means one of the items was chosen.
But with WinUI it's raised whenever a suggestion is merely highlighted.
`QuerySubmitted` is the right event instead. Clearly that naming is
a lot better than `SuggestionChosen`, since the property to get the
chosen item is called `ChosenSuggestion`.
WinUI, like the unrelenting wilderness of a world indifferent to human
suffering, stands as a testament to the futility of human aspiration.

Closes #17916

## Validation Steps Performed
* Type "Casc"
* Move up/down with the arrow keys
* Neither the filtered list nor the text updates 
* Press Enter on an item
* Text updates 

(cherry picked from commit bcac9993cb)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTW9-o
Service-Version: 1.22
2024-09-26 14:23:00 -05:00
Carlos Zamora
c49d79a1ec Improve color contrast of reset button in SUI (#17912)
Adds a theme resource for the color of the reset button in the settings UI.

Closes #17902

(cherry picked from commit 0bd19e9cfc)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTTb0w
Service-Version: 1.22
2024-09-26 14:22:59 -05:00
Leonard Hecker
ff7f1a7c83 Fix clear buffer command (#17884)
Without a VT "renderer" there's no implicit output anymore when
calling `ClearPseudoConsole`. The fix is trivial, but it works
slightly different from before: Previously, we would preserve
the line the cursor is on, while this PR doesn't do that.
I felt like there's not much merit in preserving the line,
because it may be a multi-line prompt which won't work with that.

Closes #17867

## Validation Steps Performed
Bind 3 different actions to the 3 variants of "Clear buffer"
and test them. They work. 

(cherry picked from commit 4259ce535f)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgS3NbU
Service-Version: 1.22
2024-09-24 14:12:18 -05:00
Leonard Hecker
9b8c0602a2 Stop scrolling on output when search is open (#17885)
* Don't reset the position entirely when changing the needle
* Don't change the scroll position when output arrives
* Don't interfere with the search when output arrives constantly

Closes #17301

## Validation Steps Performed
* In pwsh, run `10000..20000 | % { sleep 0.25; $_ }`
  * You can search for e.g. `1004` and it'll find 10 results. 
  * You can scroll up and down past it and it won't snap back
    when new output arrives. 
* `while ($true) { Write-Host -NoNewline "`e[Ha"; sleep 0.0001; }`
  * You can cycle between the hits effortlessly.  (This tests that
    the constantly reset `OutputIdle` event won't interfere.)
* On input change, the focused result is near the previous one. 

(cherry picked from commit d9131c6889)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgS3elo PVTI_lADOAF3p4s4AmhmQzgTEciM
Service-Version: 1.22
2024-09-24 14:08:04 -05:00
Leonard Hecker
ea60f14627 Fix a cooked read deadlock (#17905)
Because `_layoutLine` would never return `column == columnLimit` for
control character visualizers, we'd get a deadlock in `_redisplay`,
as it tries to fill the line until it's full, but never achieve it.

Closes #17893

## Validation Steps Performed
* Press Ctrl-A to insert "^A"
* Press Home to get to the start of the prompt
* Press and hold "A" until the line wraps
* The line wraps and there's no deadlock 

(cherry picked from commit 0ce654eaf6)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTEJwI
Service-Version: 1.22
2024-09-24 14:08:03 -05:00
James Holderness
145babeae0 Fix a sixel crash when the buffer is reflowed (#17951)
## Summary of the Pull Request

The sixel parser has an internal buffer that holds the indexed-color
representation of the image, prior to it being translated to RGB. This
buffer only retains the section of the image that is within the visible
viewport, so we're continually erasing segments from the top of it when
the image is large enough to trigger a scroll.

But there is a problem that arises if the window or font is resized so
that the buffer needs to reflow, because that can result in the image
being pushed entirely offscreen. At that point the segment we're trying
to erase is actually larger than the buffer itself, which can end up
causing the terminal to crash

To fix this, we just need to check for an oversized erase attempt and
simply clear the buffer instead.

## Validation Steps Performed

I could easily reproduce this crash in Windows Terminal by resizing the
font while viewing an animated gif with img2sixel. With this PR applied
the crash no longer occurs.

## PR Checklist
- [x] Closes #17947

(cherry picked from commit fc586e2662)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTTKv4
Service-Version: 1.22
2024-09-24 14:08:01 -05:00
Leonard Hecker
a2d7742567 Check EnableHexNumpad before enabling it (#17954)
This just adds a quick registry check for `EnableHexNumpad`.

Depends on #17774
Closes #17762 (again)

## Validation Steps Performed
* Alt + NumpadAdd + 221E doesn't do anything 
* Set the `EnableHexNumpad` registry key
* Restart
* Alt + NumpadAdd + 221E inserts ∞ 

(cherry picked from commit b520da26d4)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTQseA
Service-Version: 1.22
2024-09-24 14:08:00 -05:00
Carlos Zamora
44315b4909 Fix text scaling issues in settings UI (#17910)
## Summary of the Pull Request
Fixes some issues with truncated text in the settings UI when 200% text
scaling is applied.

For #17897, a minimum height was applied instead of a plain "height".
This ensures that the desired height is applied in general, but under
200% text scaling, we are allowed to grow past that, thus preventing the
truncation of the text.

For #17898, flyouts have a scroll viewer inside them by default. We
actually don't want the scroll viewer because that means the text will
appear "truncated" when in reality, the user is expected to notice the
small scrollbar and scroll horizontally (why that's the default, I will
never know). This PR introduces a new style that can be applied to these
flyouts to cause text wrapping instead of horizontal scrolling. Looked
through the app for any instances where this happens.

For #12006, simply changing the column width from a static value to
"auto" fixes the issue. Frankly, we care more about the text appearing
as a whole (and as whole words). The name of the actions wrap properly
anyways.

Closes #17897
Closes #17898
Closes #12006

(cherry picked from commit a7e47b711a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTEfj8
Service-Version: 1.22
2024-09-17 16:05:27 -05:00
Dustin L. Howett
5e8efdf008 build: fix the TSA configuration (#17929)
We are, quite literally, shipping the org chart.

(cherry picked from commit 2c97c0555d)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTGRAo
Service-Version: 1.22
2024-09-17 16:05:26 -05:00
Leonard Hecker
d95a77b369 Fix a crash on pane close (#17886)
The underlying issue is that the "Pane" is used both as a model and as
a UI element and so a pane loses its content as soon as it is closed,
but the tree only gets reordered after the animation has finished.
This PR is truly just a hotfix, because it doesn't solve this issue,
it only adds checks to the function that crashes.

Closes #17869
Closes #17871

## Validation Steps Performed
* `Split pane` a few times
* Run the "Close all other panes" action
* Doesn't crash 

(cherry picked from commit bc6f3e2275)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgS3Ndk PVTI_lADOAF3p4s4AmhmQzgTEJYM
Service-Version: 1.22
2024-09-16 16:00:36 -05:00
Carlos Zamora
cc132d5e50 Add Feature_QuickFix to preview builds (#17888)
(cherry picked from commit 6196a3d0f7)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgS4Ha8
Service-Version: 1.22
2024-09-16 16:00:35 -05:00
Dustin L. Howett
22731e8673 Remove PackageES in favor of our own versioning package (#17872)
PackageES is deprecated by known scourge-on-earth OneBranch, and is now
the cause of some non-compliance.

I got permission from them to open-source it, so that's coming next.

For now, we can just depend on a package based on our code based on
theirs.

Tested and working for C++ (DLL, EXE), C#, NuGet and MSIX.

(cherry picked from commit 4aa1624cd2)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgTD8is
Service-Version: 1.22
2024-09-16 16:00:34 -05:00
Mike Griese
c129e794f8 Add Feature_SaveSnippet to preview builds (#17881)
whoops. This should have been in preview after I sorted out #17366

----

I did this one on GH so let's hope CI works

(cherry picked from commit c699a468c9)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgS66Co
Service-Version: 1.22
2024-09-16 16:00:32 -05:00
Nihat Uygar Köseer
bd33c7f20b Add tab color indicator for tab switch menu (CTRL+Tab) (#17820)
Added tab color indicator for the tab switch menu. Tab color indicators
have the same color as the background color of the tabs. If a tab has
the default background color, the indicator is not shown in the tab
switch menu.

Closes #17465

(cherry picked from commit 544452dad4)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgS0CZA
Service-Version: 1.22
2024-09-06 18:37:04 -05:00
Leonard Hecker
893f32c642 Fix crash in AppHost::_QuitRequested (#17848)
(cherry picked from commit 00f46e400a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSwXpY
Service-Version: 1.22
2024-09-06 18:37:03 -05:00
Leonard Hecker
58a50caf6a Restore contents when a screen info is closed (#17853)
(cherry picked from commit 4eb06fee07)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSaylY
Service-Version: 1.22
2024-09-06 18:37:03 -05:00
Leonard Hecker
33b0e9dd10 Fix ScrollRect to DECCRA translation (#17849)
By translating the clip rectangle into a source-relative coordinate
space we can calculate the intersection that must be copied
much much more easily. I should've done that from the start.

Closes #17801

## Validation Steps Performed
* Test code provided in #17801

(cherry picked from commit d2c3cfd164)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSa7nQ
Service-Version: 1.22
2024-09-06 18:37:02 -05:00
James Holderness
385a9a6111 Pass through DCS responses when VT input mode is disabled (#17845)
## Summary of the Pull Request

When an app makes a VT request that returns a `DCS` response, and it
hasn't also enabled VT input mode, the new passthrough implementation
loses that response. All the app receives is an `Alt`+`\` key press
triggered by the `ST` terminator. This PR fixes that issue.

## References and Relevant Issues

This is one of the unresolved issues tracked in #17643.

## Detailed Description of the Pull Request / Additional comments

The way `DCS` sequences are handled in the input state machine engine is
by returning a nullptr from `ActionDcsDispatch`, which tells the state
machine to ignore that content. But the sequence is still buffered, and
when the `ST` terminator is eventually received, that buffer is flushed,
which passes the whole thing through to the app.

Originally this only worked when VT input mode was enabled, otherwise
the `ST` sequence is converted into a key press, and the buffered `DCS`
content is lost. The way it works now is we set a flag when the `DCS`
introducer is received, and if that flag is set when the `ST` arrives,
we know to trigger a flush rather a key press.

## Validation Steps Performed

I've tested a `DA3` request from the cmd shell (i.e. `echo ^[[=c`), and
confirmed that now works as expected. I've also hacked Windows Terminal
to disable win32-input mode, so I could check how it works with conpty
clients generating standard VT input, and confirmed that an `Alt`+`\`
keypress is still translated correctly.

(cherry picked from commit 6e5827add5)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSwKBc
Service-Version: 1.22
2024-09-06 18:37:01 -05:00
Leonard Hecker
03fc325ad1 Dedup command history by default (#17852)
Under ConPTY we don't load any user settings. `SetUpConsole` notes:
> If we are [ConPTY], we don't want to load any user settings,
> because that could result in some strange rendering results [...]

This enables deduplication by default, which I figured wouldn't cause
any regressions since it's a user-controllable setting anyway, while
it's clearly something the average user wants enabled, for the same
reason that PSReadLine has HistoryNoDuplicates enabled by default.

Closes #17797

## Validation Steps Performed
* Launch conhost, enter 2 commands, press F7, select the older one,
  press Enter, press F7. 2 entries 
* Launch WT, enter 2 commands, press F7, select the older one,
  press Enter, press F7. 2 entries 

(cherry picked from commit 5fdfd51209)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSN1FQ
Service-Version: 1.22
2024-09-04 15:04:32 -05:00
Leonard Hecker
be99f93094 Avoid dropping Esc characters from VT responses (#17833)
`GetChar` checks if the vkey is VK_ESCAPE. `CharToKeyEvents` however
tries really hard to figure out the vkeys of all characters.
To avoid these issues all we need to do is to simply use the existing
`WriteString` function we already use for all other VT responses.
If it's good for conhost responses, it's good for ConPTY responses.

Additionally, this removes another `IsVtInputEnabled` which was
redundant with `WriteString` which worked exactly the same internally.

Closes #17813
Closes #17851
Probably also related to #17823

* Wrote a small app to send and receive a DA1 request. It works 
* WSL already worked to begin with (and still works now) 
* No double-encoding of mouse input events 

(cherry picked from commit 7b50f12a78)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSa4RU PVTI_lADOAF3p4s4AmhmQzgStRA0
Service-Version: 1.22
2024-09-04 14:56:05 -05:00
Mike Griese
696fd1196b Fix two ConPTY HWND focus issues (#17828)
Worked with @ekoschik on this one.

## Bug the first: the MSAL window `ixptools` spawns

> The auth prompt in pwsh.exe is disabling the terminal window while its
opened and re-enabling it when the window closes. BUT it is enabling
Terminal after dismissing itself, instead of before, which means
terminal is disabled when activated.
>
> Terminal wants focus on the ISLAND window (a grandchild; island is
parented to bridge, which is parented to terminal’s TLW). When it is
activated, it gets a `WM_SETFOCUS` (in response to DefWindowProc
`WM_ACTIVATE`). From `WM_SETFOCUS` it calls `SetFocus` on the bridge
window, and similarly the bridge calls `SetFocus` on the island.
>
> If the TLW is disabled, these `SetFocus` calls fail (see [this
check](#internal-link-redacted) in `SetFocus`). In the case above, this
leaves Terminal’s TLW as focus, and it doesn’t handle keyboard input.
Note that the window IS foreground/active, but because focus is not on
the island it doesn’t see the keyboard input. Another thing to note is
that clicking on the space to the right of the tabs does NOT revive
keyboard input, but clicking on the tabs or main area does.

> **I recommend having the TLW handle WM_ENABLE and call SetFocus on the
island window.**

And guess what, that works!

## Bug the second: When sublime text is the git `EDITOR`, it doesn't
toss focus back to the Terminal

> In this case, Sublime is calling SFW on the pseudo console window. I
don’t have its code, but it is presumably doing something like
SetForegroundWindow(GetConsoleWindow()). This queues an event to the
pseudo window, and when that event is processed the pseudo window
becomes the active and focus window on the queue (which is shared with
Terminal).
>
> The sublime window dismisses itself and does the above SFW call.
Dismissing immediately activates the Terminal TLW, which does the
triple-focus dance (TLW sets focus on itself, then bridge, then island).
This completes but is overwritten immediately when the pseudo window
activates itself. Note that the pseudo window is active at this point
(not the terminal window).

> **I recommend having the Pseudo console window handle WM_ACTIVATE by
calling SetFocus on the island window (and not passing the message to
DefWindowProc).**

And guess what, that works!

----

Closes #15956 (I did test this)
This might be related to #13388, we'll have folks try canary and check

(cherry picked from commit 17a55da0f9)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSwIkE
Service-Version: 1.22
2024-09-04 14:55:17 -05:00
Leonard Hecker
649d8b2979 Give spacing marks space (#17826)
Spacing marks are called so, because they have a positive advance
width, unlike their non-spacing neighbors (as the name indicates).
After this we stop assigning such gc=Mc codepoints a zero width.

Closes #17810

(cherry picked from commit 0cb3426281)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSg1L4
Service-Version: 1.22
2024-09-04 14:55:17 -05:00
PankajBhojwani
3d01439c9f Add action IDs to the color selection commands (#17821)
## Summary of the Pull Request
Add action IDs to the default commands for color selection

## Validation Steps Performed
Color selection commands now show up in the command palette

## PR Checklist
- [x] Closes #17819
- [ ] Tests added/passed
- [ ] Documentation updated
- If checked, please file a pull request on [our docs
repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
- [ ] Schema updated (if necessary)

(cherry picked from commit 1482fd4ecd)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSawsY PVTI_lADOAF3p4s4AmhmQzgSwIVc
Service-Version: 1.22
2024-09-04 14:55:15 -05:00
Carlos Zamora
85afa41c32 Remove unnecessary FMT (#17795)
There's an unnecessary `fmt::format` here caught in the code review: https://github.com/microsoft/terminal/pull/17678#discussion_r1729426705

This simply removes it.

(cherry picked from commit 93d592bb41)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSwIS4
Service-Version: 1.22
2024-09-04 14:55:14 -05:00
James Holderness
b3f0afbc8f Make sure a blank title string resets the title (#17802)
## Summary of the Pull Request

When a VT title sequence sets the title to a blank string, that is meant
to trigger a reset to the default starting value. This used to work in
the past because the blank value was dealt with by conhost, so Windows
Terminal never received a blank title, but that's no longer the case
with the new VT passthrough. This PR fixes the issue by getting Windows
Terminal to handle the blank title strings itself.

## References and Relevant Issues

VT passthrough was introduced in PR #17510.

## Validation Steps Performed

I've manually verified that the `OSC 0`, `OSC 2`, and `DECSWT` sequences
now correctly reset the title when passed a blank title string.

## PR Checklist
- [x] Closes #17800

(cherry picked from commit 1f71568c2a)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSNvr0 PVTI_lADOAF3p4s4AmhmQzgSOFrc
Service-Version: 1.22
2024-09-04 14:55:13 -05:00
Dustin L. Howett
90cfb33c13 PGO: train 1.22 separately 2024-08-23 15:10:47 -05:00
346 changed files with 5139 additions and 5915 deletions

View File

@@ -1,7 +1,6 @@
name: "Bug report 🐛"
description: Report errors or unexpected behavior
labels: [Issue-Bug, Needs-Triage]
type: Bug
body:
- type: markdown
attributes:
@@ -13,7 +12,7 @@ body:
- type: input
attributes:
label: Windows Terminal version
placeholder: "1.21.2701.0"
placeholder: "1.7.3651.0"
description: |
You can copy the version number from the About dialog. Open the About dialog by opening the menu with the "V" button (to the right of the "+" button that opens a new tab) and choosing About from the end of the list.
validations:
@@ -22,7 +21,7 @@ body:
- type: input
attributes:
label: Windows build number
placeholder: "10.0.22621.0"
placeholder: "10.0.19042.0"
description: |
Please run `ver` or `[Environment]::OSVersion`.
validations:
@@ -33,9 +32,9 @@ body:
label: Other Software
description: If you're reporting a bug about our interaction with other software, what software? What versions?
placeholder: |
vim 9.1 (inside WSL)
OpenSSH_for_Windows_9.5p1
My Cool Application v0.4 (include a code snippet if it would help!)
vim 8.2 (inside WSL)
OpenSSH_for_Windows_8.1p1
My Cool Application v0.3 (include a code snippet if it would help!)
validations:
required: false

View File

@@ -0,0 +1,10 @@
---
name: "Documentation Issue 📚"
about: Report issues in our documentation
title: ''
labels: Issue-Docs
assignees: ''
---
<!-- Briefly describe which document needs to be corrected and why. -->

View File

@@ -0,0 +1,35 @@
---
name: "Feature Request/Idea 🚀"
about: Suggest a new feature or improvement (this does not mean you have to implement
it)
title: ''
labels: Issue-Feature
assignees: ''
---
<!--
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING:
1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement.
2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement.
3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number).
4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement.
5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement.
All good? Then proceed!
-->
# Description of the new feature/enhancement
<!--
A clear and concise description of what the problem is that the new feature would solve.
Describe why and how a user would use this new functionality (if applicable).
-->
# Proposed technical implementation details (optional)
<!--
A clear and concise description of what you want to happen.
-->

View File

@@ -1,20 +0,0 @@
name: "Feature Request/Idea 🚀"
description: Suggest a new feature or improvement (this does not mean you have to implement it)
labels: [Issue-Feature]
type: Feature
body:
- type: textarea
attributes:
label: Description of the new feature
description: A clear and concise description of what the problem is that the new feature would solve.
placeholder: |
... and guess what? I have four Terminals. And I have a hover car, and a hover house. And my computer's a runner, and it shows.
validations:
required: true
- type: textarea
attributes:
label: Proposed technical implementation details
description: This field is optional. If you have any ideas, let us know!
validations:
required: false

View File

@@ -5,11 +5,11 @@ breadcrumbs
ccmp
ccon
clickable
cmark
CMMI
colorbrewer
consvc
copyable
CText
dalet
dcs
deselection
@@ -21,9 +21,9 @@ dze
dzhe
Emacspeak
Fitt
flac
FTCS
gantt
gfm
ghe
gje
godbolt
@@ -57,6 +57,7 @@ ptys
pwn
pwshw
qof
QOL
qps
quickfix
rclt
@@ -75,6 +76,7 @@ slnt
stakeholders
sustainability
sxn
Tencent
TLDR
tonos
toolset

View File

@@ -43,7 +43,6 @@ DONTADDTORECENT
DWMSBT
DWMWA
DWORDLONG
EMPH
endfor
ENDSESSION
enumset
@@ -63,7 +62,6 @@ GETDESKWALLPAPER
GETHIGHCONTRAST
GETMOUSEHOVERTIME
GETTEXTLENGTH
HARDBREAKS
Hashtable
HIGHCONTRASTON
HIGHCONTRASTW
@@ -117,7 +115,6 @@ IUri
IVirtual
KEYSELECT
LCID
LINEBREAK
llabs
llu
localtime
@@ -151,7 +148,6 @@ NIF
NIN
NOAGGREGATION
NOASYNC
NOBREAKS
NOCHANGEDIR
NOPROGRESS
NOREDIRECTIONBITMAP
@@ -179,7 +175,6 @@ PALLOC
PATINVERT
PEXPLICIT
PICKFOLDERS
PINPUT
pmr
ptstr
QUERYENDSESSION
@@ -208,7 +203,6 @@ SINGLEUSE
SIZENS
smoothstep
snprintf
SOFTBREAK
spsc
sregex
SRWLOC
@@ -291,4 +285,5 @@ xtree
xutility
YIcon
YMax
zstring
zwstring

View File

@@ -104,7 +104,6 @@
^doc/reference/UTF8-torture-test\.txt$
^doc/reference/windows-terminal-logo\.ans$
^oss/
^NOTICE.md
^samples/PixelShaders/Screenshots/
^src/interactivity/onecore/BgfxEngine\.
^src/renderer/atlas/

View File

@@ -87,6 +87,7 @@ autoscrolling
Autowrap
AVerify
awch
AZCOPY
azurecr
AZZ
backgrounded
@@ -214,6 +215,7 @@ codepages
codepath
coinit
colorizing
COLORONCOLOR
COLORREFs
colorschemes
colorspec
@@ -919,7 +921,6 @@ Keymapping
keyscan
keystate
keyups
Kickstart
KILLACTIVE
KILLFOCUS
kinda
@@ -1159,6 +1160,8 @@ nfe
NLSMODE
nnn
NOACTIVATE
NOACTIVATEKEYBOARDLAYOUT
NOACTIVATETIP
NOAPPLYNOW
NOCLIP
NOCOMM
@@ -1427,6 +1430,7 @@ propvar
propvariant
propvarutil
psa
PSCRED
PSECURITY
pseudoconsole
pseudoterminal
@@ -1465,7 +1469,6 @@ QWER
Qxxxxxxxxxxxxxxx
qzmp
RAII
Ralph
RALT
rasterbar
rasterfont
@@ -1598,7 +1601,6 @@ scrolllock
scrolloffset
SCROLLSCALE
SCROLLSCREENBUFFER
scursor
sddl
SDKDDK
securityappcontainer
@@ -1690,6 +1692,7 @@ SMARTQUOTE
SMTO
snapcx
snapcy
snk
SOLIDBOX
Solutiondir
somefile
@@ -1814,10 +1817,12 @@ TEXTMETRICW
textmode
texttests
TFunction
TFCAT
THUMBPOSITION
THUMBTRACK
TIcon
tilunittests
TIPCAP
titlebars
TITLEISLINKNAME
TJson
@@ -1880,6 +1885,8 @@ UIACCESS
uiacore
uiautomationcore
uielem
UIELEMENTENABLED
UIELEMENTENABLEDONLY
UINTs
ul
uld
@@ -2015,7 +2022,6 @@ WHelper
wic
WIDTHSCROLL
Widthx
Wiggum
wil
WImpl
WINAPI

View File

@@ -13,7 +13,7 @@ jobs:
name: Add issue to project
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v1.0.2
- uses: actions/add-to-project@v1.0.1
with:
project-url: https://github.com/orgs/microsoft/projects/159
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}

175
NOTICE.md
View File

@@ -281,181 +281,6 @@ CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
```
## cmark
**Source**: [https://github.com/commonmark/cmark](https://github.com/commonmark/cmark)
### License
Copyright (c) 2014, John MacFarlane
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----
houdini.h, houdini_href_e.c, houdini_html_e.c, houdini_html_u.c
derive from https://github.com/vmg/houdini (with some modifications)
Copyright (C) 2012 Vicent Martí
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-----
buffer.h, buffer.c, chunk.h
are derived from code (C) 2012 Github, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-----
utf8.c and utf8.c
are derived from utf8proc
(<http://www.public-software-group.org/utf8proc>),
(C) 2009 Public Software Group e. V., Berlin, Germany.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-----
The normalization code in normalize.py was derived from the
markdowntest project, Copyright 2013 Karl Dubost:
The MIT License (MIT)
Copyright (c) 2013 Karl Dubost
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----
The CommonMark spec (test/spec.txt) is
Copyright (C) 2014-15 John MacFarlane
Released under the Creative Commons CC-BY-SA 4.0 license:
<http://creativecommons.org/licenses/by-sa/4.0/>.
-----
The test software in test/ is
Copyright (c) 2014, John MacFarlane
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Microsoft Open Source
This product also incorporates source code from other Microsoft open source projects, all licensed under the MIT license.

View File

@@ -4,7 +4,7 @@
<clear />
<!-- Dependencies that we can turn on to force override for testing purposes before uploading. -->
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/shine-oss/terminal/_packaging/TerminalDependencies/nuget/v3/index.json" />
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/shine-oss/terminal/_packaging/TerminalDependencies%40Local/nuget/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />

View File

@@ -405,8 +405,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenderingTests", "src\tools
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.UI", "src\cascadia\UIHelpers\UIHelpers.vcxproj", "{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.UI.Markdown", "src\cascadia\UIMarkdown\UIMarkdown.vcxproj", "{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benchcat", "src\tools\benchcat\benchcat.vcxproj", "{2C836962-9543-4CE5-B834-D28E1F124B66}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConsoleMonitor", "src\tools\ConsoleMonitor\ConsoleMonitor.vcxproj", "{328729E9-6723-416E-9C98-951F1473BBE1}"
@@ -2304,28 +2302,6 @@ Global
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x64.Build.0 = Release|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x86.ActiveCfg = Release|Win32
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x86.Build.0 = Release|Win32
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.AuditMode|Any CPU.ActiveCfg = Debug|Win32
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.AuditMode|x64.ActiveCfg = Release|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.AuditMode|x86.ActiveCfg = Release|Win32
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Debug|Any CPU.ActiveCfg = Debug|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Debug|ARM64.Build.0 = Debug|ARM64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Debug|x64.ActiveCfg = Debug|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Debug|x64.Build.0 = Debug|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Debug|x86.ActiveCfg = Debug|Win32
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Debug|x86.Build.0 = Debug|Win32
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Release|Any CPU.ActiveCfg = Release|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Release|ARM64.ActiveCfg = Release|ARM64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Release|ARM64.Build.0 = Release|ARM64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Release|x64.ActiveCfg = Release|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Release|x64.Build.0 = Release|x64
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Release|x86.ActiveCfg = Release|Win32
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}.Release|x86.Build.0 = Release|Win32
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|x64.ActiveCfg = Release|x64
@@ -2479,7 +2455,6 @@ Global
{613CCB57-5FA9-48EF-80D0-6B1E319E20C4} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{37C995E0-2349-4154-8E77-4A52C0C7F46D} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
{2C836962-9543-4CE5-B834-D28E1F124B66} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{328729E9-6723-416E-9C98-951F1473BBE1} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{BE92101C-04F8-48DA-99F0-E1F4F1D2DC48} = {A10C4720-DCA4-4640-9749-67F4314F527C}

Binary file not shown.

View File

@@ -6,6 +6,20 @@
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-233904-SN",
"OperationSetCode": "StrongNameSign",
"ToolName": "sign",
"ToolVersion": "1.0",
"Parameters": []
},
{
"KeyCode": "CP-233904-SN",
"OperationSetCode": "StrongNameVerify",
"ToolName": "sign",
"ToolVersion": "1.0",
"Parameters": []
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",

View File

@@ -1,6 +1,6 @@
{
"instanceUrl": "https://microsoft.visualstudio.com",
"projectName": "OS",
"areaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\Terminal",
"areaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SHINE\\Terminal",
"notificationAliases": ["condev@microsoft.com", "duhowett@microsoft.com"]
}

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
<package id="Microsoft.Taef" version="10.93.240607003" targetFramework="native" />
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
<package id="Microsoft.Debugging.Tools.PdbStr" version="20220617.1556.0" targetFramework="native" />

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.22</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

@@ -37,6 +37,8 @@ extends:
akvName: $(SigningAKVName)
authCertName: $(SigningAuthCertName)
signCertName: $(SigningSignCertName)
useManagedIdentity: $(SigningUseManagedIdentity)
clientId: $(SigningOriginalClientId)
publishSymbolsToPublic: true
publishVpackToWindows: false
symbolExpiryTime: 15

View File

@@ -85,6 +85,8 @@ extends:
akvName: $(SigningAKVName)
authCertName: $(SigningAuthCertName)
signCertName: $(SigningSignCertName)
useManagedIdentity: $(SigningUseManagedIdentity)
clientId: $(SigningOriginalClientId)
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}

View File

@@ -10,6 +10,6 @@ jobs:
submodules: false
clean: true
- pwsh: |-
- powershell: |-
.\build\scripts\Invoke-FormattingCheck.ps1
displayName: 'Run formatters'

View File

@@ -75,18 +75,13 @@ jobs:
}
displayName: "Wrangle Unpackaged builds into place, rename"
- powershell: |-
Get-PackageProvider -Name NuGet -ForceBootstrap
Install-Module -Verbose -AllowClobber -Force Az.Accounts, Az.Storage, Az.Network, Az.Resources, Az.Compute
displayName: Install Azure Module Dependencies
- task: AzureFileCopy@6
- task: AzurePowerShell@5
displayName: Publish to Storage Account
inputs:
sourcePath: _out/*
Destination: AzureBlob
azureSubscription: ${{ parameters.subscription }}
storage: ${{ parameters.storageAccount }}
ContainerName: ${{ parameters.storageContainer }}
AdditionalArgumentsForBlobCopy: "--content-type application/octet-stream"
azurePowerShellVersion: LatestVersion
pwsh: true
ScriptType: InlineScript
Inline: |-
$Env:AZCOPY_AUTO_LOGIN_TYPE="PSCRED"
& AzCopy copy "_out\*" "https://${{ parameters.storageAccount }}.blob.core.windows.net/${{ parameters.storageContainer }}/" --content-type application/octet-stream

View File

@@ -147,6 +147,10 @@ jobs:
ValidateSignature: true
Verbosity: 'Verbose'
- pwsh: |-
tar -c -v --format=zip -f "$(JobOutputDirectory)/GroupPolicyTemplates_$(XES_APPXMANIFESTVERSION).zip" -C "$(Build.SourcesDirectory)/policies" *
displayName: Package GPO Templates
- ${{ parameters.afterBuildSteps }}
- ${{ if eq(parameters.publishArtifacts, true) }}:

View File

@@ -52,11 +52,6 @@ jobs:
itemPattern: '**/*.pdb'
targetPath: '$(Build.SourcesDirectory)/bin'
- powershell: |-
Get-PackageProvider -Name NuGet -ForceBootstrap
Install-Module -Verbose -AllowClobber -Force Az.Accounts, Az.Storage, Az.Network, Az.Resources, Az.Compute
displayName: Install Azure Module Dependencies
# Transit the Azure token from the Service Connection into a secret variable for the rest of the pipeline to use.
- task: AzurePowerShell@5
displayName: Generate an Azure Token
@@ -66,7 +61,7 @@ jobs:
pwsh: true
ScriptType: InlineScript
Inline: |-
$AzToken = (Get-AzAccessToken -ResourceUrl api://30471ccf-0966-45b9-a979-065dbedb24c1).Token
$AzToken = (Get-AzAccessToken -AsSecureString -ResourceUrl api://30471ccf-0966-45b9-a979-065dbedb24c1).Token | ConvertFrom-SecureString -AsPlainText
Write-Host "##vso[task.setvariable variable=SymbolAccessToken;issecret=true]$AzToken"

View File

@@ -69,10 +69,3 @@ jobs:
artifact: $(JobOutputArtifactName)
displayName: 'Publish VPack Manifest to Drop'
- task: PkgESFCIBGit@12
displayName: 'Submit VPack Manifest to Windows'
inputs:
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
prTimeOut: 5

View File

@@ -78,7 +78,9 @@ extends:
template: v2/Microsoft.NonOfficial.yml@templates
parameters:
featureFlags:
WindowsHostVersion: 1ESWindows2022
WindowsHostVersion:
Version: 2022
Network: R1
platform:
name: 'windows_undocked'
product: 'Windows Terminal'

View File

@@ -1,5 +1,12 @@
steps:
- task: NuGetToolInstaller@1
displayName: Use NuGet 6.6.1
inputs:
versionSpec: 6.6.1
- ${{ if eq(variables['System.CollectionId'], 'cb55739e-4afe-46a3-970f-1b49d8ee7564') }}:
- pwsh: |-
Write-Host "Assuming NuGet is already installed..."
& nuget.exe help
displayName: Assume NuGet is fine
- ${{ else }}:
- task: NuGetToolInstaller@1
displayName: Use NuGet 6.6.1
inputs:
versionSpec: 6.6.1

View File

@@ -19,4 +19,6 @@ steps:
AuthAKVName: ${{ parameters.signingIdentity.akvName }}
AuthCertName: ${{ parameters.signingIdentity.authCertName }}
AuthSignCertName: ${{ parameters.signingIdentity.signCertName }}
UseMSIAuthentication: ${{ coalesce(parameters.signingIdentity.useManagedIdentity, 'false') }}
EsrpClientId: ${{ parameters.signingIdentity.clientId }}
${{ insert }}: ${{ parameters.inputs }}

View File

@@ -1,8 +1,28 @@
$VSInstances = ([xml](& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -include packages -format xml))
$VSPackages = $VSInstances.instances.instance.packages.package
$LatestVCPackage = ($VSInstances.instances.instance.packages.package | ? { $_.id -eq "Microsoft.VisualCpp.CRT.Source" })
$LatestVCPackage = ($VSPackages | ? { $_.id -eq "Microsoft.VisualCpp.Tools.Core" })
$LatestVCToolsVersion = $LatestVCPackage.version;
$VSRoot = (& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property 'resolvedInstallationPath')
$VCToolsRoot = Join-Path $VSRoot "VC\Tools\MSVC"
# We have observed a few instances where the VC tools package version actually
# differs from the version on the files themselves. We might as well check
# whether the version we just found _actually exists_ before we use it.
# We'll use whichever highest version exists.
$PackageVCToolPath = Join-Path $VCToolsRoot $LatestVCToolsVersion
If ($Null -Eq (Get-Item $PackageVCToolPath -ErrorAction:Ignore)) {
$VCToolsVersions = Get-ChildItem $VCToolsRoot | ForEach-Object {
[Version]$_.Name
} | Sort -Descending
$LatestActualVCToolsVersion = $VCToolsVersions | Select -First 1
If ([Version]$LatestVCToolsVersion -Ne $LatestActualVCToolsVersion) {
Write-Output "VC Tools Mismatch: Directory = $LatestActualVCToolsVersion, Package = $LatestVCToolsVersion"
$LatestVCToolsVersion = $LatestActualVCToolsVersion.ToString(3)
}
}
Write-Output "Latest VCToolsVersion: $LatestVCToolsVersion"
Write-Output "Updating VCToolsVersion environment variable for job"
Write-Output "##vso[task.setvariable variable=VCToolsVersion]$LatestVCToolsVersion"

View File

@@ -5,7 +5,10 @@
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2024</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>23</VersionMinor>
<VersionMinor>22</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
<VersionInfoCulture>1033</VersionInfoCulture>
<!-- The default has a spacing problem -->
<VersionInfoCopyRight>\xa9 Microsoft Corporation. All rights reserved.</VersionInfoCopyRight>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,13 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88c12148..967b53dd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -260,7 +260,7 @@ if (FMT_MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
join(netfxpath
"C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\"
".NETFramework\\v4.0")
- file(WRITE run-msbuild.bat "
+ file(WRITE "${CMAKE_BINARY_DIR}/run-msbuild.bat" "
${MSBUILD_SETUP}
${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*")
endif ()

View File

@@ -0,0 +1,38 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO fmtlib/fmt
REF "${VERSION}"
SHA512 573b7de1bd224b7b1b60d44808a843db35d4bc4634f72a9edcb52cf68e99ca66c744fd5d5c97b4336ba70b94abdabac5fc253b245d0d5cd8bbe2a096bf941e39
HEAD_REF master
PATCHES
fix-write-batch.patch
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
-DFMT_CMAKE_DIR=share/fmt
-DFMT_TEST=OFF
-DFMT_DOC=OFF
-DFMT_PEDANTIC=ON
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup()
vcpkg_fixup_pkgconfig()
vcpkg_copy_pdbs()
if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/fmt/base.h"
"defined(FMT_SHARED)"
"1"
)
endif()
file(REMOVE_RECURSE
"${CURRENT_PACKAGES_DIR}/debug/include"
"${CURRENT_PACKAGES_DIR}/debug/share"
)
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")

View File

@@ -0,0 +1,8 @@
The package fmt provides CMake targets:
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE fmt::fmt)
# Or use the header-only version
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE fmt::fmt-header-only)

View File

@@ -0,0 +1,17 @@
{
"name": "fmt",
"version": "11.1.4",
"description": "{fmt} is an open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.",
"homepage": "https://github.com/fmtlib/fmt",
"license": "MIT",
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
]
}

View File

@@ -380,7 +380,7 @@ Here's the AppxManifest we're using:
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.22621.0" />
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26100.0" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
</Dependencies>
@@ -517,7 +517,7 @@ This is because of a few key lines we already put in the appxmanifest:
```xml
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.22621.0" />
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26100.0" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
</Dependencies>

View File

@@ -35,7 +35,8 @@
"enum": [
"Windows.Terminal.Wsl",
"Windows.Terminal.Azure",
"Windows.Terminal.PowershellCore"
"Windows.Terminal.PowershellCore",
"Windows.Terminal.VisualStudio"
],
"type": "string"
},
@@ -733,9 +734,6 @@
"type": "string",
"default": "",
"description": "The name or GUID of the profile to show in this entry"
},
"icon": {
"$ref": "#/$defs/Icon"
}
}
}
@@ -807,9 +805,6 @@
"type": "string",
"default": "",
"description": "The ID of the action to show in this entry"
},
"icon": {
"$ref": "#/$defs/Icon"
}
}
}
@@ -885,11 +880,6 @@
"default": false,
"description": "If true, the copied content will be copied as a single line (even if there are hard line breaks present in the text). If false, newlines persist from the selected text."
},
"withControlSequences": {
"type": "boolean",
"default": false,
"description": "If true, copied content will contain ANSI escape code control sequences representing the styling of the content."
},
"dismissSelection": {
"type": "boolean",
"default": true,
@@ -2351,7 +2341,7 @@
"description": "When set to `true`, the terminal window will auto-center itself on the display it opens on. The terminal will use the \"initialPosition\" to determine which display to open on.",
"type": "boolean"
},
"warning.inputService": {
"inputServiceWarning": {
"default": true,
"description": "Warning if 'Touch Keyboard and Handwriting Panel Service' is disabled.",
"type": "boolean"
@@ -2376,10 +2366,14 @@
"description": "When set to true, Terminal windows will not be able to interact with each other (including global hotkeys, tab drag/drop, running commandlines in existing windows, etc.). This is a compatibility escape hatch for users who are running into certain windowing issues.",
"type": "boolean"
},
"compatibility.allowDECRQCRA": {
"default": false,
"description": "When set to true, the terminal will support the DECRQCRA (Request Checksum of Rectangular Area) escape sequence.",
"type": "boolean"
"compatibility.textMeasurement": {
"default": "graphemes",
"description": "This changes the way incoming text is grouped into cells. The \"graphemes\" option is the most modern and Unicode-correct way to do so, while \"wcswidth\" is a common approach on UNIX, and \"console\" replicates the way it used to work on Windows.",
"enum": [
"graphemes",
"wcswidth",
"console"
]
},
"copyFormatting": {
"default": true,
@@ -2411,12 +2405,12 @@
"description": "When set to `true`, visual animations will be disabled across the application.",
"type": "boolean"
},
"warning.largePaste": {
"largePasteWarning": {
"default": true,
"description": "When set to true, trying to paste text with more than 5 KiB of characters will display a warning asking you whether to continue or not with the paste.",
"type": "boolean"
},
"warning.multiLinePaste": {
"multiLinePasteWarning": {
"default": true,
"description": "When set to true, trying to paste text with a \"new line\" character will display a warning asking you whether to continue or not with the paste.",
"type": "boolean"
@@ -2479,11 +2473,6 @@
"minimum": 1,
"type": "integer"
},
"startOnUserLogin": {
"default": false,
"description": "When set to true, this enables the launch of Terminal at startup. Setting this to false will disable the startup task entry. If the Terminal startup task entry is disabled either by org policy or by user action this setting will have no effect.",
"type": "boolean"
},
"firstWindowPreference": {
"default": "defaultProfile",
"description": "Defines what behavior the terminal takes when it starts. \"defaultProfile\" will have the terminal launch with one tab of the default profile, and \"persistedWindowLayout\" will cause the terminal to save its layout on close and reload it on open.",
@@ -2614,7 +2603,7 @@
"description": "Determines the delimiters used in a double click selection.",
"type": "string"
},
"warning.confirmCloseAllTabs": {
"confirmCloseAllTabs": {
"default": true,
"description": "When set to \"true\" closing a window with multiple tabs open will require confirmation. When set to \"false\", the confirmation dialog will not appear.",
"type": "boolean"
@@ -2720,6 +2709,16 @@
"description": "When set to true, when opening a new tab or pane it will get reloaded environment variables.",
"type": "boolean"
},
"compatibility.allowDECRQCRA": {
"default": false,
"description": "When set to true, the terminal will support the DECRQCRA (Request Checksum of Rectangular Area) escape sequence.",
"type": "boolean"
},
"compatibility.allowOSC52": {
"default": true,
"description": "When set to true, VT applications will be allowed to set the contents of the local clipboard using OSC 52 (Manipulate Selection Data).",
"type": "boolean"
},
"unfocusedAppearance": {
"$ref": "#/$defs/AppearanceConfig",
"description": "Sets the appearance of the terminal when it is unfocused.",

View File

@@ -9,6 +9,7 @@
<supportedOn>
<definitions>
<definition name="SUPPORTED_WindowsTerminal_1_21" displayName="$(string.SUPPORTED_WindowsTerminal_1_21)" />
<definition name="SUPPORTED_DefaultTerminalApplication" displayName="$(string.SUPPORTED_DefaultTerminalApplication)" />
</definitions>
</supportedOn>
<categories>
@@ -24,5 +25,61 @@
<multiText id="DisabledProfileSources" valueName="DisabledProfileSources" required="true" />
</elements>
</policy>
<policy name="DefaultTerminalApplication" class="User" displayName="$(string.DefaultTerminalApplication)" explainText="$(string.DefaultTerminalApplicationText)" presentation="$(presentation.TermAppSelection)" key="Console\%%Startup">
<parentCategory ref="WindowsTerminal" />
<supportedOn ref="SUPPORTED_DefaultTerminalApplication" />
<elements>
<enum id="TermAppSelect" required="true" valueName="DelegationTerminal">
<item displayName="$(string.TermAppAutomatic)">
<value>
<string>{00000000-0000-0000-0000-000000000000}</string>
</value>
<valueList>
<item key="Console\%%Startup" valueName="DelegationConsole">
<value>
<string>{00000000-0000-0000-0000-000000000000}</string>
</value>
</item>
</valueList>
</item>
<item displayName="$(string.TermAppConsoleHost)">
<value>
<string>{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}</string>
</value>
<valueList>
<item key="Console\%%Startup" valueName="DelegationConsole">
<value>
<string>{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}</string>
</value>
</item>
</valueList>
</item>
<item displayName="$(string.TermAppWindowsTerminal)">
<value>
<string>{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}</string>
</value>
<valueList>
<item key="Console\%%Startup" valueName="DelegationConsole">
<value>
<string>{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}</string>
</value>
</item>
</valueList>
</item>
<item displayName="$(string.TermAppWindowsTerminalPreview)">
<value>
<string>{86633F1F-6454-40EC-89CE-DA4EBA977EE2}</string>
</value>
<valueList>
<item key="Console\%%Startup" valueName="DelegationConsole">
<value>
<string>{06EC847C-C0A5-46B8-92CB-7C92F6E35CD5}</string>
</value>
</item>
</valueList>
</item>
</enum>
</elements>
</policy>
</policies>
</policyDefinitions>

View File

@@ -7,6 +7,7 @@
<stringTable>
<string id="WindowsTerminal">Windows Terminal</string>
<string id="SUPPORTED_WindowsTerminal_1_21">At least Windows Terminal 1.21</string>
<string id="SUPPORTED_DefaultTerminalApplication">At least Windows 11 22H2 or Windows 10 22H2 (Build 19045.3031, KB5026435) with Windows Terminal 1.17</string>
<string id="DisabledProfileSources">Disabled Profile Sources</string>
<string id="DisabledProfileSourcesText">Profiles will not be generated from any sources listed here. Source names can be arbitrary strings. Potential candidates can be found as the "source" property on profile definitions in Windows Terminal's settings.json file.
@@ -18,11 +19,22 @@ Common sources are:
For instance, setting this policy to Windows.Terminal.Wsl will disable the builtin WSL integration of Windows Terminal.
Note: Existing profiles will disappear from Windows Terminal after adding their source to this policy.</string>
<string id="DefaultTerminalApplication">Default terminal application</string>
<string id="DefaultTerminalApplicationText">Select the default terminal application used in Windows.
If you select Windows Terminal Preview and it is not installed the system will fallback to the legacy Windows Console Host. (Please note that the settings interfaces showing "Let windows decide" in this case as configuration.)</string>
<string id="TermAppAutomatic">Automatic selection (Windows Terminal, if available)</string>
<string id="TermAppConsoleHost">Windows Console Host (legacy)</string>
<string id="TermAppWindowsTerminal">Windows Terminal</string>
<string id="TermAppWindowsTerminalPreview">Windows Terminal Preview (if available)</string>
</stringTable>
<presentationTable>
<presentation id="DisabledProfileSources">
<multiTextBox refId="DisabledProfileSources">List of disabled sources (one per line)</multiTextBox>
</presentation>
<presentation id="TermAppSelection">
<dropdownList refId="TermAppSelect" noSort="true" defaultItem="0">Select from the following options:</dropdownList>
</presentation>
</presentationTable>
</resources>
</policyDefinitionResources>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -8,5 +8,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
### Fonts Included
* Cascadia Code, Cascadia Mono (2404.23)
* from microsoft/cascadia-code@1034791e5fc6e060a448d2b29cd94a6c683edb36
* Cascadia Code, Cascadia Mono (2407.24)
* from microsoft/cascadia-code@56bcca3f2c1e4cb19458954f0e2bb4635960df91

View File

@@ -27,7 +27,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.22621.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.26100.0" />
</Dependencies>
<Resources>

View File

@@ -186,18 +186,20 @@ bool ImageSlice::_copyCells(const ImageSlice& srcSlice, const til::CoordType src
}
// The used destination before and after the written area must be erased.
if (dstUsedBegin < dstWriteBegin)
// If this results in the entire range being erased, we return true to let
// the caller know that the slice should be deleted.
if (dstUsedBegin < dstWriteBegin && _eraseCells(dstUsedBegin, dstWriteBegin))
{
_eraseCells(dstUsedBegin, dstWriteBegin);
return true;
}
if (dstUsedEnd > dstWriteEnd)
if (dstUsedEnd > dstWriteEnd && _eraseCells(dstWriteEnd, dstUsedEnd))
{
_eraseCells(dstWriteEnd, dstUsedEnd);
return true;
}
// If the beginning column is now not less than the end, that means the
// content has been entirely erased, so we return true to let the caller
// know that the slice should be deleted.
// At this point, if the beginning column is not less than the end, that
// means this was an empty slice into which nothing was copied, so we can
// again return true to let the caller know it should be deleted.
return _columnBegin >= _columnEnd;
}
@@ -210,10 +212,19 @@ void ImageSlice::EraseBlock(TextBuffer& buffer, const til::rect rect)
}
}
void ImageSlice::EraseCells(TextBuffer& buffer, const til::point at, const size_t distance)
void ImageSlice::EraseCells(TextBuffer& buffer, const til::point at, const til::CoordType distance)
{
auto& row = buffer.GetMutableRowByOffset(at.y);
EraseCells(row, at.x, gsl::narrow_cast<til::CoordType>(at.x + distance));
auto x = at.x;
auto y = at.y;
auto distanceRemaining = distance;
while (distanceRemaining > 0)
{
auto& row = buffer.GetMutableRowByOffset(y);
EraseCells(row, x, x + distanceRemaining);
distanceRemaining -= (static_cast<til::CoordType>(row.size()) - x);
x = 0;
y++;
}
}
void ImageSlice::EraseCells(ROW& row, const til::CoordType columnBegin, const til::CoordType columnEnd)

View File

@@ -41,7 +41,7 @@ public:
static void CopyRow(const ROW& srcRow, ROW& dstRow);
static void CopyCells(const ROW& srcRow, const til::CoordType srcColumn, ROW& dstRow, const til::CoordType dstColumnBegin, const til::CoordType dstColumnEnd);
static void EraseBlock(TextBuffer& buffer, const til::rect rect);
static void EraseCells(TextBuffer& buffer, const til::point at, const size_t distance);
static void EraseCells(TextBuffer& buffer, const til::point at, const til::CoordType distance);
static void EraseCells(ROW& row, const til::CoordType columnBegin, const til::CoordType columnEnd);
private:

View File

@@ -426,7 +426,7 @@ OutputCellIterator ROW::WriteCells(OutputCellIterator it, const til::CoordType c
THROW_HR_IF(E_INVALIDARG, limitRight.value_or(0) >= size());
// If we're given a right-side column limit, use it. Otherwise, the write limit is the final column index available in the char row.
const auto finalColumnInRow = limitRight.value_or(size() - 1);
const auto finalColumnInRow = gsl::narrow_cast<uint16_t>(limitRight.value_or(size() - 1));
auto currentColor = it->TextAttr();
uint16_t colorUses = 0;
@@ -937,12 +937,12 @@ void ROW::_resizeChars(uint16_t colEndDirty, uint16_t chBegDirty, size_t chEndDi
}
}
til::small_rle<TextAttribute, uint16_t, 1>& ROW::Attributes() noexcept
RowAttributes& ROW::Attributes() noexcept
{
return _attr;
}
const til::small_rle<TextAttribute, uint16_t, 1>& ROW::Attributes() const noexcept
const RowAttributes& ROW::Attributes() const noexcept
{
return _attr;
}

View File

@@ -14,6 +14,11 @@
class ROW;
class TextBuffer;
// Because MarkKind::Output gets set only on the actually written text,
// most rows will end up having at least 2 runs: The start of the line
// with MarkKind::Output and the rest of the line with MarkKind::None.
using RowAttributes = til::small_rle<TextAttribute, uint16_t, 2>;
enum class DelimiterClass
{
ControlChar,
@@ -148,8 +153,8 @@ public:
void ReplaceText(RowWriteState& state);
void CopyTextFrom(RowCopyTextFromState& state);
til::small_rle<TextAttribute, uint16_t, 1>& Attributes() noexcept;
const til::small_rle<TextAttribute, uint16_t, 1>& Attributes() const noexcept;
RowAttributes& Attributes() noexcept;
const RowAttributes& Attributes() const noexcept;
TextAttribute GetAttrByColumn(til::CoordType column) const;
std::vector<uint16_t> GetHyperlinks() const;
ImageSlice* SetImageSlice(ImageSlice::Pointer imageSlice) noexcept;
@@ -297,7 +302,7 @@ private:
std::span<uint16_t> _charOffsets;
// _attr is a run-length-encoded vector of TextAttribute with a decompressed
// length equal to _columnCount (= 1 TextAttribute per column).
til::small_rle<TextAttribute, uint16_t, 1> _attr;
RowAttributes _attr;
// The width of the row in visual columns.
uint16_t _columnCount = 0;
// Stores double-width/height (DECSWL/DECDWL/DECDHL) attributes.

View File

@@ -1917,41 +1917,6 @@ std::wstring TextBuffer::GetPlainText(const CopyRequest& req) const
return selectedText;
}
// Retrieves the text data from the buffer *with* ANSI escape code control sequences and presents it in
// a clipboard-ready format.
// Arguments:
// - req - the copy request having the bounds of the selected region and other related configuration flags.
// Return Value:
// - The text and control sequence data from the selected region of the text buffer. Empty if the copy request
// is invalid.
std::wstring TextBuffer::GetWithControlSequences(const CopyRequest& req) const
{
if (req.beg > req.end)
{
return {};
}
std::wstring selectedText;
std::optional<TextAttribute> previousTextAttr;
bool delayedLineBreak = false;
const auto firstRow = req.beg.y;
const auto lastRow = req.end.y;
for (til::CoordType currentRow = firstRow; currentRow <= lastRow; currentRow++)
{
const auto& row = GetRowByOffset(currentRow);
const auto [startX, endX, reqAddLineBreak] = _RowCopyHelper(req, currentRow, row);
const bool isLastRow = currentRow == lastRow;
const bool addLineBreak = reqAddLineBreak && !isLastRow;
_SerializeRow(row, startX, endX, addLineBreak, isLastRow, selectedText, previousTextAttr, delayedLineBreak);
}
return selectedText;
}
// Routine Description:
// - Generates a CF_HTML compliant structure from the selected region of the buffer
// Arguments:
@@ -2383,7 +2348,7 @@ void TextBuffer::_AppendRTFText(std::string& contentBuilder, const std::wstring_
}
}
void TextBuffer::SerializeToPath(const wchar_t* destination) const
void TextBuffer::Serialize(const wchar_t* destination) const
{
const wil::unique_handle file{ CreateFileW(destination, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr) };
THROW_LAST_ERROR_IF(!file);
@@ -2393,26 +2358,268 @@ void TextBuffer::SerializeToPath(const wchar_t* destination) const
buffer.reserve(writeThreshold + writeThreshold / 2);
buffer.push_back(L'\uFEFF');
std::optional<TextAttribute> previousTextAttr;
const til::CoordType lastRowWithText = GetLastNonSpaceCharacter(nullptr).y;
CharacterAttributes previousAttr = CharacterAttributes::Unused1;
TextColor previousFg;
TextColor previousBg;
TextColor previousUl;
uint16_t previousHyperlinkId = 0;
bool delayedLineBreak = false;
const til::CoordType firstRow = 0;
const til::CoordType lastRow = GetLastNonSpaceCharacter(nullptr).y;
// This iterates through each row. The exit condition is at the end
// of the for() loop so that we can properly handle file flushing.
for (til::CoordType currentRow = firstRow;; currentRow++)
for (til::CoordType currentRow = 0;; currentRow++)
{
const auto& row = GetRowByOffset(currentRow);
const auto isLastRow = currentRow == lastRow;
const auto startX = 0;
const auto endX = row.GetReadableColumnCount();
const bool addLineBreak = !row.WasWrapForced() || isLastRow;
if (const auto lr = row.GetLineRendition(); lr != LineRendition::SingleWidth)
{
static constexpr std::wstring_view mappings[] = {
L"\x1b#6", // LineRendition::DoubleWidth
L"\x1b#3", // LineRendition::DoubleHeightTop
L"\x1b#4", // LineRendition::DoubleHeightBottom
};
const auto idx = std::clamp(static_cast<int>(lr) - 1, 0, 2);
buffer.append(til::at(mappings, idx));
}
_SerializeRow(row, startX, endX, addLineBreak, isLastRow, buffer, previousTextAttr, delayedLineBreak);
const auto& runs = row.Attributes().runs();
const auto beg = runs.begin();
const auto end = runs.end();
auto it = beg;
const auto last = end - 1;
const auto lastCharX = row.MeasureRight();
til::CoordType oldX = 0;
if (buffer.size() >= writeThreshold || isLastRow)
for (; it != end; ++it)
{
const auto attr = it->value.GetCharacterAttributes();
const auto hyperlinkId = it->value.GetHyperlinkId();
const auto fg = it->value.GetForeground();
const auto bg = it->value.GetBackground();
const auto ul = it->value.GetUnderlineColor();
if (previousAttr != attr)
{
auto attrDelta = attr ^ previousAttr;
// There's no escape sequence that only turns off either bold/intense or dim/faint. SGR 22 turns off both.
// This results in two issues in our generic "Mapping" code below. Assuming, both Intense and Faint were on...
// * ...and either turned off, it would emit SGR 22 which turns both attributes off = Wrong.
// * ...and both are now off, it would emit SGR 22 twice.
//
// This extra branch takes care of both issues. If both attributes turned off it'll emit a single \x1b[22m,
// if faint turned off \x1b[22;1m (intense is still on), and \x1b[22;2m if intense turned off (vice versa).
if (WI_AreAllFlagsSet(previousAttr, CharacterAttributes::Intense | CharacterAttributes::Faint) &&
WI_IsAnyFlagSet(attrDelta, CharacterAttributes::Intense | CharacterAttributes::Faint))
{
wchar_t buf[8] = L"\x1b[22m";
size_t len = 5;
if (WI_IsAnyFlagSet(attr, CharacterAttributes::Intense | CharacterAttributes::Faint))
{
buf[4] = L';';
buf[5] = WI_IsAnyFlagSet(attr, CharacterAttributes::Intense) ? L'1' : L'2';
buf[6] = L'm';
len = 7;
}
buffer.append(&buf[0], len);
WI_ClearAllFlags(attrDelta, CharacterAttributes::Intense | CharacterAttributes::Faint);
}
{
struct Mapping
{
CharacterAttributes attr;
uint8_t change[2]; // [0] = off, [1] = on
};
static constexpr Mapping mappings[] = {
{ CharacterAttributes::Intense, { 22, 1 } },
{ CharacterAttributes::Italics, { 23, 3 } },
{ CharacterAttributes::Blinking, { 25, 5 } },
{ CharacterAttributes::Invisible, { 28, 8 } },
{ CharacterAttributes::CrossedOut, { 29, 9 } },
{ CharacterAttributes::Faint, { 22, 2 } },
{ CharacterAttributes::TopGridline, { 55, 53 } },
{ CharacterAttributes::ReverseVideo, { 27, 7 } },
};
for (const auto& mapping : mappings)
{
if (WI_IsAnyFlagSet(attrDelta, mapping.attr))
{
const auto n = til::at(mapping.change, WI_IsAnyFlagSet(attr, mapping.attr));
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[{}m"), n);
}
}
}
if (WI_IsAnyFlagSet(attrDelta, CharacterAttributes::UnderlineStyle))
{
static constexpr std::wstring_view mappings[] = {
L"\x1b[24m", // UnderlineStyle::NoUnderline
L"\x1b[4m", // UnderlineStyle::SinglyUnderlined
L"\x1b[21m", // UnderlineStyle::DoublyUnderlined
L"\x1b[4:3m", // UnderlineStyle::CurlyUnderlined
L"\x1b[4:4m", // UnderlineStyle::DottedUnderlined
L"\x1b[4:5m", // UnderlineStyle::DashedUnderlined
};
auto idx = WI_EnumValue(it->value.GetUnderlineStyle());
if (idx >= std::size(mappings))
{
idx = 1; // UnderlineStyle::SinglyUnderlined
}
buffer.append(til::at(mappings, idx));
}
previousAttr = attr;
}
if (previousFg != fg)
{
switch (fg.GetType())
{
case ColorType::IsDefault:
buffer.append(L"\x1b[39m");
break;
case ColorType::IsIndex16:
{
uint8_t index = WI_IsFlagSet(fg.GetIndex(), 8) ? 90 : 30;
index += fg.GetIndex() & 7;
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[{}m"), index);
break;
}
case ColorType::IsIndex256:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[38;5;{}m"), fg.GetIndex());
break;
case ColorType::IsRgb:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[38;2;{};{};{}m"), fg.GetR(), fg.GetG(), fg.GetB());
break;
default:
break;
}
previousFg = fg;
}
if (previousBg != bg)
{
switch (bg.GetType())
{
case ColorType::IsDefault:
buffer.append(L"\x1b[49m");
break;
case ColorType::IsIndex16:
{
uint8_t index = WI_IsFlagSet(bg.GetIndex(), 8) ? 100 : 40;
index += bg.GetIndex() & 7;
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[{}m"), index);
break;
}
case ColorType::IsIndex256:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[48;5;{}m"), bg.GetIndex());
break;
case ColorType::IsRgb:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[48;2;{};{};{}m"), bg.GetR(), bg.GetG(), bg.GetB());
break;
default:
break;
}
previousBg = bg;
}
if (previousUl != ul)
{
switch (fg.GetType())
{
case ColorType::IsDefault:
buffer.append(L"\x1b[59m");
break;
case ColorType::IsIndex256:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[58:5:{}m"), ul.GetIndex());
break;
case ColorType::IsRgb:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[58:2::{}:{}:{}m"), ul.GetR(), ul.GetG(), ul.GetB());
break;
default:
break;
}
previousUl = ul;
}
if (previousHyperlinkId != hyperlinkId)
{
if (hyperlinkId)
{
const auto uri = GetHyperlinkUriFromId(hyperlinkId);
if (!uri.empty())
{
buffer.append(L"\x1b]8;;");
buffer.append(uri);
buffer.append(L"\x1b\\");
previousHyperlinkId = hyperlinkId;
}
}
else
{
buffer.append(L"\x1b]8;;\x1b\\");
previousHyperlinkId = 0;
}
}
// Initially, the buffer is initialized with the default attributes, but once it begins to scroll,
// newly scrolled in rows are initialized with the current attributes. This means we need to set
// the current attributes to those of the upcoming row before the row comes up. Or inversely:
// We let the row come up, let it set its attributes and only then print the newline.
if (delayedLineBreak)
{
buffer.append(L"\r\n");
delayedLineBreak = false;
}
auto newX = oldX + it->length;
// Since our text buffer doesn't store the original input text, the information over the amount of trailing
// whitespaces was lost. If we don't do anything here then a row that just says "Hello" would be serialized
// to "Hello ...". If the user restores the buffer dump with a different window size,
// this would result in some fairly ugly reflow. This code attempts to at least trim trailing whitespaces.
//
// As mentioned above for `delayedLineBreak`, rows are initialized with their first attribute, BUT
// only if the viewport has begun to scroll. Otherwise, they're initialized with the default attributes.
// In other words, we can only skip \x1b[K = Erase in Line, if both the first/last attribute are the default attribute.
static constexpr TextAttribute defaultAttr;
const auto trimTrailingWhitespaces = it == last && lastCharX < newX;
const auto clearToEndOfLine = trimTrailingWhitespaces && (beg->value != defaultAttr || last->value != defaultAttr);
if (trimTrailingWhitespaces)
{
newX = lastCharX;
}
buffer.append(row.GetText(oldX, newX));
if (clearToEndOfLine)
{
buffer.append(L"\x1b[K");
}
oldX = newX;
}
const auto moreRowsRemaining = currentRow < lastRowWithText;
delayedLineBreak = !row.WasWrapForced();
if (!moreRowsRemaining)
{
if (previousHyperlinkId)
{
buffer.append(L"\x1b]8;;\x1b\\");
}
buffer.append(L"\x1b[m\r\n");
}
if (buffer.size() >= writeThreshold || !moreRowsRemaining)
{
const auto fileSize = gsl::narrow<DWORD>(buffer.size() * sizeof(wchar_t));
DWORD bytesWritten = 0;
@@ -2421,294 +2628,13 @@ void TextBuffer::SerializeToPath(const wchar_t* destination) const
buffer.clear();
}
if (isLastRow)
if (!moreRowsRemaining)
{
break;
}
}
}
// Serializes one row of the text buffer including ANSI escape code control sequences.
// Arguments:
// - row - A reference to the row being serialized.
// - startX - The first column (inclusive) to include in the serialized content.
// - endX - The last column (exclusive) to include in the serialized content.
// - addLineBreak - Whether to add a line break at the end of the serialized row.
// - isLastRow - Whether this is the final row to be serialized.
// - buffer - A string to write the serialized row into.
// - previousTextAttr - Used for tracking state across multiple calls to `_SerializeRow` for sequential rows.
// The value will be mutated by the call. The initial call should contain `nullopt`, and subsequent calls
// should pass the value that was written by the previous call.
// - delayedLineBreak - Similarly used for tracking state across multiple calls, and similarly will be mutated
// by the call. The initial call should pass `false` and subsequent calls should pass the value that was
// written by the previous call.
void TextBuffer::_SerializeRow(const ROW& row, const til::CoordType startX, const til::CoordType endX, const bool addLineBreak, const bool isLastRow, std::wstring& buffer, std::optional<TextAttribute>& previousTextAttr, bool& delayedLineBreak) const
{
if (const auto lr = row.GetLineRendition(); lr != LineRendition::SingleWidth)
{
static constexpr std::wstring_view mappings[] = {
L"\x1b#6", // LineRendition::DoubleWidth
L"\x1b#3", // LineRendition::DoubleHeightTop
L"\x1b#4", // LineRendition::DoubleHeightBottom
};
const auto idx = std::clamp(static_cast<int>(lr) - 1, 0, 2);
buffer.append(til::at(mappings, idx));
}
const auto startXU16 = gsl::narrow_cast<uint16_t>(startX);
const auto endXU16 = gsl::narrow_cast<uint16_t>(endX);
const auto runs = row.Attributes().slice(startXU16, endXU16).runs();
const auto beg = runs.begin();
const auto end = runs.end();
auto it = beg;
// Don't try to get `end - 1` if it's an empty iterator; in this case we're going to ignore the `last`
// value anyway so just use `end`.
const auto last = it == end ? end : end - 1;
const auto lastCharX = row.MeasureRight();
til::CoordType oldX = startX;
for (; it != end; ++it)
{
const auto effectivePreviousTextAttr = previousTextAttr.value_or(TextAttribute{ CharacterAttributes::Unused1, TextColor{}, TextColor{}, 0, TextColor{} });
const auto previousAttr = effectivePreviousTextAttr.GetCharacterAttributes();
const auto previousHyperlinkId = effectivePreviousTextAttr.GetHyperlinkId();
const auto previousFg = effectivePreviousTextAttr.GetForeground();
const auto previousBg = effectivePreviousTextAttr.GetBackground();
const auto previousUl = effectivePreviousTextAttr.GetUnderlineColor();
const auto attr = it->value.GetCharacterAttributes();
const auto hyperlinkId = it->value.GetHyperlinkId();
const auto fg = it->value.GetForeground();
const auto bg = it->value.GetBackground();
const auto ul = it->value.GetUnderlineColor();
if (previousAttr != attr)
{
auto attrDelta = attr ^ previousAttr;
// There's no escape sequence that only turns off either bold/intense or dim/faint. SGR 22 turns off both.
// This results in two issues in our generic "Mapping" code below. Assuming, both Intense and Faint were on...
// * ...and either turned off, it would emit SGR 22 which turns both attributes off = Wrong.
// * ...and both are now off, it would emit SGR 22 twice.
//
// This extra branch takes care of both issues. If both attributes turned off it'll emit a single \x1b[22m,
// if faint turned off \x1b[22;1m (intense is still on), and \x1b[22;2m if intense turned off (vice versa).
if (WI_AreAllFlagsSet(previousAttr, CharacterAttributes::Intense | CharacterAttributes::Faint) &&
WI_IsAnyFlagSet(attrDelta, CharacterAttributes::Intense | CharacterAttributes::Faint))
{
wchar_t buf[8] = L"\x1b[22m";
size_t len = 5;
if (WI_IsAnyFlagSet(attr, CharacterAttributes::Intense | CharacterAttributes::Faint))
{
buf[4] = L';';
buf[5] = WI_IsAnyFlagSet(attr, CharacterAttributes::Intense) ? L'1' : L'2';
buf[6] = L'm';
len = 7;
}
buffer.append(&buf[0], len);
WI_ClearAllFlags(attrDelta, CharacterAttributes::Intense | CharacterAttributes::Faint);
}
{
struct Mapping
{
CharacterAttributes attr;
uint8_t change[2]; // [0] = off, [1] = on
};
static constexpr Mapping mappings[] = {
{ CharacterAttributes::Intense, { 22, 1 } },
{ CharacterAttributes::Italics, { 23, 3 } },
{ CharacterAttributes::Blinking, { 25, 5 } },
{ CharacterAttributes::Invisible, { 28, 8 } },
{ CharacterAttributes::CrossedOut, { 29, 9 } },
{ CharacterAttributes::Faint, { 22, 2 } },
{ CharacterAttributes::TopGridline, { 55, 53 } },
{ CharacterAttributes::ReverseVideo, { 27, 7 } },
};
for (const auto& mapping : mappings)
{
if (WI_IsAnyFlagSet(attrDelta, mapping.attr))
{
const auto n = til::at(mapping.change, WI_IsAnyFlagSet(attr, mapping.attr));
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[{}m"), n);
}
}
}
if (WI_IsAnyFlagSet(attrDelta, CharacterAttributes::UnderlineStyle))
{
static constexpr std::wstring_view mappings[] = {
L"\x1b[24m", // UnderlineStyle::NoUnderline
L"\x1b[4m", // UnderlineStyle::SinglyUnderlined
L"\x1b[21m", // UnderlineStyle::DoublyUnderlined
L"\x1b[4:3m", // UnderlineStyle::CurlyUnderlined
L"\x1b[4:4m", // UnderlineStyle::DottedUnderlined
L"\x1b[4:5m", // UnderlineStyle::DashedUnderlined
};
auto idx = WI_EnumValue(it->value.GetUnderlineStyle());
if (idx >= std::size(mappings))
{
idx = 1; // UnderlineStyle::SinglyUnderlined
}
buffer.append(til::at(mappings, idx));
}
}
if (previousFg != fg)
{
switch (fg.GetType())
{
case ColorType::IsDefault:
buffer.append(L"\x1b[39m");
break;
case ColorType::IsIndex16:
{
uint8_t index = WI_IsFlagSet(fg.GetIndex(), 8) ? 90 : 30;
index += fg.GetIndex() & 7;
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[{}m"), index);
break;
}
case ColorType::IsIndex256:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[38;5;{}m"), fg.GetIndex());
break;
case ColorType::IsRgb:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[38;2;{};{};{}m"), fg.GetR(), fg.GetG(), fg.GetB());
break;
default:
break;
}
}
if (previousBg != bg)
{
switch (bg.GetType())
{
case ColorType::IsDefault:
buffer.append(L"\x1b[49m");
break;
case ColorType::IsIndex16:
{
uint8_t index = WI_IsFlagSet(bg.GetIndex(), 8) ? 100 : 40;
index += bg.GetIndex() & 7;
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[{}m"), index);
break;
}
case ColorType::IsIndex256:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[48;5;{}m"), bg.GetIndex());
break;
case ColorType::IsRgb:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[48;2;{};{};{}m"), bg.GetR(), bg.GetG(), bg.GetB());
break;
default:
break;
}
}
if (previousUl != ul)
{
switch (fg.GetType())
{
case ColorType::IsDefault:
buffer.append(L"\x1b[59m");
break;
case ColorType::IsIndex256:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[58:5:{}m"), ul.GetIndex());
break;
case ColorType::IsRgb:
fmt::format_to(std::back_inserter(buffer), FMT_COMPILE(L"\x1b[58:2::{}:{}:{}m"), ul.GetR(), ul.GetG(), ul.GetB());
break;
default:
break;
}
}
if (previousHyperlinkId != hyperlinkId)
{
if (hyperlinkId)
{
const auto uri = GetHyperlinkUriFromId(hyperlinkId);
if (!uri.empty())
{
buffer.append(L"\x1b]8;;");
buffer.append(uri);
buffer.append(L"\x1b\\");
}
}
else
{
buffer.append(L"\x1b]8;;\x1b\\");
}
}
previousTextAttr = it->value;
// Initially, the buffer is initialized with the default attributes, but once it begins to scroll,
// newly scrolled in rows are initialized with the current attributes. This means we need to set
// the current attributes to those of the upcoming row before the row comes up. Or inversely:
// We let the row come up, let it set its attributes and only then print the newline.
if (delayedLineBreak)
{
buffer.append(L"\r\n");
delayedLineBreak = false;
}
auto newX = oldX + it->length;
// Since our text buffer doesn't store the original input text, the information over the amount of trailing
// whitespaces was lost. If we don't do anything here then a row that just says "Hello" would be serialized
// to "Hello ...". If the user restores the buffer dump with a different window size,
// this would result in some fairly ugly reflow. This code attempts to at least trim trailing whitespaces.
//
// As mentioned above for `delayedLineBreak`, rows are initialized with their first attribute, BUT
// only if the viewport has begun to scroll. Otherwise, they're initialized with the default attributes.
// In other words, we can only skip \x1b[K = Erase in Line, if both the first/last attribute are the default attribute.
static constexpr TextAttribute defaultAttr;
const auto trimTrailingWhitespaces = it == last && lastCharX < newX;
const auto clearToEndOfLine = trimTrailingWhitespaces && (beg->value != defaultAttr || last->value != defaultAttr);
if (trimTrailingWhitespaces)
{
newX = lastCharX;
}
buffer.append(row.GetText(oldX, newX));
if (clearToEndOfLine)
{
buffer.append(L"\x1b[K");
}
oldX = newX;
}
// Handle empty rows (with no runs). See above for more details about `delayedLineBreak`.
if (delayedLineBreak)
{
buffer.append(L"\r\n");
delayedLineBreak = false;
}
delayedLineBreak = !row.WasWrapForced() && addLineBreak;
if (isLastRow)
{
if (previousTextAttr.has_value() && previousTextAttr->GetHyperlinkId())
{
buffer.append(L"\x1b]8;;\x1b\\");
}
buffer.append(L"\x1b[0m");
if (addLineBreak)
{
buffer.append(L"\r\n");
}
}
}
// Function Description:
// - Reflow the contents from the old buffer into the new buffer. The new buffer
// can have different dimensions than the old buffer. If it does, then this

View File

@@ -266,8 +266,6 @@ public:
std::wstring GetPlainText(const CopyRequest& req) const;
std::wstring GetWithControlSequences(const CopyRequest& req) const;
std::string GenHTML(const CopyRequest& req,
const int fontHeightPoints,
const std::wstring_view fontFaceName,
@@ -282,7 +280,7 @@ public:
const bool isIntenseBold,
std::function<std::tuple<COLORREF, COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors) const noexcept;
void SerializeToPath(const wchar_t* destination) const;
void Serialize(const wchar_t* destination) const;
struct PositionInformation
{
@@ -334,8 +332,6 @@ private:
std::tuple<til::CoordType, til::CoordType, bool> _RowCopyHelper(const CopyRequest& req, const til::CoordType iRow, const ROW& row) const;
void _SerializeRow(const ROW& row, const til::CoordType startX, const til::CoordType endX, const bool addLineBreak, const bool isLastRow, std::wstring& buffer, std::optional<TextAttribute>& previousTextAttr, bool& delayedLineBreak) const;
static void _AppendRTFText(std::string& contentBuilder, const std::wstring_view& text);
Microsoft::Console::Render::Renderer* _renderer = nullptr;

View File

@@ -38,7 +38,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.22621.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.26100.0" />
</Dependencies>
<Resources>

View File

@@ -38,7 +38,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.22621.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.26100.0" />
</Dependencies>
<Resources>

View File

@@ -39,7 +39,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.22621.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.26100.0" />
</Dependencies>
<Resources>

View File

@@ -39,7 +39,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.22621.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.26100.0" />
</Dependencies>
<Resources>

View File

@@ -7,6 +7,7 @@
<ProjectName>elevate-shim</ProjectName>
<TargetName>elevate-shim</TargetName>
<ConfigurationType>Application</ConfigurationType>
<VersionInfoFileDescription>Windows Terminal Administrator Launch Helper</VersionInfoFileDescription>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />

View File

@@ -10,6 +10,7 @@
<SubSystem>Console</SubSystem>
<!-- suppress a bunch of Windows Universal properties from cppwinrt.props -->
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
<VersionInfoFileDescription>Windows Terminal Open Here Shell Extension</VersionInfoFileDescription>
</PropertyGroup>
<PropertyGroup Label="NuGet Dependencies">
<TerminalCppWinrt>true</TerminalCppWinrt>

View File

@@ -118,7 +118,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_HandleCloseWindow(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
CloseRequested.raise(nullptr, nullptr);
CloseWindow();
args.Handled(true);
}
@@ -548,7 +548,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& realArgs = args.ActionArgs().try_as<CopyTextArgs>())
{
const auto handled = _CopyText(realArgs.DismissSelection(), realArgs.SingleLine(), realArgs.WithControlSequences(), realArgs.CopyFormatting());
const auto handled = _CopyText(realArgs.DismissSelection(), realArgs.SingleLine(), realArgs.CopyFormatting());
args.Handled(handled);
}
}

View File

@@ -83,8 +83,6 @@ static winrt::hstring _GetErrorText(SettingsLoadErrors error)
return _GetMessageText(static_cast<uint32_t>(error), settingsLoadErrorsLabels);
}
static constexpr std::wstring_view StartupTaskName = L"StartTerminalOnLoginTask";
namespace winrt::TerminalApp::implementation
{
// Function Description:
@@ -337,8 +335,16 @@ namespace winrt::TerminalApp::implementation
void AppLogic::_ApplyLanguageSettingChange() noexcept
try
{
const auto language = _settings.GlobalSettings().Language();
if (!IsPackaged())
{
if (!language.empty())
{
// We cannot use the packaged app API, PrimaryLanguageOverride, but we *can* tell the resource loader
// to set the Language for all loaded resources to the user's preferred language.
winrt::Windows::ApplicationModel::Resources::Core::ResourceContext::SetGlobalQualifierValue(L"Language", language);
}
return;
}
@@ -346,8 +352,6 @@ namespace winrt::TerminalApp::implementation
// NOTE: PrimaryLanguageOverride throws if this instance is unpackaged.
const auto primaryLanguageOverride = ApplicationLanguages::PrimaryLanguageOverride();
const auto language = _settings.GlobalSettings().Language();
if (primaryLanguageOverride != language)
{
ApplicationLanguages::PrimaryLanguageOverride(language);
@@ -355,40 +359,6 @@ namespace winrt::TerminalApp::implementation
}
CATCH_LOG()
safe_void_coroutine AppLogic::_ApplyStartupTaskStateChange()
try
{
// First, make sure we're running in a packaged context. This method
// won't work, and will crash mysteriously if we're running unpackaged.
if (!IsPackaged())
{
co_return;
}
const auto tryEnableStartupTask = _settings.GlobalSettings().StartOnUserLogin();
const auto task = co_await StartupTask::GetAsync(StartupTaskName);
switch (task.State())
{
case StartupTaskState::Disabled:
if (tryEnableStartupTask)
{
co_await task.RequestEnableAsync();
}
break;
case StartupTaskState::DisabledByUser:
// TODO: GH#6254: define UX for other StartupTaskStates
break;
case StartupTaskState::Enabled:
if (!tryEnableStartupTask)
{
task.Disable();
}
break;
}
}
CATCH_LOG();
// Method Description:
// - Reloads the settings from the settings.json file.
// - When this is called the first time, this initializes our settings. See
@@ -426,7 +396,7 @@ namespace winrt::TerminalApp::implementation
auto ev = winrt::make_self<SettingsLoadEventArgs>(true,
static_cast<uint64_t>(_settingsLoadedResult),
_settingsLoadExceptionText,
warnings,
warnings.GetView(),
_settings);
SettingsChanged.raise(*this, *ev);
return;
@@ -448,7 +418,6 @@ namespace winrt::TerminalApp::implementation
// TerminalSettings object.
_ApplyLanguageSettingChange();
_ApplyStartupTaskStateChange();
_ProcessLazySettingsChanges();
auto warnings{ winrt::multi_threaded_vector<SettingsLoadWarnings>() };
@@ -459,7 +428,7 @@ namespace winrt::TerminalApp::implementation
auto ev = winrt::make_self<SettingsLoadEventArgs>(!initialLoad,
_settingsLoadedResult,
_settingsLoadExceptionText,
warnings,
warnings.GetView(),
_settings);
SettingsChanged.raise(*this, *ev);
}
@@ -475,7 +444,6 @@ namespace winrt::TerminalApp::implementation
// Both LoadSettings and ReloadSettings are supposed to call this function,
// but LoadSettings skips it, so that the UI starts up faster.
// Now that the UI is present we can do them with a less significant UX impact.
_ApplyStartupTaskStateChange();
_ProcessLazySettingsChanges();
FILETIME creationTime, exitTime, kernelTime, userTime, now;
@@ -688,7 +656,7 @@ namespace winrt::TerminalApp::implementation
auto ev = winrt::make_self<SettingsLoadEventArgs>(false,
_settingsLoadedResult,
_settingsLoadExceptionText,
warnings,
warnings.GetView(),
_settings);
auto window = winrt::make_self<implementation::TerminalWindow>(*ev, _contentManager);

View File

@@ -103,7 +103,6 @@ namespace winrt::TerminalApp::implementation
const Microsoft::Terminal::Settings::Model::WindowingMode& windowingBehavior);
void _ApplyLanguageSettingChange() noexcept;
safe_void_coroutine _ApplyStartupTaskStateChange();
[[nodiscard]] HRESULT _TryLoadSettings() noexcept;
void _ProcessLazySettingsChanges();

View File

@@ -359,7 +359,7 @@ namespace winrt::TerminalApp::implementation
_switchToMode(CommandPaletteMode::CommandlineMode);
e.Handled(true);
}
else if (key == VirtualKey::C && ctrlDown)
else if ((key == VirtualKey::C || key == VirtualKey::Insert) && ctrlDown)
{
_searchBox().CopySelectionToClipboard();
e.Handled(true);

View File

@@ -60,9 +60,12 @@ namespace winrt::Microsoft::TerminalApp::implementation
DebugTapConnection::DebugTapConnection(ITerminalConnection wrappedConnection)
{
_outputRevoker = wrappedConnection.TerminalOutput(winrt::auto_revoke, { this, &DebugTapConnection::_OutputHandler });
_stateChangedRevoker = wrappedConnection.StateChanged(winrt::auto_revoke, [this](auto&& /*s*/, auto&& /*e*/) {
StateChanged.raise(*this, nullptr);
_outputRevoker = wrappedConnection.TerminalOutput(winrt::auto_revoke, { get_weak(), &DebugTapConnection::_OutputHandler });
_stateChangedRevoker = wrappedConnection.StateChanged(winrt::auto_revoke, [weak = get_weak()](auto&& /*s*/, auto&& /*e*/) {
if (const auto self = weak.get())
{
self->StateChanged.raise(*self, nullptr);
}
});
_wrappedConnection = wrappedConnection;
}

View File

@@ -1,202 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "MarkdownPaneContent.h"
#include <LibraryResources.h>
#include "MarkdownPaneContent.g.cpp"
#include <til/io.h>
using namespace std::chrono_literals;
using namespace winrt::Microsoft::Terminal;
using namespace winrt::Microsoft::Terminal::Settings;
using namespace winrt::Microsoft::Terminal::Settings::Model;
namespace winrt
{
namespace MUX = Microsoft::UI::Xaml;
namespace WUX = Windows::UI::Xaml;
using IInspectable = Windows::Foundation::IInspectable;
}
namespace winrt::TerminalApp::implementation
{
MarkdownPaneContent::MarkdownPaneContent() :
MarkdownPaneContent(L"") {}
MarkdownPaneContent::MarkdownPaneContent(const winrt::hstring& initialPath)
{
InitializeComponent();
FilePathInput().Text(initialPath);
_filePath = FilePathInput().Text();
_loadFile();
}
INewContentArgs MarkdownPaneContent::GetNewTerminalArgs(BuildStartupKind /*kind*/) const
{
return BaseContentArgs(L"x-markdown");
}
void MarkdownPaneContent::_clearOldNotebook()
{
RenderedMarkdown().Children().Clear();
}
void MarkdownPaneContent::_loadFile()
{
if (_filePath.empty())
{
return;
}
// Our title is the path of our MD file
TitleChanged.raise(*this, nullptr);
const std::filesystem::path filePath{ std::wstring_view{ _filePath } };
const auto markdownContents{ til::io::read_file_as_utf8_string_if_exists(filePath) };
Editing(false);
PropertyChanged.raise(*this, WUX::Data::PropertyChangedEventArgs{ L"Editing" });
FileContents(winrt::to_hstring(markdownContents));
PropertyChanged.raise(*this, WUX::Data::PropertyChangedEventArgs{ L"FileContents" });
_renderFileContents();
}
void MarkdownPaneContent::_renderFileContents()
{
// Was the file a .md file?
if (_filePath.ends_with(L".md"))
{
_loadMarkdown();
}
else
{
_loadText();
}
}
void MarkdownPaneContent::_loadText()
{
auto block = WUX::Controls::TextBlock();
block.IsTextSelectionEnabled(true);
block.FontFamily(WUX::Media::FontFamily{ L"Cascadia Code" });
block.Text(FileContents());
RenderedMarkdown().Children().Append(block);
}
void MarkdownPaneContent::_loadMarkdown()
{
auto rootTextBlock{ Microsoft::Terminal::UI::Markdown::Builder::Convert(FileContents(), _filePath) };
// By default, the markdown pane doesn't have play buttons next to the
// blocks. But to demonstrate how that's possible:
for (const auto& b : rootTextBlock.Blocks())
{
if (const auto& p{ b.try_as<WUX::Documents::Paragraph>() })
{
for (const auto& line : p.Inlines())
{
if (const auto& otherContent{ line.try_as<WUX::Documents::InlineUIContainer>() })
{
if (const auto& codeBlock{ otherContent.Child().try_as<Microsoft::Terminal::UI::Markdown::CodeBlock>() })
{
codeBlock.PlayButtonVisibility(WUX::Visibility::Visible);
codeBlock.RequestRunCommands({ this, &MarkdownPaneContent::_handleRunCommandRequest });
}
}
}
}
}
RenderedMarkdown().Children().Append(rootTextBlock);
}
void MarkdownPaneContent::_loadTapped(const Windows::Foundation::IInspectable&, const Windows::UI::Xaml::Input::TappedRoutedEventArgs&)
{
_filePath = FilePathInput().Text();
// Does the file exist? if not, bail
const wil::unique_handle file{ CreateFileW(_filePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr) };
if (!file)
{
return;
}
// It does. Clear the old one
_clearOldNotebook();
_loadFile();
}
void MarkdownPaneContent::_editTapped(const Windows::Foundation::IInspectable&, const Windows::UI::Xaml::Input::TappedRoutedEventArgs&)
{
if (Editing())
{
_clearOldNotebook();
_renderFileContents();
EditIcon().Glyph(L"\xe932"); // Label
_scrollViewer().Visibility(WUX::Visibility::Visible);
_editor().Visibility(WUX::Visibility::Collapsed);
Editing(false);
}
else
{
EditIcon().Glyph(L"\xe890"); // View
_scrollViewer().Visibility(WUX::Visibility::Collapsed);
_editor().Visibility(WUX::Visibility::Visible);
Editing(true);
}
PropertyChanged.raise(*this, WUX::Data::PropertyChangedEventArgs{ L"Editing" });
}
void MarkdownPaneContent::_closeTapped(const Windows::Foundation::IInspectable&, const Windows::UI::Xaml::Input::TappedRoutedEventArgs&)
{
CloseRequested.raise(*this, nullptr);
}
void MarkdownPaneContent::_handleRunCommandRequest(const Microsoft::Terminal::UI::Markdown::CodeBlock& /*sender*/,
const Microsoft::Terminal::UI::Markdown::RequestRunCommandsArgs& request)
{
auto text = request.Commandlines();
if (const auto& strongControl{ _control.get() })
{
Model::ActionAndArgs actionAndArgs{ ShortcutAction::SendInput, Model::SendInputArgs{ text } };
// By using the last active control as the sender here, the
// action dispatch will send this to the active control,
// thinking that it is the control that requested this event.
DispatchActionRequested.raise(strongControl, actionAndArgs);
strongControl.Focus(winrt::WUX::FocusState::Programmatic);
}
}
#pragma region IPaneContent
winrt::Windows::UI::Xaml::FrameworkElement MarkdownPaneContent::GetRoot()
{
return *this;
}
void MarkdownPaneContent::Close()
{
CloseRequested.raise(*this, nullptr);
}
winrt::hstring MarkdownPaneContent::Icon() const
{
static constexpr std::wstring_view glyph{ L"\xe70b" }; // QuickNote
return winrt::hstring{ glyph };
}
#pragma endregion
void MarkdownPaneContent::SetLastActiveControl(const Microsoft::Terminal::Control::TermControl& control)
{
_control = control;
}
}

View File

@@ -1,74 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "MarkdownPaneContent.g.h"
#include "BasicPaneEvents.h"
namespace winrt::TerminalApp::implementation
{
struct MarkdownPaneContent : MarkdownPaneContentT<MarkdownPaneContent>, BasicPaneEvents
{
public:
MarkdownPaneContent();
MarkdownPaneContent(const winrt::hstring& filePath);
til::property<bool> Editing{ false };
til::property<winrt::hstring> FileContents{ L"" };
void SetLastActiveControl(const Microsoft::Terminal::Control::TermControl& control);
// TODO! this should just be til::property_changed_event but I don't have that commit here
til::event<winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler> PropertyChanged;
#pragma region IPaneContent
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings&){};
winrt::Windows::Foundation::Size MinimumSize() { return { 1, 1 }; };
void Focus(winrt::Windows::UI::Xaml::FocusState reason = winrt::Windows::UI::Xaml::FocusState::Programmatic) { reason; };
void Close();
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
winrt::hstring Title() { return _filePath; }
uint64_t TaskbarState() { return 0; }
uint64_t TaskbarProgress() { return 0; }
bool ReadOnly() { return false; }
winrt::hstring Icon() const;
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() const noexcept { return nullptr; }
winrt::Windows::UI::Xaml::Media::Brush BackgroundBrush() { return Background(); }
// See BasicPaneEvents for most generic event definitions
#pragma endregion
til::typed_event<winrt::Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::ActionAndArgs> DispatchActionRequested;
void _handleRunCommandRequest(const Microsoft::Terminal::UI::Markdown::CodeBlock& sender,
const Microsoft::Terminal::UI::Markdown::RequestRunCommandsArgs& control);
private:
friend struct MarkdownPaneContentT<MarkdownPaneContent>; // for Xaml to bind events
winrt::hstring _filePath{};
winrt::weak_ref<Microsoft::Terminal::Control::TermControl> _control{ nullptr };
void _clearOldNotebook();
void _loadFile();
void _renderFileContents();
void _loadText();
void _loadMarkdown();
void _loadTapped(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::TappedRoutedEventArgs& e);
void _editTapped(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::TappedRoutedEventArgs& e);
void _closeTapped(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::TappedRoutedEventArgs& e);
};
}
namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(MarkdownPaneContent);
}

View File

@@ -1,24 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "IPaneContent.idl";
import "FilteredCommand.idl";
namespace TerminalApp
{
[default_interface] runtimeclass MarkdownPaneContent : Windows.UI.Xaml.Controls.UserControl,
IPaneContent,
Windows.UI.Xaml.Data.INotifyPropertyChanged
{
MarkdownPaneContent();
MarkdownPaneContent(String originalPath);
void SetLastActiveControl(Microsoft.Terminal.Control.TermControl control);
Boolean Editing;
String FileContents;
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.ActionAndArgs> DispatchActionRequested;
}
}

View File

@@ -1,129 +0,0 @@
<!--
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information.
-->
<UserControl x:Class="TerminalApp.MarkdownPaneContent"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:TerminalApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<!-- same as in MainPage, this is SolidBackgroundFillColorTertiary -->
<ResourceDictionary x:Key="Dark">
<Color x:Key="PageBackground">#282828</Color>
<Color x:Key="PlayButtonHoveredColor">#90ef90</Color>
<Color x:Key="PlayButtonNormalColor">#8888</Color>
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<Color x:Key="PageBackground">#F9F9F9</Color>
<Color x:Key="PlayButtonHoveredColor">#257f01</Color>
<Color x:Key="PlayButtonNormalColor">#88222222</Color>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<!-- Define resources for HighContrast mode here -->
<StaticResource x:Key="PageBackground"
ResourceKey="SystemColorWindowColorBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="Root"
Background="{ThemeResource PageBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox x:Name="FilePathInput"
Grid.Column="0"
Margin="4"
PlaceholderText="Enter a path to a markdown file..."
Text="Z:\dev\simple-test.md" />
<StackPanel Grid.Column="1"
Orientation="Horizontal">
<Button Margin="4"
Tapped="_loadTapped">
<FontIcon FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
FontSize="12"
Glyph="&#xe8e5;" />
<!-- OpenFile -->
</Button>
<Button Margin="4"
Tapped="_editTapped">
<FontIcon x:Name="EditIcon"
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
FontSize="12"
Glyph="&#xe932;" />
<!-- Label -->
</Button>
<Button Margin="4"
Tapped="_closeTapped">
<FontIcon FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
FontSize="12"
Glyph="&#xe8bb;" />
<!-- ChromeClose -->
</Button>
</StackPanel>
</Grid>
<Grid x:Name="TabContent"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid x:Name="InProcContent"
Grid.Column="0"
Padding="16"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="#ff0000" />
<TextBox x:Name="_editor"
Grid.Column="1"
Padding="3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AcceptsReturn="True"
FontFamily="Cascadia Code"
IsSpellCheckEnabled="False"
Text="{x:Bind FileContents, Mode=TwoWay}"
Visibility="{x:Bind Editing}" />
<ScrollViewer x:Name="_scrollViewer"
Grid.Column="1"
Padding="3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
BringIntoViewOnFocusChange="True"
IsVerticalScrollChainingEnabled="True">
<StackPanel x:Name="RenderedMarkdown"
Grid.Column="1"
Padding="16"
HorizontalAlignment="Stretch"
Background="Transparent"
Orientation="Vertical" />
</ScrollViewer>
</Grid>
</Grid>
</UserControl>

View File

@@ -697,12 +697,24 @@ bool Pane::SwapPanes(std::shared_ptr<Pane> first, std::shared_ptr<Pane> second)
// Refocus the last pane if there was a pane focused
if (const auto focus = first->GetActivePane())
{
focus->_Focus();
// GH#18184: manually focus the pane and content.
// _Focus() results in no-op because the pane was _lastActive
focus->GotFocus.raise(focus, FocusState::Programmatic);
if (const auto& lastContent{ focus->GetLastFocusedContent() })
{
lastContent.Focus(FocusState::Programmatic);
}
}
if (const auto focus = second->GetActivePane())
{
focus->_Focus();
// GH#18184: manually focus the pane and content.
// _Focus() results in no-op because the pane was _lastActive
focus->GotFocus.raise(focus, FocusState::Programmatic);
if (const auto& lastContent{ focus->GetLastFocusedContent() })
{
lastContent.Focus(FocusState::Programmatic);
}
}
return true;
@@ -1402,6 +1414,13 @@ void Pane::_CloseChild(const bool closeFirst)
// take the control, profile, id and isDefTermSession of the pane that _wasn't_ closed.
_setPaneContent(remainingChild->_takePaneContent());
if (!_content)
{
// GH#18071: our content is still null after taking the other pane's content,
// so just notify our parent that we're closed.
Closed.raise(nullptr, nullptr);
return;
}
_id = remainingChild->Id();
// Revoke the old event handlers. Remove both the handlers for the panes

View File

@@ -206,7 +206,7 @@
<value>ウィンドウを閉じる</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>[分割] タブ</value>
<value>タブを分割</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>ウィンドウを分割する</value>
@@ -224,7 +224,7 @@
<value>リセット</value>
</data>
<data name="RenameTabText" xml:space="preserve">
<value>[名前の変更] タブ</value>
<value>タブ名を変更</value>
</data>
<data name="DuplicateTabText" xml:space="preserve">
<value>タブを複製する</value>

View File

@@ -12,14 +12,14 @@ namespace winrt::TerminalApp::implementation
WINRT_PROPERTY(bool, Reload, false);
WINRT_PROPERTY(uint64_t, Result, S_OK);
WINRT_PROPERTY(winrt::hstring, ExceptionText, L"");
WINRT_PROPERTY(winrt::Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings>, Warnings, nullptr);
WINRT_PROPERTY(winrt::Windows::Foundation::Collections::IVectorView<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings>, Warnings, nullptr);
WINRT_PROPERTY(Microsoft::Terminal::Settings::Model::CascadiaSettings, NewSettings, nullptr);
public:
SettingsLoadEventArgs(bool reload,
uint64_t result,
winrt::hstring exceptionText,
winrt::Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> warnings,
winrt::Windows::Foundation::Collections::IVectorView<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> warnings,
Microsoft::Terminal::Settings::Model::CascadiaSettings newSettings) :
_Reload{ reload },
_Result{ result },

View File

@@ -206,10 +206,6 @@
<!-- Define resources for HighContrast mode here -->
<StaticResource x:Key="PageBackground"
ResourceKey="SystemColorWindowColorBrush" />
<StaticResource x:Key="PlayButtonHoveredColor"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="PlayButtonNormalColor"
ResourceKey="SystemColorHighlightColor" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

View File

@@ -230,6 +230,7 @@
VerticalScrollMode="Enabled"
Visibility="Visible">
<TextBlock x:Name="_descriptionComment"
Margin="0,0,20,0"
IsTextSelectionEnabled="True"
TextWrapping="WrapWholeWords" />
</ScrollViewer>

View File

@@ -519,67 +519,45 @@ namespace winrt::TerminalApp::implementation
deselectedFontBrush.Color(winrt::Windows::UI::Colors::White());
}
// Add the empty theme dictionaries
const auto& tabItemThemeResources{ TabViewItem().Resources().ThemeDictionaries() };
ResourceDictionary lightThemeDictionary;
ResourceDictionary darkThemeDictionary;
ResourceDictionary highContrastThemeDictionary;
tabItemThemeResources.Insert(winrt::box_value(L"Light"), lightThemeDictionary);
tabItemThemeResources.Insert(winrt::box_value(L"Dark"), darkThemeDictionary);
tabItemThemeResources.Insert(winrt::box_value(L"HighContrast"), highContrastThemeDictionary);
// Prior to MUX 2.7, we set TabViewItemHeaderBackground, but now we can
// use TabViewItem().Background() for that. HOWEVER,
// TabViewItem().Background() only sets the color of the tab background
// when the TabViewItem is unselected. So we still need to set the other
// properties ourselves.
//
// In GH#11294 we thought we'd still need to set
// TabViewItemHeaderBackground manually, but GH#11382 discovered that
// Background() was actually okay after all.
// Now actually set the resources we want in them.
// Before, we used to put these on the ResourceDictionary directly.
// However, HighContrast mode may require some adjustments. So let's just add
// all three so we can make those adjustments on the HighContrast version.
for (const auto& [k, v] : tabItemThemeResources)
{
const bool isHighContrast = winrt::unbox_value<hstring>(k) == L"HighContrast";
const auto& currentDictionary = v.as<ResourceDictionary>();
const auto& tabItemResources{ TabViewItem().Resources() };
// TabViewItem.Background
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackground"), deselectedTabBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), selectedTabBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPointerOver"), isHighContrast ? fontBrush : hoverTabBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPressed"), selectedTabBrush);
TabViewItem().Background(deselectedTabBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), selectedTabBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPointerOver"), hoverTabBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPressed"), selectedTabBrush);
// TabViewItem.Foreground (aka text)
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForeground"), deselectedFontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundSelected"), fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), isHighContrast ? selectedTabBrush : fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush);
// Similarly, TabViewItem().Foreground() sets the color for the text
// when the TabViewItem isn't selected, but not when it is hovered,
// pressed, dragged, or selected, so we'll need to just set them all
// anyways.
TabViewItem().Foreground(deselectedFontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderForeground"), deselectedFontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderForegroundSelected"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush);
// TabViewItem.CloseButton.Foreground (aka X)
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForeground"), deselectedFontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPressed"), isHighContrast ? deselectedFontBrush : secondaryFontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPointerOver"), isHighContrast ? deselectedFontBrush : fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForeground"), deselectedFontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPressed"), secondaryFontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPointerOver"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderPressedCloseButtonForeground"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderPointerOverCloseButtonForeground"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderSelectedCloseButtonForeground"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPressed"), subtleFillColorTertiaryBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPointerOver"), subtleFillColorSecondaryBrush);
// TabViewItem.CloseButton.Foreground _when_ interacting with the tab
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderPressedCloseButtonForeground"), fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderPointerOverCloseButtonForeground"), isHighContrast ? selectedTabBrush : fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderSelectedCloseButtonForeground"), fontBrush);
// TabViewItem.CloseButton.Background (aka X button)
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackground"), deselectedTabBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPressed"), isHighContrast ? selectedTabBrush : subtleFillColorTertiaryBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPointerOver"), isHighContrast ? selectedTabBrush : subtleFillColorSecondaryBrush);
// A few miscellaneous resources that WinUI said may be removed in the future
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundActiveTab"), fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundPressed"), fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundPointerOver"), fontBrush);
// Add a few extra ones for high contrast mode
// BODGY: contrary to the docs, Insert() seems to throw if the value already exists
// Make sure you don't touch any that already exist here!
if (isHighContrast)
{
// TabViewItem.CloseButton.Border: in HC mode, the border makes the button more clearly visible
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushPressed"), fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushPointerOver"), fontBrush);
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushSelected"), fontBrush);
}
}
tabItemResources.Insert(winrt::box_value(L"TabViewButtonForegroundActiveTab"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewButtonForegroundPressed"), fontBrush);
tabItemResources.Insert(winrt::box_value(L"TabViewButtonForegroundPointerOver"), fontBrush);
_RefreshVisualState();
}
@@ -594,55 +572,36 @@ namespace winrt::TerminalApp::implementation
void TabBase::_ClearTabBackgroundColor()
{
static const winrt::hstring keys[] = {
// TabViewItem.Background
L"TabViewItemHeaderBackground",
L"TabViewItemHeaderBackgroundSelected",
L"TabViewItemHeaderBackgroundPointerOver",
L"TabViewItemHeaderBackgroundPressed",
// TabViewItem.Foreground (aka text)
L"TabViewItemHeaderForeground",
L"TabViewItemHeaderForegroundSelected",
L"TabViewItemHeaderForegroundPointerOver",
L"TabViewItemHeaderForegroundPressed",
// TabViewItem.CloseButton.Foreground (aka X)
L"TabViewItemHeaderCloseButtonForeground",
L"TabViewItemHeaderForegroundSelected",
L"TabViewItemHeaderCloseButtonForegroundPointerOver",
L"TabViewItemHeaderCloseButtonForegroundPressed",
// TabViewItem.CloseButton.Foreground _when_ interacting with the tab
L"TabViewItemHeaderCloseButtonForegroundPointerOver",
L"TabViewItemHeaderPressedCloseButtonForeground",
L"TabViewItemHeaderPointerOverCloseButtonForeground",
L"TabViewItemHeaderSelectedCloseButtonForeground",
// TabViewItem.CloseButton.Background (aka X button)
L"TabViewItemHeaderCloseButtonBackground",
L"TabViewItemHeaderCloseButtonBackgroundPressed",
L"TabViewItemHeaderCloseButtonBackgroundPointerOver",
// A few miscellaneous resources that WinUI said may be removed in the future
L"TabViewButtonForegroundActiveTab",
L"TabViewButtonForegroundPressed",
L"TabViewButtonForegroundPointerOver",
// TabViewItem.CloseButton.Border: in HC mode, the border makes the button more clearly visible
L"TabViewItemHeaderCloseButtonBorderBrushPressed",
L"TabViewItemHeaderCloseButtonBorderBrushPointerOver",
L"TabViewItemHeaderCloseButtonBorderBrushSelected"
L"TabViewButtonForegroundPointerOver"
};
const auto& tabItemThemeResources{ TabViewItem().Resources().ThemeDictionaries() };
const auto& tabItemResources{ TabViewItem().Resources() };
// simply clear any of the colors in the tab's dict
for (const auto& keyString : keys)
{
const auto key = winrt::box_value(keyString);
for (const auto& [_, v] : tabItemThemeResources)
auto key = winrt::box_value(keyString);
if (tabItemResources.HasKey(key))
{
const auto& themeDictionary = v.as<ResourceDictionary>();
themeDictionary.Remove(key);
tabItemResources.Remove(key);
}
}

View File

@@ -158,10 +158,7 @@ namespace winrt::TerminalApp::implementation
// Set this tab's icon to the icon from the content
_UpdateTabIcon(*newTabImpl);
tabViewItem.PointerPressed({ this, &TerminalPage::_OnTabPointerPressed });
tabViewItem.PointerReleased({ this, &TerminalPage::_OnTabPointerReleased });
tabViewItem.PointerExited({ this, &TerminalPage::_OnTabPointerExited });
tabViewItem.PointerEntered({ this, &TerminalPage::_OnTabPointerEntered });
tabViewItem.PointerReleased({ this, &TerminalPage::_OnTabClick });
// When the tab requests close, try to close it (prompt for approval, if required)
newTabImpl->CloseRequested([weakTab, weakThis{ get_weak() }](auto&& /*s*/, auto&& /*e*/) {
@@ -491,14 +488,14 @@ namespace winrt::TerminalApp::implementation
// Because this will always return -1 in this scenario unfortunately.
//
// So, what we're going to try to do is move the focus to the tab
// to the right, within the bounds of how many tabs we have.
// to the left, within the bounds of how many tabs we have.
//
// EX: we have 4 tabs: [A, B, C, D]. If we close:
// * A (tabIndex=0): We'll want to focus tab B (now in index 0)
// * B (tabIndex=1): We'll want to focus tab C (now in index 1)
// * C (tabIndex=2): We'll want to focus tab D (now in index 2)
// * B (tabIndex=1): We'll want to focus tab A (now in index 0)
// * C (tabIndex=2): We'll want to focus tab B (now in index 1)
// * D (tabIndex=3): We'll want to focus tab C (now in index 2)
const auto newSelectedIndex = std::clamp<int32_t>(tabIndex, 0, _tabs.Size() - 1);
const auto newSelectedIndex = std::clamp<int32_t>(tabIndex - 1, 0, _tabs.Size() - 1);
// _UpdatedSelectedTab will do the work of setting up the new tab as
// the focused one, and unfocusing all the others.
auto newSelectedTab{ _tabs.GetAt(newSelectedIndex) };
@@ -878,66 +875,19 @@ namespace winrt::TerminalApp::implementation
// Arguments:
// - sender: the control that originated this event (TabViewItem)
// - eventArgs: the event's constituent arguments
void TerminalPage::_OnTabPointerPressed(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs)
void TerminalPage::_OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs)
{
if (eventArgs.GetCurrentPoint(nullptr).Properties().IsMiddleButtonPressed())
if (eventArgs.GetCurrentPoint(*this).Properties().IsMiddleButtonPressed())
{
if (const auto tabViewItem{ sender.try_as<MUX::Controls::TabViewItem>() })
const auto tabViewItem = sender.try_as<MUX::Controls::TabViewItem>();
if (auto tab{ _GetTabByTabViewItem(tabViewItem) })
{
_tabPointerMiddleButtonPressed = tabViewItem.CapturePointer(eventArgs.Pointer());
_tabPointerMiddleButtonExited = false;
_HandleCloseTabRequested(tab);
}
eventArgs.Handled(true);
}
}
// Method Description:
// - Tracking pointer state for tab remove
// Arguments:
// - sender: the control that originated this event (TabViewItem)
// - eventArgs: the event's constituent arguments
void TerminalPage::_OnTabPointerReleased(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs)
{
if (_tabPointerMiddleButtonPressed && !eventArgs.GetCurrentPoint(nullptr).Properties().IsMiddleButtonPressed())
else if (eventArgs.GetCurrentPoint(*this).Properties().IsRightButtonPressed())
{
_tabPointerMiddleButtonPressed = false;
if (const auto tabViewItem{ sender.try_as<MUX::Controls::TabViewItem>() })
{
tabViewItem.ReleasePointerCapture(eventArgs.Pointer());
auto tab = _GetTabByTabViewItem(tabViewItem);
if (!_tabPointerMiddleButtonExited && tab)
{
_HandleCloseTabRequested(tab);
}
}
eventArgs.Handled(true);
}
}
// Method Description:
// - Tracking pointer state for tab remove
// Arguments:
// - sender: the control that originated this event (TabViewItem)
// - eventArgs: the event's constituent arguments
void TerminalPage::_OnTabPointerEntered(const IInspectable& /*sender*/, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs)
{
if (eventArgs.GetCurrentPoint(nullptr).Properties().IsMiddleButtonPressed())
{
_tabPointerMiddleButtonExited = false;
eventArgs.Handled(true);
}
}
// Method Description:
// - Tracking pointer state for tab remove
// Arguments:
// - sender: the control that originated this event (TabViewItem)
// - eventArgs: the event's constituent arguments
void TerminalPage::_OnTabPointerExited(const IInspectable& /*sender*/, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs)
{
if (eventArgs.GetCurrentPoint(nullptr).Properties().IsMiddleButtonPressed())
{
_tabPointerMiddleButtonExited = true;
eventArgs.Handled(true);
}
}

View File

@@ -75,9 +75,6 @@
<Page Include="SnippetsPaneContent.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="MarkdownPaneContent.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<!-- ========================= Headers ======================== -->
<ItemGroup>
@@ -181,9 +178,6 @@
<ClInclude Include="SuggestionsControl.h">
<DependentUpon>SuggestionsControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="MarkdownPaneContent.h">
<DependentUpon>MarkdownPaneContent.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="WindowsPackageManagerFactory.h" />
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
@@ -302,11 +296,6 @@
<ClCompile Include="SuggestionsControl.cpp">
<DependentUpon>SuggestionsControl.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="MarkdownPaneContent.cpp">
<DependentUpon>MarkdownPaneContent.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
</ItemGroup>
<!-- ========================= idl Files ======================== -->
<ItemGroup>
@@ -379,10 +368,6 @@
<SubType>Code</SubType>
</Midl>
<Midl Include="TerminalSettingsCache.idl" />
<Midl Include="MarkdownPaneContent.idl">
<DependentUpon>MarkdownPaneContent.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
</ItemGroup>
<!-- ========================= Misc Files ======================== -->
<ItemGroup>
@@ -431,11 +416,6 @@
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIMarkdown\UIMarkdown.vcxproj">
<Project>{7615F03F-E56D-4DB4-B23D-BD4FB80DB36F}</Project>
<Private>true</Private>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
@@ -479,12 +459,6 @@
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="Microsoft.Terminal.UI.Markdown">
<HintPath>$(OpenConsoleCommonOutDir)Microsoft.Terminal.UI.Markdown\Microsoft.Terminal.UI.Markdown.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="$(WindowsSDK_MetadataPathVersioned)\Windows.UI.Xaml.Hosting.HostingContract\*\*.winmd">
<WinMDFile>true</WinMDFile>
<CopyLocal>false</CopyLocal>
@@ -530,4 +504,4 @@
</ItemGroup>
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>
</Project>

View File

@@ -17,7 +17,6 @@
#include "SettingsPaneContent.h"
#include "ScratchpadContent.h"
#include "SnippetsPaneContent.h"
#include "MarkdownPaneContent.h"
#include "TabRowControl.h"
#include "TerminalPage.g.cpp"
@@ -240,6 +239,14 @@ namespace winrt::TerminalApp::implementation
_newTabButton.Click([weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuDefaultButtonClicked",
TraceLoggingDescription("Event emitted when the default button from the new tab split button is invoked"),
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
page->_OpenNewTerminalViaDropdown(NewTerminalArgs());
}
});
@@ -881,14 +888,36 @@ namespace winrt::TerminalApp::implementation
// Since the previous focus location might be discarded in the background,
// e.g., the command palette will be dismissed by the menu,
// and then closing the fly-out will move the focus to wrong location.
newTabFlyout.Opening([this](auto&&, auto&&) {
_FocusCurrentTab(true);
newTabFlyout.Opening([weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
page->_FocusCurrentTab(true);
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuOpened",
TraceLoggingDescription("Event emitted when the new tab menu is opened"),
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The Count of tabs currently opened in this window"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
}
});
// Necessary for fly-out sub items to get focus on a tab before collapsing. Related to #15049
newTabFlyout.Closing([this](auto&&, auto&&) {
if (!_commandPaletteIs(Visibility::Visible))
newTabFlyout.Closing([weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
_FocusCurrentTab(true);
if (!page->_commandPaletteIs(Visibility::Visible))
{
page->_FocusCurrentTab(true);
}
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuClosed",
TraceLoggingDescription("Event emitted when the new tab menu is closed"),
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The Count of tabs currently opened in this window"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
}
});
_newTabButton.Flyout(newTabFlyout);
@@ -990,7 +1019,7 @@ namespace winrt::TerminalApp::implementation
for (auto&& [profileIndex, remainingProfile] : remainingProfilesEntry.Profiles())
{
items.push_back(_CreateNewTabFlyoutProfile(remainingProfile, profileIndex, {}));
items.push_back(_CreateNewTabFlyoutProfile(remainingProfile, profileIndex));
}
break;
@@ -1004,7 +1033,7 @@ namespace winrt::TerminalApp::implementation
break;
}
auto profileItem = _CreateNewTabFlyoutProfile(profileEntry.Profile(), profileEntry.ProfileIndex(), profileEntry.Icon());
auto profileItem = _CreateNewTabFlyoutProfile(profileEntry.Profile(), profileEntry.ProfileIndex());
items.push_back(profileItem);
break;
}
@@ -1014,7 +1043,7 @@ namespace winrt::TerminalApp::implementation
const auto actionId = actionEntry.ActionId();
if (_settings.ActionMap().GetActionByID(actionId))
{
auto actionItem = _CreateNewTabFlyoutAction(actionId, actionEntry.Icon());
auto actionItem = _CreateNewTabFlyoutAction(actionId);
items.push_back(actionItem);
}
@@ -1029,7 +1058,7 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - This method creates a flyout menu item for a given profile with the given index.
// It makes sure to set the correct icon, keybinding, and click-action.
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutProfile(const Profile profile, int profileIndex, const winrt::hstring& iconPathOverride)
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutProfile(const Profile profile, int profileIndex)
{
auto profileMenuItem = WUX::Controls::MenuFlyoutItem{};
@@ -1050,10 +1079,9 @@ namespace winrt::TerminalApp::implementation
auto profileName = profile.Name();
profileMenuItem.Text(profileName);
// If a custom icon path has been specified, set it as the icon for
// this flyout item. Otherwise, if an icon is set for this profile, set that icon
// for this flyout item.
const auto& iconPath = iconPathOverride.empty() ? profile.EvaluatedIcon() : iconPathOverride;
// If there's an icon set for this profile, set it as the icon for
// this flyout item
const auto& iconPath = profile.EvaluatedIcon();
if (!iconPath.empty())
{
const auto icon = _CreateNewTabFlyoutIcon(iconPath);
@@ -1094,6 +1122,15 @@ namespace winrt::TerminalApp::implementation
profileMenuItem.Click([profileIndex, weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuItemClicked",
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
TraceLoggingValue("Profile", "ItemType", "The type of item that was clicked in the new tab menu"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
NewTerminalArgs newTerminalArgs{ profileIndex };
page->_OpenNewTerminalViaDropdown(newTerminalArgs);
}
@@ -1114,7 +1151,7 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - This method creates a flyout menu item for a given action
// It makes sure to set the correct icon, keybinding, and click-action.
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutAction(const winrt::hstring& actionId, const winrt::hstring& iconPathOverride)
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutAction(const winrt::hstring& actionId)
{
auto actionMenuItem = WUX::Controls::MenuFlyoutItem{};
const auto action{ _settings.ActionMap().GetActionByID(actionId) };
@@ -1127,10 +1164,9 @@ namespace winrt::TerminalApp::implementation
actionMenuItem.Text(action.Name());
// If a custom icon path has been specified, set it as the icon for
// this flyout item. Otherwise, if an icon is set for this action, set that icon
// for this flyout item.
const auto& iconPath = iconPathOverride.empty() ? action.IconPath() : iconPathOverride;
// If there's an icon set for this action, set it as the icon for
// this flyout item
const auto& iconPath = action.IconPath();
if (!iconPath.empty())
{
const auto icon = _CreateNewTabFlyoutIcon(iconPath);
@@ -1140,6 +1176,15 @@ namespace winrt::TerminalApp::implementation
actionMenuItem.Click([action, weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuItemClicked",
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
TraceLoggingValue("Action", "ItemType", "The type of item that was clicked in the new tab menu"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
page->_actionDispatch->DoAction(action.ActionAndArgs());
}
});
@@ -1201,6 +1246,7 @@ namespace winrt::TerminalApp::implementation
const auto dispatchToElevatedWindow = ctrlPressed && !IsRunningElevated();
auto sessionType = "";
if ((shiftPressed || dispatchToElevatedWindow) && !debugTap)
{
// Manually fill in the evaluated profile.
@@ -1218,10 +1264,12 @@ namespace winrt::TerminalApp::implementation
if (dispatchToElevatedWindow)
{
_OpenElevatedWT(newTerminalArgs);
sessionType = "ElevatedWindow";
}
else
{
_OpenNewWindow(newTerminalArgs);
sessionType = "Window";
}
}
else
@@ -1240,12 +1288,23 @@ namespace winrt::TerminalApp::implementation
SplitDirection::Automatic,
0.5f,
newPane);
sessionType = "Pane";
}
else
{
_CreateNewTabFromPane(newPane);
sessionType = "Tab";
}
}
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuCreatedNewTerminalSession",
TraceLoggingDescription("Event emitted when a new terminal was created via the new tab menu"),
TraceLoggingValue(NumberOfTabs(), "NewTabCount", "The count of tabs currently opened in this window"),
TraceLoggingValue(sessionType, "SessionType", "The type of session that was created"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
}
std::wstring TerminalPage::_evaluatePathForCwd(const std::wstring_view path)
@@ -1452,6 +1511,30 @@ namespace winrt::TerminalApp::implementation
{
target = SettingsTarget::DefaultsFile;
}
const auto targetAsString = [&target]() {
switch (target)
{
case SettingsTarget::SettingsFile:
return "SettingsFile";
case SettingsTarget::DefaultsFile:
return "DefaultsFile";
case SettingsTarget::SettingsUI:
default:
return "UI";
}
}();
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuItemClicked",
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
TraceLoggingValue(NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
TraceLoggingValue("Settings", "ItemType", "The type of item that was clicked in the new tab menu"),
TraceLoggingValue(targetAsString, "SettingsTarget", "The target settings file or UI"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
_LaunchSettings(target);
}
@@ -1463,6 +1546,15 @@ namespace winrt::TerminalApp::implementation
auto p = LoadCommandPalette();
p.EnableCommandPaletteMode(CommandPaletteLaunchMode::Action);
p.Visibility(Visibility::Visible);
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuItemClicked",
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
TraceLoggingValue(NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
TraceLoggingValue("CommandPalette", "ItemType", "The type of item that was clicked in the new tab menu"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
}
// Method Description:
@@ -1475,6 +1567,15 @@ namespace winrt::TerminalApp::implementation
const RoutedEventArgs&)
{
_ShowAboutDialog();
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuItemClicked",
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
TraceLoggingValue(NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
TraceLoggingValue("About", "ItemType", "The type of item that was clicked in the new tab menu"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
}
// Method Description:
@@ -1746,8 +1847,6 @@ namespace winrt::TerminalApp::implementation
term.SearchMissingCommand({ get_weak(), &TerminalPage::_SearchMissingCommandHandler });
term.WindowSizeChanged({ get_weak(), &TerminalPage::_WindowSizeChanged });
// Don't even register for the event if the feature is compiled off.
if constexpr (Feature_ShellCompletions::IsEnabled())
{
@@ -2243,7 +2342,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_MoveContent(std::vector<Settings::Model::ActionAndArgs>&& actions,
const winrt::hstring& windowName,
const uint32_t tabIndex,
const std::optional<winrt::Windows::Foundation::Point>& dragPoint)
const std::optional<til::point>& dragPoint)
{
const auto winRtActions{ winrt::single_threaded_vector<ActionAndArgs>(std::move(actions)) };
const auto str{ ActionAndArgs::Serialize(winRtActions) };
@@ -2252,7 +2351,7 @@ namespace winrt::TerminalApp::implementation
tabIndex);
if (dragPoint.has_value())
{
request->WindowPosition(*dragPoint);
request->WindowPosition(dragPoint->to_winrt_point());
}
RequestMoveContent.raise(*this, *request);
}
@@ -2326,7 +2425,7 @@ namespace winrt::TerminalApp::implementation
// for it. The Title change will be propagated upwards through the tab's
// PropertyChanged event handler.
void TerminalPage::_activePaneChanged(winrt::TerminalApp::TerminalTab sender,
Windows::Foundation::IInspectable args)
Windows::Foundation::IInspectable /*args*/)
{
if (const auto tab{ _GetTerminalTabImpl(sender) })
{
@@ -2974,15 +3073,14 @@ namespace winrt::TerminalApp::implementation
// Arguments:
// - dismissSelection: if not enabled, copying text doesn't dismiss the selection
// - singleLine: if enabled, copy contents as a single line of text
// - withControlSequences: if enabled, the copied plain text contains color/style ANSI escape codes from the selection
// - formats: dictate which formats need to be copied
// Return Value:
// - true iff we we able to copy text (if a selection was active)
bool TerminalPage::_CopyText(const bool dismissSelection, const bool singleLine, const bool withControlSequences, const Windows::Foundation::IReference<CopyFormat>& formats)
bool TerminalPage::_CopyText(const bool dismissSelection, const bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats)
{
if (const auto& control{ _GetActiveControl() })
{
return control.CopySelectionToClipboard(dismissSelection, singleLine, withControlSequences, formats);
return control.CopySelectionToClipboard(dismissSelection, singleLine, formats);
}
return false;
}
@@ -3096,31 +3194,6 @@ namespace winrt::TerminalApp::implementation
term.RefreshQuickFixMenu();
}
void TerminalPage::_WindowSizeChanged(const IInspectable sender, const Microsoft::Terminal::Control::WindowSizeChangedEventArgs args)
{
// Raise if:
// - Not in quake mode
// - Not in fullscreen
// - Only one tab exists
// - Only one pane exists
// else:
// - Reset conpty to its original size back
if (!WindowProperties().IsQuakeWindow() && !Fullscreen() &&
NumberOfTabs() == 1 && _GetFocusedTabImpl()->GetLeafPaneCount() == 1)
{
WindowSizeChanged.raise(*this, args);
}
else if (const auto& control{ sender.try_as<TermControl>() })
{
const auto& connection = control.Connection();
if (const auto& conpty{ connection.try_as<TerminalConnection::ConptyConnection>() })
{
conpty.ResetSize();
}
}
}
// Method Description:
// - Paste text from the Windows Clipboard to the focused terminal
void TerminalPage::_PasteText()
@@ -3440,30 +3513,6 @@ namespace winrt::TerminalApp::implementation
content = *tasksContent;
}
else if (paneType == L"x-markdown")
{
if (Feature_MarkdownPane::IsEnabled())
{
const auto& markdownContent{ winrt::make_self<MarkdownPaneContent>(L"") };
markdownContent->UpdateSettings(_settings);
markdownContent->GetRoot().KeyDown({ this, &TerminalPage::_KeyDownHandler });
// This one doesn't use DispatchCommand, because we don't create
// Command's freely at runtime like we do with just plain old actions.
markdownContent->DispatchActionRequested([weak = get_weak()](const auto& sender, const auto& actionAndArgs) {
if (const auto& page{ weak.get() })
{
page->_actionDispatch->DoAction(sender, actionAndArgs);
}
});
if (const auto& termControl{ _GetActiveControl() })
{
markdownContent->SetLastActiveControl(termControl);
}
content = *markdownContent;
}
}
assert(content);
@@ -4152,6 +4201,13 @@ namespace winrt::TerminalApp::implementation
}
});
sui.ShowLoadWarningsDialog([weakThis{ get_weak() }](auto&& /*s*/, const Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Terminal::Settings::Model::SettingsLoadWarnings>& warnings) {
if (auto page{ weakThis.get() })
{
page->ShowLoadWarningsDialog.raise(*page, warnings);
}
});
return *settingsContent;
}
@@ -5203,17 +5259,16 @@ namespace winrt::TerminalApp::implementation
// position the dropped window.
// First, the position of the pointer, from the CoreWindow
const auto pointerPosition = CoreWindow::GetForCurrentThread().PointerPosition();
const til::point pointerPosition{ til::math::rounding, CoreWindow::GetForCurrentThread().PointerPosition() };
// Next, the position of the tab itself:
const auto tabPosition = eventTab.TransformToVisual(nullptr).TransformPoint({ 0, 0 });
const til::point tabPosition{ til::math::rounding, eventTab.TransformToVisual(nullptr).TransformPoint({ 0, 0 }) };
// Now, we need to add the origin of our CoreWindow to the tab
// position.
const auto windowOrigin = CoreWindow::GetForCurrentThread().Bounds();
const auto& coreWindowBounds{ CoreWindow::GetForCurrentThread().Bounds() };
const til::point windowOrigin{ til::math::rounding, coreWindowBounds.X, coreWindowBounds.Y };
const auto realTabPosition = windowOrigin + tabPosition;
// Subtract the two to get the offset.
_stashed.dragOffset = {
pointerPosition.X - windowOrigin.X - tabPosition.X,
pointerPosition.Y - windowOrigin.Y - tabPosition.Y,
};
_stashed.dragOffset = til::point{ pointerPosition - realTabPosition };
// Into the DataPackage, let's stash our own window ID.
const auto id{ _WindowProperties.WindowId() };
@@ -5357,8 +5412,8 @@ namespace winrt::TerminalApp::implementation
}
}
safe_void_coroutine TerminalPage::_onTabDroppedOutside(winrt::IInspectable sender,
winrt::MUX::Controls::TabViewTabDroppedOutsideEventArgs e)
safe_void_coroutine TerminalPage::_onTabDroppedOutside(winrt::IInspectable /*sender*/,
winrt::MUX::Controls::TabViewTabDroppedOutsideEventArgs /*e*/)
{
// Get the current pointer point from the CoreWindow
const auto& pointerPoint{ CoreWindow::GetForCurrentThread().PointerPosition() };
@@ -5387,17 +5442,14 @@ namespace winrt::TerminalApp::implementation
// -1 is the magic number for "new window"
// 0 as the tab index, because we don't care. It's making a new window. It'll be the only tab.
const winrt::Windows::Foundation::Point adjusted = {
pointerPoint.X - _stashed.dragOffset.X,
pointerPoint.Y - _stashed.dragOffset.Y,
};
const til::point adjusted = til::point{ til::math::rounding, pointerPoint } - _stashed.dragOffset;
_sendDraggedTabToWindow(winrt::hstring{ L"-1" }, 0, adjusted);
}
}
void TerminalPage::_sendDraggedTabToWindow(const winrt::hstring& windowId,
const uint32_t tabIndex,
std::optional<winrt::Windows::Foundation::Point> dragPoint)
std::optional<til::point> dragPoint)
{
auto startupActions = _stashed.draggedTab->BuildStartupActions(BuildStartupKind::Content);
_DetachTabFromWindow(_stashed.draggedTab);
@@ -5433,6 +5485,14 @@ namespace winrt::TerminalApp::implementation
runAsAdminItem.Click([profileIndex, weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
TraceLoggingWrite(
g_hTerminalAppProvider,
"NewTabMenuItemElevateSubmenuItemClicked",
TraceLoggingDescription("Event emitted when the elevate submenu item from the new tab menu is invoked"),
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
NewTerminalArgs args{ profileIndex };
args.Elevate(true);
page->_OpenNewTerminalViaDropdown(args);

View File

@@ -195,12 +195,11 @@ namespace winrt::TerminalApp::implementation
til::typed_event<IInspectable, IInspectable> IdentifyWindowsRequested;
til::typed_event<IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs> RenameWindowRequested;
til::typed_event<IInspectable, IInspectable> SummonWindowRequested;
til::typed_event<IInspectable, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs> WindowSizeChanged;
til::typed_event<IInspectable, IInspectable> CloseRequested;
til::typed_event<IInspectable, IInspectable> OpenSystemMenu;
til::typed_event<IInspectable, IInspectable> QuitRequested;
til::typed_event<IInspectable, winrt::Microsoft::Terminal::Control::ShowWindowArgs> ShowWindowChanged;
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Terminal::Settings::Model::SettingsLoadWarnings>> ShowLoadWarningsDialog;
til::typed_event<Windows::Foundation::IInspectable, winrt::TerminalApp::RequestMoveContentArgs> RequestMoveContent;
til::typed_event<Windows::Foundation::IInspectable, winrt::TerminalApp::RequestReceiveContentArgs> RequestReceiveContent;
@@ -292,7 +291,7 @@ namespace winrt::TerminalApp::implementation
struct StashedDragData
{
winrt::com_ptr<winrt::TerminalApp::implementation::TabBase> draggedTab{ nullptr };
winrt::Windows::Foundation::Point dragOffset{ 0, 0 };
til::point dragOffset{ 0, 0 };
} _stashed;
winrt::Microsoft::Terminal::TerminalConnection::ConptyConnection::NewConnection_revoker _newConnectionRevoker;
@@ -316,8 +315,8 @@ namespace winrt::TerminalApp::implementation
void _CreateNewTabFlyout();
std::vector<winrt::Windows::UI::Xaml::Controls::MenuFlyoutItemBase> _CreateNewTabFlyoutItems(winrt::Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::NewTabMenuEntry> entries);
winrt::Windows::UI::Xaml::Controls::IconElement _CreateNewTabFlyoutIcon(const winrt::hstring& icon);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutProfile(const Microsoft::Terminal::Settings::Model::Profile profile, int profileIndex, const winrt::hstring& iconPathOverride);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutAction(const winrt::hstring& actionId, const winrt::hstring& iconPathOverride);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutProfile(const Microsoft::Terminal::Settings::Model::Profile profile, int profileIndex);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutAction(const winrt::hstring& actionId);
void _OpenNewTabDropdown();
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::INewContentArgs& newContentArgs);
@@ -429,7 +428,7 @@ namespace winrt::TerminalApp::implementation
bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
bool _CopyText(const bool dismissSelection, const bool singleLine, const bool withControlSequences, const Windows::Foundation::IReference<Microsoft::Terminal::Control::CopyFormat>& formats);
bool _CopyText(const bool dismissSelection, const bool singleLine, const Windows::Foundation::IReference<Microsoft::Terminal::Control::CopyFormat>& formats);
safe_void_coroutine _SetTaskbarProgressHandler(const IInspectable sender, const IInspectable eventArgs);
@@ -443,13 +442,7 @@ namespace winrt::TerminalApp::implementation
void _TabDragStarted(const IInspectable& sender, const IInspectable& eventArgs);
void _TabDragCompleted(const IInspectable& sender, const IInspectable& eventArgs);
bool _tabPointerMiddleButtonPressed{ false };
bool _tabPointerMiddleButtonExited{ false };
void _OnTabPointerPressed(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
void _OnTabPointerReleased(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
void _OnTabPointerEntered(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
void _OnTabPointerExited(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
void _OnTabSelectionChanged(const IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& eventArgs);
void _OnTabItemsChanged(const IInspectable& sender, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs);
void _OnTabCloseRequested(const IInspectable& sender, const Microsoft::UI::Xaml::Controls::TabViewTabCloseRequestedEventArgs& eventArgs);
@@ -548,7 +541,6 @@ namespace winrt::TerminalApp::implementation
Windows::Foundation::IAsyncAction _SearchMissingCommandHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::SearchMissingCommandEventArgs args);
Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::MatchResult>> _FindPackageAsync(hstring query);
void _WindowSizeChanged(const IInspectable sender, const winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs args);
safe_void_coroutine _windowPropertyChanged(const IInspectable& sender, const winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs& args);
void _onTabDragStarting(const winrt::Microsoft::UI::Xaml::Controls::TabView& sender, const winrt::Microsoft::UI::Xaml::Controls::TabViewTabDragStartingEventArgs& e);
@@ -561,8 +553,8 @@ namespace winrt::TerminalApp::implementation
void _MoveContent(std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>&& actions,
const winrt::hstring& windowName,
const uint32_t tabIndex,
const std::optional<winrt::Windows::Foundation::Point>& dragPoint = std::nullopt);
void _sendDraggedTabToWindow(const winrt::hstring& windowId, const uint32_t tabIndex, std::optional<winrt::Windows::Foundation::Point> dragPoint);
const std::optional<til::point>& dragPoint = std::nullopt);
void _sendDraggedTabToWindow(const winrt::hstring& windowId, const uint32_t tabIndex, std::optional<til::point> dragPoint);
void _PopulateContextMenu(const Microsoft::Terminal::Control::TermControl& control, const Microsoft::UI::Xaml::Controls::CommandBarFlyout& sender, const bool withSelection);
void _PopulateQuickFixMenu(const Microsoft::Terminal::Control::TermControl& control, const Windows::UI::Xaml::Controls::MenuFlyout& sender);

View File

@@ -100,11 +100,10 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.WindowSizeChangedEventArgs> WindowSizeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> CloseRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.ShowWindowArgs> ShowWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, Windows.Foundation.Collections.IVectorView<Microsoft.Terminal.Settings.Model.SettingsLoadWarnings> > ShowLoadWarningsDialog;
event Windows.Foundation.TypedEventHandler<Object, RequestMoveContentArgs> RequestMoveContent;
event Windows.Foundation.TypedEventHandler<Object, RequestReceiveContentArgs> RequestReceiveContent;

View File

@@ -95,7 +95,7 @@ namespace winrt::TerminalApp::implementation
NewTerminalArgs args{};
const auto& controlSettings = _control.Settings();
args.Profile(controlSettings.ProfileName());
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())
{
@@ -339,8 +339,12 @@ namespace winrt::TerminalApp::implementation
RestartTerminalRequested.raise(*this, nullptr);
}
void TerminalPaneContent::UpdateSettings(const CascadiaSettings& /*settings*/)
void TerminalPaneContent::UpdateSettings(const CascadiaSettings& settings)
{
// Reload our profile from the settings model to propagate bell mode, icon, and close on exit mode (anything that uses _profile).
const auto profile{ settings.FindProfile(_profile.Guid()) };
_profile = profile ? profile : settings.ProfileDefaults();
if (const auto& settings{ _cache.TryLookup(_profile) })
{
_control.UpdateControlSettings(settings.DefaultSettings(), settings.UnfocusedSettings());

View File

@@ -1235,10 +1235,6 @@ namespace winrt::TerminalApp::implementation
{
taskPane.SetLastActiveControl(termControl);
}
else if (const auto& taskPane{ p->GetContent().try_as<MarkdownPaneContent>() })
{
taskPane.SetLastActiveControl(termControl);
}
});
}
}

View File

@@ -15,7 +15,6 @@
using namespace winrt::Windows::ApplicationModel;
using namespace winrt::Windows::ApplicationModel::DataTransfer;
using namespace winrt::Windows::Graphics::Display;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Core;
@@ -218,7 +217,7 @@ namespace winrt::TerminalApp::implementation
_root->SetSettings(_settings, false); // We're on our UI thread right now, so this is safe
_root->Loaded({ get_weak(), &TerminalWindow::_OnLoaded });
_root->Initialized({ get_weak(), &TerminalWindow::_pageInitialized });
_root->WindowSizeChanged({ get_weak(), &TerminalWindow::_WindowSizeChanged });
_root->ShowLoadWarningsDialog({ get_weak(), &TerminalWindow::_ShowLoadWarningsDialog });
_root->Create();
AppLogic::Current()->SettingsChanged({ get_weak(), &TerminalWindow::UpdateSettingsHandler });
@@ -443,7 +442,7 @@ namespace winrt::TerminalApp::implementation
// validating the settings.
// - Only one dialog can be visible at a time. If another dialog is visible
// when this is called, nothing happens. See ShowDialog for details
void TerminalWindow::_ShowLoadWarningsDialog(const Windows::Foundation::Collections::IVector<SettingsLoadWarnings>& warnings)
void TerminalWindow::_ShowLoadWarningsDialog(const IInspectable&, const Windows::Foundation::Collections::IVectorView<SettingsLoadWarnings>& warnings)
{
auto title = RS_(L"SettingsValidateErrorTitle");
auto buttonText = RS_(L"Ok");
@@ -503,7 +502,7 @@ namespace winrt::TerminalApp::implementation
}
else if (settingsLoadedResult == S_FALSE)
{
_ShowLoadWarningsDialog(_initialLoadResult.Warnings());
_ShowLoadWarningsDialog(nullptr, _initialLoadResult.Warnings());
}
}
@@ -718,8 +717,8 @@ namespace winrt::TerminalApp::implementation
//
// contentBounds is in screen pixels, but that's okay! we want to
// return screen pixels out of here. Nailed it.
const auto bounds = _contentBounds.Value();
initialPosition = { lroundf(bounds.X), lroundf(bounds.Y) };
const til::rect bounds = { til::math::rounding, _contentBounds.Value() };
initialPosition = { bounds.left, bounds.top };
}
return {
initialPosition.X ? initialPosition.X.Value() : defaultInitialX,
@@ -804,7 +803,7 @@ namespace winrt::TerminalApp::implementation
}
else if (args.Result() == S_FALSE)
{
_ShowLoadWarningsDialog(args.Warnings());
_ShowLoadWarningsDialog(nullptr, args.Warnings());
}
else if (args.Result() == S_OK)
{
@@ -1333,41 +1332,6 @@ namespace winrt::TerminalApp::implementation
}
}
void TerminalWindow::_WindowSizeChanged(const IInspectable&, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs args)
{
winrt::Windows::Foundation::Size pixelSize = { static_cast<float>(args.Width()), static_cast<float>(args.Height()) };
const auto scale = static_cast<float>(DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel());
if (!FocusMode())
{
if (!_settings.GlobalSettings().AlwaysShowTabs())
{
// Hide the title bar = off, Always show tabs = off.
static constexpr auto titlebarHeight = 10;
pixelSize.Height += (titlebarHeight)*scale;
}
else if (!_settings.GlobalSettings().ShowTabsInTitlebar())
{
// Hide the title bar = off, Always show tabs = on.
static constexpr auto titlebarAndTabBarHeight = 40;
pixelSize.Height += (titlebarAndTabBarHeight)*scale;
}
// Hide the title bar = on, Always show tabs = on.
// In this case, we don't add any height because
// NonClientIslandWindow::GetTotalNonClientExclusiveSize() gets
// called in AppHost::_resizeWindow and it already takes title bar
// height into account. In other cases above
// IslandWindow::GetTotalNonClientExclusiveSize() is called, and it
// doesn't take the title bar height into account, so we have to do
// the calculation manually.
}
args.Width(static_cast<int32_t>(pixelSize.Width));
args.Height(static_cast<int32_t>(pixelSize.Height));
WindowSizeChanged.raise(*this, args);
}
winrt::hstring WindowProperties::WindowName() const noexcept
{
return _WindowName;

View File

@@ -162,7 +162,6 @@ namespace winrt::TerminalApp::implementation
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::IInspectable> IsQuakeWindowChanged;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::SystemMenuChangeArgs> SystemMenuChangeRequested;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::SettingsLoadEventArgs> SettingsChanged;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs> WindowSizeChanged;
private:
// If you add controls here, but forget to null them either here or in
@@ -195,7 +194,7 @@ namespace winrt::TerminalApp::implementation
const winrt::hstring& contentKey,
HRESULT settingsLoadedResult,
const winrt::hstring& exceptionText);
void _ShowLoadWarningsDialog(const Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings>& warnings);
void _ShowLoadWarningsDialog(const IInspectable& sender, const Windows::Foundation::Collections::IVectorView<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings>& warnings);
bool _IsKeyboardServiceEnabled();
@@ -203,7 +202,6 @@ namespace winrt::TerminalApp::implementation
void _OnLoaded(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
void _pageInitialized(const IInspectable& sender, const IInspectable& eventArgs);
void _OpenSettingsUI();
void _WindowSizeChanged(const IInspectable& sender, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs args);
winrt::Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::ActionAndArgs> _contentStringToActions(const winrt::hstring& content,
const bool replaceFirstWithNewTab);
@@ -225,7 +223,6 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested);
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
FORWARDED_TYPED_EVENT(CloseRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, CloseRequested);
FORWARDED_TYPED_EVENT(OpenSystemMenu, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, OpenSystemMenu);
FORWARDED_TYPED_EVENT(QuitRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, QuitRequested);
FORWARDED_TYPED_EVENT(ShowWindowChanged, Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Control::ShowWindowArgs, _root, ShowWindowChanged);

View File

@@ -30,7 +30,7 @@ namespace TerminalApp
{
Boolean Reload { get; };
UInt64 Result { get; };
IVector<Microsoft.Terminal.Settings.Model.SettingsLoadWarnings> Warnings { get; };
IVectorView<Microsoft.Terminal.Settings.Model.SettingsLoadWarnings> Warnings { get; };
String ExceptionText { get; };
Microsoft.Terminal.Settings.Model.CascadiaSettings NewSettings { get; };
@@ -127,12 +127,10 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> CloseRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.SystemMenuChangeArgs> SystemMenuChangeRequested;
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.ShowWindowArgs> ShowWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.WindowSizeChangedEventArgs> WindowSizeChanged;
event Windows.Foundation.TypedEventHandler<Object, SettingsLoadEventArgs> SettingsChanged;

View File

@@ -11,6 +11,7 @@
<!-- sets a bunch of Windows Universal properties -->
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
<PgoTarget>true</PgoTarget>
<VersionInfoFileDescription>Windows Terminal Main UI Library</VersionInfoFileDescription>
</PropertyGroup>
<PropertyGroup Label="NuGet Dependencies">
<TerminalCppWinrt>true</TerminalCppWinrt>
@@ -69,7 +70,6 @@
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\dll\TerminalControl.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIMarkdown\UIMarkdown.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
</ProjectReference>

View File

@@ -27,6 +27,7 @@
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Foundation.Metadata.h>
@@ -63,8 +64,6 @@
#include <winrt/Microsoft.Terminal.Settings.Editor.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
#include <winrt/Microsoft.Terminal.UI.h>
#include <winrt/Microsoft.Terminal.UI.Markdown.h>
#include <winrt/Windows.Services.Store.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Provider.h>

View File

@@ -11,6 +11,7 @@
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
<ApplicationType>Windows Store</ApplicationType>
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
<VersionInfoFileDescription>Windows Terminal Azure Cloud Shell Connector</VersionInfoFileDescription>
</PropertyGroup>
<PropertyGroup Label="NuGet Dependencies">

View File

@@ -14,6 +14,13 @@ static DWORD g_cTerminalHandoffRegistration = 0;
// Mutex so we only do start/stop/establish one at a time.
static std::shared_mutex _mtx;
// This is the callback that will be called when a connection is received.
// Call this once during startup and don't ever change it again (race condition).
void CTerminalHandoff::s_setCallback(NewHandoffFunction callback) noexcept
{
_pfnHandoff = callback;
}
// Routine Description:
// - Starts listening for TerminalHandoff requests by registering
// our class and interface with COM.
@@ -21,24 +28,19 @@ static std::shared_mutex _mtx;
// - pfnHandoff - Function to callback when a handoff is received
// Return Value:
// - S_OK, E_NOT_VALID_STATE (start called when already started) or relevant COM registration error.
HRESULT CTerminalHandoff::s_StartListening(NewHandoffFunction pfnHandoff)
HRESULT CTerminalHandoff::s_StartListening()
try
{
std::unique_lock lock{ _mtx };
RETURN_HR_IF(E_NOT_VALID_STATE, _pfnHandoff != nullptr);
const auto classFactory = Make<SimpleClassFactory<CTerminalHandoff>>();
RETURN_IF_NULL_ALLOC(classFactory);
RETURN_LAST_ERROR_IF_NULL(classFactory);
ComPtr<IUnknown> unk;
RETURN_IF_FAILED(classFactory.As(&unk));
RETURN_IF_FAILED(CoRegisterClassObject(__uuidof(CTerminalHandoff), unk.Get(), CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &g_cTerminalHandoffRegistration));
_pfnHandoff = pfnHandoff;
return S_OK;
}
CATCH_RETURN()
@@ -53,15 +55,6 @@ CATCH_RETURN()
HRESULT CTerminalHandoff::s_StopListening()
{
std::unique_lock lock{ _mtx };
return s_StopListeningLocked();
}
// See s_StopListening()
HRESULT CTerminalHandoff::s_StopListeningLocked()
{
RETURN_HR_IF_NULL(E_NOT_VALID_STATE, _pfnHandoff);
_pfnHandoff = nullptr;
if (g_cTerminalHandoffRegistration)
{
@@ -92,22 +85,15 @@ HRESULT CTerminalHandoff::EstablishPtyHandoff(HANDLE* in, HANDLE* out, HANDLE si
{
try
{
std::unique_lock lock{ _mtx };
// s_StopListeningLocked sets _pfnHandoff to nullptr.
// localPfnHandoff is tested for nullness below.
#pragma warning(suppress : 26429) // Symbol '...' is never tested for nullness, it can be marked as not_null (f.23).
auto localPfnHandoff = _pfnHandoff;
// Because we are REGCLS_SINGLEUSE... we need to `CoRevokeClassObject` after we handle this ONE call.
// COM does not automatically clean that up for us. We must do it.
LOG_IF_FAILED(s_StopListeningLocked());
LOG_IF_FAILED(s_StopListening());
// Report an error if no one registered a handoff function before calling this.
THROW_HR_IF_NULL(E_NOT_VALID_STATE, localPfnHandoff);
THROW_HR_IF_NULL(E_NOT_VALID_STATE, _pfnHandoff);
// Call registered handler from when we started listening.
THROW_IF_FAILED(localPfnHandoff(in, out, signal, reference, server, client, startupInfo));
THROW_IF_FAILED(_pfnHandoff(in, out, signal, reference, server, client, startupInfo));
#pragma warning(suppress : 26477)
TraceLoggingWrite(

View File

@@ -38,11 +38,11 @@ struct __declspec(uuid(__CLSID_CTerminalHandoff))
#pragma endregion
static HRESULT s_StartListening(NewHandoffFunction pfnHandoff);
static HRESULT s_StopListening();
static void s_setCallback(NewHandoffFunction callback) noexcept;
static HRESULT s_StartListening();
private:
static HRESULT s_StopListeningLocked();
static HRESULT s_StopListening();
};
// Disable warnings from the CoCreatableClass macro as the value it provides for

View File

@@ -313,6 +313,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
}
CATCH_LOG()
try
{
auto processImageName{ wil::QueryFullProcessImageNameW<std::wstring>(_piClient.hProcess) };
_clientName = std::filesystem::path{ std::move(processImageName) }.filename().wstring();
}
CATCH_LOG()
_pipe = std::move(pipe.server);
*in = pipe.client.release();
*out = pipeClientClone.release();
@@ -428,6 +435,20 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TerminalOutput.raise(L"\r\n");
TerminalOutput.raise(badPathText);
}
// If the requested action requires elevation, display appropriate message
else if (hr == HRESULT_FROM_WIN32(ERROR_ELEVATION_REQUIRED))
{
const auto elevationText = RS_(L"ElevationRequired");
TerminalOutput.raise(L"\r\n");
TerminalOutput.raise(elevationText);
}
// If the requested executable was not found, display appropriate message
else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
const auto fileNotFoundText = RS_(L"FileNotFound");
TerminalOutput.raise(L"\r\n");
TerminalOutput.raise(fileNotFoundText);
}
_transitionToState(ConnectionState::Failed);
@@ -534,21 +555,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
}
}
void ConptyConnection::ResetSize()
{
if (_isConnected())
{
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), { Utils::ClampToShortMax(_cols, 1), Utils::ClampToShortMax(_rows, 1) }));
}
}
void ConptyConnection::ClearBuffer()
void ConptyConnection::ClearBuffer(bool keepCursorRow)
{
// If we haven't connected yet, then we really don't need to do
// anything. The connection should already start clear!
if (_isConnected())
{
THROW_IF_FAILED(ConptyClearPseudoConsole(_hPC.get()));
THROW_IF_FAILED(ConptyClearPseudoConsole(_hPC.get(), keepCursorRow));
}
}
@@ -780,12 +793,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
void ConptyConnection::StartInboundListener()
{
THROW_IF_FAILED(CTerminalHandoff::s_StartListening(&ConptyConnection::NewHandoff));
}
static const auto init = []() noexcept {
CTerminalHandoff::s_setCallback(&ConptyConnection::NewHandoff);
return true;
}();
void ConptyConnection::StopInboundListener()
{
THROW_IF_FAILED(CTerminalHandoff::s_StopListening());
CTerminalHandoff::s_StartListening();
}
// Function Description:

View File

@@ -23,9 +23,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
void Start();
void WriteInput(const winrt::array_view<const char16_t> buffer);
void Resize(uint32_t rows, uint32_t columns);
void ResetSize();
void Close() noexcept;
void ClearBuffer();
void ClearBuffer(bool keepCursorRow);
void ShowHide(const bool show);
@@ -36,7 +35,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
WORD ShowWindow() const noexcept;
static void StartInboundListener();
static void StopInboundListener();
static winrt::event_token NewConnection(const NewConnectionHandler& handler);
static void NewConnection(const winrt::event_token& token);

View File

@@ -14,8 +14,7 @@ namespace Microsoft.Terminal.TerminalConnection
String StartingTitle { get; };
UInt16 ShowWindow { get; };
void ResetSize();
void ClearBuffer();
void ClearBuffer(Boolean keepCursorRow);
void ShowHide(Boolean show);
@@ -23,7 +22,6 @@ namespace Microsoft.Terminal.TerminalConnection
static event NewConnectionHandler NewConnection;
static void StartInboundListener();
static void StopInboundListener();
static Windows.Foundation.Collections.ValueSet CreateSettings(String cmdline,
String startingDirectory,

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Sie können dieses Terminal jetzt mit STRG+D schließen oder zum Neustart die EINGABETASTE drücken.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[Fehler {0} beim Start von `{1}']</value>
@@ -220,4 +220,10 @@
<value>Auf das Startverzeichnis „{0}“ konnte nicht zugegriffen werden</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>Für den angeforderten Vorgang sind erhöhte Rechte erforderlich.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>Die angegebene Datei wurde nicht gefunden.</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>You can now close this terminal with Ctrl+D, or press Enter to restart.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[error {0} when launching `{1}']</value>
@@ -220,4 +220,10 @@
<value>Could not access starting directory "{0}"</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
</root>
<data name="ElevationRequired" xml:space="preserve">
<value>The requested operation requires elevation.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>The system cannot find the file specified.</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Ahora puede cerrar este terminal con Ctrl+D o presionar Entrar para reiniciar.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[error {0} al iniciar `{1}']</value>
@@ -220,4 +220,10 @@
<value>No se pudo obtener acceso al directorio inicial «{0}»</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>La operación solicitada requiere elevación.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>El sistema no puede encontrar el archivo especificado.</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Vous pouvez maintenant fermer ce terminal avec Ctrl+D, ou appuyez sur Entrée pour redémarrer.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[erreur {0} lors du lancement de `{1}']</value>
@@ -220,4 +220,10 @@
<value>Le démarrage du répertoire nest pas accessible «{0}»</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>Lopération demandée nécessite une élévation.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>Le fichier spécifié est introuvable.</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>È ora possibile chiudere il terminale con CTRL+D oppure premere INVIO per riavviarlo.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[errore {0} durante l'avvio di `{1}']</value>
@@ -220,4 +220,10 @@
<value>Non è possibile accedere alla directory di avvio "{0}"</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>Per l'operazione richiesta è necessaria l'elevazione dei privilegi.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>Impossibile trovare il file specificato.</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>このターミナルを Ctrl+D で閉じるか、Enter キーを押して再起動できます。</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>['{1}' の起動時にエラー {0} が発生しました]</value>
@@ -220,4 +220,10 @@
<value>先頭のディレクトリ "{0}" にアクセスできませんでした</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>要求された操作には、権限の昇格が必要です。</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>指定されたファイルが見つかりません。</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>이제 Ctrl+D 이 터미널을 닫거나 Enter 키를 눌러 다시 시작할 수 있습니다.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[{1}' 시작 시 {0} 오류 발생]</value>
@@ -220,4 +220,10 @@
<value>시작 디렉터리 "{0}"에 액세스할 수 없습니다.</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>요청한 작업을 수행하려면 권한 상승이 필요합니다.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>시스템에서 지정된 파일을 찾을 수 없습니다.</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Agora você pode fechar este terminal com Ctrl+D ou pressione Enter para reiniciar.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[erro {0} ao iniciar "{1}"]</value>
@@ -220,4 +220,10 @@
<value>Não foi possível acessar o diretório inicial "{0}"</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>A operação solicitada exige elevação.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>O sistema não pode encontrar o arquivo especificado.</value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Ỳóŭ ćǻή иòω сĺøѕè ťнįş тёѓмîήªŀ ωīťђ Çťѓℓ+Ď, όг ргéšѕ Σñтèř το ґèšтªят. !!! !!! !!! !!! !!! !!! !!!</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[℮ѓѓŏŕ {0} ωĥєй łåύñćђίηğ `{1}'] !!! !!! !!! </value>
@@ -220,4 +220,10 @@
<value>Ċőŭľđ йōť ª¢čеѕş şτāŗťΐиğ ðιѓεςтоŗγ "{0}" !!! !!! !!! !!!</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
</root>
<data name="ElevationRequired" xml:space="preserve">
<value>Ţнė ŗēqμĕѕŧєđ ôφ℮ґάтĩöй ŕєqΰїŗęś ėĺęνáτîøŋ. !!! !!! !!! !!! </value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>Ŧнё şγśţêм ςâлηόť ƒїлď ŧнэ ƒΐĺë śрéćιƒієð. !!! !!! !!! !!! </value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Ỳóŭ ćǻή иòω сĺøѕè ťнįş тёѓмîήªŀ ωīťђ Çťѓℓ+Ď, όг ргéšѕ Σñтèř το ґèšтªят. !!! !!! !!! !!! !!! !!! !!!</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[℮ѓѓŏŕ {0} ωĥєй łåύñćђίηğ `{1}'] !!! !!! !!! </value>
@@ -220,4 +220,10 @@
<value>Ċőŭľđ йōť ª¢čеѕş şτāŗťΐиğ ðιѓεςтоŗγ "{0}" !!! !!! !!! !!!</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
</root>
<data name="ElevationRequired" xml:space="preserve">
<value>Ţнė ŗēqμĕѕŧєđ ôφ℮ґάтĩöй ŕєqΰїŗęś ėĺęνáτîøŋ. !!! !!! !!! !!! </value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>Ŧнё şγśţêм ςâлηόť ƒїлď ŧнэ ƒΐĺë śрéćιƒієð. !!! !!! !!! !!! </value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Ỳóŭ ćǻή иòω сĺøѕè ťнįş тёѓмîήªŀ ωīťђ Çťѓℓ+Ď, όг ргéšѕ Σñтèř το ґèšтªят. !!! !!! !!! !!! !!! !!! !!!</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[℮ѓѓŏŕ {0} ωĥєй łåύñćђίηğ `{1}'] !!! !!! !!! </value>
@@ -220,4 +220,10 @@
<value>Ċőŭľđ йōť ª¢čеѕş şτāŗťΐиğ ðιѓεςтоŗγ "{0}" !!! !!! !!! !!!</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
</root>
<data name="ElevationRequired" xml:space="preserve">
<value>Ţнė ŗēqμĕѕŧєđ ôφ℮ґάтĩöй ŕєqΰїŗęś ėĺęνáτîøŋ. !!! !!! !!! !!! </value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>Ŧнё şγśţêм ςâлηόť ƒїлď ŧнэ ƒΐĺë śрéćιƒієð. !!! !!! !!! !!! </value>
</data>
</root>

View File

@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Теперь вы можете закрыть этот терминал с помощью клавиш CTRL+D. Или нажмите клавишу ВВОД для перезапуска.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[ошибка {0} при запуске "{1}"]</value>
@@ -220,4 +220,10 @@
<value>Не удалось получить доступ к запуску каталога "{0}"</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<value>Запрошенная операция требует получения дополнительных прав.</value>
</data>
<data name="FileNotFound" xml:space="preserve">
<value>Не удается найти указанный файл.</value>
</data>
</root>

Some files were not shown because too many files have changed in this diff Show More