Compare commits

...

38 Commits

Author SHA1 Message Date
Dustin L. Howett
5fdd1560fd [1.5 ONLY] Remove the close submenu (#9102)
There's a platform issue that causes it to crash.
Fixes #8944.
2021-02-10 11:28:22 -08:00
Sarim Khan
3b876cc0b5 fix tab title propagation issues (#9054)
- Fixes empty app title when  `showTerminalTitleInTitlebar` is false
- Fixes Tab title propagation to Window title when
  `showTerminalTitleInTitlebar` is false
- Fixes Tab title propagation to Window - title doesn't update when
  Window is unfocused

1. There were a missing
   `_settings.GlobalSettings().ShowTitleInTitlebar()` check. Because of
   this Title update event was being fired even when
   `showTerminalTitleInTitlebar` is false. This results in empty tab
   title to propagate to Window title. Also then after switching tabs
   back and forth, tab title propagates to window title. These shouldn't
   propagate when `showTerminalTitleInTitlebar` is false. I added the
   `showTerminalTitleInTitlebar` check in relevant logic to fix the
   behavior.

2. Code was checking `tab.FocusState() != FocusState::Unfocused` , but
   when the whole terminal window is not in focus, the active tab is
   also in Unfocused state. This was preventing tab title to propagate
   to window title when application is unfocused. I added the logic of
   checking matching selected tabs' index. This fixes the issue.

## Validation Steps Performed
I did the reproduce steps descripted in the issue to reproduce the bugs.
After applying the fixes, the bugs don't appear anymore while doing the
reproduce steps.

Closes #8704

(cherry picked from commit 47881a802f)
2021-02-09 11:45:12 -08:00
Dustin L. Howett
970d441a52 Update Cascadia Code to 2102.03 (#9088)
The February 2021 update of Cascadia Code fixes 23 issues and
introduces support for infinite arrow ligatures and control pictures.

(cherry picked from commit 6af49a5246)
2021-02-09 11:44:27 -08:00
Carlos Zamora
d86f5c1f74 Generate settings.json if deleted while WT is open (#9012)
The settings.json was not regenerated if WT was already open. This resulted in the `ShellExecute` from trying to open the settings to pop up Notepad and say that this file didn't exist. We now detect if the settings.json was deleted to kick off loading the settings.

Closes #8955

(cherry picked from commit a5931fbead)
2021-02-04 16:45:28 -08:00
Mike Griese
84a5b668c1 Manually initialize the warnings vector to prevent a crash on launch (#8995)
## Summary of the Pull Request

Oops, winrt `IVector`s need to be manually initialized, when default-constructed `std::vector`s didn't. Simple oversight.

## PR Checklist
* [x] Closes #8986
* [x] I work here
* [x] A test would be great but ain't nobody got time for that.
* [n/a] Requires documentation to be updated

## Validation Steps Performed
Ran the terminal with
```json

    "schemes" :
    [ {} ]
```
First the crash repro'd, now it doesn't.

(cherry picked from commit 9d71fa817d)
2021-02-04 16:45:28 -08:00
James Holderness
ee83677122 Fix crash in terminal when tab closed while data is being output (#8982)
If there is data being output when a tab is closed, that can sometimes
result in the application crashing, because the renderer may still be in
use at the time is it destroyed. This PR attempts to prevent that from
happening by adding a lock in the `TermControl::Close` method.

What we're trying to prevent is the connection thread still being
active, and potentially accessing the renderer, after it has been
destroyed. So by acquiring the terminal lock in `TermControl::Close`,
after we've stopped accepting new output, we can be sure that the
connection thread is no longer active (it holds the lock while it is
processing output). So once we've acquired and released the lock, it
should be safe to tear down and destroy the renderer.

## Validation Steps Performed

While this crash is difficult to reproduce in general usage, it occurred
quite frequently when testing my `DECPS` implementation (there is some
tricky thread synchronisation, which seems more likely to trigger the
issue). With this patch applied, though, those crashes have stopped
occurring.

I've also stepped through the shutdown code in the debugger, manually
freezing threads to get them aligned in the right way to trigger the
crash (as explained in issue #8734). Again with the patch applied, I can
no longer get the crash to occur.

Closes #8734

(cherry picked from commit 40ebe5ab54)
2021-02-04 16:45:28 -08:00
hereafter
2594edcec0 Fix crash in explorer background context menu logic (#8977)
Fix a bug brought in with PR: #8638

see,
#8936
#8638

* [x] Closes #8936
* [x] CLA signed
* [x] Tests passed

With the help from @nc-x, the issue is reproduced and fixed by this patch.

CLSCTX_IN_PROCESS is not good enough for all cases to create IShellWindows interface.
Put a CLSCTX_ALL fixes the issue.

Another debugging warning dialogs  for reusing not null com_ptr in the loop is fixed too.
(This was shown in debug builds only)

(cherry picked from commit e207236713)
2021-02-04 16:45:28 -08:00
Javier
b092bdd42c wpf: Add a TerminalControlSize emptiness check (#8906)
Watson reports show that an "ArgumentException" is being thrown due to `renderSize`
not being valid. Added a check for renderSize before attempting to resize.

(cherry picked from commit 96e0232603)
2021-01-27 11:07:57 -08:00
Michael Niksa
2568a7cef2 Cleanup NuGet.Config file. (#8829)
Cleans up a ton of competing and outdated sources from our NuGet.Config to improve reliability and maintainability.

## PR Checklist
* [x] Closes an overdue-to-clean mess.
* [x] I work here.
* [x] Tests covered below.
* [x] I've discussed this with @DHowett already.

## Validation Steps Performed
- [x] - NuGet restored everything I could get my hands on (all `packages.config`) in our project before and after the change.
- [x] - The build and tests still run fine. (PR automation should check this one)

(cherry picked from commit 0fa286c011)
2021-01-25 12:54:14 -08:00
Don-Vito
bda1494394 Fix tab selection to bring the tab into view (#8832)
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/3638
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already.

##Detailed Description of the Pull Request / Additional comments
A workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/3945.
Thanks to @michael-hawker and @chingucoding for the suggested solution.

(cherry picked from commit 12b12d5b07)
2021-01-25 12:54:14 -08:00
Javier
118195a970 Added negative value check for resize newsize (#8792)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Adds a negative value check for when the terminal window is hidden/show in VS

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
[Bug 1265984](https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1265984): [Terminal] VS crashes when clicking the hidden terminal tab

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes #xxx
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] 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.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Manual validation.

(cherry picked from commit 9aea904229)
2021-01-25 12:54:08 -08:00
Don-Vito
fd2b3f7632 Fix right-click paste to clear current selection (#8742)
Closes #8729

(cherry picked from commit 20fc57ee0f)
2021-01-25 12:54:08 -08:00
Don-Vito
2692874c71 Teach flyouts and palette to prefer user bindings over defaults (#8725)
Store the order of the bindings and upon lookup prefer the binding
that was added last.
The defaults will always "loose" to user overrides.

Closes #2991

(cherry picked from commit 058cbd11e7)
2021-01-25 12:54:07 -08:00
PankajBhojwani
a205f4547d Fix multi line paste detection and filtering (#8634)
- Detect `\r` when warning about multi line paste
- Translate `\n` to `\r` on paste

## PR Checklist
* [x] Closes #8601
* [x] Closes #5821

## Validation Steps Performed
Manual testing

(cherry picked from commit 49d008537f)
2021-01-25 12:54:07 -08:00
Dustin L. Howett
944fddbbe9 winconpty: close the pty host handle after terminating it (#8707)
It rather raises the question as to how we missed this.

Closes #8706

(cherry picked from commit 8bef5eefd5)
2021-01-25 12:54:07 -08:00
Sato Kenta
677ab36a8a Fix color animation bug of title bar buttons (#8649)
In dark mode (and high contrast mode), color animation of title bar
button uses wrong color.  Cause of this issue is using invalid data in
`ColorAnimation`.  I fixed this bug by changing `ColorAnimation` value
in XAML layout file.

According to a [forum post], `To` value of `ColorAnimation` must be
frozen. But original source code uses "color binding" which makes this
value dynamic.  As a result, the value set by default is always used,
that means, light mode.

So I added new resource named `CaptionButtonStrokeColor` and
`CaptionButtonBackgroundColor` which has static color value.

In light mode and dark mode, I set `SystemBaseHighColor` in the color
resource.  `SystemBaseHighColor` is the same as
`SystemControlForegroundBaseHighBrush.Color` which is originally used in
animation.

The background color animation happened to work correctly because its
value is the same between light mode and dark mode.  But I also fixed
background color animation.

## Validation Steps Performed

There is no need to add new test with this fix.

- I changed the `theme` value in `settings.json` and confirmed that the
  correct color values were used.
- I confirmed that it works correctly even if the Windows theme is
  changed.

[forum post]: https://social.msdn.microsoft.com/Forums/vstudio/en-US/027c364f-5d75-424f-aafd-7fb76b10b676/templatebinding-on-storyboard?forum=wpf

Closes #7314

(cherry picked from commit 713027b5e3)
2021-01-25 12:54:07 -08:00
hereafter
334e518773 make "open terminal here" context menu work for directory background (#8638)
This commit makes "Open in Windows Terminal" Context menu work again for
directory background even on system that OS fix is not applied.

This is a fallback solution to OS fixes mentioned in #6414.
While OS fix is on its way, we need a fallback that works on existing OS
versions.

The approach to this is: when no item is selected (nullptr for
IShellItemArray*), we use shell api to query the path of current active
Explorer window. A special case is handled for Windows Desktop. Once
we are able to obtain the path, we launch Windows Terminal with it.

1. Right click on desktop to bring up the Context menu, pick "Open in
   Windows Terminal", verify that a terminal is opened with correct
   initial path.

2. Open a few File Explorer windows, pick any window, navigate to a
   folder, click on "Background" to bring up the context menu, click
   "Open in Windows Terminal" verify that a terminal is opened with
   correct initial path.

Closes #6414

(cherry picked from commit fcca88ab25)
2021-01-25 12:54:04 -08:00
Kiminori Kaburagi
9e9c0bea83 Calculate initial height properly (#8584)
Closes #8527

(cherry picked from commit e943785e1a)
2021-01-25 12:53:26 -08:00
Mike Griese
5f29f7603d Replace the KB Dialog with a InfoBar (#8524)
This changes the keyboard warning from a dialog to an `InfoBar`, which
we just got in MUX 2.5. Some users were unhappy that we'd always display
the dialog. We learned from the input team that this service _should_
always be enabled. We're also learing from users that they don't always
want it enabled.

We're working with the Input team to help us figure out how this service
can be disabled _and the Terminal work just fine_. They're confident
that it _shouldn't_. For 99% of our users, they're right. So we don't
want to get rid of the dialog entirely, we want to understand how this
is possible. While we wait, let's make the message less aggressive.

This is instead of making a `iKnowWhatImDoingDisableTheKeyboardWarning`
setting to disable the dialog. Props to @cornem for suggesting the less
aggressive solution.

## Validation Steps Performed
Tested manually, but by forcing the message to always display. Disabling
the service requires two full reboots, and _ain't nobody got time for
that_.

Closes #8228
Closes #4448, for now

(cherry picked from commit ff5b2b84d2)
2021-01-25 12:53:26 -08:00
Kiminori Kaburagi
ceb0551066 Change tab close and rename icons to better fit the UI (#8424)
Closes #8419

Co-authored-by: KiminoriKaburagi <heipo_nogu@outlook.jp>
(cherry picked from commit 6952f1acda)
2021-01-25 12:53:26 -08:00
Dustin L. Howett
c17fdf07ee Update to Microsoft.UI.Xaml 2.5 "stable" (#8500)
This commit moves us to the Xaml prerelease (201202003) that is
equivalent to public stable release 2.5.

Remember, we need to use prereleases for some silly reason.

(cherry picked from commit 87492c4a26)
2021-01-25 12:53:26 -08:00
James Holderness
a315fd5f62 Correct horizontal coordinates in viewport overflow test (#8456)
When resizing the buffer in the `SetConsoleScreenBufferSize` and
`SetConsoleScreenBufferInfoEx` APIs, we have tests in place to make sure
that the resize doesn't result in the viewport extending past the bottom
or right of the buffer (since that can eventually result in exceptions
being thrown). Unfortunately these tests were using the wrong X
coordinate, so they failed to detect an overflow along the horizontal
axis. This PR corrects that mistake.

PR #8309 was where the overflow detection was initially added.

The original code was using the `Viewport::EndExclusive` method to
determine the extent of the viewport, mistakenly thinking that it
returned the bottom right coordinates (it actually returns the left
coordinate). So I've now added a `BottomRightExclusive` method to the
`Viewport` class, that actually does return the coordinates we need, and
have updated the overflow tests to use that method instead.

## Validation Steps Performed
I've manually confirmed that the test case is issue #8453 is no longer
throwing an exception.

Closes #8453

(cherry picked from commit 2a2f6b32a2)
2021-01-25 12:53:25 -08:00
Chester Liu
305946caa0 Improve clipboard handling in "drag and drop" scenario (#8461)
This PR improves the clipboard handling logic of "drag and drop" in
TermControl, making it more useful and less likely to crash.

* Added support for two more categories of content, `ApplicationLink`
  and `WebLink`.
* Reordered the ifs, making `StorageItem` the last clause. With WT being
  a text-oriented application, I think we can safely assume that the
  content being pasted is likely to be text/links.
* Catch possible exceptions during
  `e.DataView().GetStorageItemsAsync()`.

Closes #7804

(cherry picked from commit 60f1b0b285)
2021-01-25 12:53:25 -08:00
Dustin L. Howett
cadca1e839 Fix the xterm and SGR mouse encodings for CTRL, ALT, SHIFT (#8379)
We had the xterm and SGR codings for meta/ctrl backwards. Oops.

This commit also fixes an observed issue in Windows Terminal where we
were passing in a console-style modifiers enum when MouseInput is
expecting MK_ constants.

I decided to unify MouseInput around the console-style modifier
constants because they have support for META (which MK_ does not) and
can differentiate between left/right alt/ctrl.

Our tests are fundamentally flawed here: they use a copy of the
modifier key generating logic _themselves_, so we got a bit of "error
carried forward."

I did not fix the tests to use known-good control sequences, I simply
replaced the character generator with another copy of the modifier code.
I did, however, extend them to test ctrl|meta and left/right modifiers.

Fixes #8291

(cherry picked from commit b1e1c7cdf4)
2021-01-25 12:53:25 -08:00
Don-Vito
c5e1bbdd25 Fix a race condition in pane animation completion that broke sizing (#8241)
Fixes a race in pane entrance animation, where the animation
completion routine processes wrong children.

Validated w/ manual testing

Closes #8230

(cherry picked from commit c41e078e85)
2021-01-25 12:53:25 -08:00
Don-Vito
817df81f48 Fix combining wt args and "wt new-tab" args in implicit context (#8315)
Currently when implicit tab command is specified (i.e., we have
parameters for new-tab, but don't have the explicit subcommand name) we
fallback to parsing the entire arg list as new tab command.

However, if we also have a launch profile (or anything else that might in
the future belong to the upper scope) it is passed as a parameter to the
new tab command, failing the parsing.

The idea behind my solution is to run the parser as a prefix command -
i.e., as long as we succeed to parse [options] / [subcommand] we will
parse them (populating the fields like a launch mode), but once we will
discover something unfamiliar, like profile, we will know that the
prefix is over and will handle the remaining suffix as a new tab
command.

## Validation Steps Performed
* UT added
* Manual run of different options

Closes #7318

(cherry picked from commit 435e45726e)
2021-01-25 12:53:25 -08:00
D. Cheatham
a388adf50a Fix close button not using the tab's text color (#8046) (#8209)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
This sets the tab close button color to match the tab text color.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
#8046
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #8046
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #8046

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
This sets the tab close button color to match the tab text color.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Test light theme white tab mouse hover effect:
![Screenshot_2020-11-07_152110_3](https://user-images.githubusercontent.com/7143383/98640319-ec735e80-22de-11eb-8d35-08188405b566.png)

Test dark theme white tab mouse hover effect:
![Screenshot_2020-11-07_153021_2](https://user-images.githubusercontent.com/7143383/98640377-f006e580-22de-11eb-9bb5-dde9fe9b81b6.png)

(cherry picked from commit 2a340802dc)
2021-01-25 12:53:25 -08:00
James Holderness
5fb99657ea Fix out-of-bounds exceptions in Set...{Buffer,Screen}Size (#8309)
This fixes a number of exceptions that can cause conhost to crash when
the buffer is resized in such a way that the viewport or cursor position
end up out of bounds.

Technically this is a fix for issue #256, although that has been closed
as "needs-repro".

The main fix was to add checks in the `SetConsoleScreenBufferSizeImpl`
and `SetConsoleScreenBufferInfoExImpl` methods, to make sure the
viewport doesn't extend past the bottom or right of the buffer after a
resize. If it has overflowed, we move the viewport back up or left until
it's back within the buffer boundaries. We also check if the cursor
position has ended up out of bounds, and if so, clamp it back inside the
buffer.

The `SCREEN_INFORMATION::SetViewport` was also a source of viewport
overflow problems, because it was mistakenly using inclusive coordinates
in its range checks, which resulted in them being off by one. That has
now been corrected to use exclusive coordinates.

Finally, the `IsCursorDoubleWidth` method was incorrectly marked as
`noexcept`, which was preventing its exceptions from being caught.
Ideally it shouldn't be throwing exceptions at all any more, but I've
removed the `noexcept` specifier, so if it does throw an exception,
it'll at least have more chance of recovering without a crash.

## Validation Steps Performed

I put together a few test cases (based on the reports in issues #276 and
#1976) which consistently caused conhost to crash, or to generate an
exception visible in the debug output. With this PR applied, those test
cases are no longer crashing or triggering exceptions.

Closes #1976

(cherry picked from commit 9a070490d4)
2021-01-25 12:53:25 -08:00
Don-Vito
12c100cdb0 Prevent resizing terminal to a lower-than-minimum width (#8066)
Until now, we relied on WM_SIZING to ensure that the island is not
downsized below minimal allowed dimensions. However, on some occasions
WM_WINDOWPOSCHANGED, e.g. when anchoring a window to the top/bottom of
the screen. This message will use dimensions obtained from
WM_GETMINMAXINFO. Until now we didn't override this value, falling back
to the defaults. As a result we got an inconsistent behavior (at least
when attaching the anchor).

I added logic very similar to the one we use in IslandWindow::_OnSizing
to the MINMAXINFO handler: snap the client area, add non client
exclusive are, consider DPI along the computation.

* Manual testing of minimizing, maximizing, resizing, attaching
  different anchors, etc.

Closes #8026

(cherry picked from commit e3fcfccc52)
2021-01-25 12:53:22 -08:00
Don-Vito
431559fd83 Avoid an access violation in pane animation if the child is closed (#8218)
Some UTs crash with access violation, that occurs during pane animation.
The reason for this is a race, upon which the pane is closed (set to
nullptr) before the parent is animated.  Added a simple check against
null.  Doubt it can happen in production, yet worth taking care!

(cherry picked from commit 5a942bcb6f)
2021-01-25 12:53:06 -08:00
Dustin Howett
109f9c451f Revert "Always create a new environment block before we spawn a process (#7243)"
This reverts commit 849243af99.

References #7418

(cherry picked from commit 4204d2535c)
(cherry picked from commit fce00ff8f6)
2021-01-25 12:48:40 -08:00
Dustin Howett
95b9b7c852 Revert "Fix environment block creation (#7401)"
This reverts commit 7886f16714.

(cherry picked from commit e46ba65665)
(cherry picked from commit d1b26085e1)
2021-01-25 12:48:25 -08:00
Mike Griese
f3cdf6841f Change the default tab switch mode back to inOrder (#8326)
We changed the default to "mru", and that was unkind to all our existing users.

(cherry picked from commit a52a1d3b8d)
2020-11-19 16:01:10 -08:00
Don-Vito
1228897071 Fix default backgroundImageStretch to be uniformToFill (#8280)
This commit fixes the default value to comply with documentation.

Closes #8256

(cherry picked from commit 77a204b765)
2020-11-19 16:01:10 -08:00
Bhaskar Shankarling
0300b31117 align command palette prefix > to left when visible (#8279)
Fixes the clear button to clear the typed command not clickable in the
command palette.

- From the primary investigation it looked like the `TextBlock` element
  introduced in #7935 was somehow blocking (appearing on top of) the
  clear button.
- It was also blocking the command palette input field from being able
  to access which was preventing the text in the input field from being
  selected and the cursor would still show as `pointer` cursor instead
  of a `text selection` cursor
- Adding `HorizontalAlignment="Left"` property to the above-mentioned
  `TextBlock` element fixed the issue.

## Validation Steps Performed
- Created the Dev build for `x64` in Visual Studio and verified the
  functionality manually.

Closes #8220

(cherry picked from commit a8f3f584a0)
2020-11-19 16:01:10 -08:00
Travis Hester
368fa17c2d 8249: Remove trailing commas in profiles.schema.json (#8257)
Fixes https parsing of the latest version of `profiles.schema.json`, particularly by VS Code Intellisense.

* [x] Closes #8249

The VS Code parsing warning below is a known and unrelated existing issue due to VS Code only supporting JSON Schema Draft 7. It does not prevent Intellisense from functioning.

> Draft 2019-09 schemas are not yet fully supported.

## Validation Steps Performed

Manually tested and successfully validated by fixing a local copy of `profiles.schema.json` and defining it as `$schema` in `settings.json`

(cherry picked from commit d28a4da596)
2020-11-19 16:01:09 -08:00
Don-Vito
c7607417d3 8247: Custom key bindings are broken for tab navigation (#8250)
There are two code paths for Ctrl+Tab and for everything else:

Ctrl + Tab is working perfectly
* On the first tab navigation TerminalPage::_SelectNextTab resets the
  tab commands, and since palette is not visible selects the relevant
  tab index
* On the second navigation Ctrl+Tab is intercepted by
  CommandPalette::_previewKeyDownHandler and everything works fine

But with custom binding things are screwed:
* On the first tab navigation TerminalPage::_SelectNextTab resets the
  tab commands, and since palette is not visible selects the relevant
  tab index
* On the second navigation keys are not intercepted and thus
  TerminalPage::_SelectNextTab is called again. It resets the commands,
  but now since the palette is visible we simply invoke
  CommandPalette::SelectNextItem. Which in turn misbehaves because no
  item is selected.

The approach for the solution is not to reset anything if the command
palette is already open.

## Validation Steps Performed
* Manual testing of both custom and non-custom bindings with different
  amount of tabs.

Closes #8247

(cherry picked from commit 0437fe9d8e)
2020-11-19 16:01:09 -08:00
Don-Vito
204c9d2cf4 Make sure to disable pane entrance animation if user requests (#8237)
We were only checking app animations during pane _exit_.

(cherry picked from commit e80108118d)
2020-11-19 16:01:09 -08:00
64 changed files with 669 additions and 358 deletions

View File

@@ -0,0 +1,14 @@
checkboxes
CSIDL
csv
horiz
IDispatch
inlines
IWeb
Progman
reserialize
SHANDLE
SHGFP
udk
unfocus
WClass

View File

@@ -168,6 +168,7 @@ BOLDFONT
BOOLIFY
bools
Bopomofo
boostorg
Borland
BOTTOMLEFT
BOTTOMRIGHT
@@ -247,7 +248,6 @@ charset
CHARSETINFO
chcp
checkbox
Checkboxes
chh
Childitem
chk
@@ -382,7 +382,6 @@ CORESYSTEM
cotaskmem
countof
cout
CParams
CPG
cpinfo
CPINFOEX
@@ -411,7 +410,6 @@ csbi
csbiex
csharp
CSHORT
cso
csproj
Csr
csrmsg
@@ -424,7 +422,6 @@ cstdlib
cstr
cstring
cstyle
CSV
CSwitch
CText
ctime
@@ -836,7 +833,6 @@ gcy
gdi
gdip
gdirenderer
GENERATEPROJECTPRIFILE
geopol
GETALIAS
GETALIASES
@@ -951,7 +947,6 @@ hfont
hglobal
hh
hhh
hhhh
hhook
hhx
HIBYTE
@@ -978,7 +973,6 @@ hmod
hmodule
hmon
HMONITOR
Horiz
HORZ
hostable
hostlib
@@ -1088,10 +1082,8 @@ INITMENU
inkscape
inl
INLINEPREFIX
Inlines
INotify
inout
INPATHROOT
inproc
Inputkeyinfo
INPUTPROCESSORPROFILE
@@ -1333,7 +1325,6 @@ mailto
majorly
makeappx
MAKEINTRESOURCE
MAKEINTRESOURCEA
MAKEINTRESOURCEW
MAKELANGID
MAKELONG
@@ -1406,7 +1397,6 @@ monostate
MOUSEACTIVATE
MOUSEFIRST
MOUSEHWHEEL
mousemode
MOUSEMOVE
mousewheel
MOVESTART
@@ -1428,7 +1418,6 @@ MSGSELECTMODE
msiexec
MSIL
msix
msixbundle
msrc
msvcrt
MSVS
@@ -1943,7 +1932,6 @@ Replymessage
repositorypath
rescap
Resequence
Reserialize
RESETCONTENT
resheader
resizable
@@ -1970,7 +1958,6 @@ rgpwsz
rgrc
rgs
rgui
rgus
rgw
rgwch
rhs
@@ -2104,7 +2091,6 @@ sfi
SFINAE
SFUI
sgr
SGRXY
SHCo
shcore
shellapi
@@ -2277,6 +2263,7 @@ tcome
tcommandline
tcommands
tcon
TDelegated
TDP
TEAMPROJECT
tearoff
@@ -2443,7 +2430,6 @@ UNCPRIORITY
undef
Unescape
unexpand
Unfocus
unhighlighting
unhosted
unicode
@@ -2768,14 +2754,12 @@ XColors
xcopy
XCount
xdy
xe
XEncoding
xes
Xes
XES
xff
XFile
xlang
XManifest
XMath
XMFLOAT
@@ -2800,6 +2784,7 @@ xvalue
XVIRTUALSCREEN
XWalk
xy
Xzn
yact
YAML
YCast
@@ -2826,6 +2811,7 @@ zu
zxcvbnm
zy
AAAAABBBBBBCCC
AAAAA
BBBBBCCC
abcd
abcd
LPMINMAXINFO
MINMAXINFO

View File

@@ -1,24 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
<!-- Add repositories here to the list of available repositories -->
<!-- Dependencies that we must carry because they're not on public nuget feeds right now. -->
<clear />
<!-- Dependencies that we can turn on to force override for testing purposes before uploading. -->
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
<!-- Use our own NuGet Feed -->
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/ms/terminal/_packaging/TerminalDependencies/nuget/v3/index.json" />
<!-- Temporarily? use the feeds from our friends in MUX for Helix test stuff -->
<add key="dotnetfeed" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
<add key="dnceng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
<add key="MUX-Dependencies" value="https://pkgs.dev.azure.com/ms/microsoft-ui-xaml/_packaging/MUX-Dependencies/nuget/v3/index.json" />
<!-- Internal NuGet feeds that may not be accessible outside Microsoft corporate network -->
<!--<add key="TAEF - internal" value="https://microsoft.pkgs.visualstudio.com/DefaultCollection/_packaging/Taef/nuget/v3/index.json" />
<add key="OpenConsole - Internal" value="https://microsoft.pkgs.visualstudio.com/_packaging/OpenConsole/nuget/v3/index.json" />-->
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
<config>
<add key="repositorypath" value=".\packages" />
</config>

View File

@@ -694,7 +694,7 @@
"enum": [
"mru",
"inOrder",
"disabled",
"disabled"
],
"type": "string"
}
@@ -702,7 +702,7 @@
"deprecated": true
},
"tabSwitcherMode": {
"default": true,
"default": "inOrder",
"description": "When set to \"true\" or \"mru\", the \"nextTab\" and \"prevTab\" commands will use the tab switcher UI, with most-recently-used ordering. When set to \"inOrder\", these actions will switch tabs in their current ordering. Set to \"false\" to disable the tab switcher.",
"oneOf": [
{
@@ -712,7 +712,7 @@
"enum": [
"mru",
"inOrder",
"disabled",
"disabled"
],
"type": "string"
}

Binary file not shown.

Binary file not shown.

View File

@@ -17,5 +17,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
### Fonts Included
* Cascadia Code, Cascadia Mono (2009.21)
* from microsoft/cascadia-code@32f84124db1970fa5d032f0fe9019e6922961beb
* Cascadia Code, Cascadia Mono (2102.03)
* from microsoft/cascadia-code@b358d1ba3d1629c113671312b18eab52797cc055

View File

@@ -149,12 +149,12 @@
<!-- **END VC LIBS HACK** -->
<!-- This is required to get the package dependency in the AppXManifest. -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />

View File

@@ -82,14 +82,9 @@
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
<!-- Due to a bug in the OS, this doesn't actually work right -
we'll get a nullptr in our implementation. So this is disabled
temporarily. See MSFT:24623699 for more details.
<desktop5:ItemType Type="Directory\Background">
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
-->
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>

View File

@@ -82,15 +82,9 @@
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
<!-- Due to a bug in the OS, this doesn't actually work right -
we'll get a nullptr in our implementation. So this is disabled
temporarily. See MSFT:24623699 for more details.
<desktop5:ItemType Type="Directory\Background">
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
-->
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>

View File

@@ -83,14 +83,9 @@
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
<!-- Due to a bug in the OS, this doesn't actually work right -
we'll get a nullptr in our implementation. So this is disabled
temporarily. See MSFT:24623699 for more details.
<desktop5:ItemType Type="Directory\Background">
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
-->
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>

View File

@@ -90,10 +90,10 @@
<!-- From Microsoft.UI.Xaml.targets -->
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<!-- We actually can just straight up reference MUX here, it's fine -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
</Project>

View File

@@ -58,6 +58,7 @@ namespace TerminalAppLocalTests
TEST_METHOD(TestMultipleCommandExecuteCommandlineAction);
TEST_METHOD(TestInvalidExecuteCommandlineAction);
TEST_METHOD(TestLaunchMode);
TEST_METHOD(TestLaunchModeWithNoCommand);
private:
void _buildCommandlinesHelper(AppCommandlineArgs& appArgs,
@@ -1224,4 +1225,56 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedFocusMode);
}
}
void CommandlineTest::TestLaunchModeWithNoCommand()
{
{
Log::Comment(NoThrowString().Format(L"Pass a launch mode and profile"));
AppCommandlineArgs appArgs{};
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"-M", L"--profile", L"cmd" };
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedMode);
VERIFY_ARE_EQUAL(1u, appArgs._startupActions.size());
auto actionAndArgs = appArgs._startupActions.at(0);
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
VERIFY_IS_NOT_NULL(actionAndArgs.Args());
auto myArgs = actionAndArgs.Args().try_as<NewTabArgs>();
VERIFY_IS_NOT_NULL(myArgs);
VERIFY_IS_NOT_NULL(myArgs.TerminalArgs());
VERIFY_IS_TRUE(myArgs.TerminalArgs().Commandline().empty());
VERIFY_IS_TRUE(myArgs.TerminalArgs().StartingDirectory().empty());
VERIFY_IS_TRUE(myArgs.TerminalArgs().TabTitle().empty());
VERIFY_IS_TRUE(myArgs.TerminalArgs().ProfileIndex() == nullptr);
VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty());
VERIFY_ARE_EQUAL(L"cmd", myArgs.TerminalArgs().Profile());
}
{
Log::Comment(NoThrowString().Format(L"Pass a launch mode and command line"));
AppCommandlineArgs appArgs{};
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"-M", L"powershell.exe" };
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedMode);
VERIFY_ARE_EQUAL(1u, appArgs._startupActions.size());
auto actionAndArgs = appArgs._startupActions.at(0);
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
VERIFY_IS_NOT_NULL(actionAndArgs.Args());
auto myArgs = actionAndArgs.Args().try_as<NewTabArgs>();
VERIFY_IS_NOT_NULL(myArgs);
VERIFY_IS_NOT_NULL(myArgs.TerminalArgs());
VERIFY_IS_FALSE(myArgs.TerminalArgs().Commandline().empty());
VERIFY_IS_TRUE(myArgs.TerminalArgs().StartingDirectory().empty());
VERIFY_IS_TRUE(myArgs.TerminalArgs().TabTitle().empty());
VERIFY_IS_TRUE(myArgs.TerminalArgs().ProfileIndex() == nullptr);
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
VERIFY_ARE_EQUAL(L"powershell.exe", myArgs.TerminalArgs().Commandline());
}
}
}

View File

@@ -93,11 +93,11 @@
<!-- From Microsoft.UI.Xaml.targets -->
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<!-- We actually can just straight up reference MUX here, it's fine -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
</Project>

View File

@@ -123,7 +123,7 @@
</Reference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)\src\common.build.post.props" />

View File

@@ -3,6 +3,7 @@
#include "pch.h"
#include "OpenTerminalHere.h"
#include <ShlObj.h>
// TODO GH#6112: Localize these strings
static constexpr std::wstring_view VerbDisplayName{ L"Open in Windows Terminal" };
@@ -117,14 +118,29 @@ static std::wstring _getExePath()
HRESULT OpenTerminalHere::Invoke(IShellItemArray* psiItemArray,
IBindCtx* /*pBindContext*/)
{
DWORD count;
psiItemArray->GetCount(&count);
winrt::com_ptr<IShellItem> psi;
RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
wil::unique_cotaskmem_string pszName;
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
if (psiItemArray == nullptr)
{
// get the current path from explorer.exe
const auto path = this->_GetPathFromExplorer();
// no go, unable to get a reasonable path
if (path.empty())
{
return S_FALSE;
}
pszName = wil::make_cotaskmem_string(path.c_str(), path.length());
}
else
{
DWORD count;
psiItemArray->GetCount(&count);
winrt::com_ptr<IShellItem> psi;
RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
}
{
wil::unique_process_information _piClient;
@@ -214,3 +230,103 @@ HRESULT OpenTerminalHere::EnumSubCommands(IEnumExplorerCommand** ppEnum)
*ppEnum = nullptr;
return E_NOTIMPL;
}
std::wstring OpenTerminalHere::_GetPathFromExplorer() const
{
using namespace std;
using namespace winrt;
wstring path;
HRESULT hr = NOERROR;
auto hwnd = ::GetForegroundWindow();
if (hwnd == nullptr)
{
return path;
}
TCHAR szName[MAX_PATH] = { 0 };
::GetClassName(hwnd, szName, MAX_PATH);
if (0 == StrCmp(szName, L"WorkerW") ||
0 == StrCmp(szName, L"Progman"))
{
//special folder: desktop
hr = ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, szName);
if (FAILED(hr))
{
return path;
}
path = szName;
return path;
}
if (0 != StrCmp(szName, L"CabinetWClass"))
{
return path;
}
com_ptr<IShellWindows> shell;
try
{
shell = create_instance<IShellWindows>(CLSID_ShellWindows, CLSCTX_ALL);
}
catch (...)
{
//look like try_create_instance is not available no more
}
if (shell == nullptr)
{
return path;
}
com_ptr<IDispatch> disp;
wil::unique_variant variant;
variant.vt = VT_I4;
com_ptr<IWebBrowserApp> browser;
// look for correct explorer window
for (variant.intVal = 0;
shell->Item(variant, disp.put()) == S_OK;
variant.intVal++)
{
com_ptr<IWebBrowserApp> tmp;
if (FAILED(disp->QueryInterface(tmp.put())))
{
disp = nullptr; // get rid of DEBUG non-nullptr warning
continue;
}
HWND tmpHWND = NULL;
hr = tmp->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&tmpHWND));
if (hwnd == tmpHWND)
{
browser = tmp;
disp = nullptr; // get rid of DEBUG non-nullptr warning
break; //found
}
disp = nullptr; // get rid of DEBUG non-nullptr warning
}
if (browser != nullptr)
{
wil::unique_bstr url;
hr = browser->get_LocationURL(&url);
if (FAILED(hr))
{
return path;
}
wstring sUrl(url.get(), SysStringLen(url.get()));
DWORD size = MAX_PATH;
hr = ::PathCreateFromUrl(sUrl.c_str(), szName, &size, NULL);
if (SUCCEEDED(hr))
{
path = szName;
}
}
return path;
}

View File

@@ -46,6 +46,9 @@ struct __declspec(uuid("9f156763-7844-4dc4-b2b1-901f640f5155"))
STDMETHODIMP GetCanonicalName(GUID* pguidCommandName);
STDMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum);
#pragma endregion
private:
std::wstring _GetPathFromExplorer() const;
};
CoCreatableClass(OpenTerminalHere);

View File

@@ -11,10 +11,13 @@
<!-- sets a bunch of Windows Universal properties -->
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>User32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="OpenTerminalHere.h" />
@@ -40,7 +43,6 @@
<None Include="packages.config" />
<None Include="WindowsTerminalShellExt.def" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
<!--
@@ -56,7 +58,5 @@
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
</Project>

View File

@@ -69,50 +69,29 @@ int AppCommandlineArgs::ParseCommand(const Commandline& command)
{
throw CLI::CallForHelp();
}
// Clear the parser's internal state
_app.clear();
// attempt to parse the commandline
// attempt to parse the commandline prefix of the form [options][subcommand]
_app.parse(args);
auto remainingParams = _app.remaining_size();
// If we parsed the commandline, and _no_ subcommands were provided, try
// parsing again as a "new-tab" command.
// parse the remaining suffix as a "new-tab" command.
if (_noCommandsProvided())
{
_newTabCommand.subcommand->clear();
_newTabCommand.subcommand->parse(args);
remainingParams = _newTabCommand.subcommand->remaining_size();
}
// if after parsing the prefix and (optionally) the implicit tab subcommand
// we still have unparsed parameters we need to fail
if (remainingParams > 0)
{
throw CLI::ExtrasError(args);
}
}
catch (const CLI::CallForHelp& e)
{
return _handleExit(_app, e);
}
catch (const CLI::ParseError& e)
{
// If we parsed the commandline, and _no_ subcommands were provided, try
// parsing again as a "new-tab" command.
if (_noCommandsProvided())
{
try
{
// CLI11 mutated the original vector the first time it tried to
// parse the args. Reconstruct it the way CLI11 wants here.
// "See above for why it's begin() + 1"
std::vector<std::string> args{ command.Args().begin() + 1, command.Args().end() };
std::reverse(args.begin(), args.end());
_newTabCommand.subcommand->clear();
_newTabCommand.subcommand->parse(args);
}
catch (const CLI::ParseError& e)
{
return _handleExit(*_newTabCommand.subcommand, e);
}
}
else
{
return _handleExit(_app, e);
}
return _handleExit(_app, e);
}
return 0;
}
@@ -157,6 +136,15 @@ int AppCommandlineArgs::_handleExit(const CLI::App& command, const CLI::Error& e
// - <none>
void AppCommandlineArgs::_buildParser()
{
// We define or parser as a prefix command, to support "implicit new tab subcommand" scenario.
// In this scenario we will try to parse the prefix that contains parameters like launch mode,
// but will not encounter an explicit command.
// Instead we will encounter an argument that doesn't belong to the prefix indicating the prefix is over.
// Then we will try to parse the remaining arguments as a new tab subcommand.
// E.g., for "wt.exe -M -d c:/", we will use -M for the launch mode, but once we will encounter -d
// we will know that the prefix is over and try to handle the suffix as a new tab subcommand
_app.prefix_command();
// -v,--version: Displays version info
auto versionCallback = [this](int64_t /*count*/) {
// Set our message to display the application name and the current version.

View File

@@ -583,10 +583,10 @@ namespace winrt::TerminalApp::implementation
auto tabControl = TabRowControl();
tabControl.Measure({ SHRT_MAX, SHRT_MAX });
// For whatever reason, there's about 6px of unaccounted-for space
// in the application. I couldn't tell you where these 6px are
// For whatever reason, there's about 10px of unaccounted-for space
// in the application. I couldn't tell you where these 10px are
// coming from, but they need to be included in this math.
proposedSize.Width += (tabControl.DesiredSize().Height + 6) * scale;
proposedSize.Height += (tabControl.DesiredSize().Height + 10) * scale;
}
return proposedSize;
@@ -797,7 +797,8 @@ namespace winrt::TerminalApp::implementation
// editors, who will write a temp file, then rename it to be the
// actual file you wrote. So listen for that too.
if (!(event == wil::FolderChangeEvent::Modified ||
event == wil::FolderChangeEvent::RenameNewName))
event == wil::FolderChangeEvent::RenameNewName ||
event == wil::FolderChangeEvent::Removed))
{
return;
}

View File

@@ -178,6 +178,7 @@ the MIT License. See LICENSE in the project root for license information. -->
x:Name="_prefixCharacter"
Margin="16,16,0,-8"
FontSize="14"
HorizontalAlignment="Left"
Visibility="{x:Bind PrefixCharacter,
Mode=OneWay,
Converter={StaticResource ParentCommandVisibilityConverter}}"
@@ -185,35 +186,35 @@ the MIT License. See LICENSE in the project root for license information. -->
>
</TextBlock>
<StackPanel Orientation="Horizontal"
Padding="16, 0, 16, 4"
Grid.Row="1"
Visibility="{x:Bind ParentCommandName,
Mode=OneWay,
Converter={StaticResource ParentCommandVisibilityConverter}}">
<Button
Background="Transparent"
x:Name="_parentCommandBackButton"
x:Uid="ParentCommandBackButton"
Click="_moveBackButtonClicked"
ClickMode="Press"
VerticalAlignment="Center">
<FontIcon
FontSize="12"
FontFamily="Segoe MDL2 Assets"
Glyph="&#xE76b;">
</FontIcon>
</Button>
<TextBlock
Padding="16, 0, 16, 4"
x:Name="_parentCommandText"
FontStyle="Italic"
Grid.Row="1"
Text="{x:Bind ParentCommandName, Mode=OneWay}"
VerticalAlignment="Center">
</TextBlock>
<StackPanel Orientation="Horizontal"
Padding="16, 0, 16, 4"
Grid.Row="1"
Visibility="{x:Bind ParentCommandName,
Mode=OneWay,
Converter={StaticResource ParentCommandVisibilityConverter}}">
<Button
Background="Transparent"
x:Name="_parentCommandBackButton"
x:Uid="ParentCommandBackButton"
Click="_moveBackButtonClicked"
ClickMode="Press"
VerticalAlignment="Center">
<FontIcon
FontSize="12"
FontFamily="Segoe MDL2 Assets"
Glyph="&#xE76b;">
</FontIcon>
</Button>
<TextBlock
Padding="16, 0, 16, 4"
x:Name="_parentCommandText"
FontStyle="Italic"
Grid.Row="1"
Text="{x:Bind ParentCommandName, Mode=OneWay}"
VerticalAlignment="Center">
</TextBlock>
</StackPanel>
<TextBlock
@@ -267,7 +268,7 @@ the MIT License. See LICENSE in the project root for license information. -->
Grid.Column="1"
HorizontalAlignment="Left"
Text="{x:Bind HighlightedName, Mode=OneWay}"/>
<!-- The block for the key chord is only visible
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details. -->

View File

@@ -22,9 +22,11 @@ the MIT License. See LICENSE in the project root for license information. -->
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokeColor" ResourceKey="SystemBaseHighColor"/>
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="#e81123"/>
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
@@ -35,9 +37,11 @@ the MIT License. See LICENSE in the project root for license information. -->
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokeColor" ResourceKey="SystemBaseHighColor"/>
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="#e81123"/>
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
@@ -46,9 +50,11 @@ the MIT License. See LICENSE in the project root for license information. -->
<ResourceDictionary x:Key="HighContrast">
<x:Double x:Key="CaptionButtonStrokeWidth">3.0</x:Double>
<SolidColorBrush x:Key="CaptionButtonBackground" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<StaticResource x:Key="CaptionButtonBackgroundColor" ResourceKey="SystemColorButtonFaceColor"/>
<SolidColorBrush x:Key="CaptionButtonBackgroundPointerOver" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="CaptionButtonBackgroundPressed" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="CaptionButtonStroke" Color="{ThemeResource SystemColorButtonTextColor}"/>
<StaticResource x:Key="CaptionButtonStrokeColor" ResourceKey="SystemColorButtonTextColor"/>
<SolidColorBrush x:Key="CaptionButtonStrokePointerOver" Color="{ThemeResource SystemColorHighlightTextColor}"/>
<SolidColorBrush x:Key="CaptionButtonStrokePressed" Color="{ThemeResource SystemColorHighlightTextColor}"/>
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="{ThemeResource SystemColorHighlightColor}"/>
@@ -95,8 +101,8 @@ the MIT License. See LICENSE in the project root for license information. -->
<VisualStateGroup.Transitions>
<VisualTransition From="PointerOver" To="Normal">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBaseElement" Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)" To="{Binding Color, Source={ThemeResource CaptionButtonBackground}}" Duration="0:0:0.2"/>
<ColorAnimation Storyboard.TargetName="Path" Storyboard.TargetProperty="(UIElement.Stroke).(SolidColorBrush.Color)" To="{Binding Color, Source={ThemeResource CaptionButtonStroke}}" Duration="0:0:0.1"/>
<ColorAnimation Storyboard.TargetName="ButtonBaseElement" Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)" To="{ThemeResource CaptionButtonBackgroundColor}" Duration="0:0:0.2"/>
<ColorAnimation Storyboard.TargetName="Path" Storyboard.TargetProperty="(UIElement.Stroke).(SolidColorBrush.Color)" To="{ThemeResource CaptionButtonStrokeColor}" Duration="0:0:0.1"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>

View File

@@ -1093,13 +1093,14 @@ void Pane::_SetupEntranceAnimation()
// Windows" setting in the OS
winrt::Windows::UI::ViewManagement::UISettings uiSettings;
const auto animationsEnabledInOS = uiSettings.AnimationsEnabled();
const auto animationsEnabledInApp = Media::Animation::Timeline::AllowDependentAnimations();
const bool splitWidth = _splitState == SplitState::Vertical;
const auto totalSize = splitWidth ? _root.ActualWidth() : _root.ActualHeight();
// If we don't have a size yet, it's likely that we're in startup, or we're
// being executed as a sequence of actions. In that case, just skip the
// animation.
if (totalSize <= 0 || !animationsEnabledInOS)
if (totalSize <= 0 || !animationsEnabledInOS || !animationsEnabledInApp)
{
return;
}
@@ -1168,6 +1169,15 @@ void Pane::_SetupEntranceAnimation()
childGrid.HorizontalAlignment(isFirstChild ? HorizontalAlignment::Left : HorizontalAlignment::Right);
control.HorizontalAlignment(HorizontalAlignment::Left);
control.Width(isFirstChild ? totalSize : size);
// When the animation is completed, undo the trickiness from before, to
// restore the controls to the behavior they'd usually have.
animation.Completed([childGrid, control](auto&&, auto&&) {
control.Width(NAN);
childGrid.Width(NAN);
childGrid.HorizontalAlignment(HorizontalAlignment::Stretch);
control.HorizontalAlignment(HorizontalAlignment::Stretch);
});
}
else
{
@@ -1177,38 +1187,19 @@ void Pane::_SetupEntranceAnimation()
childGrid.VerticalAlignment(isFirstChild ? VerticalAlignment::Top : VerticalAlignment::Bottom);
control.VerticalAlignment(VerticalAlignment::Top);
control.Height(isFirstChild ? totalSize : size);
// When the animation is completed, undo the trickiness from before, to
// restore the controls to the behavior they'd usually have.
animation.Completed([childGrid, control](auto&&, auto&&) {
control.Height(NAN);
childGrid.Height(NAN);
childGrid.VerticalAlignment(VerticalAlignment::Stretch);
control.VerticalAlignment(VerticalAlignment::Stretch);
});
}
// Start the animation.
s.Begin();
std::weak_ptr<Pane> weakThis{ shared_from_this() };
// When the animation is completed, undo the trickiness from before, to
// restore the controls to the behavior they'd usually have.
animation.Completed([weakThis, isFirstChild, splitWidth](auto&&, auto&&) {
if (auto pane{ weakThis.lock() })
{
auto child = isFirstChild ? pane->_firstChild : pane->_secondChild;
auto childGrid = child->_root;
if (auto control = child->_control)
{
if (splitWidth)
{
control.Width(NAN);
childGrid.Width(NAN);
childGrid.HorizontalAlignment(HorizontalAlignment::Stretch);
control.HorizontalAlignment(HorizontalAlignment::Stretch);
}
else
{
control.Height(NAN);
childGrid.Height(NAN);
childGrid.VerticalAlignment(VerticalAlignment::Stretch);
control.VerticalAlignment(VerticalAlignment::Stretch);
}
}
}
});
};
// TODO: GH#7365 - animating the first child right now doesn't _really_ do

View File

@@ -62,7 +62,6 @@ namespace winrt::TerminalApp::implementation
// Build the menu
Controls::MenuFlyout newTabFlyout;
newTabFlyout.Items().Append(_CreateCloseSubMenu());
newTabFlyout.Items().Append(closeTabMenuItem);
TabViewItem().ContextFlyout(newTabFlyout);
}

View File

@@ -316,13 +316,13 @@
<!-- ========================= Globals ======================== -->
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>

View File

@@ -703,7 +703,6 @@ namespace winrt::TerminalApp::implementation
auto tabViewItem = newTabImpl->TabViewItem();
_tabView.TabItems().Append(tabViewItem);
_ReapplyCompactTabSize();
// Set this tab's icon to the icon from the user's profile
const auto profile = _settings.FindProfile(profileGuid);
@@ -918,8 +917,7 @@ namespace winrt::TerminalApp::implementation
{
auto newTabTitle = tab.Title();
if (_settings.GlobalSettings().ShowTitleInTitlebar() &&
tab.FocusState() != FocusState::Unfocused)
if (_settings.GlobalSettings().ShowTitleInTitlebar() && tab == _GetFocusedTab())
{
_titleChangeHandlers(*this, newTabTitle);
}
@@ -1206,6 +1204,14 @@ namespace winrt::TerminalApp::implementation
// - Sets focus to the tab to the right or left the currently selected tab.
void TerminalPage::_SelectNextTab(const bool bMoveRight)
{
if (CommandPalette().Visibility() == Visibility::Visible)
{
// If the tab switcher is currently open, don't change its mode.
// Just select the new tab.
CommandPalette().SelectNextItem(bMoveRight);
return;
}
const auto tabSwitchMode = _settings.GlobalSettings().TabSwitcherMode();
const bool useInOrderTabIndex = tabSwitchMode != TabSwitcherMode::MostRecentlyUsed;
@@ -1250,19 +1256,10 @@ namespace winrt::TerminalApp::implementation
CommandPalette().SetTabActions(_mruTabActions, true);
}
if (CommandPalette().Visibility() == Visibility::Visible)
{
// If the tab switcher is currently open, don't change its mode.
// Just select the new tab.
CommandPalette().SelectNextItem(bMoveRight);
}
else
{
// Otherwise, set up the tab switcher in the selected mode, with
// the given ordering, and make it visible.
CommandPalette().EnableTabSwitcherMode(false, newTabIndex);
CommandPalette().Visibility(Visibility::Visible);
}
// Otherwise, set up the tab switcher in the selected mode, with
// the given ordering, and make it visible.
CommandPalette().EnableTabSwitcherMode(false, newTabIndex);
CommandPalette().Visibility(Visibility::Visible);
}
else if (auto index{ _GetFocusedTabIndex() })
{
@@ -1750,7 +1747,7 @@ namespace winrt::TerminalApp::implementation
// - See Pane::CalcSnappedDimension
float TerminalPage::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
{
if (_settings.GlobalSettings().SnapToGridOnResize())
if (_settings && _settings.GlobalSettings().SnapToGridOnResize())
{
if (auto index{ _GetFocusedTabIndex() })
{
@@ -1853,8 +1850,9 @@ namespace winrt::TerminalApp::implementation
}
}
const bool hasNewLine = std::find(text.cbegin(), text.cend(), L'\n') != text.cend();
const bool warnMultiLine = hasNewLine && _settings.GlobalSettings().WarnAboutMultiLinePaste();
const auto isNewLineLambda = [](auto c) { return c == L'\n' || c == L'\r'; };
const auto hasNewLine = std::find_if(text.cbegin(), text.cend(), isNewLineLambda) != text.cend();
const auto warnMultiLine = hasNewLine && _settings.GlobalSettings().WarnAboutMultiLinePaste();
constexpr const std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
const bool warnLargeText = text.size() > minimumSizeForWarning &&
@@ -2063,8 +2061,13 @@ namespace winrt::TerminalApp::implementation
_UpdateMRUTab(index);
}
tab.TabViewItem().StartBringIntoView();
// Raise an event that our title changed
_titleChangeHandlers(*this, tab.Title());
if (_settings.GlobalSettings().ShowTitleInTitlebar())
{
_titleChangeHandlers(*this, tab.Title());
}
}
CATCH_LOG();
}
@@ -2243,7 +2246,7 @@ namespace winrt::TerminalApp::implementation
IVectorView<Profile> profiles,
IMapView<winrt::hstring, ColorScheme> schemes)
{
IVector<SettingsLoadWarnings> warnings;
IVector<SettingsLoadWarnings> warnings{ winrt::single_threaded_vector<SettingsLoadWarnings>() };
std::vector<ColorScheme> sortedSchemes;
sortedSchemes.reserve(schemes.Size());
@@ -2667,25 +2670,6 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - The TabView does not apply compact sizing to items added after Compact is enabled.
// By forcibly reapplying compact sizing every time we add a new tab, we'll make sure
// that it works.
// Workaround from https://github.com/microsoft/microsoft-ui-xaml/issues/2711
// TODO: Remove this function and its calls when ingesting the above changes.
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPage::_ReapplyCompactTabSize()
{
if (_tabView.TabWidthMode() == MUX::Controls::TabViewWidthMode::Compact)
{
_tabView.UpdateLayout();
_tabView.TabWidthMode(MUX::Controls::TabViewWidthMode::Compact);
}
}
// Method Description:
// - Initializes a SwitchToTab command object for this Tab instance.
// This should be done before the tab is added to the _tabs vector so that
@@ -2775,9 +2759,9 @@ namespace winrt::TerminalApp::implementation
// Service" is disabled.
void TerminalPage::ShowKeyboardServiceWarning()
{
if (auto presenter{ _dialogPresenter.get() })
if (auto keyboardWarningInfoBar = FindName(L"KeyboardWarningInfoBar").try_as<MUX::Controls::InfoBar>())
{
presenter.ShowDialog(FindName(L"KeyboardServiceDisabledDialog").try_as<WUX::Controls::ContentDialog>());
keyboardWarningInfoBar.IsOpen(true);
}
}
@@ -2826,9 +2810,9 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - Return the fully-formed warning message for the
// "KeyboardServiceDisabled" dialog. This dialog is used to warn the user
// "KeyboardServiceDisabled" InfoBar. This InfoBar is used to warn the user
// if the keyboard service is disabled, and uses the OS localization for
// the service's actual name. It's bound to the dialog in XAML.
// the service's actual name. It's bound to the bar in XAML.
// Return Value:
// - The warning message, including the OS-localized service name.
winrt::hstring TerminalPage::KeyboardServiceDisabledText()

View File

@@ -224,8 +224,6 @@ namespace winrt::TerminalApp::implementation
void _OpenSettingsUI();
void _ReapplyCompactTabSize();
void _MakeSwitchToTabCommand(const TerminalApp::TabBase& tab, const uint32_t index);
static int _ComputeScrollDelta(ScrollDirection scrollDirection, const uint32_t rowsToScroll);

View File

@@ -83,24 +83,18 @@ the MIT License. See LICENSE in the project root for license information. -->
</TextBlock>
</ContentDialog>
<ContentDialog
x:Load="False"
x:Name="KeyboardServiceDisabledDialog"
x:Uid="KeyboardServiceDisabledDialog"
DefaultButton="Primary">
<TextBlock
Foreground="{ThemeResource ErrorTextBrush}"
IsTextSelectionEnabled="True"
TextWrapping="WrapWholeWords"
Text="{x:Bind KeyboardServiceDisabledText, Mode=OneWay}" />
</ContentDialog>
<local:CommandPalette
x:Name="CommandPalette"
Grid.Row="1"
Visibility="Collapsed"
VerticalAlignment="Stretch" />
<mux:InfoBar x:Name="KeyboardWarningInfoBar"
x:Load="False"
IsClosable="True"
IsIconVisible="True"
IsOpen="False"
Severity="Warning"
Message="{x:Bind KeyboardServiceDisabledText, Mode=OneWay}"/>
</Grid>
</Page>

View File

@@ -500,7 +500,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem closeTabMenuItem;
Controls::FontIcon closeSymbol;
closeSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
closeSymbol.Glyph(L"\xE8BB");
closeSymbol.Glyph(L"\xE711");
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
@@ -546,7 +546,7 @@ namespace winrt::TerminalApp::implementation
// "Rename Tab"
Controls::FontIcon renameTabSymbol;
renameTabSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
renameTabSymbol.Glyph(L"\xE932"); // Label
renameTabSymbol.Glyph(L"\xE8AC"); // Rename
renameTabMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
@@ -564,7 +564,6 @@ namespace winrt::TerminalApp::implementation
newTabFlyout.Items().Append(chooseColorMenuItem);
newTabFlyout.Items().Append(renameTabMenuItem);
newTabFlyout.Items().Append(menuSeparator);
newTabFlyout.Items().Append(_CreateCloseSubMenu());
newTabFlyout.Items().Append(closeTabMenuItem);
TabViewItem().ContextFlyout(newTabFlyout);
}
@@ -855,6 +854,8 @@ namespace winrt::TerminalApp::implementation
TabViewItem().Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), fontBrush);
TabViewItem().Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush);
TabViewItem().Resources().Insert(winrt::box_value(L"TabViewButtonForegroundActiveTab"), fontBrush);
TabViewItem().Resources().Insert(winrt::box_value(L"TabViewButtonForegroundPressed"), fontBrush);
TabViewItem().Resources().Insert(winrt::box_value(L"TabViewButtonForegroundPointerOver"), fontBrush);
_RefreshVisualState();

View File

@@ -74,13 +74,13 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.200609001" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.201202003" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.201017.1" targetFramework="native" />
</packages>

View File

@@ -6,7 +6,6 @@
#include "ConptyConnection.h"
#include <windows.h>
#include <userenv.h>
#include "ConptyConnection.g.cpp"
@@ -94,11 +93,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
environment.clear();
});
{
const auto newEnvironmentBlock{ Utils::CreateEnvironmentBlock() };
// Populate the environment map with the current environment.
RETURN_IF_FAILED(Utils::UpdateEnvironmentMapW(environment, newEnvironmentBlock.get()));
}
// Populate the environment map with the current environment.
RETURN_IF_FAILED(Utils::UpdateEnvironmentMapW(environment));
{
// Convert connection Guid to string and ignore the enclosing '{}'.

View File

@@ -81,6 +81,5 @@
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -1943,6 +1943,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// - Pre-process text pasted (presumably from the clipboard)
// before sending it over the terminal's connection, converting
// Windows-space \r\n line-endings to \r line-endings
// - Also converts \n line-endings to \r line-endings
void TermControl::_SendPastedTextToConnection(const std::wstring& wstr)
{
// Some notes on this implementation:
@@ -1952,20 +1953,52 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// performance guarantees aren't exactly stellar)
// - The STL doesn't have a simple string search/replace method.
// This fact is lamentable.
// - This line-ending conversion is intentionally fairly
// conservative, to avoid stripping out lone \n characters
// where they could conceivably be intentional.
// - We search for \n, and when we find it we copy the string up to
// the \n (but not including it). Then, we check the if the
// previous character is \r, if its not, then we had a lone \n
// and so we append our own \r
std::wstring stripped{ wstr };
std::wstring stripped;
stripped.reserve(wstr.length());
std::wstring::size_type pos = 0;
std::wstring::size_type begin = 0;
while ((pos = stripped.find(L"\r\n", pos)) != std::wstring::npos)
while ((pos = wstr.find(L"\n", pos)) != std::wstring::npos)
{
stripped.replace(pos, 2, L"\r");
// copy up to but not including the \n
stripped.append(wstr.cbegin() + begin, wstr.cbegin() + pos);
if (!(pos > 0 && (wstr.at(pos - 1) == L'\r')))
{
// there was no \r before the \n we did not copy,
// so append our own \r (this effectively replaces the \n
// with a \r)
stripped.push_back(L'\r');
}
++pos;
begin = pos;
}
_connection.WriteInput(stripped);
// If we entered the while loop even once, begin would be non-zero
// (because we set begin = pos right after incrementing pos)
// So, if begin is still zero at this point it means we never found a newline
// and we can just write the original string
if (begin == 0)
{
_connection.WriteInput(wstr);
}
else
{
// copy over the part after the last \n
stripped.append(wstr.cbegin() + begin, wstr.cend());
// we may have removed some characters, so we may not need as much space
// as we reserved earlier
stripped.shrink_to_fit();
_connection.WriteInput(stripped);
}
_terminal->ClearSelection();
_terminal->TrySnapOnInput();
}
@@ -2438,6 +2471,17 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// closed. We can just do it whenever.
_AsyncCloseConnection();
{
// GH#8734:
// We lock the terminal here to make sure it isn't still being
// used in the connection thread before we destroy the renderer.
// However, we must unlock it again prior to triggering the
// teardown, to avoid the render thread being deadlocked. The
// renderer may be waiting to acquire the terminal lock, while
// we're waiting for the renderer to finish.
auto lock = _terminal->LockForWriting();
}
if (auto localRenderEngine{ std::exchange(_renderEngine, nullptr) })
{
if (auto localRenderer{ std::exchange(_renderer, nullptr) })
@@ -2917,9 +2961,46 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return;
}
if (e.DataView().Contains(StandardDataFormats::StorageItems()))
if (e.DataView().Contains(StandardDataFormats::ApplicationLink()))
{
auto items = co_await e.DataView().GetStorageItemsAsync();
try
{
Windows::Foundation::Uri link{ co_await e.DataView().GetApplicationLinkAsync() };
_SendPastedTextToConnection(std::wstring{ link.AbsoluteUri() });
}
CATCH_LOG();
}
else if (e.DataView().Contains(StandardDataFormats::WebLink()))
{
try
{
Windows::Foundation::Uri link{ co_await e.DataView().GetWebLinkAsync() };
_SendPastedTextToConnection(std::wstring{ link.AbsoluteUri() });
}
CATCH_LOG();
}
else if (e.DataView().Contains(StandardDataFormats::Text()))
{
try
{
std::wstring text{ co_await e.DataView().GetTextAsync() };
_SendPastedTextToConnection(text);
}
CATCH_LOG();
}
// StorageItem must be last. Some applications put hybrid data format items
// in a drop message and we'll eat a crash when we request them.
// Those applications usually include Text as well, so having storage items
// last makes sure we'll hit text before getting to them.
else if (e.DataView().Contains(StandardDataFormats::StorageItems()))
{
Windows::Foundation::Collections::IVectorView<Windows::Storage::IStorageItem> items;
try
{
items = co_await e.DataView().GetStorageItemsAsync();
}
CATCH_LOG();
if (items.Size() > 0)
{
std::wstring allPaths;
@@ -2949,15 +3030,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_SendInputToConnection(allPaths);
}
}
else if (e.DataView().Contains(StandardDataFormats::Text()))
{
try
{
std::wstring text{ co_await e.DataView().GetTextAsync() };
_SendPastedTextToConnection(text);
}
CATCH_LOG();
}
}
// Method Description:

View File

@@ -81,7 +81,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
GETSET_SETTING(bool, DebugFeaturesEnabled); // default value set in constructor
GETSET_SETTING(bool, StartOnUserLogin, false);
GETSET_SETTING(bool, AlwaysOnTop, false);
GETSET_SETTING(Model::TabSwitcherMode, TabSwitcherMode, Model::TabSwitcherMode::MostRecentlyUsed);
GETSET_SETTING(Model::TabSwitcherMode, TabSwitcherMode, Model::TabSwitcherMode::InOrder);
GETSET_SETTING(bool, DisableAnimations, false);
private:

View File

@@ -41,7 +41,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
void KeyMapping::SetKeyBinding(const Microsoft::Terminal::Settings::Model::ActionAndArgs& actionAndArgs,
const KeyChord& chord)
{
// if the chord is already mapped - clear the mapping
if (_keyShortcuts.find(chord) != _keyShortcuts.end())
{
ClearKeyBinding(chord);
}
_keyShortcuts[chord] = actionAndArgs;
_keyShortcutsByInsertionOrder.push_back(std::make_pair(chord, actionAndArgs));
}
// Method Description:
@@ -53,12 +60,19 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
void KeyMapping::ClearKeyBinding(const KeyChord& chord)
{
_keyShortcuts.erase(chord);
KeyChordEquality keyChordEquality;
_keyShortcutsByInsertionOrder.erase(std::remove_if(_keyShortcutsByInsertionOrder.begin(), _keyShortcutsByInsertionOrder.end(), [keyChordEquality, chord](const auto& keyBinding) {
return keyChordEquality(keyBinding.first, chord);
}),
_keyShortcutsByInsertionOrder.end());
}
KeyChord KeyMapping::GetKeyBindingForAction(Microsoft::Terminal::Settings::Model::ShortcutAction const& action)
{
for (auto& kv : _keyShortcuts)
for (auto it = _keyShortcutsByInsertionOrder.rbegin(); it != _keyShortcutsByInsertionOrder.rend(); ++it)
{
const auto& kv = *it;
if (kv.second.Action() == action)
{
return kv.first;
@@ -72,6 +86,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// and IActionArgs. This enables searching no only for the binding of a
// particular ShortcutAction, but also a particular set of values for
// arguments to that action.
// If several bindings might match the lookup, prefers the one that was added last.
// Arguments:
// - actionAndArgs: The ActionAndArgs to lookup the keybinding for.
// Return Value:
@@ -83,8 +98,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return { nullptr };
}
for (auto& kv : _keyShortcuts)
for (auto it = _keyShortcutsByInsertionOrder.rbegin(); it != _keyShortcutsByInsertionOrder.rend(); ++it)
{
const auto& kv = *it;
const auto action = kv.second.Action();
const auto args = kv.second.Args();
const auto actionMatched = action == actionAndArgs.Action();

View File

@@ -71,6 +71,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
private:
std::unordered_map<TerminalControl::KeyChord, Model::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
std::vector<std::pair<TerminalControl::KeyChord, Model::ActionAndArgs>> _keyShortcutsByInsertionOrder;
friend class SettingsModelLocalTests::DeserializationTests;
friend class SettingsModelLocalTests::KeyBindingsTests;

View File

@@ -177,12 +177,12 @@
<!-- ========================= Globals ======================== -->
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<!-- This target will take our defaults.json and stamp it into a .h file that
we can include in the code directly. This way, we don't need to worry about

View File

@@ -96,7 +96,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
GETSET_SETTING(hstring, BackgroundImagePath);
GETSET_SETTING(double, BackgroundImageOpacity, 1.0);
GETSET_SETTING(Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::Fill);
GETSET_SETTING(Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::UniformToFill);
GETSET_SETTING(Microsoft::Terminal::TerminalControl::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::TerminalControl::TextAntialiasingMode::Grayscale);
GETSET_SETTING(bool, RetroTerminalEffect, false);

View File

@@ -18,7 +18,7 @@
"showTabsInTitlebar": true,
"showTerminalTitleInTitlebar": true,
"tabWidthMode": "equal",
"useTabSwitcher": "mru",
"tabSwitcherMode": "inOrder",
// Miscellaneous
"confirmCloseAllTabs": true,

View File

@@ -70,12 +70,12 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<ItemDefinitionGroup>

View File

@@ -276,10 +276,77 @@ void IslandWindow::OnSize(const UINT width, const UINT height)
}
}
// Method Description:
// - Handles a WM_GETMINMAXINFO message, issued before the window sizing starts.
// This message allows to modify the minimal and maximal dimensions of the window.
// We focus on minimal dimensions here
// (the maximal dimension will be calculate upon maximizing)
// Our goal is to protect against to downsizing to less than minimal allowed dimensions,
// that might occur in the scenarios where _OnSizing is bypassed.
// An example of such scenario is anchoring the window to the top/bottom screen border
// in order to maximize window height (GH# 8026).
// The computation is similar to what we do in _OnSizing:
// we need to consider both the client area and non-client exclusive area sizes,
// while taking DPI into account as well.
// Arguments:
// - lParam: Pointer to the requested MINMAXINFO struct,
// a ptMinTrackSize field of which we want to update with the computed dimensions.
// It also acts as the return value (it's a ref parameter).
// Return Value:
// - <none>
void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam)
{
// Without a callback we don't know to snap the dimensions of the client area.
// Should not be a problem, the callback is not set early in the startup
// The initial dimensions will be set later on
if (!_pfnSnapDimensionCallback)
{
return;
}
HMONITOR hmon = MonitorFromWindow(GetHandle(), MONITOR_DEFAULTTONEAREST);
if (hmon == NULL)
{
return;
}
UINT dpix = USER_DEFAULT_SCREEN_DPI;
UINT dpiy = USER_DEFAULT_SCREEN_DPI;
GetDpiForMonitor(hmon, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
// From now we use dpix for all computations (same as in _OnSizing).
const auto nonClientSizeScaled = GetTotalNonClientExclusiveSize(dpix);
const auto scale = base::ClampedNumeric<float>(dpix) / USER_DEFAULT_SCREEN_DPI;
auto lpMinMaxInfo = reinterpret_cast<LPMINMAXINFO>(lParam);
lpMinMaxInfo->ptMinTrackSize.x = _calculateTotalSize(true, minimumWidth * scale, nonClientSizeScaled.cx);
lpMinMaxInfo->ptMinTrackSize.y = _calculateTotalSize(false, minimumHeight * scale, nonClientSizeScaled.cy);
}
// Method Description:
// - Helper function that calculates a singe dimension value, given initialWindow and nonClientSizes
// Arguments:
// - isWidth: parameter to pass to SnapDimensionCallback.
// True if the method is invoked for width computation, false if for height.
// - clientSize: the size of the client area (already)
// - nonClientSizeScaled: the exclusive non-client size (already scaled)
// Return Value:
// - The total dimension
long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize, const long nonClientSize)
{
return gsl::narrow_cast<int>(_pfnSnapDimensionCallback(isWidth, gsl::narrow_cast<float>(clientSize)) + nonClientSize);
}
[[nodiscard]] LRESULT IslandWindow::MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
{
switch (message)
{
case WM_GETMINMAXINFO:
{
_OnGetMinMaxInfo(wparam, lparam);
return 0;
}
case WM_CREATE:
{
_HandleCreateWindow(wparam, lparam);

View File

@@ -74,7 +74,15 @@ protected:
LONG _getDesiredWindowStyle() const;
void _OnGetMinMaxInfo(const WPARAM wParam, const LPARAM lParam);
long _calculateTotalSize(const bool isWidth, const long clientSize, const long nonClientSize);
private:
// This minimum width allows for width the tabs fit
static constexpr long minimumWidth = 460L;
// We run with no height requirement for client area,
// though the total height will take into account the non-client area
// and the requirements of components hosted in the client area
static constexpr long minimumHeight = 0L;
};

View File

@@ -95,14 +95,14 @@
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets'))" />

View File

@@ -2,7 +2,7 @@
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.201017.1" targetFramework="native" />
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.200609001" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.201202003" targetFramework="native" />
<package id="Microsoft.VCRTForwarders.140" version="1.0.1-rc" targetFramework="native" />
<package id="Terminal.ThemeHelpers" version="0.2.200324001" targetFramework="native" />
</packages>

View File

@@ -69,5 +69,5 @@ TRACELOGGING_DECLARE_PROVIDER(g_hWindowsTerminalProvider);
// For commandline argument processing
#include <shellapi.h>
#include <processenv.h>
#include <WinUser.h>
#include "til.h"

View File

@@ -73,14 +73,14 @@
</ItemGroup>
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>

View File

@@ -138,7 +138,7 @@ namespace Microsoft.Terminal.Wpf
NativeMethods.TerminalSetTheme(this.terminal, theme, fontFamily, fontSize, (int)dpiScale.PixelsPerInchX);
if (!this.RenderSize.IsEmpty)
if (!this.RenderSize.IsEmpty && !this.TerminalControlSize.IsEmpty)
{
this.Resize(this.TerminalControlSize);
}

View File

@@ -143,11 +143,16 @@ namespace Microsoft.Terminal.Wpf
{
var dpiScale = VisualTreeHelper.GetDpi(this);
// termContainer requires scaled sizes.
var newSizeWidth = (sizeInfo.NewSize.Width - this.scrollbar.ActualWidth) * dpiScale.DpiScaleX;
newSizeWidth = newSizeWidth < 0 ? 0 : newSizeWidth;
var newSizeHeight = sizeInfo.NewSize.Height * dpiScale.DpiScaleY;
newSizeHeight = newSizeHeight < 0 ? 0 : newSizeHeight;
this.termContainer.TerminalControlSize = new Size()
{
Width = (sizeInfo.NewSize.Width - this.scrollbar.ActualWidth) * dpiScale.DpiScaleX,
Height = sizeInfo.NewSize.Height * dpiScale.DpiScaleY,
Width = newSizeWidth,
Height = newSizeHeight,
};
if (!this.AutoResize)

View File

@@ -90,7 +90,7 @@
<!-- From Microsoft.UI.Xaml.targets -->
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<ItemDefinitionGroup>

View File

@@ -524,7 +524,24 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
COORD const coordScreenBufferSize = screenInfo.GetBufferSize().Dimensions();
if (size.X != coordScreenBufferSize.X || size.Y != coordScreenBufferSize.Y)
{
RETURN_NTSTATUS(screenInfo.ResizeScreenBuffer(size, TRUE));
RETURN_IF_NTSTATUS_FAILED(screenInfo.ResizeScreenBuffer(size, TRUE));
}
// Make sure the viewport doesn't now overflow the buffer dimensions.
auto overflow = screenInfo.GetViewport().BottomRightExclusive() - screenInfo.GetBufferSize().Dimensions();
if (overflow.X > 0 || overflow.Y > 0)
{
overflow = { std::max<SHORT>(overflow.X, 0), std::max<SHORT>(overflow.Y, 0) };
RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, -overflow, false));
}
// And also that the cursor position is clamped within the buffer boundaries.
auto& cursor = screenInfo.GetTextBuffer().GetCursor();
auto clampedCursorPosition = cursor.GetPosition();
screenInfo.GetBufferSize().Clamp(clampedCursorPosition);
if (clampedCursorPosition != cursor.GetPosition())
{
cursor.SetPosition(clampedCursorPosition);
}
return S_OK;
@@ -620,6 +637,23 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
// (see https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx and DoSrvSetConsoleWindowInfo)
// Note that it also doesn't set cursor position.
// However, we do need to make sure the viewport doesn't now overflow the buffer dimensions.
auto overflow = context.GetViewport().BottomRightExclusive() - context.GetBufferSize().Dimensions();
if (overflow.X > 0 || overflow.Y > 0)
{
overflow = { std::max<SHORT>(overflow.X, 0), std::max<SHORT>(overflow.Y, 0) };
RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, -overflow, false));
}
// And also that the cursor position is clamped within the buffer boundaries.
auto& cursor = context.GetTextBuffer().GetCursor();
auto clampedCursorPosition = cursor.GetPosition();
context.GetBufferSize().Clamp(clampedCursorPosition);
if (clampedCursorPosition != cursor.GetPosition())
{
cursor.SetPosition(clampedCursorPosition);
}
return S_OK;
}
CATCH_RETURN();

View File

@@ -276,7 +276,7 @@ const std::vector<Microsoft::Console::Render::RenderOverlay> RenderData::GetOver
// - <none>
// Return Value:
// - true if the cursor should be drawn twice as wide as usual
bool RenderData::IsCursorDoubleWidth() const noexcept
bool RenderData::IsCursorDoubleWidth() const
{
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
return gci.GetActiveOutputBuffer().CursorIsDoubleWidth();

View File

@@ -46,7 +46,7 @@ public:
CursorType GetCursorStyle() const noexcept override;
ULONG GetCursorPixelWidth() const noexcept override;
COLORREF GetCursorColor() const noexcept override;
bool IsCursorDoubleWidth() const noexcept override;
bool IsCursorDoubleWidth() const override;
bool IsScreenReversed() const noexcept override;

View File

@@ -2146,7 +2146,7 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport,
}
// do adjustments on a copy that's easily manipulated.
SMALL_RECT srCorrected = newViewport.ToInclusive();
SMALL_RECT srCorrected = newViewport.ToExclusive();
if (srCorrected.Left < 0)
{
@@ -2160,16 +2160,16 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport,
}
const COORD coordScreenBufferSize = GetBufferSize().Dimensions();
if (srCorrected.Right >= coordScreenBufferSize.X)
if (srCorrected.Right > coordScreenBufferSize.X)
{
srCorrected.Right = coordScreenBufferSize.X;
}
if (srCorrected.Bottom >= coordScreenBufferSize.Y)
if (srCorrected.Bottom > coordScreenBufferSize.Y)
{
srCorrected.Bottom = coordScreenBufferSize.Y;
}
_viewport = Viewport::FromInclusive(srCorrected);
_viewport = Viewport::FromExclusive(srCorrected);
if (updateBottom)
{
UpdateBottom();

View File

@@ -651,8 +651,12 @@ BOOL HandleMouseEvent(const SCREEN_INFORMATION& ScreenInfo,
sDelta = GET_WHEEL_DELTA_WPARAM(wParam);
}
if (HandleTerminalMouseEvent(MousePosition, Message, GET_KEYSTATE_WPARAM(wParam), sDelta))
if (HandleTerminalMouseEvent(MousePosition, Message, LOWORD(GetControlKeyState(0)), sDelta))
{
// Use GetControlKeyState here to get the control state in console event mode.
// This will ensure that we get ALT and SHIFT, the former of which is not available
// through MK_ constants. We only care about the bottom 16 bits.
// GH#6401: Capturing the mouse ensures that we get drag/release events
// even if the user moves outside the window.
// HandleTerminalMouseEvent returns false if the terminal's not in VT mode,

View File

@@ -186,8 +186,10 @@ public:
wch = L'\x0';
break;
}
// MK_SHIFT is ignored by the translator
wch += (sModifierKeystate & MK_CONTROL) ? 0x08 : 0x00;
// Use Any here with the multi-flag constants -- they capture left/right key state
WI_UpdateFlag(wch, 0x04, WI_IsAnyFlagSet(sModifierKeystate, SHIFT_PRESSED));
WI_UpdateFlag(wch, 0x08, WI_IsAnyFlagSet(sModifierKeystate, ALT_PRESSED));
WI_UpdateFlag(wch, 0x10, WI_IsAnyFlagSet(sModifierKeystate, CTRL_PRESSED));
return wch;
}
@@ -222,8 +224,10 @@ public:
result = 0;
break;
}
// MK_SHIFT and MK_ALT is ignored by the translator
result += (sModifierKeystate & MK_CONTROL) ? 0x08 : 0x00;
// Use Any here with the multi-flag constants -- they capture left/right key state
WI_UpdateFlag(result, 0x04, WI_IsAnyFlagSet(sModifierKeystate, SHIFT_PRESSED));
WI_UpdateFlag(result, 0x08, WI_IsAnyFlagSet(sModifierKeystate, ALT_PRESSED));
WI_UpdateFlag(result, 0x10, WI_IsAnyFlagSet(sModifierKeystate, CTRL_PRESSED));
return result;
}
@@ -274,8 +278,8 @@ public:
BEGIN_TEST_METHOD_PROPERTIES()
// TEST_METHOD_PROPERTY(L"Data:uiButton", L"{WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP}")
TEST_METHOD_PROPERTY(L"Data:uiButton", L"{0x0201, 0x0202, 0x0207, 0x0208, 0x0204, 0x0205}")
// None, MK_SHIFT, MK_CONTROL
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0004, 0x0008}")
// None, SHIFT, LEFT_CONTROL, RIGHT_ALT, RIGHT_ALT | LEFT_CONTROL
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0010, 0x0008, 0x0001, 0x0009}")
END_TEST_METHOD_PROPERTIES()
Log::Comment(L"Starting test...");
@@ -357,7 +361,8 @@ public:
BEGIN_TEST_METHOD_PROPERTIES()
// TEST_METHOD_PROPERTY(L"Data:uiButton", L"{WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP}")
TEST_METHOD_PROPERTY(L"Data:uiButton", L"{0x0201, 0x0202, 0x0207, 0x0208, 0x0204, 0x0205}")
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0004, 0x0008}")
// None, SHIFT, LEFT_CONTROL, RIGHT_ALT, RIGHT_ALT | LEFT_CONTROL
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0010, 0x0008, 0x0001, 0x0009}")
END_TEST_METHOD_PROPERTIES()
Log::Comment(L"Starting test...");
@@ -443,7 +448,8 @@ public:
BEGIN_TEST_METHOD_PROPERTIES()
// TEST_METHOD_PROPERTY(L"Data:uiButton", L"{WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_MOUSEMOVE}")
TEST_METHOD_PROPERTY(L"Data:uiButton", L"{0x0201, 0x0202, 0x0207, 0x0208, 0x0204, 0x0205, 0x0200}")
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0004, 0x0008}")
// None, SHIFT, LEFT_CONTROL, RIGHT_ALT, RIGHT_ALT | LEFT_CONTROL
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0010, 0x0008, 0x0001, 0x0009}")
END_TEST_METHOD_PROPERTIES()
Log::Comment(L"Starting test...");
@@ -523,7 +529,8 @@ public:
{
BEGIN_TEST_METHOD_PROPERTIES()
TEST_METHOD_PROPERTY(L"Data:sScrollDelta", L"{-120, 120, -10000, 32736}")
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0004, 0x0008}")
// None, SHIFT, LEFT_CONTROL, RIGHT_ALT, RIGHT_ALT | LEFT_CONTROL
TEST_METHOD_PROPERTY(L"Data:uiModifierKeystate", L"{0x0000, 0x0010, 0x0008, 0x0001, 0x0009}")
END_TEST_METHOD_PROPERTIES()
Log::Comment(L"Starting test...");

