TerminalControl doesn't use any of the built in text input and edit
controls provided by XAML for text input, which means TermianlControl
needs to communicate with the Text Services Framework (TSF) in order to
provide Input Method Editor (IME) support. Just like the rest of
Terminal we get to take advantage of newer APIs (Windows.UI.Text.Core)
namespace to provide support vs. the old TSF 1.0.
Windows.UI.Text.Core handles communication between a text edit control
and the text services primarily through a CoreTextEditContext object.
This change introduces a new UserControl TSFInputControl which is a
custom EditControl similar to the CustomEditControl sample[1].
TSFInputControl is similar (overlay with IME text) to how old console
(conimeinfo) handled IME.
# Details
TSFInputControl is a Windows.UI.Xaml.Controls.UserControl
TSFInputControl contains a Canvas control for absolution positioning a
TextBlock control within its containing control (TerminalControl).
The TextBlock control is used for displaying candidate text from the
IME. When the user makes a choice in the IME the TextBlock is cleared
and the text is written to the Terminal buffer like normal text.
TSFInputControl creates an instance of the CoreTextEditContext and
attaches appropriate event handlers to CoreTextEditContext in order to
interact with the IME.
A good write-up on how to interact with CoreTextEditContext can be found
here[2].
## Text Updates
Text updates from the IME come in on the TextUpdating event handler,
text updates are stored in an internal buffer (_inputBuffer).
## Completed Text
Once a user selects a text in the IME, the CompositionCompleted handler
is invoked. The input buffer (_inputBuffer) is written to the Terminal
buffer, _inputBuffer is cleared and Canvas and TextBlock controls are
hidden until the user starts a composition session again.
## Positioning
Telling the IME where to properly position itself was the hardest part
of this change. The IME expects to know it's location in screen
coordinates as supposed to client coordinates. This is pretty easy if
you are a pure UWP, but since we are hosted inside a XAMLIsland the
client to screen coordinate translation is a little harder.
### Calculating Screen Coordinates
1. Obtaining the Window position in Screen coordinates.
2. Determining the Client coordinate of the cursor.
3. Converting the Client coordinate of the cursor to Screen coordinates.
4. Offsetting the X and Y coordinate of the cursor by the position of
the TerminalControl within the window (tabs if present, margins, etc..).
5. Applying any scale factor of the display.
Once we have the right position in screen coordinates, this is supplied
in the LayoutBounds of the CoreTextLayoutRequestedEventArgs which lets
the IME know where to position itself on the Screen.
## Font Information/Cursor/Writing to Terminal
3 events were added to the TSFInputControl to create a loosely-coupled
implementation between the TerminalControl and the TSFInputControl.
These events are used for obtaining Font information from the
TerminalControl, getting the Cursor position and writing to the terminal
buffer.
## Known Issues
- Width of TextBlock is hardcoded to 200 pixels and most likely should
adjust to the available width of the current input line on the console
(#3640)
- Entering text in the middle of an existing set of text has TextBlock
render under existing text. Current Console behavior here isn't good
experience either (writes over text)
- Text input at edges of window is clipped versus wrapping around to
next line. This isn't any worse than the original command line, but
Terminal should be better (#3657)
## Future Considerations
Ideally, we'd be able to interact with the console buffer directly and
replace characters as the user types.
## Validation
General steps to try functionality
- Open Console
- Switch to Simplified Chinese (Shortcut: Windows+Spacebar)
- Switch to Chinese mode on language bar
Scenarios validated:
- As user types unformatted candidates appear on command line and IME
renders in correct position under unformatted characters.
- User can dismiss IME and text doesn't appear on command line
- Switch back to English mode, functions like normal
- New tab has proper behavior
- Switching between tabs has proper behavior
- Switching away from Terminal Window with IME present causes IME to
disappear
[1]: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CustomEditControl
[2]: https://docs.microsoft.com/en-us/windows/uwp/design/input/custom-text-inputCloses#459Closes#2213Closes#3641
* first take at suppressApplicationTitle rewrite
* Rebased tab title fixes
* updated settings doc
* incomplete - not suppressing where application title is changing
* added original startingTitle functionality back
* moved suppressApplicationTitle to ICoreSettings
* suppression is working, but tab navigation overrides it
* suppression works, but not with panes
* it works!
* code cleanup
* added suppressApplicationTitle to JSON schema
* more code cleanup
* changed starting title from wstring_view to wstring
* Formatting fix
## Summary of the Pull Request
With #3391, I almost certainly regressed the ability for the new tab dropdown to display the keybindings for each profile. This adds them back.
## PR Checklist
* [x] Closes#3603
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
Now, we can lookup keybindings not only for `ShortcutAction`s, but also `ActionAndArgs`s, so we can look up the binding for an action with a particular set of arguments.
---------------------------------------------
* fixes#3603 by searching for ActionAndArgs too
* Apply suggestions from code review
Co-Authored-By: Carlos Zamora <carlos.zamora@microsoft.com>
<!-- 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
Fixes#3604 where Increase/Decrease font size bindings were not working.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#3604
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Increase and decrease font size works once again!
-------------------------------------
* adding FromJson to AdjustFontSizeArgs
* made a legacy function that just allows you to do 1/-1 delta for adjusting font size
* adding test case
* removing extra quotes
* comments lmao
* FORMATTING WHY
## Summary of the Pull Request
Unties the concept of "focused control" from "active control".
Previously, we were exclusively using the "Focused" state of `TermControl`s to determine which one was active. This was fraught with gotchas - if anything else became focused, then suddenly there was _no_ pane focused in the Tab. This happened especially frequently if the user clicked on a tab to focus the window. Furthermore, in experimental branches with more UI added to the Terminal (such as [dev/migrie/f/2046-command-palette](https://github.com/microsoft/terminal/tree/dev/migrie/f/2046-command-palette)), when these UIs were added to the Terminal, they'd take focus, which again meant that there was no focused pane.
This fixes these issue by having each Tab manually track which Pane is active in that tab. The Tab is now the arbiter of who in the tree is "active". Panes still track this state, for them to be able to MoveFocus appropriately.
It also contains a related fix to prevent the tab separator from stealing focus from the TermControl. This required us to set the color of the un-focused Pane border to some color other that Transparent, so I went with the TabViewBackground. Panes now look like the following:
![image](https://user-images.githubusercontent.com/18356694/68697343-41ea2380-0544-11ea-8218-601b57fdd835.png)
## References
See also: #2046
## PR Checklist
* [x] Closes#1205
* [x] Closes#522
* [x] Closes#999
* [x] I work here
* [😢] Tests added/passed
* [n/a] Requires documentation to be updated
## Validation Steps Performed
Tested manually opening panes, closing panes, clicking around panes, the whole dance.
---------------------------------------------------
* this is janky but is close for some reason?
* This is _almost_ right to solve #1205
If I want to double up and also fix#522 (which I do), then I need to also
* when a tab GetsFocus, send the focus instead to the Pane
* When the border is clicked on, focus that pane's control
And like a lot of cleanup, because this is horrifying
* hey this autorevoker is really nice
* Encapsulate Pane::pfnGotFocus
* Propogate the events back up on close
* Encapsulate Tab::pfnFocusChanged, and clean up TerminalPage a bit
* Mostly just code cleanup, commenting
* This works to hittest on the borders
If the border is `Transparent`, then it can't hittest for Tapped events, and it'll fall through (to someone)
THis at least works, but looks garish
* Match the pane border to the TabViewHeader
* Fix a bit of dead code and a bad copy-pasta
* This _works_ to use a winrt event, but it's dirty
* Clean up everything from the winrt::event debacle.
* This is dead code that shouldn't have been there
* Turn Tab's callback into a winrt::event as well
This commit renames the functions in conpty.lib to Conpty* so that they
can be explicitly linked and introduces a header so they can be located.
It also updates the DEF for conpty.dll to reexport them with their
original names.
The crux of the issue here is that TerminalConnection is consuming the
_import_ symbols for the *PseudoConsole family of APIs, which simply
cannot be supplanted by a static library.
Avenues explored: * Exporting __imp_x from the static library to get all
up in kernel32's business. * Using /ALTERNATENAME:__imp_X=StaticX. It
turns out ALTERNATENAME is only consulted when the symbol isn't found
through traditional means.
This, renaming them, is the straightest path forward.
Fixes#3553.
* Adds HasBackgroundImage() and GetExpandedBackgroundImagePath() to
Profiles.cpp/h
* Fills Terminal Settings with expanded path, rather than path value
from profiles.json
* Adds simple regression tests to detect and fail if this fix is
circumvented in the future
Fixes#2922
* Make search a shared component for conhost and terminal
* Remove inclusion of deprecated interface file
* Code review changes, remove text buffer modification in Terminal
* remove unreferenced objects to fix build errors
* Fix test failure, guarantee uiaData object is correctly initialized in Search
* minor comment typo fix and format fix
* minor PR comments change
* ColorSeclection directly throw and return
* remove coordAnchor initialization
* minor method signature change
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes#1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
* Make ConPTY build as both LIB and DLL.
* Update TerminalConnection reference to LIB version (because Terminal builds both UWP and Centennial, requiring different CRTs each).
* DLL is now available (and against desktop CRT) to be PInvokable from C# for WPF terminal.
Note, DLL MUST BUILD PRECOMP to get the magic pragma linking information to the Desktop CRT.
* don't audit PTY lib. I can't do safe things because the safe things we use don't fit back inside kernelbase.dll.
Closes#3563.
## Summary of the Pull Request
RTF data is now copied to the clipboard. Tested by copy pasting text from terminal to WordPad.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#2487
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] 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: #2487
<!-- 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
Mostly similar to PR #1224. Added a new static method `GenRTF` in `TextBuffer` that is responsible
for generating the RTF representation of a given text. The generated RTF is added to the `DataPackage` that is ultimately passed to the clipboard.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Validated by copy pasting text from the terminal to WordPad. Validated with different colors to make sure that is working. (MS Word seems to prefer HTML data from the clipboard instead of RTF.)
<hr>
* Copy RTF data to the clipboard
* Added comment explaining various parts of the header
* Fixed static code analysis issues and added noexcept to GenRTF()
* Removed noexcept
<!-- 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 introduces a setting to both Profiles and ColorSchemes called <code>selectionBackground</code> that allows you to change the selection background color to what's specified. If <code>selectionBackground</code> isn't set in either the profile or color scheme, it'll default to what it was before - white.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#3326
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [x] Requires documentation to be updated
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- Added selectionBackground to existing profile and colorscheme tests.
- Verified that the color does change to what I expect it to be when I add "selectionBackground" to either/both a profile and a color scheme.
<hr>
* adding selectionBackground to ColorScheme and TerminalSettings
* Changing PaintSelection inside the renderers to take a SelectionBackground COLORREF
* changes to conhost and terminal renderdata, and to terminal settings and core
* IT WORKS
* modification of unit tests, json schemas, reordering of functions
* more movement
* changed a couple of unit tests to add selectionBackground, added the setting to schemas, also added the optional setting to profiles
* default selection background should be slightly offwhite like the default foreground is
* reverting changes to .sln
* cleaning up
* adding comment
* oops
* added clangformat to my vs hehe
* moving selectionBackground to IControlSettings and removing from ICoreSettings
* trying to figure out why the WHOLE FILE LOOKS LIKE ITS CHANGED
* here it goes again
* pls
* adding default foreground as the default for selection background in dx
## Summary of the Pull Request
This PR potentially fixes#3101.
## PR Checklist
* [x] Closes#3101.
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be 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
## Detailed Description of the Pull Request / Additional comments
This PR fixes#3101 by setting flag 0 in `ToUnicodeEx()` even though the documentation says "If bit 0 is set, a menu is active.". I'm not 100% sure why it works, but it definitely does in this case.
I thought that bit 2, which claims that "keyboard state is not changed" would be sufficient to prevent this from happening, but it seems that's not the case.
I believe this PR should be verified by a developer at Microsoft who's familiar with the internal workings of `ToUnicodeEx()`.
We need this function (or something similar) to translate Alt+Key combinations to proper unicode.
But at the same time it should not send us any additional IBM-style Alt Codes to our character handler if that translation fails (and `ToUnicodeEx()` returns 0).
## Validation Steps Performed
See #3101 for more information. I ensured that Alt+Arrow-Key combinations do not print ◘☻♠♦ anymore.
<!-- 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
Another tiny performance fix.
<!-- 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
Correct me if I'm wrong, It doesn't really make sense to update scroll status faster than frame rate limit.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
<hr>
* Throttle scroll position update
* Review
This new cpprestsdk package, 2.10.14, switches us to the app CRT.
cpprestsdk turns fof a bunch of boost and openssl dependencies when it's
built for the Windows Store subplatform, so we got a bunch of stuff for
free.
Incidentally, I fixed#2338 the real/correct way -- the build rules in
the package now make sure they're not using the system vcpkg root.
* Change to use App CRT in preparation for universal.
* Try to make project build again by setting winconpty to static lib so it'll use the CRT inside TerminalConnection (or its other consumers) instead of linking its own.
* Remove test for conpty dll, it's a lib now. Add additional commentary on how CRT linking works for future reference. I'm sure this will come up again.
* use the _apiset variant until proven otherwise to match the existing one.
* Clarification in the comments for linking.
This commit deletes ConhostConnection and replaces it with
ConptyConnection. The ConptyConnection uses CreatePseudoConsole and
depends on winconpty to override the one from kernel32.
* winconpty must be packageable, so I've added GetPackagingOutputs.
* To validate this, I added conpty.dll to the MSIX regression script.
* I moved the code from conpty-universal that deals with environment
strings into the types library.
This puts us in a way better place to implement #2563, as we can now
separately detect a failure to launch a pseudoconsole, a failure to
CreateProcess, and an unexpected termination of the launched process.
Fixes#1131.
* Create a doc for adding common third-party tools
Maybe it would be helpful to have a comprehensive guide on adding some common third-party tools as profiles.
* add some additional tools from PR
* Add a note on using WSL paths to documentation
Co-Authored-By: greg904 <56923875+greg904@users.noreply.github.com>
Co-Authored-By: Carlos Zamora <carlos.zamora@microsoft.com>
It's apparently perfectly possible that DWM will just crash or close, and when
it does, `DwmExtendFrameIntoClientArea` will return a failure. If we
THROW_IF_FAILED that call, then we'll also crash when DWM does.
This converts that THROW_IF_FAILED to a LOG_IF_FAILED. When DWM comes back,
we'll hit this codepath again, and all will be right again in the world.
<!-- 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
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
#1091#1094#2390#3314
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#1091
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] 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
Combination of the PRs #1094, #2390, and #3314, especially as discussed in #3314.
In short, this changes line endings from Windows-space \r\n to the more universal \r.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Copied and pasted text into the terminal without the patch, line endings were doubled.
With the patch, line endings weren't doubled.
--------------------
* Replacing \r\n line endings with \r line endings
* Fixing Formatting
This commit cleans up and deduplicates all of the common build
preamble/postamble across exe, dll, lib and c++/winrt projects.
The following specific changes have been made:
* All projects now define their ConfigurationType
* All projects now set all their properties *before* including a common
build file (or any other build files)
* cppwinrt.pre and cppwinrt.post now delegate most of their
configuration to common.pre and common.post
* (becuase of the above,) all build options are conserved between
console and c++/winrt components, including specific warnings and
preprocessor definitions.
* More properties that are configurable per-project are now
conditioned so the common props don't override them.
* The exe, dll, exe.or.dll, and lib postincludes have been merged into
pre or post and switched based on condition as required
* Shared items (-shared, -common) are now explicitly vcxitems instead of
vcxproj files.
* The link line is now manipulated after Microsoft.Cpp sets it, so the
libraries we specify "win". All console things link first against
onecore_apiset.lib.
* Fix all compilation errors caused by build unification
* Move CascadiaPackage's resources into a separate item file
Fixes#922.