Compare commits

...

174 Commits

Author SHA1 Message Date
Mike Griese
727b051fd4 Merge branch 'dev/migrie/f/sui-panes' into dev/migrie/fhl/tasks-pane 2024-05-02 16:27:09 -05:00
Mike Griese
7c4dfff451 Merge remote-tracking branch 'origin/main' into dev/migrie/f/sui-panes 2024-04-03 11:03:46 -05:00
Mike Griese
67ae9f6c3e Refactor the SettingsTab to be a pane (#16172)
... technically. We still won't let it actually _be_ a pane, but now it
acts like one. It's hosted in a `SettingsPaneContent`. There's no more
`SettingsTab`. It totally _can_ be in a pane (but don't?)

## Validation Steps Performed

* Still opens the settings
* Only opens a single settings tab, or re-activates the existing one
* Session restores!
* Updates the title of the tab appropriately
* I previously _did_ use the scratchpad action to open the settings in a
pane, and that worked.

## Related PRs
* #16170
  * #16171 
    * #16172 <-- you are here 
      * #16895

Refs #997
Closes #8452
2024-04-03 15:31:13 +00:00
Mike Griese
a0e014f277 Merge remote-tracking branch 'origin/main' into dev/migrie/f/sui-panes 2024-04-03 10:13:40 -05:00
Dustin L. Howett
2bcbe6b492 ci/rel: publish symbols using the internal symbol request API instead (#16991)
Work is ongoing to remove individually-authenticated service accounts
from some pipelines. This moves us closer to that goal.

Tested in Nightly 2403.28002.
2024-04-02 22:52:29 +00:00
Mike Griese
04fa18de71 Scratch tool: generate a fragment extension with every color scheme (#16962)
#16953 got me thinking: what if we just published an extension ourselves
that just packages up every color scheme in the ever-amazing
https://github.com/mbadolato/iTerm2-Color-Schemes?

Well, this isn't a package for that file. 

But it is a script to generate a fragment with all of them, and blat it
into your `%LOCALAPPDATA%\Microsoft\Windows Terminal\Fragments`.

It's a notebook because I've been really fascinated with the Polyglot
Notebooks recently.
2024-04-02 20:27:43 +00:00
Tushar Singh
4d58137bd4 Fix selection expansion for Double-Width and Double-Height rows (#16812)
Closes #16782

### Validation Steps Performed
- Double-clicking on a Double-Width row selects the word (identified by
delimiters) under the cursor.
- Tripple-clicking on a Double-Width row selects the whole line under
the cursor.
- The same works for Double-Height rows also.
- The same works for Single-Width rows also.
2024-04-02 19:57:19 +00:00
Marcel W
ad0c28b30d Add clamping of initial rows and columns settings (#16989)
This clamps the initial rows and columns settings in two areas:
- When reading the JSON file
- In the settings dialogue

For consistency, I've also added a minimum value to the NumberBoxes even
though the default Minimum is 1. The Maximum and Minimum are taken from
the JSON Schema file (Min 1, Max 999).

Closes #11957

---------

Co-authored-by: Dustin L. Howett <dustin@howett.net>
2024-04-02 17:56:26 +00:00
Mike Griese
5f1015953f Don't explode on session restore (#16998)
As noted in #16995. 

Don't persist us if we weren't ever initialized. In that case, we
never got an initial size, never instantiated a buffer, and didn't
start the connection yet, so there's nothing for us to add here.

If we were supposed to be restored from a path, then we don't need to
do anything special here. We'll leave the original file untouched,
and the next time we actually are initialized, we'll just use that
file then.

Closes #16995
2024-04-02 17:08:03 +00:00
Mike Griese
ad0b67239d Add some docs on how to resolve DEP0700 errors in VS (#16997)
This happens to me once a month, and I finally solved it.
2024-04-02 10:07:33 -07:00
Windows Console Service Bot
f2d6cceb2a Localization Updates - main - 03/30/2024 03:04:37 (#16973) 2024-04-02 10:06:27 -07:00
Leonard Hecker
9f3dbab7bf Fix bugs introduced in #16821 (custom font fallback) (#16993)
* Since `FindFontWithLocalizedName` is broken (intentionally and
  temporarily until #16943 is fixed) we have to be extra be careful
  not to return a nullptr `Font`.
* Portable builds may not have a broken font cache, but also not have
  the given font (Cascadia Mono for instance) installed. This requires
  us to load the nearby fonts even if there aren't any exceptions.

## Validation Steps Performed
* Open `src/cascadia/CascadiaResources.build.items`
  and remove the `Condition` for .ttf files
* Deploy on a clean Windows 10 VM
* Cascadia Mono loads without issues 
* Open the `Settings > Defaults > Appearance`,
  enter a non-existing font and hit Save
* Doesn't crash 
2024-04-01 18:32:31 -05:00
Leonard Hecker
3cc82a51d8 Replace til::some with til::small_vector (#16952)
`til::small_vector` had a bug: Its internal backing buffer didn't
prevent default initialization! Wrapping it in an `union` fixed that.

`til::some` had the same issue, but thinking about it I realized we
don't need both classes to exist, so I removed `til::some` since
`til::small_vector` is more flexible.

Checking the assembly, I noticed that `til::small_vector` with the
`union` fix produced a more compact result. I also noticed that in
combination with function calls and inlining the bit-wise ANDs in
the point/size/rect boolean operators produced poor-ish results.
Since their impact on performance is negligible to begin with I
simplified that code slightly.

Finally, I noticed that the boolean operator for `til::point`
was incorrect since it checked for `>0` instead of `>=0`.
Luckily nothing seemed to have used that operator yet.
(= No inbox regression.)
2024-03-29 23:15:46 +00:00
Mike Griese
e05b2bbe37 Merge branch 'main' into dev/migrie/f/sui-panes 2024-03-29 15:13:01 -05:00
Windows Console Service Bot
75dea24d6b Localization Updates - main - 03/29/2024 03:04:36 (#16967) 2024-03-29 14:47:11 +00:00
Leonard Hecker
9f08ee7af9 Buffer Restore: Fix turning off intense/faint (#16970)
This takes care of an edge case in regards to SGR 22: It turns off
both intense and faint attributes which means that we may need to
turn on one of the two if only one of them turned off.

Additionally, this removes the mapping for `BottomGridline` which
has no real VT equivalent anyway.

## Validation Steps Performed
* Turn session restore on
* In pwsh write:
  ```pwsh
  "`e[1;2mboth`e[0;1mintense`e[m`n`e[1;2mboth`e[0;2mfaint`e[m"
  ```
* Close the app and open the `buffer_*.txt` file next to settings.json
* It contains... 
  ```
  ␛[1m␛[2mboth␛[22;1mintense␛[22m
  ␛[1m␛[2mboth␛[22;2mfaint␛[22m
  ```
2024-03-29 14:46:51 +00:00
Leonard Hecker
c4c52061d5 Implement buffer restore (#16598)
This changeset allows Windows Terminal to dump its buffer contents as
UTF-16LE VT text onto disk and restore it later. This functionality is
enabled whenever `persistedWindowLayout` is being used.

Closes #961
Closes #16741

## Validation Steps Performed
* Open multiple windows with multiple tabs and restart the app
  Everything's restored 
* Reopen a tab with output from `RenderingTests.exe`
  Everything's restored 
* Closing tabs and windows with Ctrl+W deletes their buffer dumps 
* Closing tabs doesn't create buffer dumps 
2024-03-29 11:48:58 +00:00
Leonard Hecker
1ede023331 Properly fix ConPTY buffer corking (#16793)
I've found that #16079 was never properly addressed (it still randomly
occurred after even after PR #16349), which later led to the issues
described in #16769 (nushell flickering due to too many flushes).

The crux of the fix is that this brings back the `_noFlushOnEnd` flag
that was removed in PR #15991. This is then combined with a change to
the cork API: An `uncork` on `VtEngine` now only flushes if `_Flush`
got called while it was corked in the first place.

`_noFlushOnEnd` prevents us from flushing in between two "unknown"
VT sequences (like soft fonts or FTCS) which prevents them from being
corrupted. The corking prevents the remaining cases of flushing too
often. Long-term, a proper fix would be to pass through VT unmodified.

Closes #16769
2024-03-28 20:12:10 +00:00
Mike Griese
36c81f24fb Add a WT_SETTINGS_DIR env variable that portable profiles can use (#16949)
Basically, title. 

It'd be a neat idea for portable installs of the Terminal to reference
files that are right there in the portable install.

This PR adds a `WT_SETTINGS_DIR` var to Terminal's own env block. This
allows us to resolve profiles relative to our own settings folder.

Closes #16295
2024-03-28 20:11:36 +00:00
Leonard Hecker
0f81ac43b6 Replace til::bit_cast with std::bit_cast (#16948)
The former was introduced when we were still using C++17.
We're using C++20 now so it's not needed anymore.
2024-03-28 18:45:36 +00:00
Leonard Hecker
2050416997 Remove VtApiRoutines (#16954)
This removes `VtApiRoutines` and the VT passthrough mode.
Why? While VT passthrough mode has a clear advantage (doesn't corrupt
VT sequences) it fails to address other pain points (performance,
out-of-sync issues after resize, etc.). Alternative options are
available which have less restrictions.
Why now? It's spring! Spring cleanup!
2024-03-28 18:22:39 +00:00
Mike Griese
8349fd2728 Fix repositionCursorWithMouse after the viewport starts scrolling (#16950)
Yea, I used a viewport-relative mouse position, rather than the
buffer-relative position. Pretty obvious in retrospect.

Closes #16423
2024-03-28 18:19:42 +00:00
Mike Griese
68955d1ddb Add Dark+, CGA and IBM color schemes (#16953)
As discussed in #6176 and #16754. 

The "CGA" and "IBM 5153" names I'm told are the right ones to use:
https://github.com/microsoft/terminal/issues/16754#issuecomment-2024066880

Closes #6176 
Closes #16754
2024-03-28 12:28:26 +00:00
Windows Console Service Bot
e44fab921b Localization Updates - main - 03/28/2024 03:03:16 (#16959) 2024-03-28 12:12:46 +00:00
charli
4458a6d8c6 Replace 'it'll' with 'it will' to adhere to Microsoft Style Guidelines (#16955)
## Summary of the Pull Request

## References and Relevant Issues
Fixes "Align 'Run this profile as Administrator' Settings Description
with Microsoft Style Guidelines" #16946
## Detailed Description of the Pull Request / Additional comments
Expanded the contraction "it'll" to "it will" on line 993 of
`src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw`
## Validation Steps Performed
N/A

## PR Checklist
- [X] Closes #16946
- [ ] Tests added/passed
   - No tests were added
- [ ] Documentation updated
   - No documentation was updated
- [ ] Schema updated (if necessary)
   - No schema was updated
2024-03-28 12:11:25 +00:00
Dustin L. Howett
b0b7e50ec5 Revert "Move to AzureFileCopy@6 for Managed Identity support (#16957)"
This reverts commit 2e7c3fa313.
2024-03-27 18:12:50 -05:00
Dustin L. Howett
2e7c3fa313 Move to AzureFileCopy@6 for Managed Identity support (#16957)
This is required for us to move off Entra ID Application identity.
2024-03-27 16:05:56 -07:00
Windows Console Service Bot
26e6320374 Localization Updates - main - 03/27/2024 02:34:17 (#16945) 2024-03-27 10:58:36 +00:00
Leonard Hecker
de7f931228 Add support for customizing font fallback (#16821)
This adds support for specifying more than one font family using a
syntax that is similar to CSS' `font-family` property.
The implementation is straight-forward and is effectively
just a wrapper around `IDWriteFontFallbackBuilder`.

Closes #2664

## PR Checklist
* Font fallback
  * Write "「猫」"
  * Use "Consolas" and remember the shape of the glyphs
  * Use "Consolas, MS Gothic" and check that it changed 
* Settings UI autocompletion
  * It completes 
  * It filters 
  * It recognizes commas and starts a new name 
* All invalid font names are listed in the warning message 

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2024-03-26 23:10:29 +00:00
Leonard Hecker
a67a13288c AtlasEngine: Make Direct2D/3D and Present1 configurable (#16939)
This implements `SetForceFullRepaintRendering` and adds a new
`SetGraphicsAPI` function. The former toggles `Present1` on and off
and the latter allows users to explicitly request Direct2D/3D.

On top of these changes I did a minor cleanup of the interface,
because now that DxRenderer is gone we don't need all that anymore.

Closes #14254
Closes #16747

## Validation Steps Performed
* Toggling Direct2D on/off changes colored ligature support 
* Toggling Present1 on/off can be observed in a debugger 
* Toggling WARP on/off changes GPU metrics 

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2024-03-26 21:31:24 +00:00
Mike Griese
ef560bf48e Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-26 13:56:21 -05:00
Mike Griese
7243d220e5 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/scratchpad-pane 2024-03-26 13:55:54 -05:00
Mike Griese
10e1e46945 ALSO doesn't really need to be projected 2024-03-26 13:55:11 -05:00
Mike Griese
ddc88c83b2 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-26 13:26:16 -05:00
Mike Griese
501522d690 Add an experimental "scratchpad pane", for testing (#16171)
## Summary of the Pull Request

Builds upon #16170. This PR simply adds a singly type of non-terminal
pane - a "scratchpad pane". This is literally just a single text box, in
a pane. It's on the `{ "command": "experimental.openScratchpad" }`
action.

## References and Relevant Issues

See: #997

## Detailed Description of the Pull Request / Additional comments

I also put it behind velocity so it won't even go into preview while
this bakes.

This is really just here to demonstrate that this works, and is viable.
The next PR is much more interesting.

## Validation Steps Performed
Screenshot below. 


## other PRs
* #16170
* #16171 <-- you are here 
* #16172
2024-03-26 17:56:31 +00:00
Dustin L. Howett
e8f18ea92c ci: trigger builds for gh-readonly-queue/* merge queue branches (#16941)
We may try a thing!
2024-03-26 12:55:14 -05:00
Mike Griese
1d20599186 un fix this file 2024-03-26 11:38:47 -05:00
Mike Griese
b6e4b62e15 Doesn't really need to be projected 2024-03-26 11:37:35 -05:00
Mike Griese
0979cd6c44 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-03-26 11:22:45 -05:00
Mike Griese
61e952c58e Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2024-03-26 11:22:27 -05:00
Mike Griese
08dc346120 Refactor Pane to be able to host non-terminal content (#16170)
Instead of `Pane` hosting a `TermControl` directly, it now hosts an
`IPaneContent`. This is an abstraction between the TermControl and the
pane itself, to allow for arbitrary implementations of `IPaneContent`,
with things that might not be terminals.

## References and Relevant Issues

* #997
* #1000

## Detailed Description of the Pull Request / Additional comments

This PR by itself doesn't do much. It's just a refactoring. 
- It doesn't actually add any other types of pane content. 
- It overall just tries to move code whenever possible, with as little
refactoring as possible. There are some patterns from before that don't
super scale well to other types of pane content (think: the `xyzChanged`
events on `IPaneContent`).
- There's a few remaining places where Pane is explicitly checking if
its content is a terminal. We probably shouldn't, but meh

There are two follow-up PRs to this PR:
* #16171 
* #16172 

In addition, there's more work to be done after these merge:
* TODO! issue number for "Replace `IPaneContent::xyzChanged` with
`PropertyChanged` events"
* TODO! issue number for "Re-write state restoration so panes don't
produce `NewTerminalArgs`"

## Validation Steps Performed

* It still launches
* It still works
* Broadcasting still works
* The weird restart connection thing from #16001 still works

## PR Checklist
- [x] Closes #997


## other PRs
* #16170 <-- you are here 
* #16171
* #16172
2024-03-26 11:03:05 -05:00
Windows Console Service Bot
2ee7783f23 Localization Updates - main - 03/25/2024 19:34:25 (#16934) 2024-03-25 20:01:42 +00:00
Leonard Hecker
77d5e23ef2 Make ploc translations predictable (#16924) 2024-03-25 13:42:22 -05:00
Leonard Hecker
8403b38c81 Enable /Ob1 in Debug builds (#16932)
This makes the build a tiny bit faster (less time spent linking)
and makes everything run roughly 50% faster.
2024-03-25 11:34:49 -07:00
Tushar Singh
038cfca029 Add VSCode configs for better out-of-box LSP support (#16920)
Prevents errors generated due to unresolved headers in VSCode

## Validation Steps Performed
- Errors messages are removed.
- Headers are resolved properly.
2024-03-25 12:40:04 +00:00
Mike Griese
37b4b7b6c0 fix builds 2024-03-22 06:54:29 -05:00
Leonard Hecker
5b8e731e5d AtlasEngine: Fix a OOB read when rendering PUA chars (#16894)
When no soft fonts are set up but we're asked to draw a U+EF20, etc.,
character we'll currently read out-of-bounds, because we don't check
whether the soft fonts array is non-empty. This PR fixes the issue by
first getting a slice of the data and then checking if it's ok to use.

This changeset additionally fixes a couple constinit vs. constexpr
cases. I changed them to constinit at some point because I thought
that it's more constexpr than constexpr by guaranteeing initialization
at compile time. But nope, constinit is actually weaker in a way,
because while it does guarantee that, it doesn't actually make the
data constant. In other words, constinit is not `.rdata`.
2024-03-21 15:38:53 -05:00
Mike Griese
6576f949c4 Merge branch 'dev/migrie/f/sui-panes' into dev/migrie/fhl/tasks-pane 2024-03-21 14:02:45 -05:00
Mike Griese
216cc3fa66 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-21 14:02:24 -05:00
Mike Griese
d41793470f Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-03-21 13:51:52 -05:00
Mike Griese
df73d75541 derp 2024-03-21 13:51:34 -05:00
Mike Griese
66878d2ddc Merge branch 'dev/migrie/f/sui-panes' into dev/migrie/fhl/tasks-pane 2024-03-21 13:21:51 -05:00
Mike Griese
77022e92f1 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-21 13:17:20 -05:00
Mike Griese
f1ab16e7d5 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-03-21 13:16:08 -05:00
Mike Griese
2083b2ff9e Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2024-03-21 13:14:32 -05:00
Mike Griese
b9a0cae010 Add a pile of 'experimental' settings to the profile SUI (#16809)
As noted in #3337, we never actually added this menu to the settings. 

Since we're planning on taking this out of "experimental" in 1.21, we
should have a visible setting for it too.
2024-03-21 12:07:57 -05:00
Craig Loewen
0a83946214 Update similarIssues.yml to include issue bodies (#16915)
Improved the GitGudSimilarIssues bot to include issue body info now.
2024-03-21 11:07:32 -05:00
Windows Console Service Bot
b3348d3bbb Localization Updates - main - 03/21/2024 03:04:53 (#16910) 2024-03-21 09:27:26 -05:00
Dustin L. Howett
febfbebf9b Remove the "set default terminal" banner (#16873)
**Default Terminal**: Everyone who cares to know, knows. Everyone who
doesn't, has an annoying bar above all terminals

I had to introduce a workaround for the fact that unknown dismissed
message keys in `state.json` result in Terminal exploding on launch.
😁 That's tracked in #16874.

Closes #11930 (but not in the way you'd expect)
2024-03-20 21:23:11 +00:00
Dustin L. Howett
ff47e0c257 build: roll back to a build container with the 14.38 compiler (#16907)
The 14.39 compiler seems pretty busted.

Refs #16794
2024-03-20 15:52:53 -05:00
Leonard Hecker
373faf00c9 Fix a ReadConsoleOutputCharacter regression (#16898)
The `nLength` parameter of `ReadConsoleOutputCharacterW` indicates
the number of columns that should be read. For single-column (narrow)
surrogate pairs this previously clipped a trailing character of the
returned string. In the major Unicode support update in #13626
surrogate pairs truly got stored as atomic units for the first time.
This now meant that a 120 column read with such codepoints resulted
in 121 characters. Other parts of conhost still assume UCS2 however,
and so this results in the entire read failing.

This fixes the issue by turning surrogate pairs into U+FFFD
which makes it UCS2 compatible.

Closes #16892

## Validation Steps Performed
* Write U+F15C0 and read it back with `ReadConsoleOutputCharacterW`
* Read succeeds with a single U+FFFD 
2024-03-20 19:37:03 +00:00
Mike Griese
a971663449 Replace usages of TYPED_EVENT with til::event (#16837)
This PR automagically finds and replaces all[^1] usages of our
TYPED_EVENT macro with `til::event`. Benefits include:
* less macro magic
* editors are more easily able to figure out the relationship between
`til::event<> Foo;`, `Foo.raise(...)`, and `bar.Foo({this,
&Bar::FooHandler})` (whereas before the relationship between
`_FooHandlers(...)` and `bar.Foo({...})`) couldn't be figured out by
vscode & sublime.


Other find & replace work that had to be done: 
* I added the `til::typed_event<>` == `<IInspectable, IInspectable>`
thing from #16170, since that is goodness
* I actually fixed `til::property_changed_event`, so you can use that
for your property changed events. They're all the same anyways.
* events had to come before `WINRT_PROPERTY`s, since the latter macro
leaves us in a `private:` block
* `Pane::SetupChildCloseHandlers` I had to swap _back_, because the
script thought that was an event 🤦
* `ProfileViewModel::DeleteProfile` had to be renamed
`DeleteProfileRequested`, since there was already a `DeleteProfile`
method on it.
* WindowManager.cpp was directly wiring up it's `winrt::event`s to the
monarch & peasant. That doesn't work with `til::event`s and I'm kinda
surprised it ever did


<details>
<summary>The script in question</summary>

```py
import os
import re

def replace_in_file(file_path, file_name):
    with open(file_path, 'r', encoding="utf8") as file:
        content = file.read()
    
    found_matches = False

    # Define the pattern for matching
    pattern = r' WINRT_CALLBACK\((\w+),\s*(.*?)\);'
    event_matches = re.findall(pattern, content)
    if event_matches:
        found_matches = True

        print(f'found events in {file_path}:')
        for match in event_matches:
            name = match[0]
            args = match[1]

            if name == "newConnection" and file_name == "ConptyConnection.cpp":
                # This one is special
                continue

            old_declaration = 'WINRT_CALLBACK(' + name + ', ' + args + ');'
            new_declaration = 'til::event<' + args + '> ' + name + ';' if name != "PropertyChanged" else 'til::property_changed_event PropertyChanged;'
            print(f'  {old_declaration} -> {new_declaration}')
            content = content.replace(old_declaration, new_declaration)


    typed_event_pattern = r' TYPED_EVENT\((\w+),\s*(.*?)\);'
    typed_matches = re.findall(typed_event_pattern, content)
    if typed_matches:
        found_matches = True
        print(f'found typed_events in {file_path}:')
        for match in typed_matches:
            name = match[0]
            args = match[1]

            if name == "newConnection" and file_name == "ConptyConnection.cpp":
                # This one is special
                continue

            old_declaration = f'TYPED_EVENT({name}, {args});'
            was_inspectable = (args == "winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable" ) or (args == "IInspectable, IInspectable" )
            new_declaration = f'til::typed_event<{args}> {name};' if not was_inspectable else f"til::typed_event<> {name};"
            print(f'  {old_declaration} -> {new_declaration}')
            content = content.replace(old_declaration, new_declaration)

    handlers_pattern = r'_(\w+)Handlers\('
    handler_matches = re.findall(handlers_pattern, content)
    if handler_matches:
        found_matches = True
        print(f'found handlers in {file_path}:')
        for match in handler_matches:
            name = match

            if name == "newConnection" and file_name == "ConptyConnection.cpp":
                # This one is special
                continue

            old_declaration = f'_{name}Handlers('
            new_declaration = f'{name}.raise('
            print(f'  {old_declaration} -> {new_declaration}')
            content = content.replace(old_declaration, new_declaration)


    if found_matches:
        with open(file_path, 'w', encoding="utf8") as file:
            file.write(content)

def find_and_replace(directory):
    for root, dirs, files in os.walk(directory):
        if 'Generated Files' in dirs:
            dirs.remove('Generated Files')  # Exclude the "Generated Files" directory

        for file in files:
            if file.endswith('.cpp') or file.endswith('.h') or file.endswith('.hpp'):
                file_path = os.path.join(root, file)
                try:
                    replace_in_file(file_path, file)
                except Exception as e:
                    print(f"error reading {file_path}")
                    if file == "TermControl.cpp":
                        print(e)
                    # raise e

# Replace in files within a specific directory
directory_path = 'D:\\dev\\public\\terminal\\src'
find_and_replace(directory_path)

```

</details>


[^1]: there are other macros we use that were also using this macro,
those weren't replaced.

---------

Co-authored-by: Dustin Howett <duhowett@microsoft.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2024-03-20 11:02:26 -05:00
Mike Griese
7b84041ae1 Merge branch 'dev/migrie/f/sui-panes' into dev/migrie/fhl/tasks-pane 2024-03-20 09:38:28 -05:00
Mike Griese
bcceb85057 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-20 09:20:16 -05:00
Mike Griese
352e0a211a fix settings pane for merge
(cherry picked from commit 0c6a353967)
2024-03-20 09:19:03 -05:00
Mike Griese
e0bb8409b3 Fix scratch pane for merge
(cherry picked from commit 591080db39)
2024-03-20 09:17:55 -05:00
Mike Griese
8f2a129a1e Merge branch 'dev/migrie/f/sui-panes' into dev/migrie/fhl/tasks-pane 2024-03-20 06:50:28 -05:00
Mike Griese
c8d0c0aab7 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-20 06:40:43 -05:00
Mike Griese
2357653de5 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-03-20 06:40:04 -05:00
PankajBhojwani
5f272804c4 Add OriginTag to Command (#16823)
## Summary of the Pull Request
As outlined in #16816 , adding `OriginTag` to `Command` is one of the
prerequisites to implementing Action IDs. This PR does that.

## Validation Steps Performed
Actions/Commands still get parsed and work

## PR Checklist
- [ ] Closes #xxx
- [ ] 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)
2024-03-19 17:00:59 -05:00
Mike Griese
52970ef854 RegisterBigTimeEncapsulationViolatingTerminalPaneContentEvents 2024-03-19 16:30:00 -05:00
Mike Griese
826fc087b0 hey there buddy, did you get lost? 2024-03-19 15:50:58 -05:00
Mike Griese
a7533faf45 eh these events are from pane content anyways! 2024-03-19 15:15:08 -05:00
Mike Griese
052dc78af5 more nits 2024-03-19 14:54:30 -05:00
Mike Griese
fd8b083a46 get rid of this file 2024-03-19 13:55:11 -05:00
Mike Griese
6789ec0765 some of the easier nits 2024-03-19 13:34:35 -05:00
Windows Console Service Bot
5383cb3a1b Localization Updates - main - 03/15/2024 03:03:49 (#16877) 2024-03-19 10:38:18 -05:00
Jvr
ba34abb7b3 Update to CLI11 version 2.4.1 (#16669)
## Summary of the Pull Request
update to the latest cli11 version

## References and Relevant Issues
none

## Detailed Description of the Pull Request / Additional comments
none

## Validation Steps Performed

## PR Checklist
- [ ] Closes #xxx
- [ ] 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)

---------

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2024-03-18 13:48:06 -05:00
Tushar Singh
07a6f6a755 Add SearchBox entry/exit animations (#16808)
Adds animations at the Entry and Exit of the Search Box.


https://github.com/microsoft/terminal/assets/55626797/14773bb7-89d8-4dc4-9aa4-1600139e97ae

Inspired by WinUI
[CommandBarFlyout](https://github.com/microsoft/microsoft-ui-xaml/tree/v2.8.6/dev/CommandBarFlyout)

## Validation Steps Performed
- Animation feels good 
- Works with multiple panes open.
- Pane opening/closing doesn't cause re-animations.
2024-03-18 13:45:59 -05:00
Mike Griese
863840ee0f Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-18 13:20:43 -05:00
Mike Griese
1951f30434 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-03-18 13:20:26 -05:00
Mike Griese
524d658699 GREAT-GREAT-GRANDPARENT: Hey when a pane wants to get closed, we should close it 2024-03-18 13:19:45 -05:00
Mike Griese
ef775a87c9 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2024-03-18 13:19:26 -05:00
Leonard Hecker
287422b211 Clean up the Converters implementation (#16820)
I thought the Converters.idl file had a really neat ordering,
and I felt like the .cpp implementation fell short of this.

This PR reorders the functions in the implementation to match the IDL.
It also gets rid of some unnecessary math (int vs. float, clamping)
and removes another use of `std::stringstream` (= bad STL class).
2024-03-18 09:26:18 -05:00
Dustin L. Howett
a4945488db Add SettingContainer Warning/Error styles to replace InfoBar (#16876)
This commit adds some styles to SettingContainer that can be used to
display informational messages. They don't have reset buttons or content
and they can't be interacted with.

I did this because the InfoBars didn't scale properly when the window
was wide. Also they had an [X] button that hid the warning but didn't
persist that they had been hidden or anything.
2024-03-18 09:22:51 -05:00
Dustin L. Howett
d2bd18735e Fix a number of minor issues that Clang flagged (again! again!) (#16863)
* `[[nodiscard]]` and `[[maybe_unused]]` must come before `virtual` and
`static` qualifiers
* MSVC and Clang disagree on how `gsl::suppress` should look;
fortunately, GSL provides a macro to paper over the difference
* Clang throws "pessimizing move" warnings when you `std::move` a
temporary, as it makes copy elision impossible
* The fuzzing logic was using an unspecified template expansion
`CFuzzLogic<>` before the type had been declared
* LibraryResources was emitting most of the `.util` section with
read-write permissions and some of it with read-only

Refs #15952
2024-03-18 09:15:35 -05:00
Dustin L. Howett
c3ab2fb6a8 Add support for turning off full-color Emoji (#16871)
This pull request introduces support for disabling full-color emoji (and
technically other COLR-related font features!)

Full-color emoji don't respond to SGR colors, intensity, faint or blink.
Some users also just prefer the line art ones.

Related to #15979
Refs #1790
Closes #956
2024-03-14 17:05:12 -07:00
PankajBhojwani
566b660eb2 Use .rc files in TSM instead of string literals (#16844)
More prerequisite work for Action IDs - turns out if we add the action
IDs to the actions defined in `defaults.json` the string ends up being
too large and the compiler complains about it. Use a `.rc` file for
`defaults.json` instead and also for `enableColorSelection.json` +
`userDefaults.json`.
2024-03-14 15:50:07 -05:00
Isaac Blanco
806d5e2d05 Update CommandPalette.cpp to ignore _filterTextChanged on TabSwitchMode (#16858)
As mentioned in #11146, when the "Next/Prev" command is executed from
the command line with a string in the search bar, this is setting always
the first tab.

When using the command "Next/Previous Tab" from the command line, we are
creating another tab (as if we are using the keyboard shortcut), and
this triggers the `_filterTextChanged` that resets the index to the
first item in because the current mode that it has.

This could be cause because, It seems that it detects as if we are
deleting the entered letter or creating an empty string, causing the
execution of the mentioned method and resetting its index to 0.

To avoid this, we are making sure that when this action is triggerd and
we are in the `TabSwitchMode`, we should ignore the following execution
of the method.

## Validation Steps Performed
I tested out the following scenarios:
1. Performing the action with the keyboard shorcut
2. Perfoming the action with an empty string
3. Performing the action with a string in the search bar.

Also validated with the current tests.

Closes #11146
2024-03-14 14:58:05 -05:00
Mike Griese
5b4747f7b7 Merge remote-tracking branch 'origin/dev/migrie/f/sui-panes' into dev/migrie/fhl/tasks-pane 2024-03-14 14:10:21 -05:00
Mike Griese
978fd6e2ba Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-03-08 10:36:17 -06:00
Mike Griese
35651bc92c Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-03-08 10:33:31 -06:00
Mike Griese
a3fbc64384 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2024-03-08 10:33:00 -06:00
Mike Griese
b6254f8294 GREAT-GRANDPARENT: This fixes a crash in parent pane selection
(cherry picked from commit 91a0d0e26d)
2024-03-07 16:51:02 -06:00
Mike Griese
4d47cd5866 cleanup 2024-03-04 16:34:36 -06:00
Mike Griese
0a11643f1d sanely pass around a cache instead of... whatever that was. 2024-03-04 16:30:16 -06:00
Mike Griese
17075d6744 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-02-28 11:50:29 -06:00
Mike Griese
25a8851986 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-02-28 11:36:02 -06:00
Mike Griese
de5f7af25d Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2024-02-28 11:32:40 -06:00
Mike Griese
14a00c8abf lots of cleanup 2024-02-21 12:14:47 -06:00
Mike Griese
02a5593f5b this is amazing, I'm amazing, everything is awesome 2024-02-21 12:07:45 -06:00
Mike Griese
2960476019 holy fuck this is better than I imagined a week ago 2024-02-21 11:39:58 -06:00
Mike Griese
9300647b58 turns out Visibility works exactly like you'd want for a TreeView 2024-02-21 11:20:33 -06:00
Mike Griese
b706a6d679 yes yes subclasses are hard in C 2024-02-21 11:01:36 -06:00
Mike Griese
17d70f5221 weird but works surprisingly well 2024-02-21 10:57:05 -06:00
Mike Griese
69cb54509c Blindly, what if TaskViewModel was a FilteredCommand? 2024-02-21 10:16:41 -06:00
Mike Griese
def66306a1 I wanted to start adding a filter box, but that got tricky 2024-02-21 09:32:50 -06:00
Mike Griese
d86bd57876 Merge branch 'dev/migrie/fhl/tasks-pane' of https://github.com/microsoft/terminal into dev/migrie/fhl/tasks-pane 2024-02-21 09:18:46 -06:00
Mike Griese
01ca03f433 Don't generate names with visualized SPC and BS for the sxnui
You know, this doesn't really help right now, but it should fix #16577,
and maybe help with #16578 (but not the command palette part)
2024-02-21 09:17:44 -06:00
Mike Griese
c94c00b760 more better styling 2024-02-21 09:11:47 -06:00
Mike Griese
afa7a2478b more better styling 2024-02-20 16:12:12 -06:00
Mike Griese
db427f2cd1 better styling 2024-02-20 16:11:34 -06:00
Mike Griese
2f3ecf1ea0 plumb the action through to the task pane 2024-02-20 15:41:10 -06:00
Mike Griese
d7a6b1899c re-add the visibility hack; add a play button that does nothing 2024-02-20 09:28:42 -06:00
Mike Griese
365c068da1 this fixes that random item reuse problem 2024-02-19 12:42:24 -06:00
Mike Griese
8418d6a1cb omg bind to the IsSelected 2024-02-16 15:54:21 -06:00
Mike Griese
0bb13f9eee real xaml 2024-02-16 09:23:50 -06:00
Mike Griese
e72b1bf835 nested commands are easy guys 2024-02-16 08:40:29 -06:00
Mike Griese
81b35ff143 this worked surprisingly quickly 2024-02-16 08:32:30 -06:00
Mike Griese
092b3558f3 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2024-02-08 09:47:33 -06:00
Mike Griese
c2446334e6 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2024-02-08 09:46:46 -06:00
Mike Griese
3982358188 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2024-02-08 09:40:19 -06:00
Mike Griese
0d528f84f2 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2024-01-19 16:25:31 -06:00
Mike Griese
6bc711de06 maybe I'm not that good at coding 2023-11-08 11:10:58 -06:00
Mike Griese
f622d80004 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2023-11-08 05:55:27 -06:00
Mike Griese
4cec7e9b4b try to remove a few of these but ultimately, eh 2023-11-06 06:01:55 -06:00
Mike Griese
cf920e7d58 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2023-11-02 06:13:22 -05:00
Mike Griese
389ba20a98 spel 2023-10-25 14:41:57 -05:00
Mike Griese
dd8606ff9b Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2023-10-25 11:04:43 -05:00
Mike Griese
7bc1457d42 nits and such 2023-10-25 11:03:41 -05:00
Mike Griese
e9e04d4e70 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2023-10-25 09:37:37 -05:00
Mike Griese
58e8f3c11c mostly nits 2023-10-25 09:37:23 -05:00
Mike Griese
8df9523a77 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2023-10-25 09:04:35 -05:00
Mike Griese
fd0640997d annoying build break 2023-10-13 15:17:38 -05:00
Mike Griese
fb74fc8c6a dead code 2023-10-13 14:58:19 -05:00
Mike Griese
5f4087ff00 finish exorcising SettingsTab 2023-10-13 14:56:50 -05:00
Mike Griese
81889a685c derp 2023-10-13 14:08:49 -05:00
Mike Griese
e82c627ebe dead code removal 2023-10-13 12:09:08 -05:00
Mike Griese
d726165330 terrible, but it works 2023-10-13 12:06:59 -05:00
Mike Griese
57e1f26d14 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2023-10-13 11:36:27 -05:00
Mike Griese
b49997b4b4 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2023-10-13 11:12:24 -05:00
Mike Griese
2086e0f3af Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2023-10-13 10:39:02 -05:00
Mike Griese
6107c3e551 Merge branch 'dev/migrie/fhl/scratchpad-pane' into dev/migrie/f/sui-panes 2023-09-11 05:43:06 -05:00
Mike Griese
46469aa5e3 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2023-09-11 05:24:30 -05:00
Mike Griese
c869b47e13 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2023-09-11 05:22:43 -05:00
Mike Griese
9531069538 background brush, done 2023-08-07 15:17:09 -05:00
Mike Griese
521e301541 update settings should work now 2023-08-03 13:50:11 -05:00
Mike Griese
842326daa5 icons for non-terminal pane content 2023-08-03 11:31:57 -05:00
Mike Griese
fb7c80938b derp 2023-08-01 11:37:10 -05:00
Mike Griese
29d0d57656 this works better than it has any right to 2023-07-27 16:29:26 -05:00
Mike Griese
cbd61b0a7d POC: yea, this works 2023-07-27 15:55:05 -05:00
Mike Griese
1cc9835454 feature flags too 2023-07-27 13:58:44 -05:00
Mike Griese
86914bdfc1 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2023-07-25 13:28:25 -05:00
Mike Griese
e0b003ad4d Merge branch 'main' into dev/migrie/fhl/non-terminal-panes-2023 2023-07-24 14:10:40 -05:00
Mike Griese
f89368c19b [PARENT] try to use GetActiveTerminalControl less in TerminalTab
(cherry picked from commit 262d95aae5)
2023-07-20 10:59:41 -05:00
Mike Griese
5582e1bcc8 [PARENT] You know what, I just went for it.
(cherry picked from commit 63ba8e19fd)
2023-07-20 10:59:28 -05:00
Mike Griese
a23c1a24dc keybindings too 2023-07-20 07:39:02 -05:00
Mike Griese
5f9add4000 Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane 2023-07-20 07:04:10 -05:00
Mike Griese
11126f9b37 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2023-07-20 07:02:16 -05:00
Mike Griese
e31202b0b8 Merge commit '6a10ea5' into dev/migrie/fhl/non-terminal-panes-2023 2023-07-20 07:02:04 -05:00
Mike Griese
e6dc314c17 Merge commit 'b4042ea' into dev/migrie/fhl/non-terminal-panes-2023 2023-07-19 16:22:03 -05:00
Mike Griese
2d4030683a Let's just make it experimental 2023-07-18 13:47:58 -05:00
Mike Griese
262d95aae5 [PARENT] try to use GetActiveTerminalControl less in TerminalTab 2023-07-18 13:47:38 -05:00
Mike Griese
63ba8e19fd [PARENT] You know what, I just went for it. 2023-07-18 13:21:18 -05:00
Mike Griese
1b39db7ab0 Single commit that adds the whole scratchpad and action 2023-07-18 12:58:55 -05:00
Mike Griese
2dd8f409b2 [TO PARENT] dead code 2023-07-18 11:48:33 -05:00
Mike Griese
049c043279 some last cleanups 2023-07-18 10:26:32 -05:00
Mike Griese
a1da6c117e huge shuffling so that pane content can raise events instead of relying on termcontrol 2023-07-18 10:13:44 -05:00
Mike Griese
7c9ffb0e02 snapping now uses an interface, so that it's not TermControl-specific 2023-07-18 06:06:07 -05:00
Mike Griese
84df8197d4 close event 2023-07-17 14:22:12 -05:00
Mike Griese
5b3aa54b56 move GetNewTerminalArgs into IPaneContent 2023-07-17 12:42:43 -05:00
Mike Griese
ef6bb8a73c hey look, it builds now 2023-07-17 12:35:27 -05:00
Mike Griese
4e144425f0 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/non-terminal-panes-2023 2023-07-17 10:53:56 -05:00
Mike Griese
f353323a23 I wanted to do this in one shot but _zelda_ 2023-05-12 13:32:12 -05:00
394 changed files with 20612 additions and 17840 deletions

View File

@@ -32,6 +32,7 @@ DWINRT
enablewttlogging
HOMESHARE
Intelli
issecret
IVisual
libucrt
libucrtd
@@ -74,6 +75,7 @@ sid
Skype
SRW
sxs
symbolrequestprod
Sysinternals
sysnative
systemroot

View File

@@ -91,7 +91,6 @@ backgrounding
backported
backstory
barbaz
Batang
Bazz
BBDM
bbwe
@@ -180,7 +179,6 @@ changelists
chaof
charinfo
CHARSETINFO
chcbpat
chh
chshdng
CHT
@@ -198,7 +196,6 @@ cloudconsole
cloudvault
CLSCTX
clsids
CLUSTERMAP
cmatrix
cmder
CMDEXT
@@ -214,7 +211,6 @@ codepages
codepath
coinit
colorizing
COLORMATRIX
COLORREFs
colorschemes
colorspec
@@ -222,7 +218,6 @@ colortable
colortbl
colortest
colortool
COLR
combaseapi
comctl
commandline
@@ -367,11 +362,9 @@ DBGFONTS
DBGOUTPUT
dbh
dblclk
DBlob
DColor
DCOLORVALUE
dcommon
dcompile
dcompiler
DComposition
dde
@@ -479,7 +472,6 @@ depersist
deprioritized
deserializers
desktopwindowxamlsource
DESTINATIONNAME
devicecode
Dext
DFactory
@@ -539,7 +531,6 @@ DWORDs
dwrite
dxgi
dxgidwm
dxguid
dxinterop
dxsm
dxttbmp
@@ -606,8 +597,9 @@ FECF
FEEF
fesb
FFAF
ffd
FFDE
FFrom
FFFDb
fgbg
FGCOLOR
FGHIJ
@@ -719,7 +711,6 @@ GETWAITTOKILLTIMEOUT
GETWHEELSCROLLCHARACTERS
GETWHEELSCROLLCHARS
GETWHEELSCROLLLINES
GFEh
Gfun
gfx
GGI
@@ -767,6 +758,7 @@ hdr
HDROP
hdrstop
HEIGHTSCROLL
hfind
hfont
hfontresource
hglobal
@@ -867,7 +859,6 @@ INLINEPREFIX
inproc
Inputkeyinfo
INPUTPROCESSORPROFILE
inputrc
Inputreadhandledata
INSERTMODE
INTERACTIVITYBASE
@@ -908,10 +899,6 @@ KAttrs
kawa
Kazu
kazum
kcub
kcud
kcuf
kcuu
kernelbase
kernelbasestaging
KEYBDINPUT
@@ -923,7 +910,6 @@ Keymapping
keyscan
keystate
keyups
khome
KILLACTIVE
KILLFOCUS
kinda
@@ -1061,7 +1047,6 @@ MBUTTON
MBUTTONDBLCLK
MBUTTONDOWN
MBUTTONUP
Mbxy
mdmerge
MDs
MEASUREITEM
@@ -1086,7 +1071,6 @@ minkernel
MINMAXINFO
minwin
minwindef
Mip
MMBB
mmcc
MMCPL
@@ -1123,8 +1107,8 @@ msix
msrc
MSVCRTD
MTSM
munges
Munged
munges
murmurhash
muxes
myapplet
@@ -1173,6 +1157,7 @@ NOCONTEXTHELP
NOCOPYBITS
NODUP
noexcepts
NOFONT
NOINTEGRALHEIGHT
NOINTERFACE
NOLINKINFO
@@ -1221,7 +1206,6 @@ ntdll
ntifs
ntlpcapi
ntm
nto
ntrtl
ntstatus
NTSYSCALLAPI
@@ -1297,7 +1281,6 @@ parentable
parms
PATCOPY
pathcch
Pathto
PATTERNID
pcat
pcb
@@ -1456,7 +1439,6 @@ pwsz
pythonw
Qaabbcc
QUERYOPEN
QUESTIONMARK
quickedit
QUZ
QWER
@@ -1489,8 +1471,6 @@ READCONSOLE
READCONSOLEOUTPUT
READCONSOLEOUTPUTSTRING
READMODE
reallocs
reamapping
rectread
redef
redefinable
@@ -1518,7 +1498,6 @@ repositorypath
Requiresx
rerasterize
rescap
Resequence
RESETCONTENT
resheader
resmimetype
@@ -1551,7 +1530,6 @@ RRRGGGBB
rsas
rtcore
RTEXT
RTFTo
RTLREADING
Rtn
ruleset
@@ -1699,7 +1677,6 @@ srcsrv
SRCSRVTRG
srctool
srect
srv
srvinit
srvpipe
ssa
@@ -1731,7 +1708,6 @@ SUA
subcompartment
subkeys
SUBLANG
subresource
subsystemconsole
subsystemwindows
swapchain
@@ -1835,7 +1811,6 @@ tosign
touchpad
Tpp
Tpqrst
tracelog
tracelogging
traceviewpp
trackbar
@@ -1846,7 +1821,6 @@ Trd
TREX
triaged
triaging
TRIANGLESTRIP
Tribool
TRIMZEROHEADINGS
trx
@@ -1888,8 +1862,8 @@ UINTs
ul
ulcch
uld
uldb
uldash
uldb
ulwave
Unadvise
unattend
@@ -1900,7 +1874,6 @@ unhosted
UNICODETEXT
UNICRT
Unintense
Uniscribe
unittesting
unittests
unk
@@ -1912,7 +1885,6 @@ untextured
UPDATEDISPLAY
UPDOWN
UPKEY
UPSS
upss
uregex
URegular
@@ -1996,7 +1968,6 @@ VTRGBTo
vtseq
vtterm
vttest
waitable
WANSUNG
WANTARROWS
WANTTAB
@@ -2121,7 +2092,6 @@ wrkstr
wrl
wrp
WRunoff
WScript
wsl
WSLENV
wstr
@@ -2156,13 +2126,11 @@ XBUTTONDOWN
XBUTTONUP
XCast
XCENTER
XColors
xcopy
XCount
xdy
XEncoding
xes
xff
XFG
XFile
XFORM
@@ -2171,7 +2139,6 @@ xinchaof
xinxinchaof
XManifest
XMath
XMFLOAT
xorg
XResource
xsi

View File

@@ -13,7 +13,8 @@ jobs:
- id: getBody
uses: craigloewen-msft/GitGudSimilarIssues@main
with:
issuetitle: ${{ github.event.issue.title }}
issueTitle: ${{ github.event.issue.title }}
issueBody: ${{ github.event.issue.body }}
repo: ${{ github.repository }}
similaritytolerance: "0.75"
add-comment:

31
.vscode/settings.json vendored
View File

@@ -1,8 +1,28 @@
{
"C_Cpp.default.browse.databaseFilename": "${workspaceFolder}\\.vscode\\.BROWSE.VC.DB",
"C_Cpp.default.browse.limitSymbolsToIncludedHeaders": true,
"C_Cpp.default.browse.path": [
"${workspaceFolder}"
],
"C_Cpp.default.cppStandard": "c++20",
"C_Cpp.default.cStandard": "c17",
"C_Cpp.default.defines": [
"_DEBUG",
"_UNICODE",
"BUILD_ONECORE_INTERACTIVITY",
"DBG",
"NT_SUCCESS",
"UNICODE",
"UNIT_TESTING",
"INLINE_TEST_METHOD_MARKUP",
],
"C_Cpp.default.includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/**/Generated Files",
"${workspaceFolder}/**/inc",
"${workspaceFolder}/**/include",
"${workspaceFolder}/**/Include"
],
"C_Cpp.loggingLevel": "None",
"files.associations": {
"xstring": "cpp",
@@ -98,14 +118,13 @@
"coroutine": "cpp",
"format": "cpp",
"forward_list": "cpp",
"latch": "cpp"
"latch": "cpp",
"gsl_assert": "cpp"
},
"files.exclude": {
"**/bin/**": true,
"**/Generated Files/**": true,
"**/obj/**": true,
"**/Generated Files/**": true
"**/packages/**": true,
},
"search.exclude": {
"**/packages/**": true
}
}
}

View File

@@ -4,6 +4,7 @@ trigger:
include:
- main
- feature/*
- gh-readonly-queue/*
paths:
exclude:
- doc/*

View File

@@ -75,6 +75,7 @@ steps:
rm LocOutputMunged.tar
rm -r -fo LocOutput
& ./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
& ./build/scripts/Generate-PseudoLocalizations.ps1
displayName: Move Loc files to the right places
- pwsh: |-

View File

@@ -33,6 +33,8 @@ extends:
publishSymbolsToPublic: true
publishVpackToWindows: false
symbolExpiryTime: 15
symbolPublishingSubscription: $(SymbolPublishingServiceConnection)
symbolPublishingProject: $(SymbolPublishingProject)
${{ if eq(true, parameters.publishToAzure) }}:
extraPublishJobs:
- template: build/pipelines/templates-v2/job-deploy-to-azure-storage.yml@self

View File

@@ -81,3 +81,5 @@ extends:
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
symbolPublishingSubscription: $(SymbolPublishingServiceConnection)
symbolPublishingProject: $(SymbolPublishingProject)

View File

@@ -0,0 +1,117 @@
parameters:
- name: includePublicSymbolServer
type: boolean
default: false
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: PublishSymbols
- name: symbolExpiryTime
type: string
default: 36530 # This is the default from PublishSymbols@2
- name: variables
type: object
default: {}
- name: subscription
type: string
- name: symbolProject
type: string
jobs:
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
${{ if eq(parameters.includePublicSymbolServer, true) }}:
displayName: Publish Symbols to Internal and MSDL
${{ else }}:
displayName: Publish Symbols Internally
dependsOn: ${{ parameters.dependsOn }}
variables:
${{ insert }}: ${{ parameters.variables }}
steps:
- checkout: self
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- task: DownloadPipelineArtifact@2
displayName: Download all PDBs from all prior build phases
inputs:
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
inputs:
azureSubscription: ${{ parameters.subscription }}
azurePowerShellVersion: LatestVersion
pwsh: true
ScriptType: InlineScript
Inline: |-
$AzToken = (Get-AzAccessToken -ResourceUrl api://30471ccf-0966-45b9-a979-065dbedb24c1).Token
Write-Host "##vso[task.setvariable variable=SymbolAccessToken;issecret=true]$AzToken"
- task: PublishSymbols@2
displayName: Publish Symbols (to current Azure DevOps tenant)
continueOnError: True
inputs:
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
SearchPattern: '**/*.pdb'
IndexSources: false
DetailedLog: true
SymbolsMaximumWaitTime: 30
SymbolServerType: 'TeamServices'
SymbolsProduct: 'Windows Terminal Converged Symbols'
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
SymbolsArtifactName: 'WindowsTerminal_$(XES_APPXMANIFESTVERSION)'
SymbolExpirationInDays: ${{ parameters.symbolExpiryTime }}
env:
LIB: $(Build.SourcesDirectory)
- pwsh: |-
# Prepare the defaults for IRM
$PSDefaultParameterValues['Invoke-RestMethod:Headers'] = @{ Authorization = "Bearer $(SymbolAccessToken)" }
$PSDefaultParameterValues['Invoke-RestMethod:ContentType'] = "application/json"
$PSDefaultParameterValues['Invoke-RestMethod:Method'] = "POST"
$BaseUri = "https://symbolrequestprod.trafficmanager.net/projects/${{ parameters.symbolProject }}/requests"
# Prepare the request
$expiration = (Get-Date).Add([TimeSpan]::FromDays(${{ parameters.symbolExpiryTime }}))
$createRequestBody = @{
requestName = "WindowsTerminal_$(XES_APPXMANIFESTVERSION)";
expirationTime = $expiration.ToString();
}
Write-Host "##[debug]Starting request $($createRequestBody.requestName) with expiration date of $($createRequestBody.expirationTime)"
Invoke-RestMethod -Uri "$BaseUri" -Body ($createRequestBody | ConvertTo-Json -Compress) -Verbose
# Request symbol publication
$publishRequestBody = @{
publishToInternalServer = $true;
publishToPublicServer = $${{ parameters.includePublicSymbolServer }};
}
Write-Host "##[debug]Submitting request $($createRequestBody.requestName) ($($publishRequestBody | ConvertTo-Json -Compress))"
Invoke-RestMethod -Uri "$BaseUri/$($createRequestBody.requestName)" -Body ($publishRequestBody | ConvertTo-Json -Compress) -Verbose
displayName: Publish Symbols using internal REST API

View File

@@ -52,6 +52,10 @@ parameters:
- name: publishVpackToWindows
type: boolean
default: false
- name: symbolPublishingSubscription
type: string
- name: symbolPublishingProject
type: string
- name: extraPublishJobs
type: object
@@ -248,12 +252,13 @@ extends:
displayName: Publish
dependsOn: [Build]
jobs:
- template: ./build/pipelines/templates-v2/job-publish-symbols.yml@self
- template: ./build/pipelines/templates-v2/job-publish-symbols-using-symbolrequestprod-api.yml@self
parameters:
pool: { type: windows }
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
symbolPatGoesInTaskInputs: true # onebranch tries to muck with the PAT variable, so we need to change how it get the PAT
symbolExpiryTime: ${{ parameters.symbolExpiryTime }}
subscription: ${{ parameters.symbolPublishingSubscription }}
symbolProject: ${{ parameters.symbolPublishingProject }}
variables:
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true

View File

@@ -1,2 +1,2 @@
variables:
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest'
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:1.0.02566.28'

View File

@@ -0,0 +1,16 @@
Get-ChildItem -Recurse -Filter *.resw
| Where-Object { $_.Directory.Name.StartsWith("qps-ploc") }
| ForEach-Object {
$source = Join-Path $_.Directory "../en-US/$($_.Name)"
$target = $_
$ploc = ./tools/ConvertTo-PseudoLocalization.ps1 -Path $source
$writerSettings = [System.Xml.XmlWriterSettings]::new()
$writerSettings.NewLineChars = "`r`n"
$writerSettings.Indent = $true
$writer = [System.Xml.XmlWriter]::Create($target, $writerSettings)
$ploc.Save($writer)
$writer.Flush()
$writer.Close()
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
# CLI11
Taken from [release v1.9.1](https://github.com/CLIUtils/CLI11/releases/tag/v1.9.1), source commit
[5cb3efa](https://github.com/CLIUtils/CLI11/commit/5cb3efabce007c3a0230e4cc2e27da491c646b6c)
Taken from [release v2.4.1](https://github.com/CLIUtils/CLI11/releases/tag/v2.4.1), source commit
[f4d0731](https://github.com/CLIUtils/CLI11/commit/f4d0731cebb123ff0ace712c099dffbcd2c58e5a)

View File

@@ -6,7 +6,7 @@
"type": "git",
"git": {
"repositoryUrl": "https://github.com/CLIUtils/CLI11",
"commitHash": "5cb3efabce007c3a0230e4cc2e27da491c646b6c"
"commitHash": "88e9bb17418ee730817d5942894d99a4bdd78fb3"
}
}
}

View File

@@ -154,3 +154,47 @@ popd
The `bx` will build just the Terminal package, critically, populating the `CascadiaPackage.build.appxrecipe` file. Once that's been built, then the `DeployAppRecipe.exe` command can be used to deploy a loose layout in the same way that Visual Studio does.
Notably, this method of building the Terminal package can't leverage the FastUpToDate check in Visual Studio, so the builds end up being considerably slower for the whole package, as cppwinrt does a lot of work before confirming that it's up to date and doing nothing.
### Are you seeing `DEP0700: Registration of the app failed`?
Once in a blue moon, I get a `DEP0700: Registration of the app failed.
[0x80073CF6] error 0x80070020: Windows cannot register the package because of an
internal error or low memory.` when trying to deploy in VS. For us, that can
happen if the `OpenConsoleProxy.dll` gets locked up, in use by some other
terminal package.
Doing the equivalent command in powershell can give us more info:
```pwsh
Add-AppxPackage -register "Z:\dev\public\OpenConsole\src\cascadia\CascadiaPackage\bin\x64\Debug\AppX\AppxManifest.xml"
```
That'll suggest `NOTE: For additional information, look for [ActivityId]
dbf551f1-83d0-0007-43e7-9cded083da01 in the Event Log or use the command line
Get-AppPackageLog -ActivityID dbf551f1-83d0-0007-43e7-9cded083da01`. So do that:
```pwsh
Get-AppPackageLog -ActivityID dbf551f1-83d0-0007-43e7-9cded083da01
```
which will give you a lot of info. In my case, that revealed that the platform
couldn't delete the packaged com entries. The key line was: `AppX Deployment
operation failed with error 0x0 from API Logging data because access was denied
for file:
C:\ProgramData\Microsoft\Windows\AppRepository\Packages\WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe,
user SID: S-1-5-18`
Take that path, and
```pwsh
sudo start C:\ProgramData\Microsoft\Windows\AppRepository\Packages\WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe
```
(use `sudo`, since the path is otherwise locked down). From there, go into the
`PackagedCom` folder, and open [File
Locksmith](https://learn.microsoft.com/en-us/windows/powertoys/file-locksmith)
(or Process Explorer, if you're more familiar with that) on
`OpenConsoleProxy.dll`. Just go ahead and immediately re-launch it as admin,
too. That should list off a couple terminal processes that are just hanging
around. Go ahead and end them all. You should be good to deploy again after
that.

View File

@@ -2332,12 +2332,20 @@
},
"type": "array"
},
"experimental.rendering.forceFullRepaint": {
"description": "When set to true, we will redraw the entire screen each frame. When set to false, we will render only the updates to the screen between frames.",
"rendering.graphicsAPI": {
"description": "Direct3D 11 provides a more performant and feature-rich experience, whereas Direct2D is more stable. The default option \"Automatic\" will pick the API that best fits your graphics hardware. If you experience significant issues, consider using Direct2D.",
"type": "string",
"enum": [
"direct2d",
"direct3d11"
]
},
"rendering.disablePartialInvalidation": {
"description": "By default, the text renderer uses a FLIP_SEQUENTIAL Swap Chain and declares dirty rectangles via the Present1 API. When this setting is enabled, a FLIP_DISCARD Swap Chain will be used instead, and no dirty rectangles will be declared. Whether one or the other is better depends on your hardware and various other factors.",
"type": "boolean"
},
"experimental.rendering.software": {
"description": "When set to true, we will use the software renderer (a.k.a. WARP) instead of the hardware one.",
"rendering.software": {
"description": "When enabled, the terminal will use a software rasterizer (WARP). This setting should be left disabled under almost all circumstances.",
"type": "boolean"
},
"experimental.input.forceVT": {
@@ -2769,10 +2777,6 @@
"description": "When set to true, prompts will automatically be marked.",
"type": "boolean"
},
"experimental.connection.passthroughMode": {
"description": "When set to true, directs the PTY for this connection to use pass-through mode instead of the original Conhost PTY simulation engine. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "boolean"
},
"experimental.retroTerminalEffect": {
"description": "When set to true, enable retro terminal effects. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "boolean"

View File

@@ -118,6 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppDescription" xml:space="preserve">
<value>А şςѓάţćћ ǻрр ƒθŗ χÂΜĿ Íŝĺąήðş ŧеšτş !!! !!! !!! !</value>
<value>Ά śςґàτсн ąρφ ƒоř ΧΆΜĻ Ìŝļàиđś τёşτś !!! !!! !!! !</value>
</data>
</root>

View File

@@ -118,6 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppDescription" xml:space="preserve">
<value>Ă šςґаτćĥ àρφ ƒǿя ЖΆΜĹ Іѕℓаñďş ťêšţŝ !!! !!! !!! !</value>
<value>Ά śςґàτсн ąρφ ƒоř ΧΆΜĻ Ìŝļàиđś τёşτś !!! !!! !!! !</value>
</data>
</root>

View File

@@ -118,6 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppDescription" xml:space="preserve">
<value>Ă śćяǻт¢н ãрρ ƒσг ХĂМĽ Īşłдήďѕ ťέśτş !!! !!! !!! !</value>
<value>Ά śςґàτсн ąρφ ƒоř ΧΆΜĻ Ìŝļàиđś τёşτś !!! !!! !!! !</value>
</data>
</root>

View File

@@ -29,7 +29,8 @@ OutputCellView::OutputCellView(const std::wstring_view view,
// - Reference to UTF-16 character data
// C26445 - suppressed to enable the `TextBufferTextIterator::operator->` method which needs a non-temporary memory location holding the wstring_view.
// TODO: GH 2681 - remove this suppression by reconciling the probably bad design of the iterators that leads to this being required.
[[gsl::suppress(26445)]] const std::wstring_view& OutputCellView::Chars() const noexcept
GSL_SUPPRESS(26445)
const std::wstring_view& OutputCellView::Chars() const noexcept
{
return _view;
}

View File

@@ -62,6 +62,11 @@ bool TextColor::CanBeBrightened() const noexcept
return IsIndex16() || IsDefault();
}
ColorType TextColor::GetType() const noexcept
{
return _meta;
}
bool TextColor::IsLegacy() const noexcept
{
return (IsIndex16() || IsIndex256()) && _index < 16;
@@ -202,7 +207,7 @@ COLORREF TextColor::GetColor(const std::array<COLORREF, TextColor::TABLE_SIZE>&
// the result will be something like 0b00100000.
// 5. Use BitScanForward (bsf) to find the index of the most significant 1 bit.
const auto haystack = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(colorTable.data())); // 1.
const auto needle = _mm256_set1_epi32(til::bit_cast<int>(defaultColor)); // 2.
const auto needle = _mm256_set1_epi32(std::bit_cast<int>(defaultColor)); // 2.
const auto result = _mm256_cmpeq_epi32(haystack, needle); // 3.
const auto mask = _mm256_movemask_ps(_mm256_castsi256_ps(result)); // 4.
unsigned long index;
@@ -219,7 +224,7 @@ COLORREF TextColor::GetColor(const std::array<COLORREF, TextColor::TABLE_SIZE>&
// --> the index returned by _BitScanForward must be divided by 2.
const auto haystack1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(colorTable.data() + 0));
const auto haystack2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(colorTable.data() + 4));
const auto needle = _mm_set1_epi32(til::bit_cast<int>(defaultColor));
const auto needle = _mm_set1_epi32(std::bit_cast<int>(defaultColor));
const auto result1 = _mm_cmpeq_epi32(haystack1, needle);
const auto result2 = _mm_cmpeq_epi32(haystack2, needle);
const auto result = _mm_packs_epi32(result1, result2); // 3.5
@@ -280,15 +285,3 @@ BYTE TextColor::GetLegacyIndex(const BYTE defaultIndex) const noexcept
return til::at(CompressedRgbToIndex16, compressedRgb);
}
}
// Method Description:
// - Return a COLORREF containing our stored value. Will return garbage if this
//attribute is not a RGB attribute.
// Arguments:
// - <none>
// Return Value:
// - a COLORREF containing our stored value
COLORREF TextColor::GetRGB() const noexcept
{
return RGB(_red, _green, _blue);
}

View File

@@ -119,6 +119,7 @@ public:
}
bool CanBeBrightened() const noexcept;
ColorType GetType() const noexcept;
bool IsLegacy() const noexcept;
bool IsIndex16() const noexcept;
bool IsIndex256() const noexcept;
@@ -133,12 +134,11 @@ public:
COLORREF GetColor(const std::array<COLORREF, TABLE_SIZE>& colorTable, const size_t defaultIndex, bool brighten = false) const noexcept;
BYTE GetLegacyIndex(const BYTE defaultIndex) const noexcept;
constexpr BYTE GetIndex() const noexcept
{
return _index;
}
COLORREF GetRGB() const noexcept;
constexpr BYTE GetIndex() const noexcept { return _index; }
constexpr BYTE GetR() const noexcept { return _red; }
constexpr BYTE GetG() const noexcept { return _green; }
constexpr BYTE GetB() const noexcept { return _blue; }
constexpr COLORREF GetRGB() const noexcept { return RGB(_red, _green, _blue); }
static constexpr BYTE TransposeLegacyIndex(const size_t index)
{

View File

@@ -11,7 +11,6 @@
#include "UTextAdapter.h"
#include "../../types/inc/GlyphWidth.hpp"
#include "../renderer/base/renderer.hpp"
#include "../types/inc/convert.hpp"
#include "../types/inc/utils.hpp"
using namespace Microsoft::Console;
@@ -1298,7 +1297,8 @@ void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
// - the delimiter class for the given char
DelimiterClass TextBuffer::_GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const
{
return GetRowByOffset(pos.y).DelimiterClassAt(pos.x, wordDelimiters);
const auto realPos = ScreenToBufferPosition(pos);
return GetRowByOffset(realPos.y).DelimiterClassAt(realPos.x, wordDelimiters);
}
// Method Description:
@@ -2502,12 +2502,267 @@ void TextBuffer::_AppendRTFText(std::string& contentBuilder, const std::wstring_
{
// Windows uses unsigned wchar_t - RTF uses signed ones.
// '?' is the fallback ascii character.
const auto codeUnitRTFStr = std::to_string(til::bit_cast<int16_t>(codeUnit));
const auto codeUnitRTFStr = std::to_string(std::bit_cast<int16_t>(codeUnit));
fmt::format_to(std::back_inserter(contentBuilder), FMT_COMPILE("\\u{}?"), codeUnitRTFStr);
}
}
}
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);
static constexpr size_t writeThreshold = 32 * 1024;
std::wstring buffer;
buffer.reserve(writeThreshold + writeThreshold / 2);
buffer.push_back(L'\uFEFF');
const til::CoordType lastRowWithText = GetLastNonSpaceCharacter(nullptr).y;
CharacterAttributes previousAttr = CharacterAttributes::Unused1;
TextColor previousFg;
TextColor previousBg;
TextColor previousUl;
uint16_t previousHyperlinkId = 0;
// 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 = 0;; currentRow++)
{
const auto& row = GetRowByOffset(currentRow);
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& runs = row.Attributes().runs();
auto it = runs.begin();
const auto end = runs.end();
const auto last = end - 1;
til::CoordType oldX = 0;
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;
}
}
auto newX = oldX + it->length;
// Trim whitespace with default attributes from the end of each line.
if (it == last && it->value == TextAttribute{})
{
// This can result in oldX > newX, but that's okay because GetText()
// is robust against that and returns an empty string.
newX = row.MeasureRight();
}
buffer.append(row.GetText(oldX, newX));
oldX = newX;
}
const auto moreRowsRemaining = currentRow < lastRowWithText;
if (!row.WasWrapForced() || !moreRowsRemaining)
{
buffer.append(L"\r\n");
}
if (buffer.size() >= writeThreshold || !moreRowsRemaining)
{
const auto fileSize = gsl::narrow<DWORD>(buffer.size() * sizeof(wchar_t));
DWORD bytesWritten = 0;
THROW_IF_WIN32_BOOL_FALSE(WriteFile(file.get(), buffer.data(), fileSize, &bytesWritten, nullptr));
if (bytesWritten != fileSize)
{
THROW_WIN32_MSG(ERROR_WRITE_FAULT, "failed to write");
}
}
if (!moreRowsRemaining)
{
break;
}
}
}
// 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

@@ -319,6 +319,8 @@ public:
const bool isIntenseBold,
std::function<std::tuple<COLORREF, COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors) const noexcept;
void Serialize(const wchar_t* destination) const;
struct PositionInformation
{
til::CoordType mutableViewportTop{ 0 };

View File

@@ -25,7 +25,8 @@ TextBufferTextIterator::TextBufferTextIterator(const TextBufferCellIterator& cel
// Return Value:
// - Read only UTF-16 text data
// TODO GH 2682, fix design so this doesn't have to be suppressed.
[[gsl::suppress(26434)]] const std::wstring_view TextBufferTextIterator::operator*() const noexcept
GSL_SUPPRESS(26434)
const std::wstring_view TextBufferTextIterator::operator*() const noexcept
{
return _view.Chars();
}
@@ -35,7 +36,8 @@ TextBufferTextIterator::TextBufferTextIterator(const TextBufferCellIterator& cel
// Return Value:
// - Read only UTF-16 text data
// TODO GH 2682, fix design so this doesn't have to be suppressed.
[[gsl::suppress(26434)]] const std::wstring_view* TextBufferTextIterator::operator->() const noexcept
GSL_SUPPRESS(26434)
const std::wstring_view* TextBufferTextIterator::operator->() const noexcept
{
return &_view.Chars();
}

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Τнĕ Ņëω Ẅίηđŏẃś Ťėŗmįйάĺ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Ŵíňďōẁŝ Тєřмīπǻļ ωїτĥ å ρѓēνіéŵ θƒ ũφсőмϊπġ ƒєąτΰґёѕ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Ŏрέи ìη Тèřmīŋªŀ (&amp;Cãńãґγ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Φφєň ΐñ Ŧéгмϊñаľ &amp;Pŕėνĭώ !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ωρєⁿ ïπ &amp;Těѓmĭñäĺ !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Ťĥё Ñēщ Шίⁿðоẅś Ťėгмîήāľ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Шίηđóŵš Ŧĕяmїйà ẁітħ ª φяęνîёщ όƒ ûφĉбмíήĝ ƒêåťµřεŝ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Óрëπ íи Ťēяmілǻŀ (&amp;Cäηàřÿ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Óрзń ΐή Ŧěґмιлāℓ &amp;Pѓéνīĕω !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ôрëη ïп &amp;Tēѓмϊŋãł !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Тĥё Ńēẁ Шіπđοωš Тěřмιňαŀ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Шίήďŏшś Ŧêямĩňāľ ŵíτн ă ρѓëνιêω øƒ ũρčŏмįηğ ƒєáţũŗêš !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Фφěй ĩń Тêřmιπâł (&amp;Cãⁿǻřу) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Óφ℮ʼn ΐŋ Τėřmīйäĺ &amp;Pяєνϊëẃ !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ορέл ϊŋ &amp;Téŕmįñā !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

View File

@@ -1326,7 +1326,7 @@ namespace TerminalAppLocalTests
const auto& controlSettings = activeControl.Settings();
VERIFY_IS_NOT_NULL(controlSettings);
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, til::color{ controlSettings.DefaultBackground() });
});
TestOnUIThread([&page]() {
@@ -1344,7 +1344,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(controlSettings);
Log::Comment(L"Color should be changed to the preview");
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, til::color{ controlSettings.DefaultBackground() });
// And we should have stored a function to revert the change.
VERIFY_ARE_EQUAL(1u, page->_restorePreviewFuncs.size());
@@ -1366,7 +1366,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(controlSettings);
Log::Comment(L"Color should be changed");
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, til::color{ controlSettings.DefaultBackground() });
// After preview there should be no more restore functions to execute.
VERIFY_ARE_EQUAL(0u, page->_restorePreviewFuncs.size());
@@ -1394,7 +1394,7 @@ namespace TerminalAppLocalTests
const auto& controlSettings = activeControl.Settings();
VERIFY_IS_NOT_NULL(controlSettings);
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, til::color{ controlSettings.DefaultBackground() });
});
TestOnUIThread([&page]() {
@@ -1412,7 +1412,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(controlSettings);
Log::Comment(L"Color should be changed to the preview");
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, til::color{ controlSettings.DefaultBackground() });
});
TestOnUIThread([&page]() {
@@ -1428,7 +1428,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(controlSettings);
Log::Comment(L"Color should be the same as it originally was");
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, til::color{ controlSettings.DefaultBackground() });
});
Log::Comment(L"Sleep to let events propagate");
Sleep(250);
@@ -1450,7 +1450,7 @@ namespace TerminalAppLocalTests
const auto& controlSettings = activeControl.Settings();
VERIFY_IS_NOT_NULL(controlSettings);
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, til::color{ controlSettings.DefaultBackground() });
});
TestOnUIThread([&page]() {
@@ -1467,7 +1467,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(controlSettings);
Log::Comment(L"Color should be changed to the preview");
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, til::color{ controlSettings.DefaultBackground() });
});
TestOnUIThread([&page]() {
@@ -1484,7 +1484,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(controlSettings);
Log::Comment(L"Color should be changed to the preview");
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, til::color{ controlSettings.DefaultBackground() });
});
TestOnUIThread([&page]() {
@@ -1503,7 +1503,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(controlSettings);
Log::Comment(L"Color should be changed");
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, controlSettings.DefaultBackground());
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, til::color{ controlSettings.DefaultBackground() });
});
Log::Comment(L"Sleep to let events propagate");
Sleep(250);

View File

@@ -56,6 +56,8 @@ Author(s):
#include <winrt/windows.applicationmodel.core.h>
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
#include <winrt/Microsoft.Terminal.Core.h>
#include <winrt/Microsoft.Terminal.Control.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>

View File

@@ -1,5 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "GetWindowLayoutArgs.h"
#include "GetWindowLayoutArgs.g.cpp"

View File

@@ -1,31 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Class Name:
- GetWindowLayoutArgs.h
Abstract:
- This is a helper class for getting the window layout from a peasant.
Depending on if we are running on the monarch or on a peasant we might need
to switch what thread we are executing on. This gives us the option of
either returning the json result synchronously, or as a promise.
--*/
#pragma once
#include "GetWindowLayoutArgs.g.h"
namespace winrt::Microsoft::Terminal::Remoting::implementation
{
struct GetWindowLayoutArgs : public GetWindowLayoutArgsT<GetWindowLayoutArgs>
{
WINRT_PROPERTY(winrt::hstring, WindowLayoutJson, L"");
WINRT_PROPERTY(winrt::Windows::Foundation::IAsyncOperation<winrt::hstring>, WindowLayoutJsonAsync, nullptr)
};
}
namespace winrt::Microsoft::Terminal::Remoting::factory_implementation
{
BASIC_FACTORY(GetWindowLayoutArgs);
}

View File

@@ -37,12 +37,6 @@
<ClInclude Include="WindowActivatedArgs.h">
<DependentUpon>Peasant.idl</DependentUpon>
</ClInclude>
<ClInclude Include="GetWindowLayoutArgs.h">
<DependentUpon>Peasant.idl</DependentUpon>
</ClInclude>
<ClInclude Include="QuitAllRequestedArgs.h">
<DependentUpon>Monarch.idl</DependentUpon>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="MonarchFactory.h" />
<ClInclude Include="Peasant.h">
@@ -78,12 +72,6 @@
<ClCompile Include="WindowActivatedArgs.cpp">
<DependentUpon>Peasant.idl</DependentUpon>
</ClCompile>
<ClCompile Include="GetWindowLayoutArgs.cpp">
<DependentUpon>Peasant.idl</DependentUpon>
</ClCompile>
<ClCompile Include="QuitAllRequestedArgs.cpp">
<DependentUpon>Monarch.idl</DependentUpon>
</ClCompile>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>

View File

@@ -6,7 +6,6 @@
#include "Monarch.h"
#include "CommandlineArgs.h"
#include "FindTargetWindowArgs.h"
#include "QuitAllRequestedArgs.h"
#include "ProposeCommandlineResult.h"
#include "Monarch.g.cpp"
@@ -95,8 +94,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
peasant.IdentifyWindowsRequested({ this, &Monarch::_identifyWindows });
peasant.RenameRequested({ this, &Monarch::_renameRequested });
peasant.ShowNotificationIconRequested([this](auto&&, auto&&) { _ShowNotificationIconRequestedHandlers(*this, nullptr); });
peasant.HideNotificationIconRequested([this](auto&&, auto&&) { _HideNotificationIconRequestedHandlers(*this, nullptr); });
peasant.ShowNotificationIconRequested([this](auto&&, auto&&) { ShowNotificationIconRequested.raise(*this, nullptr); });
peasant.HideNotificationIconRequested([this](auto&&, auto&&) { HideNotificationIconRequested.raise(*this, nullptr); });
peasant.QuitAllRequested({ this, &Monarch::_handleQuitAll });
{
@@ -111,7 +110,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
_WindowCreatedHandlers(nullptr, nullptr);
WindowCreated.raise(nullptr, nullptr);
return newPeasantsId;
}
catch (...)
@@ -135,21 +134,13 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// - <none> used
// Return Value:
// - <none>
winrt::fire_and_forget Monarch::_handleQuitAll(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
void Monarch::_handleQuitAll(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/)
{
// Let the process hosting the monarch run any needed logic before
// closing all windows.
auto args = winrt::make_self<implementation::QuitAllRequestedArgs>();
_QuitAllRequestedHandlers(*this, *args);
if (const auto action = args->BeforeQuitAllAction())
if (_quitting.exchange(true, std::memory_order_relaxed))
{
co_await action;
return;
}
_quitting.store(true);
// Tell all peasants to exit.
const auto callback = [&](const auto& id, const auto& p) {
// We want to tell our peasant to quit last, so that we don't try
// to perform a bunch of elections on quit.
@@ -197,7 +188,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// If we are quitting we don't care about maintaining our list of
// peasants anymore, and don't need to notify the host that something
// changed.
if (_quitting.load(std::memory_order_acquire))
if (_quitting.load(std::memory_order_relaxed))
{
return;
}
@@ -207,7 +198,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
std::unique_lock lock{ _peasantsMutex };
_peasants.erase(peasantId);
}
_WindowClosedHandlers(nullptr, nullptr);
WindowClosed.raise(nullptr, nullptr);
}
// Method Description:
@@ -650,7 +641,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
auto findWindowArgs{ winrt::make_self<Remoting::implementation::FindTargetWindowArgs>(args) };
// This is handled by some handler in-proc
_FindTargetWindowRequestedHandlers(*this, *findWindowArgs);
FindTargetWindowRequested.raise(*this, *findWindowArgs);
// After the event was handled, ResultTargetWindow() will be filled with
// the parsed result.
@@ -741,7 +732,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
result->WindowName(targetWindowName);
result->ShouldCreateWindow(true);
_RequestNewWindowHandlers(*this, *winrt::make_self<WindowRequestedArgs>(*result, args));
RequestNewWindow.raise(*this, *winrt::make_self<WindowRequestedArgs>(*result, args));
// If this fails, it'll be logged in the following
// TraceLoggingWrite statement, with succeeded=false
@@ -779,7 +770,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
result->Id(windowID);
result->WindowName(targetWindowName);
_RequestNewWindowHandlers(*this, *winrt::make_self<WindowRequestedArgs>(*result, args));
RequestNewWindow.raise(*this, *winrt::make_self<WindowRequestedArgs>(*result, args));
return *result;
}
@@ -796,7 +787,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
auto result = winrt::make_self<Remoting::implementation::ProposeCommandlineResult>(true);
result->WindowName(targetWindowName);
_RequestNewWindowHandlers(*this, *winrt::make_self<WindowRequestedArgs>(*result, args));
RequestNewWindow.raise(*this, *winrt::make_self<WindowRequestedArgs>(*result, args));
return *result;
}
@@ -1036,30 +1027,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
_forEachPeasant(func, onError);
}
// Method Description:
// - Ask all peasants to return their window layout as json
// Arguments:
// - <none>
// Return Value:
// - The collection of window layouts from each peasant.
Windows::Foundation::Collections::IVector<winrt::hstring> Monarch::GetAllWindowLayouts()
{
std::vector<winrt::hstring> vec;
auto callback = [&](const auto& /*id*/, const auto& p) {
vec.emplace_back(p.GetWindowLayout());
};
auto onError = [](auto&& id) {
TraceLoggingWrite(g_hRemotingProvider,
"Monarch_GetAllWindowLayouts_Failed",
TraceLoggingInt64(id, "peasantID", "The ID of the peasant which we could not get a window layout from"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
};
_forEachPeasant(callback, onError);
return winrt::single_threaded_vector(std::move(vec));
}
void Monarch::RequestMoveContent(winrt::hstring window,
winrt::hstring content,
uint32_t tabIndex,
@@ -1115,7 +1082,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
auto request = winrt::make_self<implementation::WindowRequestedArgs>(nameIsReserved ? L"" : window,
content,
windowBounds);
_RequestNewWindowHandlers(*this, *request);
RequestNewWindow.raise(*this, *request);
}
}

View File

@@ -96,19 +96,17 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void SummonAllWindows();
bool DoesQuakeWindowExist();
Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Terminal::Remoting::PeasantInfo> GetPeasantInfos();
Windows::Foundation::Collections::IVector<winrt::hstring> GetAllWindowLayouts();
void RequestMoveContent(winrt::hstring window, winrt::hstring content, uint32_t tabIndex, const Windows::Foundation::IReference<Windows::Foundation::Rect>& windowBounds);
void RequestSendContent(const Remoting::RequestReceiveContentArgs& args);
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
TYPED_EVENT(ShowNotificationIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(HideNotificationIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(WindowCreated, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(WindowClosed, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitAllRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::QuitAllRequestedArgs);
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs> FindTargetWindowRequested;
til::typed_event<> ShowNotificationIconRequested;
til::typed_event<> HideNotificationIconRequested;
til::typed_event<> WindowCreated;
til::typed_event<> WindowClosed;
TYPED_EVENT(RequestNewWindow, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs);
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs> RequestNewWindow;
private:
uint64_t _ourPID;
@@ -146,8 +144,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void _renameRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
winrt::fire_and_forget _handleQuitAll(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
void _handleQuitAll(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
// Method Description:
// - Helper for doing something on each and every peasant.
@@ -223,7 +221,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// A peasant died, let the app host know that the number of
// windows has changed.
_WindowClosedHandlers(nullptr, nullptr);
WindowClosed.raise(nullptr, nullptr);
}
}

View File

@@ -46,11 +46,6 @@ namespace Microsoft.Terminal.Remoting
Windows.Foundation.IReference<UInt64> WindowID;
}
[default_interface] runtimeclass QuitAllRequestedArgs {
QuitAllRequestedArgs();
Windows.Foundation.IAsyncAction BeforeQuitAllAction;
}
struct PeasantInfo
{
UInt64 Id;
@@ -72,7 +67,6 @@ namespace Microsoft.Terminal.Remoting
void SummonAllWindows();
Boolean DoesQuakeWindowExist();
Windows.Foundation.Collections.IVectorView<PeasantInfo> GetPeasantInfos { get; };
Windows.Foundation.Collections.IVector<String> GetAllWindowLayouts();
void RequestMoveContent(String window, String content, UInt32 tabIndex, Windows.Foundation.IReference<Windows.Foundation.Rect> bounds);
void RequestSendContent(RequestReceiveContentArgs args);
@@ -82,7 +76,6 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, Object> HideNotificationIconRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> WindowCreated;
event Windows.Foundation.TypedEventHandler<Object, Object> WindowClosed;
event Windows.Foundation.TypedEventHandler<Object, QuitAllRequestedArgs> QuitAllRequested;
event Windows.Foundation.TypedEventHandler<Object, WindowRequestedArgs> RequestNewWindow;
};

View File

@@ -5,7 +5,6 @@
#include "Peasant.h"
#include "CommandlineArgs.h"
#include "SummonWindowBehavior.h"
#include "GetWindowLayoutArgs.h"
#include "Peasant.g.cpp"
#include "../../types/inc/utils.hpp"
#include "AttachRequest.g.cpp"
@@ -67,7 +66,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// Raise an event with these args. The AppHost will listen for this
// event to know when to take these args and dispatch them to a
// currently-running window.
_ExecuteCommandlineRequestedHandlers(*this, args);
ExecuteCommandlineRequested.raise(*this, args);
return true;
}
@@ -97,7 +96,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// by the monarch. The monarch might have died. If they have, this
// will throw an exception. Just eat it, the election thread will
// handle hooking up the new one.
_WindowActivatedHandlers(*this, args);
WindowActivated.raise(*this, args);
successfullyNotified = true;
}
catch (...)
@@ -146,7 +145,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
_SummonRequestedHandlers(*this, localCopy);
SummonRequested.raise(*this, localCopy);
}
// Method Description:
@@ -161,7 +160,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
{
// Not worried about try/catching this. The handler is in AppHost, which
// is in-proc for us.
_DisplayWindowIdRequestedHandlers(*this, nullptr);
DisplayWindowIdRequested.raise(*this, nullptr);
}
// Method Description:
@@ -182,7 +181,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// by the monarch. The monarch might have died. If they have, this
// will throw an exception. Just eat it, the election thread will
// handle hooking up the new one.
_IdentifyWindowsRequestedHandlers(*this, nullptr);
IdentifyWindowsRequested.raise(*this, nullptr);
successfullyNotified = true;
}
catch (...)
@@ -207,7 +206,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// by the monarch. The monarch might have died. If they have, this
// will throw an exception. Just eat it, the election thread will
// handle hooking up the new one.
_RenameRequestedHandlers(*this, args);
RenameRequested.raise(*this, args);
if (args.Succeeded())
{
_WindowName = args.NewName();
@@ -233,7 +232,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
{
try
{
_ShowNotificationIconRequestedHandlers(*this, nullptr);
ShowNotificationIconRequested.raise(*this, nullptr);
}
catch (...)
{
@@ -249,7 +248,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
{
try
{
_HideNotificationIconRequestedHandlers(*this, nullptr);
HideNotificationIconRequested.raise(*this, nullptr);
}
catch (...)
{
@@ -265,7 +264,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
{
try
{
_QuitAllRequestedHandlers(*this, nullptr);
QuitAllRequested.raise(*this, nullptr);
}
catch (...)
{
@@ -281,7 +280,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
{
try
{
_AttachRequestedHandlers(*this, request);
AttachRequested.raise(*this, request);
}
catch (...)
{
@@ -297,7 +296,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
{
try
{
_QuitRequestedHandlers(*this, nullptr);
QuitRequested.raise(*this, nullptr);
}
catch (...)
{
@@ -309,28 +308,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
// Method Description:
// - Request and return the window layout from the current TerminalPage
// Arguments:
// - <none>
// Return Value:
// - the window layout as a json string
hstring Peasant::GetWindowLayout()
{
auto args = winrt::make_self<implementation::GetWindowLayoutArgs>();
_GetWindowLayoutRequestedHandlers(nullptr, *args);
if (const auto op = args->WindowLayoutJsonAsync())
{
// This will fail if called on the UI thread, so the monarch should
// never set WindowLayoutJsonAsync.
auto str = op.get();
return str;
}
return args->WindowLayoutJson();
}
void Peasant::SendContent(const Remoting::RequestReceiveContentArgs& args)
{
_SendContentRequestedHandlers(*this, args);
SendContentRequested.raise(*this, args);
}
}

View File

@@ -65,28 +65,26 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::Microsoft::Terminal::Remoting::CommandlineArgs InitialArgs();
winrt::hstring GetWindowLayout();
void SendContent(const winrt::Microsoft::Terminal::Remoting::RequestReceiveContentArgs& args);
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs> WindowActivated;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::CommandlineArgs> ExecuteCommandlineRequested;
til::typed_event<> IdentifyWindowsRequested;
til::typed_event<> DisplayWindowIdRequested;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs> RenameRequested;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior> SummonRequested;
til::typed_event<> ShowNotificationIconRequested;
til::typed_event<> HideNotificationIconRequested;
til::typed_event<> QuitAllRequested;
til::typed_event<> QuitRequested;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::AttachRequest> AttachRequested;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RequestReceiveContentArgs> SendContentRequested;
WINRT_PROPERTY(winrt::hstring, WindowName);
WINRT_PROPERTY(winrt::hstring, ActiveTabTitle);
TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs);
TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::CommandlineArgs);
TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs);
TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior);
TYPED_EVENT(ShowNotificationIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(HideNotificationIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitAllRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(GetWindowLayoutRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::GetWindowLayoutArgs);
TYPED_EVENT(AttachRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::AttachRequest);
TYPED_EVENT(SendContentRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RequestReceiveContentArgs);
private:
Peasant(const uint64_t testPID);
uint64_t _ourPID;

View File

@@ -32,12 +32,6 @@ namespace Microsoft.Terminal.Remoting
Windows.Foundation.DateTime ActivatedTime { get; };
};
[default_interface] runtimeclass GetWindowLayoutArgs {
GetWindowLayoutArgs();
String WindowLayoutJson;
Windows.Foundation.IAsyncOperation<String> WindowLayoutJsonAsync;
}
enum MonitorBehavior
{
InPlace,
@@ -88,7 +82,6 @@ namespace Microsoft.Terminal.Remoting
void RequestHideNotificationIcon();
void RequestQuitAll();
void Quit();
String GetWindowLayout();
void AttachContentToWindow(AttachRequest request);
void SendContent(RequestReceiveContentArgs args);
@@ -102,7 +95,6 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, Object> ShowNotificationIconRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> HideNotificationIconRequested;
event Windows.Foundation.TypedEventHandler<Object, GetWindowLayoutArgs> GetWindowLayoutRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> QuitAllRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;

View File

@@ -1,5 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "QuitAllRequestedArgs.h"
#include "QuitAllRequestedArgs.g.cpp"

View File

@@ -1,29 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Class Name:
- QuitAllRequestedArgs.h
Abstract:
- This is a helper class for allowing the monarch to run code before telling all
peasants to quit. This way the monarch can raise an event and get back a future
to wait for before continuing.
--*/
#pragma once
#include "QuitAllRequestedArgs.g.h"
namespace winrt::Microsoft::Terminal::Remoting::implementation
{
struct QuitAllRequestedArgs : public QuitAllRequestedArgsT<QuitAllRequestedArgs>
{
WINRT_PROPERTY(winrt::Windows::Foundation::IAsyncAction, BeforeQuitAllAction, nullptr)
};
}
namespace winrt::Microsoft::Terminal::Remoting::factory_implementation
{
BASIC_FACTORY(QuitAllRequestedArgs);
}

View File

@@ -89,10 +89,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// done when we become the king. This will be called both for the first
// window, and when the current monarch dies.
_monarch.WindowCreated({ get_weak(), &WindowManager::_WindowCreatedHandlers });
_monarch.WindowClosed({ get_weak(), &WindowManager::_WindowClosedHandlers });
_monarch.WindowCreated({ get_weak(), &WindowManager::_bubbleWindowCreated });
_monarch.WindowClosed({ get_weak(), &WindowManager::_bubbleWindowClosed });
_monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested });
_monarch.QuitAllRequested({ get_weak(), &WindowManager::_QuitAllRequestedHandlers });
_monarch.RequestNewWindow({ get_weak(), &WindowManager::_raiseRequestNewWindow });
}
@@ -109,12 +108,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void WindowManager::_raiseFindTargetWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args)
{
_FindTargetWindowRequestedHandlers(sender, args);
FindTargetWindowRequested.raise(sender, args);
}
void WindowManager::_raiseRequestNewWindow(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs& args)
{
_RequestNewWindowHandlers(sender, args);
RequestNewWindow.raise(sender, args);
}
Remoting::ProposeCommandlineResult WindowManager::ProposeCommandline(const Remoting::CommandlineArgs& args, const bool isolatedMode)
@@ -162,7 +161,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
auto findWindowArgs{ winrt::make_self<Remoting::implementation::FindTargetWindowArgs>(args) };
// This is handled by some handler in-proc
_FindTargetWindowRequestedHandlers(*this, *findWindowArgs);
FindTargetWindowRequested.raise(*this, *findWindowArgs);
// After the event was handled, ResultTargetWindow() will be filled with
// the parsed result.
@@ -356,8 +355,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
_monarch.AddPeasant(*p);
p->GetWindowLayoutRequested({ get_weak(), &WindowManager::_GetWindowLayoutRequestedHandlers });
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_CreateOurPeasant",
TraceLoggingUInt64(p->GetID(), "peasantID", "The ID of our new peasant"),
@@ -367,6 +364,15 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
return *p;
}
void WindowManager::_bubbleWindowCreated(const winrt::Windows::Foundation::IInspectable& s, const winrt::Windows::Foundation::IInspectable& e)
{
WindowCreated.raise(s, e);
}
void WindowManager::_bubbleWindowClosed(const winrt::Windows::Foundation::IInspectable& s, const winrt::Windows::Foundation::IInspectable& e)
{
WindowClosed.raise(s, e);
}
void WindowManager::SignalClose(const Remoting::Peasant& peasant)
{
if (_monarch)
@@ -412,18 +418,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
return 0;
}
// Method Description:
// - Ask the monarch to quit all windows.
// Arguments:
// - <none>
// Return Value:
// - <none>
winrt::fire_and_forget WindowManager::RequestQuitAll(Remoting::Peasant peasant)
{
co_await winrt::resume_background();
peasant.RequestQuitAll();
}
bool WindowManager::DoesQuakeWindowExist()
{
return _monarch.DoesQuakeWindowExist();
@@ -434,19 +428,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::get_self<implementation::Peasant>(peasant)->ActiveTabTitle(title);
}
Windows::Foundation::Collections::IVector<winrt::hstring> WindowManager::GetAllWindowLayouts()
{
if (_monarch)
{
try
{
return _monarch.GetAllWindowLayouts();
}
CATCH_LOG()
}
return nullptr;
}
winrt::fire_and_forget WindowManager::RequestMoveContent(winrt::hstring window,
winrt::hstring content,
uint32_t tabIndex,

View File

@@ -38,23 +38,18 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
uint64_t GetNumberOfPeasants();
static winrt::fire_and_forget RequestQuitAll(Remoting::Peasant peasant);
void UpdateActiveTabTitle(const winrt::hstring& title, const Remoting::Peasant& peasant);
Windows::Foundation::Collections::IVector<winrt::hstring> GetAllWindowLayouts();
bool DoesQuakeWindowExist();
winrt::fire_and_forget RequestMoveContent(winrt::hstring window, winrt::hstring content, uint32_t tabIndex, Windows::Foundation::IReference<Windows::Foundation::Rect> windowBounds);
winrt::fire_and_forget RequestSendContent(Remoting::RequestReceiveContentArgs args);
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs> FindTargetWindowRequested;
TYPED_EVENT(WindowCreated, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(WindowClosed, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitAllRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::QuitAllRequestedArgs);
TYPED_EVENT(GetWindowLayoutRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::GetWindowLayoutArgs);
TYPED_EVENT(RequestNewWindow, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs);
til::typed_event<> WindowCreated;
til::typed_event<> WindowClosed;
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs> RequestNewWindow;
private:
DWORD _registrationHostClass{ 0 };
@@ -70,6 +65,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args);
void _raiseRequestNewWindow(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs& args);
void _bubbleWindowCreated(const winrt::Windows::Foundation::IInspectable& s, const winrt::Windows::Foundation::IInspectable& e);
void _bubbleWindowClosed(const winrt::Windows::Foundation::IInspectable& s, const winrt::Windows::Foundation::IInspectable& e);
};
}

View File

@@ -14,12 +14,10 @@ namespace Microsoft.Terminal.Remoting
void SignalClose(Peasant p);
void UpdateActiveTabTitle(String title, Peasant p);
static void RequestQuitAll(Peasant p);
void SummonWindow(SummonWindowSelectionArgs args);
void SummonAllWindows();
Windows.Foundation.Collections.IVector<String> GetAllWindowLayouts();
Windows.Foundation.Collections.IVectorView<PeasantInfo> GetPeasantInfos();
UInt64 GetNumberOfPeasants();
@@ -33,8 +31,6 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, Object> WindowCreated;
event Windows.Foundation.TypedEventHandler<Object, Object> WindowClosed;
event Windows.Foundation.TypedEventHandler<Object, QuitAllRequestedArgs> QuitAllRequested;
event Windows.Foundation.TypedEventHandler<Object, GetWindowLayoutArgs> GetWindowLayoutRequested;
event Windows.Foundation.TypedEventHandler<Object, WindowRequestedArgs> RequestNewWindow;

View File

@@ -15,9 +15,9 @@ namespace winrt::TerminalApp::implementation
winrt::hstring ApplicationDisplayName();
winrt::hstring ApplicationVersion();
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(bool, UpdatesAvailable, _PropertyChangedHandlers, false);
WINRT_OBSERVABLE_PROPERTY(bool, CheckingForUpdates, _PropertyChangedHandlers, false);
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(bool, UpdatesAvailable, PropertyChanged.raise, false);
WINRT_OBSERVABLE_PROPERTY(bool, CheckingForUpdates, PropertyChanged.raise, false);
private:
friend struct AboutDialogT<AboutDialog>; // for Xaml to bind events

View File

@@ -5,6 +5,8 @@
#include "App.h"
#include "TerminalPage.h"
#include "ScratchpadContent.h"
#include "TasksPaneContent.h"
#include "../WinRTUtils/inc/WtExeUtils.h"
#include "../../types/inc/utils.hpp"
#include "Utils.h"
@@ -117,7 +119,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_HandleCloseWindow(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_CloseRequestedHandlers(nullptr, nullptr);
CloseRequested.raise(nullptr, nullptr);
args.Handled(true);
}
@@ -737,8 +739,8 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& realArgs = actionArgs.ActionArgs().try_as<ExecuteCommandlineArgs>())
{
auto actions = winrt::single_threaded_vector<ActionAndArgs>(std::move(
TerminalPage::ConvertExecuteCommandlineToActions(realArgs)));
auto actions = winrt::single_threaded_vector<ActionAndArgs>(
TerminalPage::ConvertExecuteCommandlineToActions(realArgs));
if (actions.Size() != 0)
{
@@ -948,7 +950,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_HandleIdentifyWindows(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_IdentifyWindowsRequestedHandlers(*this, nullptr);
IdentifyWindowsRequested.raise(*this, nullptr);
args.Handled(true);
}
@@ -977,7 +979,7 @@ namespace winrt::TerminalApp::implementation
{
const auto newName = realArgs.Name();
const auto request = winrt::make_self<implementation::RenameWindowRequestedArgs>(newName);
_RenameWindowRequestedHandlers(*this, *request);
RenameWindowRequested.raise(*this, *request);
args.Handled(true);
}
}
@@ -1147,7 +1149,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_HandleOpenSystemMenu(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_OpenSystemMenuHandlers(*this, nullptr);
OpenSystemMenu.raise(*this, nullptr);
args.Handled(true);
}
@@ -1401,7 +1403,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto activePane{ activeTab->GetActivePane() })
{
_restartPaneConnection(activePane);
_restartPaneConnection(activePane->GetContent().try_as<TerminalApp::TerminalPaneContent>(), nullptr);
}
}
args.Handled(true);
@@ -1416,10 +1418,50 @@ namespace winrt::TerminalApp::implementation
}
args.Handled(true);
}
void TerminalPage::_HandleOpenScratchpad(const IInspectable& sender,
const ActionEventArgs& args)
{
if (Feature_ScratchpadPane::IsEnabled())
{
const auto& scratchPane{ winrt::make_self<ScratchpadContent>() };
// This is maybe a little wacky - add our key event handler to the pane
// we made. So that we can get actions for keys that the content didn't
// handle.
scratchPane->GetRoot().KeyDown({ this, &TerminalPage::_KeyDownHandler });
const auto resultPane = std::make_shared<Pane>(*scratchPane);
_SplitPane(_senderOrFocusedTab(sender), SplitDirection::Automatic, 0.5f, resultPane);
args.Handled(true);
}
}
void TerminalPage::_HandleOpenAbout(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_ShowAboutDialog();
args.Handled(true);
}
void TerminalPage::_HandleOpenTasksPane(const IInspectable& sender,
const ActionEventArgs& args)
{
if (Feature_ScratchpadPane::IsEnabled())
{
const auto& scratchPane{ winrt::make_self<TasksPaneContent>() };
scratchPane->UpdateSettings(_settings);
// This is maybe a little wacky - add our key event handler to the pane
// we made. So that we can get actions for keys that the content didn't
// handle.
scratchPane->GetRoot().KeyDown({ this, &TerminalPage::_KeyDownHandler });
scratchPane->DispatchCommandRequested({ this, &TerminalPage::_OnDispatchCommandRequested });
const auto resultPane = std::make_shared<Pane>(*scratchPane);
_SplitPane(_senderOrFocusedTab(sender), SplitDirection::Automatic, 0.5f, resultPane);
args.Handled(true);
}
}
}

View File

@@ -549,6 +549,9 @@ void AppCommandlineArgs::_addNewTerminalArgs(AppCommandlineArgs::NewTerminalSubc
subcommand.profileNameOption = subcommand.subcommand->add_option("-p,--profile",
_profileName,
RS_A(L"CmdProfileArgDesc"));
subcommand.sessionIdOption = subcommand.subcommand->add_option("--sessionId",
_sessionId,
RS_A(L"CmdSessionIdArgDesc"));
subcommand.startingDirectoryOption = subcommand.subcommand->add_option("-d,--startingDirectory",
_startingDirectory,
RS_A(L"CmdStartingDirArgDesc"));
@@ -628,6 +631,13 @@ NewTerminalArgs AppCommandlineArgs::_getNewTerminalArgs(AppCommandlineArgs::NewT
args.Profile(winrt::to_hstring(_profileName));
}
if (*subcommand.sessionIdOption)
{
const auto str = winrt::to_hstring(_sessionId);
const auto id = ::Microsoft::Console::Utils::GuidFromString(str.c_str());
args.SessionId(id);
}
if (*subcommand.startingDirectoryOption)
{
args.StartingDirectory(winrt::to_hstring(_startingDirectory));
@@ -714,6 +724,7 @@ bool AppCommandlineArgs::_noCommandsProvided()
void AppCommandlineArgs::_resetStateToDefault()
{
_profileName.clear();
_sessionId.clear();
_startingDirectory.clear();
_startingTitle.clear();
_startingTabColor.clear();

View File

@@ -62,6 +62,7 @@ private:
CLI::App* subcommand;
CLI::Option* commandlineOption;
CLI::Option* profileNameOption;
CLI::Option* sessionIdOption;
CLI::Option* startingDirectoryOption;
CLI::Option* titleOption;
CLI::Option* tabColorOption;
@@ -96,6 +97,7 @@ private:
// Are you adding a new sub-command? Make sure to update _noCommandsProvided!
std::string _profileName;
std::string _sessionId;
std::string _startingDirectory;
std::string _startingTitle;
std::string _startingTabColor;

View File

@@ -149,6 +149,11 @@ namespace winrt::TerminalApp::implementation
_languageProfileNotifier = winrt::make_self<LanguageProfileNotifier>([this]() {
_reloadSettings->Run();
});
// Do this here, rather than at the top of main. This will prevent us from
// including this variable in the vars we serialize in the
// Remoting::CommandlineArgs up in HandleCommandlineArgs.
_setupFolderPathEnvVar();
}
// Method Description:
@@ -423,7 +428,7 @@ namespace winrt::TerminalApp::implementation
_settingsLoadExceptionText,
warnings,
_settings);
_SettingsChangedHandlers(*this, *ev);
SettingsChanged.raise(*this, *ev);
return;
}
}
@@ -452,7 +457,7 @@ namespace winrt::TerminalApp::implementation
_settingsLoadExceptionText,
warnings,
_settings);
_SettingsChangedHandlers(*this, *ev);
SettingsChanged.raise(*this, *ev);
}
// This is a continuation of AppLogic::Create() and includes the more expensive parts.
@@ -697,22 +702,6 @@ namespace winrt::TerminalApp::implementation
return _settings.GlobalSettings().ShouldUsePersistedLayout();
}
void AppLogic::SaveWindowLayoutJsons(const Windows::Foundation::Collections::IVector<hstring>& layouts)
{
std::vector<WindowLayout> converted;
converted.reserve(layouts.Size());
for (const auto& json : layouts)
{
if (json != L"")
{
converted.emplace_back(WindowLayout::FromJson(json));
}
}
ApplicationState::SharedInstance().PersistedWindowLayouts(winrt::single_threaded_vector(std::move(converted)));
}
TerminalApp::ParseCommandlineResult AppLogic::GetParseCommandlineMessage(array_view<const winrt::hstring> args)
{
::TerminalApp::AppCommandlineArgs _appArgs;
@@ -720,4 +709,14 @@ namespace winrt::TerminalApp::implementation
return TerminalApp::ParseCommandlineResult{ winrt::to_hstring(_appArgs.GetExitMessage()), r };
}
// Function Description
// * Adds a `WT_SETTINGS_DIR` env var to our own environment block, that
// points at our settings directory. This allows portable installs to
// refer to files in the portable install using %WT_SETTINGS_DIR%
void AppLogic::_setupFolderPathEnvVar()
{
std::wstring path{ CascadiaSettings::SettingsPath() };
auto folderPath = path.substr(0, path.find_last_of(L"\\"));
SetEnvironmentVariableW(L"WT_SETTINGS_DIR", folderPath.c_str());
}
}

View File

@@ -53,9 +53,7 @@ namespace winrt::TerminalApp::implementation
void NotifyRootInitialized();
bool HasSettingsStartupActions() const noexcept;
bool ShouldUsePersistedLayout() const;
void SaveWindowLayoutJsons(const Windows::Foundation::Collections::IVector<hstring>& layouts);
[[nodiscard]] Microsoft::Terminal::Settings::Model::CascadiaSettings GetSettings() const noexcept;
@@ -74,7 +72,7 @@ namespace winrt::TerminalApp::implementation
TerminalApp::ParseCommandlineResult GetParseCommandlineMessage(array_view<const winrt::hstring> args);
TYPED_EVENT(SettingsChanged, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::SettingsLoadEventArgs);
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::SettingsLoadEventArgs> SettingsChanged;
private:
bool _isElevated{ false };
@@ -112,6 +110,8 @@ namespace winrt::TerminalApp::implementation
void _RegisterSettingsChange();
fire_and_forget _DispatchReloadSettings();
void _setupFolderPathEnvVar();
#ifdef UNIT_TESTING
friend class TerminalAppLocalTests::CommandlineTest;
#endif

View File

@@ -37,7 +37,6 @@ namespace TerminalApp
Boolean HasSettingsStartupActions();
Boolean ShouldUsePersistedLayout();
void SaveWindowLayoutJsons(Windows.Foundation.Collections.IVector<String> layouts);
void ReloadSettings();

View File

@@ -32,7 +32,7 @@ namespace winrt::TerminalApp::implementation
{
auto button{ sender.as<Windows::UI::Xaml::Controls::Button>() };
auto rectClr{ button.Background().as<Windows::UI::Xaml::Media::SolidColorBrush>() };
_ColorSelectedHandlers(rectClr.Color());
ColorSelected.raise(rectClr.Color());
Hide();
}
@@ -45,7 +45,7 @@ namespace winrt::TerminalApp::implementation
// - <none>
void ColorPickupFlyout::ClearColorButton_Click(const IInspectable&, const Windows::UI::Xaml::RoutedEventArgs&)
{
_ColorClearedHandlers();
ColorCleared.raise();
Hide();
}
@@ -80,12 +80,12 @@ namespace winrt::TerminalApp::implementation
void ColorPickupFlyout::CustomColorButton_Click(const Windows::Foundation::IInspectable&, const Windows::UI::Xaml::RoutedEventArgs&)
{
auto color = customColorPicker().Color();
_ColorSelectedHandlers(color);
ColorSelected.raise(color);
Hide();
}
void ColorPickupFlyout::ColorPicker_ColorChanged(const Microsoft::UI::Xaml::Controls::ColorPicker&, const Microsoft::UI::Xaml::Controls::ColorChangedEventArgs& args)
{
_ColorSelectedHandlers(args.NewColor());
ColorSelected.raise(args.NewColor());
}
}

View File

@@ -13,8 +13,8 @@ namespace winrt::TerminalApp::implementation
void ClearColorButton_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
void ColorPicker_ColorChanged(const Microsoft::UI::Xaml::Controls::ColorPicker&, const Microsoft::UI::Xaml::Controls::ColorChangedEventArgs& args);
WINRT_CALLBACK(ColorCleared, TerminalApp::ColorClearedArgs);
WINRT_CALLBACK(ColorSelected, TerminalApp::ColorSelectedArgs);
til::event<TerminalApp::ColorClearedArgs> ColorCleared;
til::event<TerminalApp::ColorSelectedArgs> ColorSelected;
};
}

View File

@@ -235,7 +235,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
{
_PreviewActionHandlers(*this, actionPaletteItem.Command());
PreviewAction.raise(*this, actionPaletteItem.Command());
}
}
else if (_currentMode == CommandPaletteMode::CommandlineMode)
@@ -569,7 +569,7 @@ namespace winrt::TerminalApp::implementation
void CommandPalette::_moveBackButtonClicked(const Windows::Foundation::IInspectable& /*sender*/,
const Windows::UI::Xaml::RoutedEventArgs&)
{
_PreviewActionHandlers(*this, nullptr);
PreviewAction.raise(*this, nullptr);
_searchBox().Focus(FocusState::Programmatic);
const auto previousAction{ _nestedActionStack.GetAt(_nestedActionStack.Size() - 1) };
@@ -714,7 +714,7 @@ namespace winrt::TerminalApp::implementation
// All other actions can just be dispatched.
if (actionPaletteItem.Command().ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
{
_DispatchCommandRequestedHandlers(*this, actionPaletteItem.Command());
DispatchCommandRequested.raise(*this, actionPaletteItem.Command());
}
TraceLoggingWrite(
@@ -768,7 +768,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto tab{ tabPaletteItem.Tab() })
{
_SwitchToTabRequestedHandlers(*this, tab);
SwitchToTabRequested.raise(*this, tab);
}
}
}
@@ -796,7 +796,7 @@ namespace winrt::TerminalApp::implementation
if (const auto commandLinePaletteItem{ filteredCommand.value().Item().try_as<winrt::TerminalApp::CommandLinePaletteItem>() })
{
_CommandLineExecutionRequestedHandlers(*this, commandLinePaletteItem.CommandLine());
CommandLineExecutionRequested.raise(*this, commandLinePaletteItem.CommandLine());
_close();
}
}
@@ -843,6 +843,16 @@ namespace winrt::TerminalApp::implementation
void CommandPalette::_filterTextChanged(const IInspectable& /*sender*/,
const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
{
// When we are executing the _SelectNextTab in the TabManagement.cpp, this method
// is getting triggered because we set up the default value for that CommandPalette
// with an empty string. Therefore, to avoid the reset of the index when executing
// the Next/Prev tab command, we are skipping this execution.
// Check issue https://github.com/microsoft/terminal/issues/11146
if (_currentMode == CommandPaletteMode::TabSwitchMode)
{
return;
}
if (_currentMode == CommandPaletteMode::CommandlineMode)
{
_evaluatePrefix();
@@ -1187,7 +1197,7 @@ namespace winrt::TerminalApp::implementation
{
Visibility(Visibility::Collapsed);
_PreviewActionHandlers(*this, nullptr);
PreviewAction.raise(*this, nullptr);
// Reset visibility in case anchor mode tab switcher just finished.
_searchBox().Visibility(Visibility::Visible);
@@ -1338,7 +1348,7 @@ namespace winrt::TerminalApp::implementation
// there aren't any recent commands, then just store the new command.
if (!recentCommands)
{
ApplicationState::SharedInstance().RecentCommands(single_threaded_vector(std::move(std::vector{ command })));
ApplicationState::SharedInstance().RecentCommands(single_threaded_vector(std::vector{ command }));
return;
}

View File

@@ -48,18 +48,18 @@ namespace winrt::TerminalApp::implementation
void EnableTabSwitcherMode(const uint32_t startIdx, Microsoft::Terminal::Settings::Model::TabSwitcherMode tabSwitcherMode);
void EnableTabSearchMode();
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, SearchBoxPlaceholderText, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, PrefixCharacter, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ControlName, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParentCommandName, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParsedCommandLineText, _PropertyChangedHandlers);
til::property_changed_event PropertyChanged;
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::TerminalApp::TabBase> SwitchToTabRequested;
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::hstring> CommandLineExecutionRequested;
til::typed_event<winrt::TerminalApp::CommandPalette, Microsoft::Terminal::Settings::Model::Command> DispatchCommandRequested;
til::typed_event<Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command> PreviewAction;
TYPED_EVENT(SwitchToTabRequested, winrt::TerminalApp::CommandPalette, winrt::TerminalApp::TabBase);
TYPED_EVENT(CommandLineExecutionRequested, winrt::TerminalApp::CommandPalette, winrt::hstring);
TYPED_EVENT(DispatchCommandRequested, winrt::TerminalApp::CommandPalette, Microsoft::Terminal::Settings::Model::Command);
TYPED_EVENT(PreviewAction, Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, NoMatchesText, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, SearchBoxPlaceholderText, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, PrefixCharacter, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ControlName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParentCommandName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParsedCommandLineText, PropertyChanged.raise);
private:
struct winrt_object_hash

View File

@@ -62,7 +62,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
{
_outputRevoker = wrappedConnection.TerminalOutput(winrt::auto_revoke, { this, &DebugTapConnection::_OutputHandler });
_stateChangedRevoker = wrappedConnection.StateChanged(winrt::auto_revoke, [this](auto&& /*s*/, auto&& /*e*/) {
_StateChangedHandlers(*this, nullptr);
StateChanged.raise(*this, nullptr);
});
_wrappedConnection = wrappedConnection;
}
@@ -127,7 +127,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
{
output.insert(++lfPos, L"\r\n");
}
_TerminalOutputHandlers(output);
TerminalOutput.raise(output);
}
// Called by the DebugInputTapConnection to print user input
@@ -135,7 +135,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
{
auto clean{ til::visualize_control_codes(str) };
auto formatted{ wil::str_printf<std::wstring>(L"\x1b[91m%ls\x1b[m", clean.data()) };
_TerminalOutputHandlers(formatted);
TerminalOutput.raise(formatted);
}
// Wire us up so that we can forward input through

View File

@@ -25,9 +25,9 @@ namespace winrt::Microsoft::TerminalApp::implementation
void SetInputTap(const Microsoft::Terminal::TerminalConnection::ITerminalConnection& inputTap);
WINRT_CALLBACK(TerminalOutput, winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputHandler);
til::event<winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputHandler> TerminalOutput;
TYPED_EVENT(StateChanged, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection, winrt::Windows::Foundation::IInspectable);
til::typed_event<winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection, winrt::Windows::Foundation::IInspectable> StateChanged;
private:
void _PrintInput(const hstring& data);

View File

@@ -21,11 +21,22 @@ namespace winrt::TerminalApp::implementation
{
// This class is a wrapper of PaletteItem, that is used as an item of a filterable list in CommandPalette.
// It manages a highlighted text that is computed by matching search filter characters to item name
FilteredCommand::FilteredCommand(const winrt::TerminalApp::PaletteItem& item) :
_Item(item),
_Filter(L""),
_Weight(0)
FilteredCommand::FilteredCommand(const winrt::TerminalApp::PaletteItem& item)
{
// Actually implement the ctor in _constructFilteredCommand
_constructFilteredCommand(item);
}
// We need to actually implement the ctor in a separate helper. This is
// because we have a FilteredTask class which derives from FilteredCommand.
// HOWEVER, for cppwinrt ~ r e a s o n s ~, it doesn't actually derive from
// FilteredCommand directly, so we can't just use the FilteredCommand ctor
// directly in the base class.
void FilteredCommand::_constructFilteredCommand(const winrt::TerminalApp::PaletteItem& item)
{
_Item = item;
_Filter = L"";
_Weight = 0;
_HighlightedName = _computeHighlightedName();
// Recompute the highlighted name if the item name changes

View File

@@ -19,15 +19,18 @@ namespace winrt::TerminalApp::implementation
FilteredCommand() = default;
FilteredCommand(const winrt::TerminalApp::PaletteItem& item);
void UpdateFilter(const winrt::hstring& filter);
virtual void UpdateFilter(const winrt::hstring& filter);
static int Compare(const winrt::TerminalApp::FilteredCommand& first, const winrt::TerminalApp::FilteredCommand& second);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::PaletteItem, Item, _PropertyChangedHandlers, nullptr);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Filter, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::HighlightedText, HighlightedName, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(int, Weight, _PropertyChangedHandlers);
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::PaletteItem, Item, PropertyChanged.raise, nullptr);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Filter, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::HighlightedText, HighlightedName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(int, Weight, PropertyChanged.raise);
protected:
void _constructFilteredCommand(const winrt::TerminalApp::PaletteItem& item);
private:
winrt::TerminalApp::HighlightedText _computeHighlightedName();

View File

@@ -6,7 +6,7 @@ import "HighlightedTextControl.idl";
namespace TerminalApp
{
[default_interface] runtimeclass FilteredCommand : Windows.UI.Xaml.Data.INotifyPropertyChanged
[default_interface] unsealed runtimeclass FilteredCommand : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
FilteredCommand();
FilteredCommand(PaletteItem item);

View File

@@ -13,9 +13,9 @@ namespace winrt::TerminalApp::implementation
HighlightedTextSegment() = default;
HighlightedTextSegment(const winrt::hstring& text, bool isHighlighted);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, TextSegment, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(bool, IsHighlighted, _PropertyChangedHandlers);
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, TextSegment, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, IsHighlighted, PropertyChanged.raise);
};
struct HighlightedText : HighlightedTextT<HighlightedText>
@@ -23,8 +23,8 @@ namespace winrt::TerminalApp::implementation
HighlightedText() = default;
HighlightedText(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::HighlightedTextSegment>& segments);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::HighlightedTextSegment>, Segments, _PropertyChangedHandlers);
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::HighlightedTextSegment>, Segments, PropertyChanged.raise);
};
}

View File

@@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
enum BuildStartupKind
{
None,
Content,
MovePane,
Persist,
};
runtimeclass BellEventArgs
{
Boolean FlashTaskbar { get; };
};
interface IPaneContent
{
Windows.UI.Xaml.FrameworkElement GetRoot();
void UpdateSettings(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);
Windows.Foundation.Size MinimumSize { get; };
String Title { get; };
UInt64 TaskbarState { get; };
UInt64 TaskbarProgress { get; };
Boolean ReadOnly { get; };
String Icon { get; };
Windows.Foundation.IReference<Windows.UI.Color> TabColor { get; };
Windows.UI.Xaml.Media.Brush BackgroundBrush { get; };
Microsoft.Terminal.Settings.Model.NewTerminalArgs GetNewTerminalArgs(BuildStartupKind kind);
void Focus(Windows.UI.Xaml.FocusState reason);
void Close();
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> CloseRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> ConnectionStateChanged;
event Windows.Foundation.TypedEventHandler<IPaneContent, BellEventArgs> BellRequested;
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> TitleChanged;
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> TabColorChanged;
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> TaskbarProgressChanged;
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> ReadOnlyChanged;
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> FocusRequested;
};
enum PaneSnapDirection
{
Width,
Height
};
interface ISnappable
{
Single SnapDownToGrid(PaneSnapDirection direction, Single sizeToSnap);
Windows.Foundation.Size GridUnitSize { get; };
};
}

View File

@@ -69,18 +69,18 @@ namespace winrt::TerminalApp::implementation
void MinMaxCloseControl::_MinimizeClick(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const RoutedEventArgs& e)
{
_MinimizeClickHandlers(*this, e);
MinimizeClick.raise(*this, e);
}
void MinMaxCloseControl::_MaximizeClick(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const RoutedEventArgs& e)
{
_MaximizeClickHandlers(*this, e);
MaximizeClick.raise(*this, e);
}
void MinMaxCloseControl::_CloseClick(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const RoutedEventArgs& e)
{
_CloseClickHandlers(*this, e);
CloseClick.raise(*this, e);
}
void MinMaxCloseControl::SetWindowVisualState(WindowVisualState visualState)

View File

@@ -28,9 +28,9 @@ namespace winrt::TerminalApp::implementation
void _CloseClick(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
TYPED_EVENT(MinimizeClick, TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs);
TYPED_EVENT(MaximizeClick, TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs);
TYPED_EVENT(CloseClick, TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs);
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> MinimizeClick;
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> MaximizeClick;
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> CloseClick;
std::shared_ptr<ThrottledFuncTrailing<winrt::Windows::UI::Xaml::Controls::Button>> _displayToolTip{ nullptr };
std::optional<CaptionButton> _lastPressedButton{ std::nullopt };

View File

@@ -11,10 +11,10 @@ namespace winrt::TerminalApp::implementation
public:
Windows::UI::Xaml::Controls::IconElement ResolvedIcon();
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Name, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Name, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, KeyChordText, PropertyChanged.raise);
};
}

View File

@@ -3,11 +3,6 @@
#include "pch.h"
#include "Pane.h"
#include "AppLogic.h"
#include "Utils.h"
#include <Mmsystem.h>
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Graphics::Display;
@@ -19,7 +14,6 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Control;
using namespace winrt::Microsoft::Terminal::TerminalConnection;
using namespace winrt::TerminalApp;
using namespace TerminalApp;
static const int PaneBorderSize = 2;
static const int CombinedPaneBorderSize = 2 * PaneBorderSize;
@@ -33,19 +27,21 @@ static const int CombinedPaneBorderSize = 2 * PaneBorderSize;
static const int AnimationDurationInMilliseconds = 200;
static const Duration AnimationDuration = DurationHelper::FromTimeSpan(winrt::Windows::Foundation::TimeSpan(std::chrono::milliseconds(AnimationDurationInMilliseconds)));
Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFocused) :
_control{ control },
_lastActive{ lastFocused },
_profile{ profile }
Pane::Pane(const IPaneContent& content, const bool lastFocused) :
_content{ content },
_lastActive{ lastFocused }
{
_root.Children().Append(_borderFirst);
_borderFirst.Child(_control);
_setupControlEvents();
const auto& control{ _content.GetRoot() };
_borderFirst.Child(control);
// Register an event with the control to have it inform us when it gains focus.
_gotFocusRevoker = _control.GotFocus(winrt::auto_revoke, { this, &Pane::_ControlGotFocusHandler });
_lostFocusRevoker = _control.LostFocus(winrt::auto_revoke, { this, &Pane::_ControlLostFocusHandler });
if (control)
{
_gotFocusRevoker = control.GotFocus(winrt::auto_revoke, { this, &Pane::_ContentGotFocusHandler });
_lostFocusRevoker = control.LostFocus(winrt::auto_revoke, { this, &Pane::_ContentLostFocusHandler });
}
// When our border is tapped, make sure to transfer focus to our control.
// LOAD-BEARING: This will NOT work if the border's BorderBrush is set to
@@ -102,82 +98,13 @@ Pane::Pane(std::shared_ptr<Pane> first,
});
}
void Pane::_setupControlEvents()
{
_controlEvents._ConnectionStateChanged = _control.ConnectionStateChanged(winrt::auto_revoke, { this, &Pane::_ControlConnectionStateChangedHandler });
_controlEvents._WarningBell = _control.WarningBell(winrt::auto_revoke, { this, &Pane::_ControlWarningBellHandler });
_controlEvents._CloseTerminalRequested = _control.CloseTerminalRequested(winrt::auto_revoke, { this, &Pane::_CloseTerminalRequestedHandler });
_controlEvents._RestartTerminalRequested = _control.RestartTerminalRequested(winrt::auto_revoke, { this, &Pane::_RestartTerminalRequestedHandler });
_controlEvents._ReadOnlyChanged = _control.ReadOnlyChanged(winrt::auto_revoke, { this, &Pane::_ControlReadOnlyChangedHandler });
}
void Pane::_removeControlEvents()
{
_controlEvents = {};
}
// Method Description:
// - Extract the terminal settings from the current (leaf) pane's control
// to be used to create an equivalent control
// Arguments:
// - asContent: when true, we're trying to serialize this pane for moving across
// windows. In that case, we'll need to fill in the content guid for our new
// terminal args.
// Return Value:
// - Arguments appropriate for a SplitPane or NewTab action
NewTerminalArgs Pane::GetTerminalArgsForPane(const bool asContent) const
// Extract the terminal settings from the current (leaf) pane's control
// to be used to create an equivalent control
NewTerminalArgs Pane::GetTerminalArgsForPane(BuildStartupKind kind) const
{
// Leaves are the only things that have controls
assert(_IsLeaf());
NewTerminalArgs args{};
auto controlSettings = _control.Settings();
args.Profile(controlSettings.ProfileName());
// If we know the user's working directory use it instead of the profile.
if (const auto dir = _control.WorkingDirectory(); !dir.empty())
{
args.StartingDirectory(dir);
}
else
{
args.StartingDirectory(controlSettings.StartingDirectory());
}
args.TabTitle(controlSettings.StartingTitle());
args.Commandline(controlSettings.Commandline());
args.SuppressApplicationTitle(controlSettings.SuppressApplicationTitle());
if (controlSettings.TabColor() || controlSettings.StartingTabColor())
{
til::color c;
// StartingTabColor is prioritized over other colors
if (const auto color = controlSettings.StartingTabColor())
{
c = til::color(color.Value());
}
else
{
c = til::color(controlSettings.TabColor().Value());
}
args.TabColor(winrt::Windows::Foundation::IReference<winrt::Windows::UI::Color>{ static_cast<winrt::Windows::UI::Color>(c) });
}
// TODO:GH#9800 - we used to be able to persist the color scheme that a
// TermControl was initialized with, by name. With the change to having the
// control own its own copy of its settings, this isn't possible anymore.
//
// We may be able to get around this by storing the Name in the Core::Scheme
// object. That would work for schemes set by the Terminal, but not ones set
// by VT, but that seems good enough.
// Only fill in the ContentId if absolutely needed. If you fill in a number
// here (even 0), we'll serialize that number, AND treat that action as an
// "attach existing" rather than a "create"
if (asContent)
{
args.ContentId(_control.ContentId());
}
return args;
return _content.GetNewTerminalArgs(kind);
}
// Method Description:
@@ -200,16 +127,13 @@ NewTerminalArgs Pane::GetTerminalArgsForPane(const bool asContent) const
// - The state from building the startup actions, includes a vector of commands,
// the original root pane, the id of the focused pane, and the number of panes
// created.
Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId,
uint32_t nextId,
const bool asContent,
const bool asMovePane)
Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId, uint32_t nextId, BuildStartupKind kind)
{
// Normally, if we're a leaf, return an empt set of actions, because the
// parent pane will build the SplitPane action for us. If we're building
// actions for a movePane action though, we'll still need to include
// ourselves.
if (!asMovePane && _IsLeaf())
if (kind != BuildStartupKind::MovePane && _IsLeaf())
{
if (_lastActive)
{
@@ -223,18 +147,18 @@ Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId,
auto buildSplitPane = [&](auto newPane) {
ActionAndArgs actionAndArgs;
actionAndArgs.Action(ShortcutAction::SplitPane);
const auto terminalArgs{ newPane->GetTerminalArgsForPane(asContent) };
const auto terminalArgs{ newPane->GetTerminalArgsForPane(kind) };
// When creating a pane the split size is the size of the new pane
// and not position.
const auto splitDirection = _splitState == SplitState::Horizontal ? SplitDirection::Down : SplitDirection::Right;
const auto splitSize = (asContent && _IsLeaf() ? .5 : 1. - _desiredSplitPosition);
const auto splitSize = (kind != BuildStartupKind::None && _IsLeaf() ? .5 : 1. - _desiredSplitPosition);
SplitPaneArgs args{ SplitType::Manual, splitDirection, splitSize, terminalArgs };
actionAndArgs.Args(args);
return actionAndArgs;
};
if (asContent && _IsLeaf())
if (kind != BuildStartupKind::None && _IsLeaf())
{
return {
.args = { buildSplitPane(shared_from_this()) },
@@ -281,10 +205,10 @@ Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId,
// We now need to execute the commands for each side of the tree
// We've done one split, so the first-most child will have currentId, and the
// one after it will be incremented.
auto firstState = _firstChild->BuildStartupActions(currentId, nextId + 1);
auto firstState = _firstChild->BuildStartupActions(currentId, nextId + 1, kind);
// the next id for the second branch depends on how many splits were in the
// first child.
auto secondState = _secondChild->BuildStartupActions(nextId, nextId + firstState.panesCreated + 1);
auto secondState = _secondChild->BuildStartupActions(nextId, nextId + firstState.panesCreated + 1, kind);
std::vector<ActionAndArgs> actions{};
actions.reserve(firstState.args.size() + secondState.args.size() + 3);
@@ -1022,181 +946,18 @@ Pane::PaneNeighborSearch Pane::_FindPaneAndNeighbor(const std::shared_ptr<Pane>
}
// Method Description:
// - Called when our attached control is closed. Triggers listeners to our close
// event, if we're a leaf pane.
// - If this was called, and we became a parent pane (due to work on another
// thread), this function will do nothing (allowing the control's new parent
// to handle the event instead).
// - Returns true if the connection state of this pane is closed.
// Arguments:
// - <none>
// Return Value:
// - <none>
winrt::fire_and_forget Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& /*args*/)
// - true if the connection state of this Pane is closed.
bool Pane::IsConnectionClosed() const
{
auto newConnectionState = ConnectionState::Closed;
if (const auto coreState = sender.try_as<ICoreState>())
if (const auto& control{ GetTerminalControl() })
{
newConnectionState = coreState.ConnectionState();
}
const auto previousConnectionState = std::exchange(_connectionState, newConnectionState);
if (newConnectionState < ConnectionState::Closed)
{
// Pane doesn't care if the connection isn't entering a terminal state.
co_return;
}
const auto weakThis = weak_from_this();
co_await wil::resume_foreground(_root.Dispatcher());
const auto strongThis = weakThis.lock();
if (!strongThis)
{
co_return;
}
// It's possible that this event handler started being executed, scheduled
// on the UI thread, another child got created. So our control is
// actually no longer _our_ control, and instead could be a descendant.
//
// When the control's new Pane takes ownership of the control, the new
// parent will register its own event handler. That event handler will get
// fired after this handler returns, and will properly cleanup state.
if (!_IsLeaf())
{
co_return;
}
if (previousConnectionState < ConnectionState::Connected && newConnectionState >= ConnectionState::Failed)
{
// A failure to complete the connection (before it has _connected_) is not covered by "closeOnExit".
// This is to prevent a misconfiguration (closeOnExit: always, startingDirectory: garbage) resulting
// in Terminal flashing open and immediately closed.
co_return;
}
if (_profile)
{
if (_isDefTermSession && _profile.CloseOnExit() == CloseOnExitMode::Automatic)
{
// For 'automatic', we only care about the connection state if we were launched by Terminal
// Since we were launched via defterm, ignore the connection state (i.e. we treat the
// close on exit mode as 'always', see GH #13325 for discussion)
Close();
}
const auto mode = _profile.CloseOnExit();
if ((mode == CloseOnExitMode::Always) ||
((mode == CloseOnExitMode::Graceful || mode == CloseOnExitMode::Automatic) && newConnectionState == ConnectionState::Closed))
{
Close();
}
}
}
void Pane::_CloseTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
{
// It's possible that this event handler started being executed, then before
// we got the lock, another thread created another child. So our control is
// actually no longer _our_ control, and instead could be a descendant.
//
// When the control's new Pane takes ownership of the control, the new
// parent will register its own event handler. That event handler will get
// fired after this handler returns, and will properly cleanup state.
if (!_IsLeaf())
{
return;
}
Close();
}
void Pane::_RestartTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
{
if (!_IsLeaf())
{
return;
}
_RestartTerminalRequestedHandlers(shared_from_this());
}
winrt::fire_and_forget Pane::_playBellSound(winrt::Windows::Foundation::Uri uri)
{
auto weakThis{ weak_from_this() };
co_await wil::resume_foreground(_root.Dispatcher());
if (auto pane{ weakThis.lock() })
{
if (!_bellPlayerCreated)
{
// The MediaPlayer might not exist on Windows N SKU.
try
{
_bellPlayerCreated = true;
_bellPlayer = winrt::Windows::Media::Playback::MediaPlayer();
// GH#12258: The media keys (like play/pause) should have no effect on our bell sound.
_bellPlayer.CommandManager().IsEnabled(false);
}
CATCH_LOG();
}
if (_bellPlayer)
{
const auto source{ winrt::Windows::Media::Core::MediaSource::CreateFromUri(uri) };
const auto item{ winrt::Windows::Media::Playback::MediaPlaybackItem(source) };
_bellPlayer.Source(item);
_bellPlayer.Play();
}
}
}
// Method Description:
// - Plays a warning note when triggered by the BEL control character,
// using the sound configured for the "Critical Stop" system event.`
// This matches the behavior of the Windows Console host.
// - Will also flash the taskbar if the bellStyle setting for this profile
// has the 'visual' flag set
// Arguments:
// - <unused>
void Pane::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
{
if (!_IsLeaf())
{
return;
}
if (_profile)
{
// We don't want to do anything if nothing is set, so check for that first
if (static_cast<int>(_profile.BellStyle()) != 0)
{
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
{
// Audible is set, play the sound
auto sounds{ _profile.BellSound() };
if (sounds && sounds.Size() > 0)
{
winrt::hstring soundPath{ wil::ExpandEnvironmentStringsW<std::wstring>(sounds.GetAt(rand() % sounds.Size()).c_str()) };
winrt::Windows::Foundation::Uri uri{ soundPath };
_playBellSound(uri);
}
else
{
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
}
}
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
{
_control.BellLightOn();
}
// raise the event with the bool value corresponding to the taskbar flag
_PaneRaiseBellHandlers(nullptr, WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Taskbar));
}
return control.ConnectionState() >= ConnectionState::Closed;
}
return false;
}
// Event Description:
@@ -1207,7 +968,7 @@ void Pane::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspect
// - <unused>
// Return Value:
// - <none>
void Pane::_ControlGotFocusHandler(const winrt::Windows::Foundation::IInspectable& sender,
void Pane::_ContentGotFocusHandler(const winrt::Windows::Foundation::IInspectable& sender,
const RoutedEventArgs& /* args */)
{
auto f = FocusState::Programmatic;
@@ -1215,17 +976,17 @@ void Pane::_ControlGotFocusHandler(const winrt::Windows::Foundation::IInspectabl
{
f = o.FocusState();
}
_GotFocusHandlers(shared_from_this(), f);
GotFocus.raise(shared_from_this(), f);
}
// Event Description:
// - Called when our control loses focus. We'll use this to trigger our LostFocus
// callback. The tab that's hosting us should have registered a callback which
// can be used to update its own internal focus state
void Pane::_ControlLostFocusHandler(const winrt::Windows::Foundation::IInspectable& /* sender */,
void Pane::_ContentLostFocusHandler(const winrt::Windows::Foundation::IInspectable& /* sender */,
const RoutedEventArgs& /* args */)
{
_LostFocusHandlers(shared_from_this());
LostFocus.raise(shared_from_this());
}
// Method Description:
@@ -1237,7 +998,7 @@ void Pane::_ControlLostFocusHandler(const winrt::Windows::Foundation::IInspectab
void Pane::Close()
{
// Fire our Closed event to tell our parent that we should be removed.
_ClosedHandlers(nullptr, nullptr);
Closed.raise(nullptr, nullptr);
}
// Method Description:
@@ -1245,21 +1006,9 @@ void Pane::Close()
// and connections beneath it.
void Pane::Shutdown()
{
// Clear out our media player callbacks, and stop any playing media. This
// will prevent the callback from being triggered after we've closed, and
// also make sure that our sound stops when we're closed.
if (_bellPlayer)
{
_bellPlayer.Pause();
_bellPlayer.Source(nullptr);
_bellPlayer.Close();
_bellPlayer = nullptr;
_bellPlayerCreated = false;
}
if (_IsLeaf())
{
_control.Close();
_content.Close();
}
else
{
@@ -1314,7 +1063,7 @@ TermControl Pane::GetLastFocusedTerminalControl()
{
if (p->_IsLeaf())
{
return p->_control;
return p->GetTerminalControl();
}
pane = p;
}
@@ -1322,7 +1071,31 @@ TermControl Pane::GetLastFocusedTerminalControl()
}
return _firstChild->GetLastFocusedTerminalControl();
}
return _control;
// we _are_ a leaf.
return GetTerminalControl();
}
IPaneContent Pane::GetLastFocusedContent()
{
if (!_IsLeaf())
{
if (_lastActive)
{
auto pane = shared_from_this();
while (const auto p = pane->_parentChildPath.lock())
{
if (p->_IsLeaf())
{
return p->_content;
}
pane = p;
}
// We didn't find our child somehow, they might have closed under us.
}
return _firstChild->GetLastFocusedContent();
}
return _content;
}
// Method Description:
@@ -1332,9 +1105,16 @@ TermControl Pane::GetLastFocusedTerminalControl()
// - <none>
// Return Value:
// - nullptr if this Pane is a parent, otherwise the TermControl of this Pane.
TermControl Pane::GetTerminalControl()
TermControl Pane::GetTerminalControl() const
{
return _IsLeaf() ? _control : nullptr;
if (const auto& terminalPane{ _getTerminalContent() })
{
return terminalPane.GetTermControl();
}
else
{
return nullptr;
}
}
// Method Description:
@@ -1381,19 +1161,11 @@ void Pane::SetActive()
Profile Pane::GetFocusedProfile()
{
auto lastFocused = GetActivePane();
return lastFocused ? lastFocused->_profile : nullptr;
}
// Method Description:
// - Returns true if the connection state of this pane is closed. If this Pane is not a leaf this will
// return false.
// Arguments:
// - <none>
// Return Value:
// - true if the connection state of this Pane is closed.
bool Pane::IsConnectionClosed() const
{
return _control && _control.ConnectionState() >= ConnectionState::Closed;
if (const auto& terminalPane{ lastFocused->_getTerminalContent() })
{
return terminalPane.GetProfile();
}
return nullptr;
}
// Method Description:
@@ -1465,10 +1237,10 @@ void Pane::UpdateVisuals()
// - <none>
void Pane::_Focus()
{
_GotFocusHandlers(shared_from_this(), FocusState::Programmatic);
if (const auto& control = GetLastFocusedTerminalControl())
GotFocus.raise(shared_from_this(), FocusState::Programmatic);
if (const auto& lastContent{ GetLastFocusedContent() })
{
control.Focus(FocusState::Programmatic);
lastContent.Focus(FocusState::Programmatic);
}
}
@@ -1508,20 +1280,22 @@ void Pane::_FocusFirstChild()
}
}
// Method Description:
// - Updates the settings of this pane, presuming that it is a leaf.
// Arguments:
// - settings: The new TerminalSettings to apply to any matching controls
// - profile: The profile from which these settings originated.
// Return Value:
// - <none>
void Pane::UpdateSettings(const TerminalSettingsCreateResult& settings, const Profile& profile)
void Pane::UpdateSettings(const CascadiaSettings& settings, const winrt::TerminalApp::TerminalSettingsCache& cache)
{
assert(_IsLeaf());
_profile = profile;
_control.UpdateControlSettings(settings.DefaultSettings(), settings.UnfocusedSettings());
if (_content)
{
// We need to do a bit more work here for terminal
// panes. They need to know about the profile that was used for
// them, and about the focused/unfocused settings.
if (const auto& terminalPaneContent{ _content.try_as<TerminalPaneContent>() })
{
terminalPaneContent.UpdateTerminalSettings(cache);
}
else
{
_content.UpdateSettings(settings);
}
}
}
// Method Description:
@@ -1573,7 +1347,7 @@ std::shared_ptr<Pane> Pane::DetachPane(std::shared_ptr<Pane> pane)
auto detached = isFirstChild ? _firstChild : _secondChild;
// Remove the child from the tree, replace the current node with the
// other child.
_CloseChild(isFirstChild, true);
_CloseChild(isFirstChild);
// Update the borders on this pane and any children to match if we have
// no parent.
@@ -1582,7 +1356,7 @@ std::shared_ptr<Pane> Pane::DetachPane(std::shared_ptr<Pane> pane)
// Trigger the detached event on each child
detached->WalkTree([](auto pane) {
pane->_DetachedHandlers(pane);
pane->Detached.raise(pane);
});
return detached;
@@ -1602,12 +1376,9 @@ std::shared_ptr<Pane> Pane::DetachPane(std::shared_ptr<Pane> pane)
// Arguments:
// - closeFirst: if true, the first child should be closed, and the second
// should be preserved, and vice-versa for false.
// - isDetaching: if true, then the pane event handlers for the closed child
// should be kept, this way they don't have to be recreated when it is later
// reattached to a tree somewhere as the control moves with the pane.
// Return Value:
// - <none>
void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
void Pane::_CloseChild(const bool closeFirst)
{
// If we're a leaf, then chances are both our children closed in close
// succession. We waited on the lock while the other child was closed, so
@@ -1643,35 +1414,16 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
_borders = _GetCommonBorders();
// take the control, profile, id and isDefTermSession of the pane that _wasn't_ closed.
_control = remainingChild->_control;
_connectionState = remainingChild->_connectionState;
_profile = remainingChild->_profile;
_content = remainingChild->_content;
_id = remainingChild->Id();
_isDefTermSession = remainingChild->_isDefTermSession;
// Add our new event handler before revoking the old one.
_setupControlEvents();
// Revoke the old event handlers. Remove both the handlers for the panes
// themselves closing, and remove their handlers for their controls
// closing. At this point, if the remaining child's control is closed,
// they'll trigger only our event handler for the control's close.
// However, if we are detaching the pane we want to keep its control
// handlers since it is just getting moved.
if (!isDetaching)
{
closedChild->WalkTree([](auto p) {
if (p->_IsLeaf())
{
p->_removeControlEvents();
}
});
}
closedChild->Closed(closedChildClosedToken);
remainingChild->Closed(remainingChildClosedToken);
remainingChild->_removeControlEvents();
// If we or either of our children was focused, we want to take that
// focus from them.
@@ -1691,7 +1443,8 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
// Reattach the TermControl to our grid.
_root.Children().Append(_borderFirst);
_borderFirst.Child(_control);
const auto& control{ _content.GetRoot() };
_borderFirst.Child(control);
// Make sure to set our _splitState before focusing the control. If you
// fail to do this, when the tab handles the GotFocus event and asks us
@@ -1700,14 +1453,17 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
_splitState = SplitState::None;
// re-attach our handler for the control's GotFocus event.
_gotFocusRevoker = _control.GotFocus(winrt::auto_revoke, { this, &Pane::_ControlGotFocusHandler });
_lostFocusRevoker = _control.LostFocus(winrt::auto_revoke, { this, &Pane::_ControlLostFocusHandler });
if (control)
{
_gotFocusRevoker = control.GotFocus(winrt::auto_revoke, { this, &Pane::_ContentGotFocusHandler });
_lostFocusRevoker = control.LostFocus(winrt::auto_revoke, { this, &Pane::_ContentLostFocusHandler });
}
// If we're inheriting the "last active" state from one of our children,
// focus our control now. This should trigger our own GotFocus event.
if (usedToFocusClosedChildsTerminal || _lastActive)
{
_control.Focus(FocusState::Programmatic);
_content.Focus(FocusState::Programmatic);
// See GH#7252
// Manually fire off the GotFocus event. Typically, this is done
@@ -1717,7 +1473,7 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
// the control. Because Tab is relying on GotFocus to know who the
// active pane in the tree is, without this call, _no one_ will be
// the active pane any longer.
_GotFocusHandlers(shared_from_this(), FocusState::Programmatic);
GotFocus.raise(shared_from_this(), FocusState::Programmatic);
}
_UpdateBorders();
@@ -1746,15 +1502,6 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
// Remove the event handlers on the old children
remainingChild->Closed(remainingChildClosedToken);
closedChild->Closed(closedChildClosedToken);
if (!isDetaching)
{
closedChild->WalkTree([](auto p) {
if (p->_IsLeaf())
{
p->_removeControlEvents();
}
});
}
// Reset our UI:
_root.Children().Clear();
@@ -1828,7 +1575,7 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
}
// Notify the discarded child that it was closed by its parent
closedChild->_ClosedByParentHandlers();
closedChild->ClosedByParent.raise();
}
void Pane::_CloseChildRoutine(const bool closeFirst)
@@ -1847,7 +1594,7 @@ void Pane::_CloseChildRoutine(const bool closeFirst)
// this one doesn't seem to.
if (!animationsEnabledInOS || !animationsEnabledInApp || eitherChildZoomed)
{
_CloseChild(closeFirst, false);
_CloseChild(closeFirst);
return;
}
@@ -1950,7 +1697,7 @@ void Pane::_CloseChildRoutine(const bool closeFirst)
{
// We don't need to manually undo any of the above trickiness.
// We're going to re-parent the child's content into us anyways
pane->_CloseChild(closeFirst, false);
pane->_CloseChild(closeFirst);
}
});
}
@@ -2173,7 +1920,7 @@ void Pane::_SetupEntranceAnimation()
auto child = isFirstChild ? _firstChild : _secondChild;
auto childGrid = child->_root;
// If we are splitting a parent pane this may be null
auto control = child->_control;
auto control = child->_content ? child->_content.GetRoot() : nullptr;
// Build up our animation:
// * it'll take as long as our duration (200ms)
// * it'll change the value of our property from 0 to secondSize
@@ -2494,9 +2241,6 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
if (_IsLeaf())
{
// revoke our handler - the child will take care of the control now.
_removeControlEvents();
// Remove our old GotFocus handler from the control. We don't want the
// control telling us that it's now focused, we want it telling its new
// parent.
@@ -2525,11 +2269,8 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
else
{
// Move our control, guid, isDefTermSession into the first one.
_firstChild = std::make_shared<Pane>(_profile, _control);
_firstChild->_connectionState = std::exchange(_connectionState, ConnectionState::NotConnected);
_profile = nullptr;
_control = { nullptr };
_firstChild->_isDefTermSession = _isDefTermSession;
_firstChild = std::make_shared<Pane>(_content);
_content = nullptr;
_firstChild->_broadcastEnabled = _broadcastEnabled;
}
@@ -2852,8 +2593,16 @@ float Pane::CalcSnappedDimension(const bool widthOrHeight, const float dimension
// If requested size is already snapped, then both returned values equal this value.
Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
{
const auto direction{ widthOrHeight ? PaneSnapDirection::Width : PaneSnapDirection::Height };
if (_IsLeaf())
{
const auto& snappable{ _content.try_as<ISnappable>() };
if (!snappable)
{
return { dimension, dimension };
}
// If we're a leaf pane, align to the grid of controlling terminal
const auto minSize = _GetMinSize();
@@ -2864,8 +2613,10 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const
return { minDimension, minDimension };
}
auto lower = _control.SnapDimensionToGrid(widthOrHeight, dimension);
if (widthOrHeight)
auto lower = snappable.SnapDownToGrid(widthOrHeight ? PaneSnapDirection::Width : PaneSnapDirection::Height,
dimension);
if (direction == PaneSnapDirection::Width)
{
lower += WI_IsFlagSet(_borders, Borders::Left) ? PaneBorderSize : 0;
lower += WI_IsFlagSet(_borders, Borders::Right) ? PaneBorderSize : 0;
@@ -2884,8 +2635,10 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const
}
else
{
const auto cellSize = _control.CharacterDimensions();
const auto higher = lower + (widthOrHeight ? cellSize.Width : cellSize.Height);
const auto cellSize = snappable.GridUnitSize();
const auto higher = lower + (direction == PaneSnapDirection::Width ?
cellSize.Width :
cellSize.Height);
return { lower, higher };
}
}
@@ -2931,21 +2684,34 @@ void Pane::_AdvanceSnappedDimension(const bool widthOrHeight, LayoutSizeNode& si
{
if (_IsLeaf())
{
// We're a leaf pane, so just add one more row or column (unless isMinimumSize
// is true, see below).
if (sizeNode.isMinimumSize)
const auto& snappable{ _content.try_as<ISnappable>() };
if (snappable)
{
// If the node is of its minimum size, this size might not be snapped (it might
// be, say, half a character, or fixed 10 pixels), so snap it upward. It might
// however be already snapped, so add 1 to make sure it really increases
// (not strictly necessary but to avoid surprises).
sizeNode.size = _CalcSnappedDimension(widthOrHeight, sizeNode.size + 1).higher;
// We're a leaf pane, so just add one more row or column (unless isMinimumSize
// is true, see below).
if (sizeNode.isMinimumSize)
{
// If the node is of its minimum size, this size might not be snapped (it might
// be, say, half a character, or fixed 10 pixels), so snap it upward. It might
// however be already snapped, so add 1 to make sure it really increases
// (not strictly necessary but to avoid surprises).
sizeNode.size = _CalcSnappedDimension(widthOrHeight, sizeNode.size + 1).higher;
}
else
{
const auto cellSize = snappable.GridUnitSize();
sizeNode.size += widthOrHeight ? cellSize.Width : cellSize.Height;
}
}
else
{
const auto cellSize = _control.CharacterDimensions();
sizeNode.size += widthOrHeight ? cellSize.Width : cellSize.Height;
// If we're a leaf that didn't have a TermControl, then just increment
// by one. We have to increment by _some_ value, because this is used in
// a while() loop to find the next bigger size we can snap to. But since
// a non-terminal control doesn't really care what size it's snapped to,
// we can just say "one pixel larger is the next snap point"
sizeNode.size += 1;
}
}
else
@@ -3050,7 +2816,7 @@ Size Pane::_GetMinSize() const
{
if (_IsLeaf())
{
auto controlSize = _control.MinimumSize();
auto controlSize = _content.MinimumSize();
auto newWidth = controlSize.Width;
auto newHeight = controlSize.Height;
@@ -3148,14 +2914,17 @@ int Pane::GetLeafPaneCount() const noexcept
// created via default handoff
void Pane::FinalizeConfigurationGivenDefault()
{
_isDefTermSession = true;
if (const auto& terminalPane{ _content.try_as<TerminalPaneContent>() })
{
terminalPane.MarkAsDefterm();
}
}
// Method Description:
// - Returns true if the pane or one of its descendants is read-only
bool Pane::ContainsReadOnly() const
{
return _IsLeaf() ? _control.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly());
return _IsLeaf() ? _content.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly());
}
// Method Description:
@@ -3170,8 +2939,8 @@ void Pane::CollectTaskbarStates(std::vector<winrt::TerminalApp::TaskbarState>& s
{
if (_IsLeaf())
{
auto tbState{ winrt::make<winrt::TerminalApp::implementation::TaskbarState>(_control.TaskbarState(),
_control.TaskbarProgress()) };
auto tbState{ winrt::make<winrt::TerminalApp::implementation::TaskbarState>(_content.TaskbarState(),
_content.TaskbarProgress()) };
states.push_back(tbState);
}
else
@@ -3186,9 +2955,12 @@ void Pane::EnableBroadcast(bool enabled)
if (_IsLeaf())
{
_broadcastEnabled = enabled;
_control.CursorVisibility(enabled ?
CursorDisplayState::Shown :
CursorDisplayState::Default);
if (const auto& termControl{ GetTerminalControl() })
{
termControl.CursorVisibility(enabled ?
CursorDisplayState::Shown :
CursorDisplayState::Default);
}
UpdateVisuals();
}
else
@@ -3205,9 +2977,12 @@ void Pane::BroadcastKey(const winrt::Microsoft::Terminal::Control::TermControl&
const bool keyDown)
{
WalkTree([&](const auto& pane) {
if (pane->_IsLeaf() && pane->_control != sourceControl && !pane->_control.ReadOnly())
if (const auto& termControl{ pane->GetTerminalControl() })
{
pane->_control.RawWriteKeyEvent(vkey, scanCode, modifiers, keyDown);
if (termControl != sourceControl && !termControl.ReadOnly())
{
termControl.RawWriteKeyEvent(vkey, scanCode, modifiers, keyDown);
}
}
});
}
@@ -3218,9 +2993,12 @@ void Pane::BroadcastChar(const winrt::Microsoft::Terminal::Control::TermControl&
const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers)
{
WalkTree([&](const auto& pane) {
if (pane->_IsLeaf() && pane->_control != sourceControl && !pane->_control.ReadOnly())
if (const auto& termControl{ pane->GetTerminalControl() })
{
pane->_control.RawWriteChar(character, scanCode, modifiers);
if (termControl != sourceControl && !termControl.ReadOnly())
{
termControl.RawWriteChar(character, scanCode, modifiers);
}
}
});
}
@@ -3229,19 +3007,16 @@ void Pane::BroadcastString(const winrt::Microsoft::Terminal::Control::TermContro
const winrt::hstring& text)
{
WalkTree([&](const auto& pane) {
if (pane->_IsLeaf() && pane->_control != sourceControl && !pane->_control.ReadOnly())
if (const auto& termControl{ pane->GetTerminalControl() })
{
pane->_control.RawWriteString(text);
if (termControl != sourceControl && !termControl.ReadOnly())
{
termControl.RawWriteString(text);
}
}
});
}
void Pane::_ControlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*e*/)
{
UpdateVisuals();
}
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::_ComputeBorderColor()
{
if (_lastActive)
@@ -3249,7 +3024,7 @@ winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::_ComputeBorderColor()
return _themeResources.focusedBorderBrush;
}
if (_broadcastEnabled && (_IsLeaf() && !_control.ReadOnly()))
if (_broadcastEnabled && (_IsLeaf() && !_content.ReadOnly()))
{
return _themeResources.broadcastBorderBrush;
}

View File

@@ -21,6 +21,7 @@
#pragma once
#include "TaskbarState.h"
#include "TerminalPaneContent.h"
// fwdecl unittest classes
namespace TerminalAppLocalTests
@@ -61,8 +62,7 @@ struct PaneResources
class Pane : public std::enable_shared_from_this<Pane>
{
public:
Pane(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
const winrt::Microsoft::Terminal::Control::TermControl& control,
Pane(const winrt::TerminalApp::IPaneContent& content,
const bool lastFocused = false);
Pane(std::shared_ptr<Pane> first,
@@ -73,7 +73,8 @@ public:
std::shared_ptr<Pane> GetActivePane();
winrt::Microsoft::Terminal::Control::TermControl GetLastFocusedTerminalControl();
winrt::Microsoft::Terminal::Control::TermControl GetTerminalControl();
winrt::TerminalApp::IPaneContent GetLastFocusedContent();
winrt::Microsoft::Terminal::Control::TermControl GetTerminalControl() const;
winrt::Microsoft::Terminal::Settings::Model::Profile GetFocusedProfile();
bool IsConnectionClosed() const;
@@ -82,10 +83,15 @@ public:
// - If this is a branch/root pane, return nullptr.
winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const
{
return _profile;
if (const auto& c{ _content.try_as<winrt::TerminalApp::TerminalPaneContent>() })
{
return c.GetProfile();
}
return nullptr;
}
winrt::Windows::UI::Xaml::Controls::Grid GetRootElement();
winrt::TerminalApp::IPaneContent GetContent() const noexcept { return _IsLeaf() ? _content : nullptr; }
bool WasLastFocused() const noexcept;
void UpdateVisuals();
@@ -99,11 +105,10 @@ public:
std::optional<uint32_t> focusedPaneId;
uint32_t panesCreated;
};
BuildStartupState BuildStartupActions(uint32_t currentId, uint32_t nextId, const bool asContent = false, const bool asMovePane = false);
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetTerminalArgsForPane(const bool asContent = false) const;
BuildStartupState BuildStartupActions(uint32_t currentId, uint32_t nextId, winrt::TerminalApp::BuildStartupKind kind);
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetTerminalArgsForPane(winrt::TerminalApp::BuildStartupKind kind) const;
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const winrt::TerminalApp::TerminalSettingsCache& cache);
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
std::shared_ptr<Pane> NavigateDirection(const std::shared_ptr<Pane> sourcePane,
const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction,
@@ -210,16 +215,14 @@ public:
void CollectTaskbarStates(std::vector<winrt::TerminalApp::TaskbarState>& states);
WINRT_CALLBACK(ClosedByParent, winrt::delegate<>);
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
til::event<winrt::delegate<>> ClosedByParent;
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> Closed;
using gotFocusArgs = winrt::delegate<std::shared_ptr<Pane>, winrt::Windows::UI::Xaml::FocusState>;
WINRT_CALLBACK(GotFocus, gotFocusArgs);
WINRT_CALLBACK(LostFocus, winrt::delegate<std::shared_ptr<Pane>>);
WINRT_CALLBACK(PaneRaiseBell, winrt::Windows::Foundation::EventHandler<bool>);
WINRT_CALLBACK(Detached, winrt::delegate<std::shared_ptr<Pane>>);
WINRT_CALLBACK(RestartTerminalRequested, winrt::delegate<std::shared_ptr<Pane>>);
til::event<gotFocusArgs> GotFocus;
til::event<winrt::delegate<std::shared_ptr<Pane>>> LostFocus;
til::event<winrt::delegate<std::shared_ptr<Pane>>> Detached;
private:
struct PanePoint;
@@ -239,10 +242,8 @@ private:
std::shared_ptr<Pane> _secondChild{ nullptr };
SplitState _splitState{ SplitState::None };
float _desiredSplitPosition;
winrt::Microsoft::Terminal::Control::TermControl _control{ nullptr };
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState _connectionState{ winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::NotConnected };
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
bool _isDefTermSession{ false };
winrt::TerminalApp::IPaneContent _content{ nullptr };
#pragma endregion
std::optional<uint32_t> _id;
@@ -252,17 +253,6 @@ private:
winrt::event_token _firstClosedToken{ 0 };
winrt::event_token _secondClosedToken{ 0 };
struct ControlEventTokens
{
winrt::Microsoft::Terminal::Control::TermControl::ConnectionStateChanged_revoker _ConnectionStateChanged;
winrt::Microsoft::Terminal::Control::TermControl::WarningBell_revoker _WarningBell;
winrt::Microsoft::Terminal::Control::TermControl::CloseTerminalRequested_revoker _CloseTerminalRequested;
winrt::Microsoft::Terminal::Control::TermControl::RestartTerminalRequested_revoker _RestartTerminalRequested;
winrt::Microsoft::Terminal::Control::TermControl::ReadOnlyChanged_revoker _ReadOnlyChanged;
} _controlEvents;
void _setupControlEvents();
void _removeControlEvents();
winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;
winrt::Windows::UI::Xaml::UIElement::LostFocus_revoker _lostFocusRevoker;
@@ -271,13 +261,14 @@ private:
bool _zoomed{ false };
bool _broadcastEnabled{ false };
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
bool _bellPlayerCreated{ false };
bool _IsLeaf() const noexcept;
bool _HasFocusedChild() const noexcept;
void _SetupChildCloseHandlers();
bool _HasChild(const std::shared_ptr<Pane> child);
winrt::TerminalApp::TerminalPaneContent _getTerminalContent() const
{
return _IsLeaf() ? _content.try_as<winrt::TerminalApp::TerminalPaneContent>() : nullptr;
}
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> _Split(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
@@ -303,24 +294,16 @@ private:
const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction,
const PanePoint offset);
void _CloseChild(const bool closeFirst, const bool isDetaching);
void _CloseChild(const bool closeFirst);
void _CloseChildRoutine(const bool closeFirst);
void _Focus();
void _FocusFirstChild();
winrt::fire_and_forget _ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
void _ControlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& e);
void _ControlGotFocusHandler(const winrt::Windows::Foundation::IInspectable& sender,
void _ContentGotFocusHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
void _ControlLostFocusHandler(const winrt::Windows::Foundation::IInspectable& sender,
void _ContentLostFocusHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
void _ControlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& e);
void _CloseTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
void _RestartTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
std::pair<float, float> _CalcChildrenSizes(const float fullSize) const;
SnapChildrenSizeResult _CalcSnappedChildrenSizes(const bool widthOrHeight, const float fullSize) const;
SnapSizeResult _CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
@@ -331,8 +314,6 @@ private:
SplitState _convertAutomaticOrDirectionalSplitState(const winrt::Microsoft::Terminal::Settings::Model::SplitDirection& splitType) const;
winrt::fire_and_forget _playBellSound(winrt::Windows::Foundation::Uri uri);
// Function Description:
// - Returns true if the given direction can be used with the given split
// type.

View File

@@ -186,9 +186,6 @@
<data name="Quit" xml:space="preserve">
<value>Beenden</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Möchten Sie alle Registerkarten schließen?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Mehrere Bereiche</value>
</data>
@@ -335,6 +332,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>Mit dem angegebenen Profil öffnen. Akzeptiert entweder den Namen oder die GUID eines Profils</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>Legt die WT_SESSION-Variable fest; muss eine GUID sein.</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>Erstellen eines neuen geteilten Bereichs</value>
</data>
@@ -766,19 +766,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Das Beendigungsverhalten kann in den erweiterten Profileinstellungen konfiguriert werden.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Windows-Terminal kann in Ihren Einstellungen als standardmäßige Terminalanwendung festgelegt werden.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Nicht mehr anzeigen</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Dieses Terminalfenster wird als Administrator ausgeführt.</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Einstellungen öffnen</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Gefundene Vorschläge: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -187,9 +187,6 @@
<data name="Quit" xml:space="preserve">
<value>Quit</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Do you want to close all tabs?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Multiple panes</value>
</data>
@@ -340,6 +337,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>Open with the given profile. Accepts either the name or GUID of a profile</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>Sets the WT_SESSION variable; must be a GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>Create a new split pane</value>
</data>
@@ -771,19 +771,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Termination behavior can be configured in advanced profile settings.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Windows Terminal can be set as the default terminal application in your settings.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Don't show again</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>This Terminal window is running as Admin</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Open Settings</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Suggestions found: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>Salir</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>¿Quieres cerrar todas las pestañas?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Varios paneles</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>Abre con el perfil determinado. Acepta el nombre o el GUID de un perfil.</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>Establece la variable WT_SESSION; debe ser un GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>Crear un nuevo panel de división</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>El comportamiento de finalización se puede configurar en la configuración avanzada del perfil.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Terminal Windows se puede establecer como la aplicación de terminal predeterminada en la configuración.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>No volver a mostrar</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Esta ventana de terminal se está ejecutando como administrador</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Abrir Configuración</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Sugerencias encontradas: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>Quitter</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Voulez-vous fermer tous les onglets ?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Volets multiples</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>Ouvrez avec le profil donné. Accepte le nom ou le GUID dun profil</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>Définit la variable WT_SESSION ; doit être un GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>Créer un volet de fractionnement</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Le comportement darrêt peut être configuré dans les paramètres de profil avancés.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Terminal Windows peut être défini comme application de terminal par défaut dans vos paramètres.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Ne plus afficher</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Cette fenêtre de terminal sexécute en tant quAdministrateur</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Ouvrir les paramètres</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>{0} suggestions trouvées</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>Esci</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Vuoi chiudere tutte le schede?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Più riquadri</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>Apri con il profilo specificato. Accetta il nome oppure il GUID di un profilo</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>Imposta la variabile di WT_SESSION; deve essere un GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>Crea un nuovo riquadro suddiviso</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>È possibile configurare il comportamento di terminazione nelle impostazioni avanzate del profilo.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Terminale Windows può essere impostato come applicazione terminale predefinita nelle impostazioni.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Non mostrare più questo messaggio</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Questa finestra del terminale è in esecuzione come amministratore</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Apri Impostazioni</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Suggerimenti trovati: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -184,9 +184,6 @@
<data name="Quit" xml:space="preserve">
<value>終了</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>すべてのタブを閉じますか?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>複数ウィンドウ</value>
</data>
@@ -333,6 +330,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>指定されたプロファイルで開きます。プロファイルの名前または GUID を指定できます</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>WT_SESSION 変数を設定します; GUID である必要があります</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>新しい分割ウィンドウの作成</value>
</data>
@@ -764,19 +764,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>終了動作は、プロファイルの詳細設定で構成できます。</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Windows ターミナルは、設定で既定のターミナル アプリケーションとして設定できます。</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>今後表示しない</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>このターミナル ウィンドウは管理者として実行されています</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>設定を開く</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>候補が見つかりました: {0} 件</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>끝내기</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>모든 탭을 닫으시겠습니까?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>여러 창</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>지정된 프로필로 엽니다. 프로필 이름 또는 GUID 허용</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>WT_SESSION 변수를 설정합니다. GUID여야 합니다.</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>새 분할 창 만들기</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>고급 프로필 설정에서 종료 동작을 구성할 수 있습니다.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Windows 터미널 설정에서 기본 터미널 응용 프로그램으로 설정할 수 있습니다.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>다시 표시 안 함</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>이 터미널 창이 관리자 권한으로 실행되고 있습니다.</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>설정 열기</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>찾은 제안: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>Encerrar</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Deseja fechar todas as guias?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Vários painéis</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>Abrir com o perfil determinado. Aceite o nome ou o GUID de um perfil</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>Define a variável WT_SESSION; deve ser um GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>Criar um novo painel dividido</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>O comportamento de término pode ser configurado nas configurações avançadas do perfil.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Terminal do Windows pode ser definido como o aplicativo de terminal padrão em suas configurações.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Não mostra de novo</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Esta janela do Terminal está funcionando como Administrador</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Abrir Configurações</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Sugestões encontradas: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Τнĕ Ņëω Ẅίηđŏẃś Ťėŗmįйάĺ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Ŵíňďōẁŝ Тєřмīπǻļ ωїτĥ å ρѓēνіéŵ θƒ ũφсőмϊπġ ƒєąτΰґёѕ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Ŏрέи ìη Тèřmīŋªŀ (&amp;Cãńãґγ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Φφєň ΐñ Ŧéгмϊñаľ &amp;Pŕėνĭώ !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ωρєⁿ ïπ &amp;Těѓmĭñäĺ !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Ťĥё Ñēщ Шίⁿðоẅś Ťėгмîήāľ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Шίηđóŵš Ŧĕяmїйà ẁітħ ª φяęνîёщ όƒ ûφĉбмíήĝ ƒêåťµřεŝ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Óрëπ íи Ťēяmілǻŀ (&amp;Cäηàřÿ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Óрзń ΐή Ŧěґмιлāℓ &amp;Pѓéνīĕω !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ôрëη ïп &amp;Tēѓмϊŋãł !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Тĥё Ńēẁ Шіπđοωš Тěřмιňαŀ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Шίήďŏшś Ŧêямĩňāľ ŵíτн ă ρѓëνιêω øƒ ũρčŏмįηğ ƒєáţũŗêš !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Фφěй ĩń Тêřmιπâł (&amp;Cãⁿǻřу) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Óφ℮ʼn ΐŋ Τėřmīйäĺ &amp;Pяєνϊëẃ !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ορέл ϊŋ &amp;Téŕmįñā !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>Выход</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Закрыть все вкладки?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Несколько областей</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>Открыть с помощью данного профиля. Принимается имя или GUID профиля</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>Задает переменную WT_SESSION; должно быть GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>Создать новую область разделения</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Поведение завершения можно настроить в дополнительных параметрах профиля.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Терминал Windows можно настроить в параметрах как приложение терминала по умолчанию.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Больше не показывать</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Это окно терминала запущено от имени администратора</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Открыть параметры</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Найдено рекомендаций: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>退出</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>是否要关闭所有标签页?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>多个窗格</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>使用给定的配置文件打开。接受配置文件的名称或 GUID</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>设置 WT_SESSION 变量;必须是 GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>创建新的拆分窗格</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>可以在高级配置文件设置中配置终止行为。</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Windows 终端可在设置中设置为默认终端应用程序。</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>不再显示</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>此终端窗口正在以管理员身份运行</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>打开设置</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>找到的建议: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -183,9 +183,6 @@
<data name="Quit" xml:space="preserve">
<value>結束</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>您要關閉所有索引標籤嗎?</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>多個窗格</value>
</data>
@@ -332,6 +329,9 @@
<data name="CmdProfileArgDesc" xml:space="preserve">
<value>使用指定的設定檔開啟。接受設定檔的名稱或 GUID</value>
</data>
<data name="CmdSessionIdArgDesc" xml:space="preserve">
<value>設定 WT_SESSION 變數; 必須為 GUID</value>
</data>
<data name="CmdSplitPaneDesc" xml:space="preserve">
<value>建立新的分割窗格</value>
</data>
@@ -763,19 +763,12 @@
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>您可以在進階設定檔設定中設定終止行為。</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Windows 終端機可在您的設定中設定為預設終端機應用程式。</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>不要再顯示</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>此終端機視窗目前以系統管理員身分執行</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>開啟設定</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>找到的建議: {0}</value>
<comment>{0} will be replaced with a number.</comment>

View File

@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ScratchpadContent.h"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Microsoft::Terminal::Settings::Model;
namespace winrt::TerminalApp::implementation
{
ScratchpadContent::ScratchpadContent()
{
_root = winrt::Windows::UI::Xaml::Controls::Grid{};
// Vertical and HorizontalAlignment are Stretch by default
auto res = Windows::UI::Xaml::Application::Current().Resources();
auto bg = res.Lookup(winrt::box_value(L"UnfocusedBorderBrush"));
_root.Background(bg.try_as<Media::Brush>());
_box = winrt::Windows::UI::Xaml::Controls::TextBox{};
_box.Margin({ 10, 10, 10, 10 });
_box.AcceptsReturn(true);
_box.TextWrapping(TextWrapping::Wrap);
_root.Children().Append(_box);
}
void ScratchpadContent::UpdateSettings(const CascadiaSettings& /*settings*/)
{
// Nothing to do.
}
winrt::Windows::UI::Xaml::FrameworkElement ScratchpadContent::GetRoot()
{
return _root;
}
winrt::Windows::Foundation::Size ScratchpadContent::MinimumSize()
{
return { 1, 1 };
}
void ScratchpadContent::Focus(winrt::Windows::UI::Xaml::FocusState reason)
{
_box.Focus(reason);
}
void ScratchpadContent::Close()
{
CloseRequested.raise(*this, nullptr);
}
NewTerminalArgs ScratchpadContent::GetNewTerminalArgs(const BuildStartupKind /* kind */) const
{
return nullptr;
}
winrt::hstring ScratchpadContent::Icon() const
{
static constexpr std::wstring_view glyph{ L"\xe70b" }; // QuickNote
return winrt::hstring{ glyph };
}
winrt::Windows::UI::Xaml::Media::Brush ScratchpadContent::BackgroundBrush()
{
return _root.Background();
}
}

View File

@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "winrt/TerminalApp.h"
namespace winrt::TerminalApp::implementation
{
class ScratchpadContent : public winrt::implements<ScratchpadContent, IPaneContent>
{
public:
ScratchpadContent();
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
winrt::Windows::Foundation::Size MinimumSize();
void Focus(winrt::Windows::UI::Xaml::FocusState reason = winrt::Windows::UI::Xaml::FocusState::Programmatic);
void Close();
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetNewTerminalArgs(BuildStartupKind kind) const;
winrt::hstring Title() { return L"Scratchpad"; }
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();
til::typed_event<> ConnectionStateChanged;
til::typed_event<IPaneContent> CloseRequested;
til::typed_event<IPaneContent, winrt::TerminalApp::BellEventArgs> BellRequested;
til::typed_event<IPaneContent> TitleChanged;
til::typed_event<IPaneContent> TabColorChanged;
til::typed_event<IPaneContent> TaskbarProgressChanged;
til::typed_event<IPaneContent> ReadOnlyChanged;
til::typed_event<IPaneContent> FocusRequested;
private:
winrt::Windows::UI::Xaml::Controls::Grid _root{ nullptr };
winrt::Windows::UI::Xaml::Controls::TextBox _box{ nullptr };
};
}

View File

@@ -0,0 +1,84 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "SettingsPaneContent.h"
#include "Utils.h"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Microsoft::Terminal::Settings::Model;
#define ASSERT_UI_THREAD() assert(_sui.Dispatcher().HasThreadAccess())
namespace winrt::TerminalApp::implementation
{
SettingsPaneContent::SettingsPaneContent(CascadiaSettings settings)
{
_sui = winrt::Microsoft::Terminal::Settings::Editor::MainPage{ settings };
// Stash away the current requested theme of the app. We'll need that in
// _BackgroundBrush() to do a theme-aware resource lookup
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
}
void SettingsPaneContent::UpdateSettings(const CascadiaSettings& settings)
{
ASSERT_UI_THREAD();
_sui.UpdateSettings(settings);
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
}
winrt::Windows::UI::Xaml::FrameworkElement SettingsPaneContent::GetRoot()
{
return _sui;
}
winrt::Windows::Foundation::Size SettingsPaneContent::MinimumSize()
{
return { 1, 1 };
}
void SettingsPaneContent::Focus(winrt::Windows::UI::Xaml::FocusState reason)
{
if (reason != FocusState::Unfocused)
{
_sui.as<Controls::Page>().Focus(reason);
}
}
void SettingsPaneContent::Close()
{
CloseRequested.raise(*this, nullptr);
}
NewTerminalArgs SettingsPaneContent::GetNewTerminalArgs(const BuildStartupKind /*kind*/) const
{
// For now, we're doing a terrible thing in TerminalTab itself to
// generate an OpenSettings action manually, without asking for the pane
// structure.
return nullptr;
}
winrt::hstring SettingsPaneContent::Icon() const
{
// This is the Setting icon (looks like a gear)
static constexpr std::wstring_view glyph{ L"\xE713" };
return winrt::hstring{ glyph };
}
Windows::Foundation::IReference<winrt::Windows::UI::Color> SettingsPaneContent::TabColor() const noexcept
{
return nullptr;
}
winrt::Windows::UI::Xaml::Media::Brush SettingsPaneContent::BackgroundBrush()
{
// Look up the color we should use for the settings tab item from our
// resources. This should only be used for when "terminalBackground" is
// requested.
static const auto key = winrt::box_value(L"SettingsUiTabBrush");
// You can't just do a Application::Current().Resources().TryLookup
// lookup, cause the app theme never changes! Do the hacky version
// instead.
return ThemeLookup(Application::Current().Resources(), _requestedTheme, key).try_as<winrt::Windows::UI::Xaml::Media::Brush>();
}
}

View File

@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "winrt/TerminalApp.h"
#include <LibraryResources.h>
namespace winrt::TerminalApp::implementation
{
class SettingsPaneContent : public winrt::implements<SettingsPaneContent, IPaneContent>
{
public:
SettingsPaneContent(winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings settings);
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
winrt::Microsoft::Terminal::Settings::Editor::MainPage SettingsUI() { return _sui; }
winrt::Windows::Foundation::Size MinimumSize();
void Focus(winrt::Windows::UI::Xaml::FocusState reason = winrt::Windows::UI::Xaml::FocusState::Programmatic);
void Close();
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetNewTerminalArgs(const BuildStartupKind kind) const;
winrt::hstring Title() { return RS_(L"SettingsTab"); }
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;
winrt::Windows::UI::Xaml::Media::Brush BackgroundBrush();
til::typed_event<> ConnectionStateChanged;
til::typed_event<IPaneContent> CloseRequested;
til::typed_event<IPaneContent, winrt::TerminalApp::BellEventArgs> BellRequested;
til::typed_event<IPaneContent> TitleChanged;
til::typed_event<IPaneContent> TabColorChanged;
til::typed_event<IPaneContent> TaskbarProgressChanged;
til::typed_event<IPaneContent> ReadOnlyChanged;
til::typed_event<IPaneContent> FocusRequested;
private:
winrt::Microsoft::Terminal::Settings::Editor::MainPage _sui{ nullptr };
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;
};
}

View File

@@ -1,131 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include <LibraryResources.h>
#include "SettingsTab.h"
#include "SettingsTab.g.cpp"
#include "Utils.h"
using namespace winrt;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Microsoft::Terminal::Control;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Settings::Editor;
using namespace winrt::Windows::System;
namespace winrt
{
namespace MUX = Microsoft::UI::Xaml;
namespace WUX = Windows::UI::Xaml;
}
#define ASSERT_UI_THREAD() assert(TabViewItem().Dispatcher().HasThreadAccess())
namespace winrt::TerminalApp::implementation
{
SettingsTab::SettingsTab(MainPage settingsUI,
winrt::Windows::UI::Xaml::ElementTheme requestedTheme)
{
Content(settingsUI);
_requestedTheme = requestedTheme;
_MakeTabViewItem();
_CreateContextMenu();
_CreateIcon();
}
void SettingsTab::UpdateSettings(CascadiaSettings settings)
{
ASSERT_UI_THREAD();
auto settingsUI{ Content().as<MainPage>() };
settingsUI.UpdateSettings(settings);
// Stash away the current requested theme of the app. We'll need that in
// _BackgroundBrush() to do a theme-aware resource lookup
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
}
// Method Description:
// - Creates a list of actions that can be run to recreate the state of this tab
// Arguments:
// - asContent: unused. There's nothing different we need to do when
// serializing the settings tab for moving to another window. If we ever
// really want to support opening the SUI to a specific page, we can
// re-evaluate including that arg in this action then.
// Return Value:
// - The list of actions.
std::vector<ActionAndArgs> SettingsTab::BuildStartupActions(const bool /*asContent*/) const
{
ASSERT_UI_THREAD();
ActionAndArgs action;
action.Action(ShortcutAction::OpenSettings);
OpenSettingsArgs args{ SettingsTarget::SettingsUI };
action.Args(args);
return std::vector{ std::move(action) };
}
// Method Description:
// - Focus the settings UI
// Arguments:
// - focusState: The FocusState mode by which focus is to be obtained.
// Return Value:
// - <none>
void SettingsTab::Focus(WUX::FocusState focusState)
{
ASSERT_UI_THREAD();
_focusState = focusState;
if (_focusState != FocusState::Unfocused)
{
Content().as<WUX::Controls::Page>().Focus(focusState);
}
}
// Method Description:
// - Initializes a TabViewItem for this Tab instance.
// Arguments:
// - <none>
// Return Value:
// - <none>
void SettingsTab::_MakeTabViewItem()
{
TabBase::_MakeTabViewItem();
Title(RS_(L"SettingsTab"));
TabViewItem().Header(winrt::box_value(Title()));
}
// Method Description:
// - Set the icon on the TabViewItem for this tab.
// Arguments:
// - <none>
// Return Value:
// - <none>
void SettingsTab::_CreateIcon()
{
// This is the Setting icon (looks like a gear)
static constexpr std::wstring_view glyph{ L"\xE713" };
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
Icon(winrt::hstring{ glyph });
TabViewItem().IconSource(Microsoft::Terminal::UI::IconPathConverter::IconSourceMUX(glyph, false));
}
winrt::Windows::UI::Xaml::Media::Brush SettingsTab::_BackgroundBrush()
{
// Look up the color we should use for the settings tab item from our
// resources. This should only be used for when "terminalBackground" is
// requested.
static const auto key = winrt::box_value(L"SettingsUiTabBrush");
// You can't just do a Application::Current().Resources().TryLookup
// lookup, cause the app theme never changes! Do the hacky version
// instead.
return ThemeLookup(Application::Current().Resources(), _requestedTheme, key).try_as<winrt::Windows::UI::Xaml::Media::Brush>();
}
}

View File

@@ -1,43 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- SettingsTab.h
Abstract:
- The SettingsTab is a tab whose content is a Settings UI control. They can
coexist in a TabView with all other types of tabs, like the TerminalTab.
There should only be at most one SettingsTab open at any given time.
Author(s):
- Leon Liang - October 2020
--*/
#pragma once
#include "TabBase.h"
#include "SettingsTab.g.h"
namespace winrt::TerminalApp::implementation
{
struct SettingsTab : SettingsTabT<SettingsTab, TabBase>
{
public:
SettingsTab(winrt::Microsoft::Terminal::Settings::Editor::MainPage settingsUI,
winrt::Windows::UI::Xaml::ElementTheme requestedTheme);
void UpdateSettings(Microsoft::Terminal::Settings::Model::CascadiaSettings settings);
void Focus(winrt::Windows::UI::Xaml::FocusState focusState) override;
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(const bool asContent = false) const override;
private:
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;
void _MakeTabViewItem() override;
void _CreateIcon();
virtual winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush() override;
};
}

View File

@@ -1,12 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "TabBase.idl";
namespace TerminalApp
{
[default_interface] runtimeclass SettingsTab : TabBase
{
void UpdateSettings(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);
}
}

View File

@@ -268,7 +268,7 @@ namespace winrt::TerminalApp::implementation
const auto selectedCommand = _filteredActionsView().SelectedItem();
const auto filteredCommand{ selectedCommand.try_as<winrt::TerminalApp::FilteredCommand>() };
_PropertyChangedHandlers(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"SelectedItem" });
PropertyChanged.raise(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"SelectedItem" });
// Make sure to not send the preview if we're collapsed. This can
// sometimes fire after we've been closed, which can trigger us to

View File

@@ -50,12 +50,12 @@ namespace winrt::TerminalApp::implementation
til::typed_event<winrt::TerminalApp::SuggestionsControl, Microsoft::Terminal::Settings::Model::Command> DispatchCommandRequested;
til::typed_event<Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command> PreviewAction;
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, SearchBoxPlaceholderText, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ControlName, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParentCommandName, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParsedCommandLineText, _PropertyChangedHandlers);
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, NoMatchesText, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, SearchBoxPlaceholderText, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ControlName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParentCommandName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, ParsedCommandLineText, PropertyChanged.raise);
private:
struct winrt_object_hash

View File

@@ -53,7 +53,7 @@ namespace winrt::TerminalApp::implementation
contextMenuFlyout.Closed([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
tab->_RequestFocusActiveControlHandlers();
tab->RequestFocusActiveControl.raise();
}
});
_AppendCloseMenuItems(contextMenuFlyout);
@@ -106,7 +106,7 @@ namespace winrt::TerminalApp::implementation
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
tab->_CloseRequestedHandlers(nullptr, nullptr);
tab->CloseRequested.raise(nullptr, nullptr);
}
});
closeTabMenuItem.Text(RS_(L"TabClose"));
@@ -260,7 +260,7 @@ namespace winrt::TerminalApp::implementation
TabViewItem().Tapped([weakThis{ get_weak() }](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
tab->_RequestFocusActiveControlHandlers();
tab->RequestFocusActiveControl.raise();
}
});

View File

@@ -22,7 +22,7 @@ namespace winrt::TerminalApp::implementation
void UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs);
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
virtual std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(const bool asContent = false) const = 0;
virtual std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const = 0;
virtual std::optional<winrt::Windows::UI::Color> GetTabColor();
void ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,
@@ -32,23 +32,23 @@ namespace winrt::TerminalApp::implementation
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility CloseButtonVisibility();
void CloseButtonVisibility(Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility visible);
WINRT_CALLBACK(RequestFocusActiveControl, winrt::delegate<void()>);
til::event<winrt::delegate<void()>> RequestFocusActiveControl;
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
WINRT_CALLBACK(CloseRequested, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> Closed;
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> CloseRequested;
til::property_changed_event PropertyChanged;
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
WINRT_PROPERTY(uint32_t, TabViewIndex, 0);
// The TabViewNumTabs is the number of Tab objects in TerminalPage's _tabs vector.
WINRT_PROPERTY(uint32_t, TabViewNumTabs, 0);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(bool, ReadOnly, _PropertyChangedHandlers, false);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, ReadOnly, PropertyChanged.raise, false);
WINRT_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewItem, TabViewItem, nullptr);
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::FrameworkElement, Content, _PropertyChangedHandlers, nullptr);
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::FrameworkElement, Content, PropertyChanged.raise, nullptr);
protected:
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };

View File

@@ -120,7 +120,7 @@ namespace winrt::TerminalApp::implementation
_CloseRenameBox();
if (!_renameCancelled)
{
_TitleChangeRequestedHandlers(HeaderRenamerTextBox().Text());
TitleChangeRequested.raise(HeaderRenamerTextBox().Text());
}
}
@@ -132,7 +132,7 @@ namespace winrt::TerminalApp::implementation
{
HeaderRenamerTextBox().Visibility(Windows::UI::Xaml::Visibility::Collapsed);
HeaderTextBlock().Visibility(Windows::UI::Xaml::Visibility::Visible);
_RenameEndedHandlers(*this, nullptr);
RenameEnded.raise(*this, nullptr);
}
}
}

View File

@@ -19,14 +19,13 @@ namespace winrt::TerminalApp::implementation
bool InRename();
WINRT_CALLBACK(TitleChangeRequested, TerminalApp::TitleChangeRequestedArgs);
til::event<TerminalApp::TitleChangeRequestedArgs> TitleChangeRequested;
til::typed_event<> RenameEnded;
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(double, RenamerMaxWidth, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::TerminalTabStatus, TabStatus, _PropertyChangedHandlers);
TYPED_EVENT(RenameEnded, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(double, RenamerMaxWidth, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::TerminalTabStatus, TabStatus, PropertyChanged.raise);
private:
bool _receivedKeyDown{ false };

View File

@@ -19,7 +19,6 @@
#include "TabRowControl.h"
#include "ColorHelper.h"
#include "DebugTapConnection.h"
#include "SettingsTab.h"
#include "..\TerminalSettingsModel\FileUtils.h"
#include <shlobj.h>
@@ -63,7 +62,7 @@ namespace winrt::TerminalApp::implementation
// - existingConnection: An optional connection that is already established to a PTY
// for this tab to host instead of creating one.
// If not defined, the tab will create the connection.
HRESULT TerminalPage::_OpenNewTab(const NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection)
HRESULT TerminalPage::_OpenNewTab(const NewTerminalArgs& newTerminalArgs)
try
{
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
@@ -86,7 +85,7 @@ namespace winrt::TerminalApp::implementation
//
// This call to _MakePane won't return nullptr, we already checked that
// case above with the _maybeElevate call.
_CreateNewTabFromPane(_MakePane(newTerminalArgs, nullptr, existingConnection));
_CreateNewTabFromPane(_MakePane(newTerminalArgs, nullptr));
return S_OK;
}
CATCH_RETURN();
@@ -135,6 +134,16 @@ namespace winrt::TerminalApp::implementation
// for it. The Title change will be propagated upwards through the tab's
// PropertyChanged event handler.
newTabImpl->ActivePaneChanged([weakTab, weakThis{ get_weak() }]() {
// TODO!
//
// * Make this a method on TerminalPage.
// * Convert ActivePaneChanged to a typed event, so it sends the sender (so we don't need to make all these lambdas)
// * Stash the task pane as a member on the Terminal? if one was opened.
// * If the tab does have a taskpane, then tell the taskpane the active pane changed
//
// wait don't do any of that. just do that in TerminalTab directly
// before we even raise the event you donkey
auto page{ weakThis.get() };
auto tab{ weakTab.get() };
@@ -148,7 +157,7 @@ namespace winrt::TerminalApp::implementation
// Update the taskbar progress as well. We'll raise our own
// SetTaskbarProgress event here, to get tell the hosting
// application to re-query this value from us.
page->_SetTaskbarProgressHandlers(*page, nullptr);
page->SetTaskbarProgress.raise(*page, nullptr);
auto profile = tab->GetFocusedProfile();
page->_UpdateBackground(profile);
@@ -164,24 +173,15 @@ namespace winrt::TerminalApp::implementation
if (page && tab)
{
page->_RaiseVisualBellHandlers(nullptr, nullptr);
page->RaiseVisualBell.raise(nullptr, nullptr);
}
});
auto tabViewItem = newTabImpl->TabViewItem();
_tabView.TabItems().InsertAt(insertPosition, tabViewItem);
// Set this tab's icon to the icon from the user's profile
if (const auto profile{ newTabImpl->GetFocusedProfile() })
{
const auto& icon = profile.EvaluatedIcon();
if (!icon.empty())
{
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default;
newTabImpl->UpdateIcon(icon, iconStyle);
}
}
// Set this tab's icon to the icon from the content
_UpdateTabIcon(*newTabImpl);
tabViewItem.PointerReleased({ this, &TerminalPage::_OnTabClick });
@@ -226,13 +226,15 @@ namespace winrt::TerminalApp::implementation
// Arguments:
// - pane: The pane to use as the root.
// - insertPosition: Optional parameter to indicate the position of tab.
void TerminalPage::_CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition)
TerminalApp::TerminalTab TerminalPage::_CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition)
{
if (pane)
{
auto newTabImpl = winrt::make_self<TerminalTab>(pane);
_InitializeTab(newTabImpl, insertPosition);
return *newTabImpl;
}
return nullptr;
}
// Method Description:
@@ -242,11 +244,13 @@ namespace winrt::TerminalApp::implementation
// - tab: the Tab to update the title for.
void TerminalPage::_UpdateTabIcon(TerminalTab& tab)
{
if (const auto profile = tab.GetFocusedProfile())
if (const auto content{ tab.GetActiveContent() })
{
const auto& icon{ content.Icon() };
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default;
tab.UpdateIcon(profile.EvaluatedIcon(), iconStyle);
tab.UpdateIcon(icon, iconStyle);
}
}
@@ -429,7 +433,7 @@ namespace winrt::TerminalApp::implementation
}
auto t = winrt::get_self<implementation::TabBase>(tab);
auto actions = t->BuildStartupActions();
auto actions = t->BuildStartupActions(BuildStartupKind::None);
_AddPreviouslyClosedPaneOrTab(std::move(actions));
_RemoveTab(tab);
@@ -486,7 +490,7 @@ namespace winrt::TerminalApp::implementation
// if the user manually closed all tabs.
// Do this only if we are the last window; the monarch will notice
// we are missing and remove us that way otherwise.
_LastTabClosedHandlers(*this, winrt::make<LastTabClosedEventArgs>(!_maintainStateOnTabClose));
CloseWindowRequested.raise(*this, nullptr);
}
else if (focusedTabIndex.has_value() && focusedTabIndex.value() == gsl::narrow_cast<uint32_t>(tabIndex))
{
@@ -767,11 +771,11 @@ namespace winrt::TerminalApp::implementation
// This doesn't handle refocusing anything in particular, the
// result will be that the last pane created is focused. In the
// case of a single pane that is the desired behavior anyways.
auto state = pane->BuildStartupActions(0, 1);
auto state = pane->BuildStartupActions(0, 1, BuildStartupKind::None);
{
ActionAndArgs splitPaneAction{};
splitPaneAction.Action(ShortcutAction::SplitPane);
SplitPaneArgs splitPaneArgs{ SplitDirection::Automatic, state.firstPane->GetTerminalArgsForPane() };
SplitPaneArgs splitPaneArgs{ SplitDirection::Automatic, state.firstPane->GetTerminalArgsForPane(BuildStartupKind::None) };
splitPaneAction.Args(splitPaneArgs);
state.args.emplace(state.args.begin(), std::move(splitPaneAction));
@@ -800,14 +804,6 @@ namespace winrt::TerminalApp::implementation
}
}
}
else if (auto index{ _GetFocusedTabIndex() })
{
const auto tab{ _tabs.GetAt(*index) };
if (tab.try_as<TerminalApp::SettingsTab>())
{
_HandleCloseTabRequested(tab);
}
}
}
// Method Description:
@@ -954,7 +950,7 @@ namespace winrt::TerminalApp::implementation
// Raise an event that our title changed
if (_settings.GlobalSettings().ShowTitleInTitlebar())
{
_TitleChangedHandlers(*this, tab.Title());
TitleChanged.raise(*this, tab.Title());
}
_updateThemeColors();
@@ -1139,12 +1135,4 @@ namespace winrt::TerminalApp::implementation
{
return _tabs.Size() > 1;
}
void TerminalPage::_RemoveAllTabs()
{
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
std::copy(begin(_tabs), end(_tabs), std::back_inserter(tabsToRemove));
_RemoveTabs(tabsToRemove);
}
}

View File

@@ -52,7 +52,7 @@ namespace winrt::TerminalApp::implementation
// Sometimes nested bindings do not get updated,
// thus let's notify property changed on TabStatus when one of its properties changes
auto item{ weakThis.get() };
item->_PropertyChangedHandlers(*item, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"TabStatus" });
item->PropertyChanged.raise(*item, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"TabStatus" });
});
}
}

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