## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes#531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
We take the standard window frame except that we remove the top part
(see `NonClientIslandWindow::_OnNcCalcSize`), then we put little 1 pixel
wide top border back in the client area using
`DwmExtendFrameIntoClientArea` and then we put the XAML island and the
drag bar on top.
Most of this PR is comments to explain how the code works and also
removing complex code that was needed to handle the weird cases when the
borders were custom.
I've also refactored a little bit the `NonClientIslandWindow` class.
* Fix DwmExtendFrameIntoClientArea values
* Fix WM_NCHITTEST handling
* Position the XAML island window correctly
* Fix weird colors in drag bar and hide old title bar buttons
* Fix the window's position when maximized
* Add support for dark theme on the frame
* DRY shared code between conhost and new terminal
* Fix drag bar and remove dead code
* Remove dead code and use cached DPI
* Refactor code
* Remove impossible TODO
* Use system metrics instead of hardcoding resize border height
* Use theme from app settings instead of system theme. Improve comments. Remove unused DWM frame on maximize.
* Fix initial position DPI handling bug and apply review changes
* Fix thick borders with DPI > 96
Closes#3064.
Closes#1307.
Closes#3136.
Closes#1897.
Closes#3222.
Closes#1859.
This commit introduces a C++/WinRT utility library and moves
ScopedResourceLoader into it. I decided to get uppity and introduce
something I like to call "checked resources." The idea is that every
resource reference from a library is knowable at compile time, and we
should be able to statically ensure that all resources exist.
This is a system that lets us immediately failfast (on launch) when a
library makes a static reference to a resource that doesn't exist at
runtime.
It exposes two new (preprocessor) APIs:
* `RS_(wchar_t)`: loads a localizable string resource by name.
* `USES_RESOURCE(wchar_t)`: marks a resource key as used, but is intended
for loading images or passing static resource keys as parameters to
functions that will look them up later.
Resource checking relies on diligent use of `USES_RESOURCE()` and `RS_()`
(which uses `USES_RESOURCE`), but can make sure we don't ship something
that'll blow up at runtime.
It works like this:
**IN DEBUG MODE**
- All resource names referenced through `USES_RESOURCE()` are emitted
alongside their referencing filenames and line numbers into a static
section of the binary.
That section is named `.util$res$m`.
- We emit two sentinel values into two different sections, `.util$res$a`
and `.util$res$z`.
- The linker sorts all sections alphabetically before crushing them
together into the final binary.
- When we first construct a library's scoped resource loader, we
iterate over every resource reference between `$a` and `$z` and check
residency.
**IN RELEASE MODE**
- All checked resource code is compiled out.
Fixes#2146.
Macros are the only way to do something this cool, incidentally.
## Validation Steps Performed
Made references to a bunch of bad resources, tried to break it a lot.
It looks like this when it fails:
### App.cpp
```
36 static const std::array<std::wstring_view, 2> settingsLoadErrorsLabels {
37 USES_RESOURCE(L"NoProfilesText"),
38 USES_RESOURCE(L"AllProfilesHiddenText_HA_JUST_KIDDING")
39 };
```
```
WinRTUtils\LibraryResources.cpp(68)\TerminalApp.dll:
FailFast(1) tid(1034) 8000FFFF Catastrophic failure
Msg:[Resource AllProfilesHiddenText_HA_JUST_KIDDING not found in
scope TerminalApp/Resources (App.cpp:38)] [EnsureAllResourcesArePresent]
```
The WAP packaging project in VS <= 16.3.7 produces a couple global
properties as part of its normal operation that cause MSBuild to flag
our projects as out-of-date and requiring a rebuild. By forcing those
properties to match the WAP values, we can get consistent builds.
One of those properties, however, is "GenerateAppxPackageOnBuild", and
WAP sets it to *false*. When we set that, of course, we don't get an
MSIX out of our build pipeline. Therefore, we have to break our build
into two phases -- build, then package.
This required us to change our approach to PCH deletion. A project
without a PCH is *also* considered out-of-date. Now, we keep all PCH
files but truncate them to 0 bytes.
TerminalApp, however, is re-linked during packaging because the Xaml
compiler emits a new generated C++ file on every build. We have to keep
those PCHs around.
* Remove WpfTerminalControl AnyCPU from Arch-specific builds
This removes another source of build nondeterminism: that WpfTerminalControl was propagating TargetFramework into architecture-specific C++ builds. Its "Any CPU" platform has been removed from architecture builds at the solution level.
This also cleans up some new projects that were added and build for "Any
CPU".
## Summary of the Pull Request
Adds a small border with the accent color to indicate a pane is focused
<img src="https://user-images.githubusercontent.com/18356694/66218711-560e4b80-e68f-11e9-85b0-1f387d35bb92.png" width="480">
<img src="https://user-images.githubusercontent.com/18356694/66218757-6f16fc80-e68f-11e9-8d39-db9ab748c4de.png" width="480">
<img src="https://user-images.githubusercontent.com/18356694/66219194-55c28000-e690-11e9-9835-8b5212e70e8a.png" width="480">
## PR Checklist
* [x] Closes#994
* [x] I work here
* [😢] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
I've removed the simple Grid we were using as the pane separator, and replaced it with a Border that might appear on any side of a pane.
When we add a split, we'll create each child with one of the `Border` flags set (each child with one of a pair of flags). E.g. creating a horizontal split creates one child with the `Top` border, and another with the `Bottom`.
Then, if one of those panes is split, it will pass it's border flag to is new children, with the additional flag set. So adding another Vertical split to the above scenario would create a set of panes with either (`Top|Left`, `Top|Right`) or (`Bottom|Left`, `Bottom|Right`) borders set, depending on which pane was split.
<hr>
* start work on this by tracking border state
* Colorize the border
* Use the accent color for highlighting
* Cleanup the accent color code
* Don't buy any rural real estate when closing a pane
* Closing panes works well now too
* Cleanup for review
* Update src/cascadia/TerminalApp/Pane.cpp
* try some things that don't work to fix the resizing crash
* Revert "try some things that don't work to fix the resizing crash"
This reverts commit 3fc14da113.
* this _does_ work, but I think it's not semantically correct
* This doesn't seem to work either.
I tried adding the pane seperators to the Pane::_GetMinWidth calculation. That
works for prevent the crash, but the resizing is wonky now. If you add a
Vertical split, then a second, then resize the middle pane really small,
you'll see that the _last_ resize doesn't work properly. The text seems to
overhand into the border.
Additionally, there's really weird behavior resizing panes to be small. They
don't always seem to be resizable to the smallest size.
* Revert "This doesn't seem to work either."
This reverts commit 2fd8323e7b.
* Merge the changes from the "this is the one" branch
Again, no idea what I really did that worked, but it does
* Cleanup from my mess of a commit
This makes so much more sense now
* Other PR feedback from @carlos-zamora
* Fix a typo
* Add support for the HPA escape sequence as an alias for CHA.
* Extend the output engine tests for cursor movement to confirm that HPA is dispatched in the same way as CHA.
The _FindMatchingColorScheme currently iterates through all pairs in the
map to find the matching color scheme for a given JSON.
Improved this by using the name from the JSON to lookup the color scheme
in the map.
As a part of setting up UIA Events, we need to be able to identify WHEN to notify the client. We'll be adopting the RendererEngine model that the VTRenderer and DxRenderer follow to identify when something on the screen is changing and what to alert the automation clients about.
This PR just introduces the UiaRenderer. There's a lot of E_NOTIMPLs and S_FALSEs and a few comments throughout as to my thoughts. This'll make diffing future PRs easier and can make this process more iterative. The code does run with the PR so I plan on merging this into master as normal.
Due to a platform issue, elevated application packages occasionally fail
to find all of their dependencies. The real fix for this is going to
take a lot of time and probably a new build of Windows.
The fix we have here switches us to a non-"release" build of
Microsoft.UI.Xaml. The critical thing about their non-release builds is
that they prefer to embed their DLLs into the hosting package instead of
expressing a platform dependency.
This build of Microsoft.UI.Xaml was produced from the same commit as
the original and official build; the only difference is that it will
embed into our package.
Fixes#3275.
* Switch all of the UIA providers to WRL::RuntimeClass
Fixes#3209.
References #3051.
Co-authored-by: Carlos Zamora <cazamor@microsoft.com>
Co-authored-by: Dustin Howett <duhowett@microsoft.com>
[Git2Git] Git Train: Merge of building/rs_onecore_dep_uxp/191011-1234 into official/rs_onecore_dep_uxp Retrieved from https://microsoft.visualstudio.com os OS official/rs_onecore_dep_uxp b80345479891d1e7a9f7e38b6b5f40083c6a564a
sources changes from 21H1
Merged PR 3896217: [Git2Git] Changes from vb_release_dep_dev1
server init changes from 20H1 (onecore headless mode)
conhost has been leaving the clipboard open for all HTML copies because
StringCchCopyA needs an extra byte for the null terminator and we
haven't been giving it one. We should also make sure that we always
close the clipboard (always).
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes#1043
From Egmont Koblinger:
> In terminal emulation, apps have to be able to print something and
keep track of the cursor, whereas they by design have no idea of the
font being used. In many terminals the font can also be changed runtime
and it's absolutely not feasible to then rearrange the cells. In some
other cases there is no font at all (e.g. the libvterm headless terminal
emulation library, or a detached screen/tmux), or there are multiple
fonts at once (a screen/tmux attached from multiple graphical
emulators).
> The only way to do that is via some external agreement on the number
of cells, which is typically the Unicode EastAsianWidth, often accessed
via wcwidth(). It's not perfect (changes through Unicode versions, has
ambiguous characters, etc.) but is still the best we have.
> glibc's wcwidth() reports 1 for ambiguous width characters, so the de
facto standard is that in terminals they are narrow.
> If the glyph is wider then the terminal has to figure out what to do.
It could crop it (newer versions of Konsole, as far as I know), overflow
to the right (VTE), shrink it (Kitty I believe does this), etc.
See Also:
https://bugzilla.gnome.org/show_bug.cgi?id=767529https://gitlab.freedesktop.org/terminal-wg/specifications/issues/9https://www.unicode.org/reports/tr11/tr11-34.html
Salient point from proposed update to Unicode Standard Annex 11:
> Note: The East_Asian_Width property is not intended for use by modern
terminal emulators without appropriate tailoring on a case-by-case
basis.
Fixes#2066Fixes#2375
Related to #900
* We had to move to the final API:
* Items -> TabItems
* Items.VectorChanged -> TabItemsChanged
* TabClose -> TabCloseRequested
* TabViewItem.Icon -> TabViewItem.IconSource
* TabRowControl has been converted to a ContentPresenter, which
simplifies its logic a little bit.
* TerminalPage now differentiates MUX and WUX a little better
* Because of the change from Icon to IconSource in TabViewItem,
Utils::GetColoredIcon needed to be augmented to support MUX IconSources.
It was still necessary to use for WUX, so it's been templatized.
* I moved us from WUX SplitButton to MUX SplitButton and brought the
style in line with the one typically provided by TabView.
* Some of our local controls have had their backgrounds removed so
they're more amenable to being placed on other surfaces.
* I'm suppressing the TabView's padding.
* I removed a number of apparently dead methods from App.
* I've simplified the dragbar's sizing logic and eventing.
* The winmd harvester needed to be taught to not try to copy winmds for
framework packages.
* We now only initialize the terminal once we know the size
Closes#1896.
Closes#444.
Closes#857.
Closes#771.
Closes#760.
Add a warning when the user sets their colorScheme to a scheme that doesn't exist. When that occurs, we'll set their color table to the campbell scheme, to prevent it from being just entirely black.
This commit also switches scheme storage to a map keyed on name.
Closes#2547
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.
I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.
There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.
* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)
* Should we fix Settings here, or later?
-> Later; followup filed (#3123)
* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)
* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32
This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.
Closes#602.
Related to #3123.
This adds the WPF control to our project, courtesy of the Visual Studio team.
It re-hosts the Terminal Control components inside a reusable WPF adapter so it can be composed onto C# type surfaces like Visual Studio requires.