View File

@@ -133,8 +133,8 @@ constexpr unsigned int TerminalInput::s_GetPressedButton(const MouseButtonState
// 11 - released (none)
// Next three bits indicate modifier keys:
// 0x04 - shift (This never makes it through, as our emulator is skipped when shift is pressed.)
// 0x08 - ctrl
// 0x10 - meta
// 0x08 - meta
// 0x10 - ctrl
// 32 (x20) is added for "hover" events:
// "For example, motion into cell x,y with button 1 down is reported as `CSI M @ CxCy`.
// ( @ = 32 + 0 (button 1) + 32 (motion indicator) ).
@@ -146,7 +146,7 @@ constexpr unsigned int TerminalInput::s_GetPressedButton(const MouseButtonState
// Parameters:
// - button - the message to decode.
// - isHover - whether or not this is a hover event
// - modifierKeyState - alt/ctrl/shift key hold state
// - modifierKeyState - the modifier keys _in console format_
// - delta - scroll wheel delta
// Return value:
// - the int representing the equivalent X button encoding.
@@ -188,12 +188,10 @@ static constexpr int _windowsButtonToXEncoding(const unsigned int button,
xvalue += 0x20;
}
// Shift will never pass through to us, because shift is used by the host to skip VT mouse and use the default handler.
// TODO: MSFT:8804719 Add an option to disable/remap shift as a bypass for VT mousemode handling
// xvalue += (modifierKeyState & MK_SHIFT) ? 0x04 : 0x00;
xvalue += (modifierKeyState & MK_CONTROL) ? 0x08 : 0x00;
// Unfortunately, we don't get meta/alt as a part of mouse events. Only Ctrl and Shift.
// xvalue += (modifierKeyState & MK_META) ? 0x10 : 0x00;
// Use Any here with the multi-flag constants -- they capture left/right key state
WI_UpdateFlag(xvalue, 0x04, WI_IsAnyFlagSet(modifierKeyState, SHIFT_PRESSED));
WI_UpdateFlag(xvalue, 0x08, WI_IsAnyFlagSet(modifierKeyState, ALT_PRESSED));
WI_UpdateFlag(xvalue, 0x10, WI_IsAnyFlagSet(modifierKeyState, CTRL_PRESSED));
return xvalue;
}
@@ -206,6 +204,7 @@ static constexpr int _windowsButtonToXEncoding(const unsigned int button,
// See MSFT:19461988 and https://github.com/Microsoft/console/issues/296
// Parameters:
// - button - the message to decode.
// - modifierKeyState - the modifier keys _in console format_
// Return value:
// - the int representing the equivalent X button encoding.
static constexpr int _windowsButtonToSGREncoding(const unsigned int button,
@@ -247,12 +246,10 @@ static constexpr int _windowsButtonToSGREncoding(const unsigned int button,
xvalue += 0x20;
}
// Shift will never pass through to us, because shift is used by the host to skip VT mouse and use the default handler.
// TODO: MSFT:8804719 Add an option to disable/remap shift as a bypass for VT mousemode handling
// xvalue += (modifierKeyState & MK_SHIFT) ? 0x04 : 0x00;
xvalue += (modifierKeyState & MK_CONTROL) ? 0x08 : 0x00;
// Unfortunately, we don't get meta/alt as a part of mouse events. Only Ctrl and Shift.
// xvalue += (modifierKeyState & MK_META) ? 0x10 : 0x00;
// Use Any here with the multi-flag constants -- they capture left/right key state
WI_UpdateFlag(xvalue, 0x04, WI_IsAnyFlagSet(modifierKeyState, SHIFT_PRESSED));
WI_UpdateFlag(xvalue, 0x08, WI_IsAnyFlagSet(modifierKeyState, ALT_PRESSED));
WI_UpdateFlag(xvalue, 0x10, WI_IsAnyFlagSet(modifierKeyState, CTRL_PRESSED));
return xvalue;
}

View File

@@ -3,50 +3,36 @@
#include "precomp.h"
#include "inc/Environment.hpp"
#include "wil/token_helpers.h"
using namespace ::Microsoft::Console::Utils;
// We cannot use spand or not_null because we're dealing with \0\0-terminated buffers of unknown length
#pragma warning(disable : 26481 26429)
// Function Description:
// - Wraps win32's CreateEnvironmentBlock to return a smart pointer.
EnvironmentBlockPtr Microsoft::Console::Utils::CreateEnvironmentBlock()
{
void* newEnvironmentBlock{ nullptr };
auto processToken{ wil::open_current_access_token(TOKEN_QUERY | TOKEN_DUPLICATE) };
if (!::CreateEnvironmentBlock(&newEnvironmentBlock, processToken.get(), FALSE))
{
return nullptr;
}
return EnvironmentBlockPtr{ newEnvironmentBlock };
}
// Function Description:
// - Updates an EnvironmentVariableMapW with the current process's unicode
// environment variables ignoring ones already set in the provided map.
// Arguments:
// - map: The map to populate with the current processes's environment variables.
// - environmentBlock: Optional environment block to use when filling map. If omitted,
// defaults to the current environment.
// Return Value:
// - S_OK if we succeeded, or an appropriate HRESULT for failing
HRESULT Microsoft::Console::Utils::UpdateEnvironmentMapW(EnvironmentVariableMapW& map, void* environmentBlock) noexcept
HRESULT Microsoft::Console::Utils::UpdateEnvironmentMapW(EnvironmentVariableMapW& map) noexcept
try
{
wchar_t const* activeEnvironmentBlock{ static_cast<wchar_t const*>(environmentBlock) };
LPWCH currentEnvVars{};
auto freeCurrentEnv = wil::scope_exit([&] {
if (currentEnvVars)
{
FreeEnvironmentStringsW(currentEnvVars);
currentEnvVars = nullptr;
}
});
wil::unique_environstrings_ptr currentEnvVars;
if (!activeEnvironmentBlock)
{
currentEnvVars.reset(::GetEnvironmentStringsW());
RETURN_HR_IF_NULL(E_OUTOFMEMORY, currentEnvVars);
activeEnvironmentBlock = currentEnvVars.get();
}
currentEnvVars = ::GetEnvironmentStringsW();
RETURN_HR_IF_NULL(E_OUTOFMEMORY, currentEnvVars);
// Each entry is NULL-terminated; block is guaranteed to be double-NULL terminated at a minimum.
for (wchar_t const* lastCh{ activeEnvironmentBlock }; *lastCh != '\0'; ++lastCh)
for (wchar_t const* lastCh{ currentEnvVars }; *lastCh != '\0'; ++lastCh)
{
// Copy current entry into temporary map.
const size_t cchEntry{ ::wcslen(lastCh) };

View File

@@ -21,12 +21,9 @@ namespace Microsoft::Console::Utils
}
};
using EnvironmentBlockPtr = wil::unique_any<void*, decltype(::DestroyEnvironmentBlock), ::DestroyEnvironmentBlock>;
[[nodiscard]] EnvironmentBlockPtr CreateEnvironmentBlock();
using EnvironmentVariableMapW = std::map<std::wstring, std::wstring, WStringCaseInsensitiveCompare>;
[[nodiscard]] HRESULT UpdateEnvironmentMapW(EnvironmentVariableMapW& map, void* environmentBlock = nullptr) noexcept;
[[nodiscard]] HRESULT UpdateEnvironmentMapW(EnvironmentVariableMapW& map) noexcept;
[[nodiscard]] HRESULT EnvironmentMapToEnvironmentStringsW(EnvironmentVariableMapW& map,
std::vector<wchar_t>& newEnvVars) noexcept;

View File

@@ -57,6 +57,7 @@ namespace Microsoft::Console::Types
SHORT Height() const noexcept;
SHORT Width() const noexcept;
COORD Origin() const noexcept;
COORD BottomRightExclusive() const noexcept;
COORD EndExclusive() const noexcept;
COORD Dimensions() const noexcept;

View File

@@ -29,7 +29,6 @@ Abstract:
// Windows Header Files:
#include <windows.h>
#include <userenv.h>
#include <combaseapi.h>
#include <UIAutomation.h>
#include <objbase.h>

View File

@@ -137,6 +137,17 @@ COORD Viewport::Origin() const noexcept
return { Left(), Top() };
}
// Method Description:
// - Get a coord representing the bottom right of the viewport in exclusive terms.
// Arguments:
// - <none>
// Return Value:
// - the exclusive bottom right coordinates of this viewport.
COORD Viewport::BottomRightExclusive() const noexcept
{
return { RightExclusive(), BottomExclusive() };
}
// Method Description:
// - For Accessibility, get a COORD representing the end of this viewport in exclusive terms.
// - This is needed to represent an exclusive endpoint in UiaTextRange that includes the last

View File

@@ -440,10 +440,11 @@ void ConPtyTests::DiesOnClose()
VERIFY_IS_TRUE(GetExitCodeProcess(piClient.hProcess, &dwExit));
VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE);
// Stash the pty process, it'll get zero'd after the call to close
const auto hConPtyProcess = pty.hConPtyProcess;
// Duplicate the pty process, it'll get closed and zero'd after the call to close
wil::unique_handle hConPtyProcess{};
THROW_IF_WIN32_BOOL_FALSE(DuplicateHandle(GetCurrentProcess(), pty.hConPtyProcess, GetCurrentProcess(), hConPtyProcess.put(), 0, FALSE, DUPLICATE_SAME_ACCESS));
VERIFY_IS_TRUE(GetExitCodeProcess(hConPtyProcess, &dwExit));
VERIFY_IS_TRUE(GetExitCodeProcess(hConPtyProcess.get(), &dwExit));
VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE);
Log::Comment(NoThrowString().Format(L"Sleep a bit to let the process attach"));
@@ -451,6 +452,6 @@ void ConPtyTests::DiesOnClose()
_ClosePseudoConsoleMembers(&pty);
GetExitCodeProcess(hConPtyProcess, &dwExit);
GetExitCodeProcess(hConPtyProcess.get(), &dwExit);
VERIFY_ARE_NOT_EQUAL(dwExit, (DWORD)STILL_ACTIVE);
}

View File

@@ -269,6 +269,7 @@ void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
}
TerminateProcess(pPty->hConPtyProcess, 0);
CloseHandle(pPty->hConPtyProcess);
pPty->hConPtyProcess = nullptr;
}
// Then take care of the reference handle.