Compare commits

..

55 Commits

Author SHA1 Message Date
Dustin L. Howett
7243ee6157 Migrate spelling-0.0.21 changes from main 2022-08-22 09:58:14 -07:00
Dustin L. Howett
b8b412ceb0 [1.14] Use the viewport-rel. cursor pos for CursorPosition (#13786)
In #13024, we removed `Terminal::GetCursorPosition` from TerminalCore.
This has been widely regarded as a good move.

Now, you might rightly be wondering: why didn't compilation immediately
fail? Well. It turns out that there were _two_ copies of
`GetCursorPosition`. One for `const Terminal`, and one for `Terminal`.
This is important.

`Terminal::GetCursorPosition()` returned the cursor position relative to
the viewport. `Terminal::GetCursorPosition() const`, however, returns
the cursor position in absolute.

We removed the non-`const` one. Fortunately, thanks to the lookup rules
for `const`-qualified members, this didn't matter. Code that called
`GetCursorPosition()` still called `GetCursorPosition()`, and everything
was fine.

Except that part about the relative coordinates. That was not fine.

The TSF control is the _only_ consumer of `ControlCore.CursorPosition`,
and that was the _only_ consumer of relative-`GetCursorPosition()`.

This commit restores equilibrium by introducing a new
`GetViewportRelativeCursorPosition()` member to `Terminal` and switching
over the only consumer of relative cursor position to use it.

Closes #13769.
Backport of #13785.
2022-08-22 11:58:14 -05:00
Mike Griese
a277b56f6a [1.14] Update the MUX package to 2.7.3 (#13761)
Does two things:

* the first two commits: shakes up the way we reference MUX in our projects so we can actually just 
  ```xml
  <PropertyGroup Label="NuGet Dependencies">
    <TerminalMUX>true</TerminalMUX>
  </PropertyGroup>
  ```
  Like every other dependency we have
* the last commit: update to MUX.2.7.3

This is the 1.14 PR, which should be appropriately cherry-picked through to `release-1.15` and `main`
2022-08-16 16:42:55 -05:00
Dustin Howett
2d00432dab Revert "Hide "Open in Terminal" context menu option appropriately (#13206)"
This reverts commit 93b5dff5f8.
2022-08-16 15:47:16 -05:00
Leonard Hecker
793e4170a6 Call UpdatePatternLocations from a background thread (#13758)
We have a number of theories why #12607 is happening, one of which is that
some GPU drivers somehow rely on Win32 messages or similar which we process
on the main thread. If we then try to acquire the console lock on the main
thread, while the GPU-driver thread itself is holding that lock, we've got
ourselves a deadlock. This PR makes this less likely by running the repeat
offender `UpdatePatternLocations` on a background thread instead.
We have a number of other locations which acquire the console lock on the
main thread and a thorough bug fix must be done in a different way.

* After pasting an URL it gets underlined on hover 

(cherry picked from commit 23e4d313d5)
Service-Card-Id: 85033018
Service-Version: 1.14
2022-08-16 13:58:06 -05:00
Mike Griese
3bf217419e Fix conpty not emitting colored spaces on the VERY FIRST frame (#13665)
This bug arose from a "race condition" in the first frame handling of conpty. We'd try to optimize out spaces if we've cleared the entire frame (which always happens on the first frame). However, doing that even for colored spaces meant that things like powerline prompts could be emitted to conhost during the first frame, and we'd optimize the spaces out. That's silly.

This is hard to repro naturally, but this comment has another repro I used
https://github.com/microsoft/terminal/issues/8341#issuecomment-731310022

Modified to facilitate simpler testing, it looks like:

![image](https://user-images.githubusercontent.com/18356694/182680119-bb22179c-a328-43f3-b64a-0d1d5773b813.png)

![image](https://user-images.githubusercontent.com/18356694/182680159-805964c5-c4cc-411a-8865-3866fca8d6e9.png)

* [x] Closes #8341
* [x] Tests added

Co-authored by @DHowett

(cherry picked from commit 210a98e449)
Service-Card-Id: 84836596
Service-Version: 1.14
2022-08-16 13:56:40 -05:00
Dustin L. Howett
13236a2d91 [1.14/5] Propagate the color scheme resw changes from df671377 (#13712)
Due to the way our localization pipeline works, we cannot delete
resources in main until the resources in question are totally flushed
out of the active-servicing release branches. Unfortunately, in #13179,
we _did_ remove resource keys. Because the Color Schemes page in 1.14
and 1.15 uses the resources directly (rather than by way of x:Uid), it
is easier for us to backport the resource changes now than to
reintroduce the old keys on main.

Closes #13606

(cherry picked from commit 6933429721)
Service-Card-Id: 84870299
Service-Version: 1.14
2022-08-10 15:20:37 -05:00
Mike Griese
4948f25d40 Fix the ConPTY extended attributes optimization (#13661)
... which should have never worked in the first place

Quick filing a PR for review. This is the bulk of the actual code changes. Figured it was best to review the conpty changes sooner than later and I can add tests in the morning.

Test cases:
```
printf "\e[7m         test         \e[m\n"
```

```
printf "\e[7m"; printf ' %.0s' $(seq 1 $COLUMNS); printf "\e[m\n"
```

After:
![image](https://user-images.githubusercontent.com/18356694/182478185-6e65ab99-5c27-4772-af3b-2baa22387ec1.png)

Closes #13229

Definitely fixes:
* [x] #13643
* [x] https://github.com/PowerShell/PowerShell/issues/17812

(cherry picked from commit ffe9a0f09b)
Service-Card-Id: 84736231
Service-Version: 1.15
(cherry picked from commit fff3372ed2)
Service-Card-Id: 84736230
Service-Version: 1.14
2022-08-10 15:20:32 -05:00
Leonard Hecker
5cc4805439 Fix input corruption for high code points (#13667)
We must use 65535 as `MAX_PARAMETER_VALUE` in order for us to properly parse
win32-input-mode sequences, which transmit UTF-16 characters as parameters.

Closes #12977

## Validation Steps Performed
* Call `SendInput` with 🙁 (`L'\xD83D'`, `L'\xDE41'`)
* 🙁 appears on the input line 

(cherry picked from commit 74cdffe921)
Service-Card-Id: 84772549
Service-Version: 1.15
(cherry picked from commit f3f9eba5c9)
Service-Card-Id: 84772548
Service-Version: 1.14
2022-08-10 15:20:30 -05:00
Mike Griese
ac9d69790f Restore the ability for alt+tab to restore the Terminal after minimizing with taskbar (#13624)
Curiously, at least on Windows 10 (and rarely on Windows 11), if you minimize the Terminal by clicking on the taskbar, then alt-tab to try and restore the window, the Taskbar will decide to call `SwitchToWindow` on the invisible, owned ConPTY window instead of the main window. When that happens, ConPTY'll get a `WM_SIZE(SIZE_RESTORED, lParam=0)`. The main window will NOT get a `SwitchToWindow` called. If ConPTY doesn't actually inform the hosting process about this, then the main HWND might stay hidden.

* Refer to #13158 where we disabled this.
* Closes #13589
* Closes #13248
* Tested manually on a Windows 10 VM.
* Confirmed that opening tabs while maximized/snapped doesn't restore down.
* `[Native]::ShowWindow([Native]::GetConsoleWindow(), 6)` still works

(cherry picked from commit d1fc11248c)
Service-Card-Id: 84673887
Service-Version: 1.15
(cherry picked from commit b670800460)
Service-Card-Id: 84673886
Service-Version: 1.14
2022-08-10 15:20:29 -05:00
Dustin L. Howett
1642360c4c Lock the app names in the pseudoloc locales (#13563)
On occasion, when we submit to the store we get a package rejection
because the app name has changed for the `qps-*` locales. Instead of
constantly reserving new pseudolocalized app names every time the
pseudolocalization seed changes, we should just lock our app name so
that it does not get pseudolocalized.

(cherry picked from commit bb40efc00b)
Service-Card-Id: 84417902
Service-Version: 1.15
(cherry picked from commit 210145a709)
Service-Card-Id: 84417901
Service-Version: 1.14
2022-08-10 15:20:27 -05:00
Mike Griese
1a56bc5101 Send focus events even in ReadOnly mode (#13483)
Does what it says on the tin. When we get focused, temporarily turn off readonly mode, as to not pop the dialog when the focus sequence is eventually sent to the connection.

* closes #13461

(cherry picked from commit b4a52c847f)
Service-Card-Id: 84111370
Service-Version: 1.14
2022-07-15 17:30:30 -05:00
James Holderness
ec6dc8dd67 Add line breaks in the debug tap output (#13475)
## Summary of the Pull Request

When the debug tap converts control characters into visible glyphs, it
ends up losing the structure of the output, and that can sometimes make
things difficult to read. This PR attempts to alleviate that problem by
reinjecting an actual line break in the debug stream whenever an `LF`
control is received.

## PR Checklist
* [x] Closes #12312
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #12312

## Validation Steps Performed

I've tested the updated debug tab with a number of different shells, and
also a couple of different apps. When there aren't many linefeeds in the
output, it's obviously not going to make much of a difference, but when
there are, I think it definitely improves the readability.

(cherry picked from commit 04478d1df0)
Service-Card-Id: 84116394
Service-Version: 1.14
2022-07-15 17:30:29 -05:00
Davide Giacometti
f1b75e5557 Don't set full screen to quake window (#13473)
If launch mode is set to full screen quake window is opened in full
screen.

## Validation Steps Performed
- Set startup > launch mode > full screen
- Launch quake window
- Quake window shouldn't be opened in full screen

Closes #12894

(cherry picked from commit 589286a357)
Service-Card-Id: 84116409
Service-Version: 1.14
2022-07-15 17:30:28 -05:00
Mike Griese
e110c5b639 Wrap the tooltips on the new tab button (#13463)
In non-en-us locales, these tooltips can get really long and get clipped.

Closes MSFT:39603031
See Also #9913

(cherry picked from commit 32379c29f0)
Service-Card-Id: 84008281
Service-Version: 1.14
2022-07-15 17:30:26 -05:00
Dustin L. Howett
a47bb0d0dc Remove the fallback to wsl.exe when HKCU\...\Lxss doesn't exist (#13436)
The main result of this fallback is that we attempt to launch wsl.exe
when the user hasn't installed or interacted with WSL. On our test
machines, that results in the creation of a wsl.exe process that tells
us precisely nothing; on WDAC managed machines it results in an Event
Log entry about spawning another (possibly blocked) process.

The registry is more reliable, and if the "API" it provides changes we
can just rev terminal.

Closes #11716

(cherry picked from commit f025c53dba)
Service-Card-Id: 83892843
Service-Version: 1.14
2022-07-05 17:01:29 -05:00
Leonard Hecker
d7d15db93b Fix a race condition in CTerminalHandoff::s_StopListening (#13410)
This commit fixes a minor race condition covered as part of #13368.
The member `_pfnHandoff` was read without the mutex `_mtx` being locked first.
The issue was solved by acquiring the lock early and running the entire
`s_StopListening` function with that lock held.

(cherry picked from commit 95a19624a4)
Service-Card-Id: 83893125
Service-Version: 1.14
2022-07-05 15:31:52 -05:00
Mike Griese
e5239f8931 Fix the bellsound schema, for real (#13433)
As noted in https://github.com/microsoft/terminal/pull/11511#issuecomment-1173541384.

Missed in #13035

(cherry picked from commit 86dfefa690)
Service-Card-Id: 83891742
Service-Version: 1.14
2022-07-05 15:31:51 -05:00
dependabot[bot]
970d2d0514 Bump Newtonsoft.Json from 12.0.3 to 13.0.1 (#13363)
* Bump Newtonsoft.Json from 12.0.3 to 13.0.1 in /dep/nuget

Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 12.0.3 to 13.0.1.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/12.0.3...13.0.1)

Service-Card-Id: 83757939
Service-Version: 1.14

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Complete the Newtonsoft.Json upgrade to 13.0.1

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dustin Howett <duhowett@microsoft.com>
(cherry picked from commit f1b6b17c58)
2022-06-30 23:03:30 -05:00
Mike Griese
df6c43fc69 Make sure foreground access works for DefTerm (#13247)
See also: #12799, the origin of much of this.

This change evolved over multiple phases.

When we create a defterm connection in `TerminalPage::_OnNewConnection`,
we don't have the hosting HWND yet, so the tab gets created without one.
We'll later get called with the owner, in `Initialize`.

To remedy this, we need to:
* In `Initialize`, make sure to update any existing controls with the
  new owner.
* In `ControlCore`, actually propogate the new owner down to the
  connection

DefTerm launches don't actually request focus mode, so the Terminal
never sends them focus events. We need those focus events so that the
console can request foreground rights.

To remedy this, we need to:
* pass `--win32input` to the commandline used to initialize OpenConsole
  in ConPTY mode. We request focus events at the same time we request
  win32-input-mode.
* I also added `--resizeQuirk`, because _by all accounts that should be
  there_. Resizing in defterm windows should be _wacky_ without it, and
  I'm a little surprised we haven't seen any bugs due to this yet.

`ConsoleSetForeground` expects a `HANDLE` to the process we want to give
foreground rights to. The problem is, the wire format we used _also_
decided that a HANDLE value was a good idea. It's not. If we pass the
literal value of the HANDLE to the process from OpenConsole to conhost,
so conhost can call that API, the value that conhost uses there will
most likely be an invalid handle. The HANDLE's value is its value in
_OpenConsole_, not in conhost.

To remedy this, we need to:
* Just not forward `ConsoleSetForeground`. Turns out, we _can_ just call
  that in OpenConsole safely. There's no validation. So just instantiate
  a static version of the Win32 version of ConsoleControl, just to use
  for SetForeground. (thanks Dustin)

* [x] Tested manually - Win+R `powershell`, `notepad` spawns on top.

Closes #13211

(cherry picked from commit 2a7dd8b730)
Service-Card-Id: 83026847
Service-Version: 1.14
2022-06-30 18:15:55 -05:00
Leonard Hecker
2844209834 Dismiss Terminal-by-default banner on handoff (#13344)
It's not useful to notify users that WT can be made the default if it's already
clearly being used for handoff. This commit will suppresses the banner then.

## PR Checklist
* [x] Closes #13314
* [x] I work here

## Validation Steps Performed
* Modify `TerminalPage::ShowSetAsDefaultInfoBar` to not check for
  `CascadiaSettings::IsDefaultTerminalSet()`
* Set Terminal Dev as the default
* Set incoming connections to open in the latest Terminal window
* Delete `state.json` after every test below
* Launching Terminal Dev shows the banner 
  Launching `cmd.exe` dismisses the banner in the current Terminal 
* Launching `cmd.exe` launches Terminal Dev without banner 

(cherry picked from commit 24a53d4968)
Service-Card-Id: 83434412
Service-Version: 1.14
2022-06-30 18:14:49 -05:00
Dustin L. Howett
f40aa7d957 Strip XAML files from the MSIX payload (#13351)
These files are vestigial, because we are also shipping (either as loose
files or embedded in resources.pri) precompiled xbf/xaml binary format
files.

This saves us almost 500kb on disk.

Fixes #11687

Validation
----------
I ran a local build and saw that it produced a working Terminal, packaged
and unpackaged.

(cherry picked from commit 0b97c7b5ca)
Service-Card-Id: 83425307
Service-Version: 1.14
2022-06-30 18:14:47 -05:00
James Holderness
741ea4d96a Make sure conpty is flushed before clearing scrollback (#13324)
## Summary of the Pull Request

When you execute a `cls` in the cmd shell, or `Clear-Host` in
PowerShell, we have a pair of shims that attempt to detect those
operations and forward an `ED3` sequence to conpty to clear the
scrollback.

If there was a linefeed at the bottom of the viewport immediately
prior to those functions being called, that event might still be
pending, and only forwarded to conpty after the `ED3`. The result
then is a line pushed into the scrollback that shouldn't be there.

This PR tries to avoid that situation by forcing the renderer to
flush before the `ED3` sequence is sent.

## References

The `cls` and `Clear-Host` shims were originally added in PR #5627.

## PR Checklist
* [x] Closes #5770
* [x] Closes #13320
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] 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

## Validation Steps Performed

I've manually tested in PowerShell with `echo Hello; Clear-Host` (this
is the only way I could reliably reproduce the original problem), and in
the cmd shell with `cls`. Both cases are now working as expected.

(cherry picked from commit 08c2f350e6)
Service-Card-Id: 83388911
Service-Version: 1.14
2022-06-30 18:14:46 -05:00
Mike Griese
fbfb83bb97 Fix a deadlock in ShowWindow (#13309)
When we send this ShowWindow message, if we send it to it's
going to need to get processed by the window message thread before
returning. We're handling this message under lock. However, the first
thing the conhost message thread does is lock the console. That'll
deadlock us. So unlock here, first, to let the message thread deal with
this message, then re-lock so later on this thread can unlock again
safely.

* [x] Closes #13301
* [x] Tested conhost
* [x] Tested terminal

(cherry picked from commit 848314ef17)
Service-Card-Id: 83224338
Service-Version: 1.14
2022-06-30 18:14:45 -05:00
Dustin L. Howett
2687865790 Regenerate CodepointWidthDetector from Unicode 14.0 (#13292)
(cherry picked from commit deffbbc7f5)
Service-Card-Id: 83142420
Service-Version: 1.14
2022-06-30 18:14:43 -05:00
Dustin L. Howett
6dcc1762ee Fix an issue preventing the compliance pipeline from running (#13289)
(cherry picked from commit 9eb191d545)
Service-Card-Id: 83131511
Service-Version: 1.14
2022-06-30 18:14:42 -05:00
Ian O'Neill
102f612689 Add an accelerator key for the shell extension (#13080)
Adds an accelerator key for the shell extension: `T` for stable, `P` for preview and `D` for dev.

# Validation
Ran a dev build and saw the keyboard accelerator assigned.

Closes #13061

(cherry picked from commit 75e462441d)
Service-Card-Id: 83524177
Service-Version: 1.14
2022-06-30 18:14:41 -05:00
Mike Griese
199992a867 Filter focus events that came from the API (#13260)
As described in #13238. libuv sends a focus event to jiggle the handle. Now that we support focus events as VT input (#12900), we'd translate those focus events to VT input as well. That combination of things caused exiting neovim to emit a `\x1b[O` to the input line of the shell when exited.

To fix this, we're going to secretly filter out any focus events that came from the API, before translating to VT. We're fortunate here, the `FOCUS_EVENT_RECORD` version of the ctor is only called by the API.

* [x] Closes #13238

(cherry picked from commit b22684e697)
Service-Card-Id: 83027721
Service-Version: 1.14
2022-06-30 18:14:40 -05:00
Carlos Zamora
efa02f35e2 Fix a11y crash in alt buffer apps (#13250)
This fixes the crashes caused by using a screen reader when in an app that uses the alt buffer via two changes:
1. Fix `Terminal::ViewEndIndex()`
   - `UiaTextRangeBase` receives a coordinate that is outside of the bounds of the text buffer via the following chain of functions... `_getDocumentEnd()` --> `GetLastNonSpaceCharacter()` --> `_getOptimizedBufferSize()` --> `GetTextBufferEndPoisition()` --> `ViewEndIndex()`
   - Since support for the alt buffer was added recently, `ViewEndIndex()` was recently changed, so that explains why this issue came up recently. We were accidentally setting the view end index to `height` instead of `height-1`. Thanks @j4james for finding this!
   - The UIA code would get the "exclusive end" of the alt buffer. Since it was using `ViewEndIndex()` to calculate that, it was one more than it should be. The UIA code has explicit allowance for "one past the end of the viewport" in its `IsInBounds()` check. Since the `ViewEndIndex()` is way beyond that, it's not allowed, hitting the fail fast.
2. Replace `FAIL_FAST_IF` with `assert`
   - These fail fast calls have caused so many issues with our UIA code. Those checks still provide value, but they shouldn't take the whole app down. This change replaces the `Viewport` and `UiaTextRangeBase` fail fasts with asserts to still perform those checks, but not take down the entire app in release builds.

Closes #13183

While using Narrator...
- opened nano in bash
- generated text and scrolled in nano
- generated text and scrolled in PowerShell

(cherry picked from commit 94e1697a48)
Service-Card-Id: 82972865
Service-Version: 1.14
2022-06-30 18:14:39 -05:00
Mike Griese
ddf46f2727 Add "JSON" to the "Open settings file" command names (#13265)
![image](https://user-images.githubusercontent.com/18356694/173090336-3512ee36-ae8b-41d5-8823-09cb1354c7ef.png)

* [x] Closes #13225

(cherry picked from commit dc8183a525)
Service-Card-Id: 83524146
Service-Version: 1.14
2022-06-30 18:13:27 -05:00
PankajBhojwani
0bd085d11b Fix deleting the last profile crashing Terminal (#13242)
## Summary of the Pull Request
When a profile gets deleted, we were navigating to the next item assuming it was a profile when it may not be. This commit fixes this by checking the tag of the next menu item before we navigate to it.

## PR Checklist
* [x] Closes #13125
* [x] 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.
* [x] I work here

## Validation Steps Performed
Deleting the last profile in the SUI doesn't cause a crash

(cherry picked from commit 4e20a8631c)
Service-Card-Id: 82925050
Service-Version: 1.14
2022-06-30 18:12:20 -05:00
Dustin Howett
78cda41828 Backport the DefTerm SUI stability fix from #13160 2022-06-30 18:12:01 -05:00
Leonard Hecker
9165c00d49 Fix SetConsoleWindowInfo being able to crash ConPTY (#13212)
MSFT-33471786 is one of the most common crashes we have right now.
Memory dumps suggest that `VtEngine::UpdateViewport` is called with a rectangle
like `(0, 46, 119, 29)` (left, top, right, bottom), which is a rectangle of
negative height. When the `_invalidMap` is resized the negative size gets
turned into a very large unsigned integer, which results in an OOM exception,
crashing OpenConsole.

`VtEngine::UpdateViewport` is called by `Renderer::_CheckViewportAndScroll`
which holds a (cached) old and a new viewport. The old viewport was
`(0, 46, 119, 75)` which is exceedingly similar to the invalid, new viewport.
It's bottom coordinate is also coincidentally larger by exactly 46 (top).

The viewport comes from the `SCREEN_INFORMATION` class whose `SetViewport`
function was highly suspicious as it has a branch which updates the bottom
to be the buffer height, but leaves the top unmodified.

`SCREEN_INFORMATION::SetViewport` is called by `SetConsoleWindowInfo` which
processes user-provided data. A repro of the crash can be constructed with:
```
SMALL_RECT rect{0, 46, 119, 75};
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &rect);
```

Closes #13193
Closes MSFT-33471786

## Validation Steps Performed
Ensured the following code doesn't crash when run under Windows Terminal:
```
SMALL_RECT rect{0, 46, 119, 75};
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &rect);
```

(cherry picked from commit 7dbe741e1a)
Service-Card-Id: 82642053
Service-Version: 1.14
2022-06-30 18:08:09 -05:00
leejy12
93b5dff5f8 Hide "Open in Terminal" context menu option appropriately (#13206)
This commit hides the "Open in Terminal" context menu option when the
context menu is opened in a non-filesystem path like "Quick Actions".

Closes #12578

(cherry picked from commit fb1491a4af)
Service-Card-Id: 83524152
Service-Version: 1.14
2022-06-30 18:08:08 -05:00
Sergey Semushin
31757a44ee Add find item to tab menu (#13055)
## Summary of the Pull Request

Add `Find` to tab context menu as describe in issue #5633.

## PR Checklist
* [x] Closes #5633
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA

## Detailed Description of the Pull Request / Additional comments

Just wanted to solve `Easy Starter` issue, so any corrections/suggestions welcome. There's a couple of points I'm not sure of
* Placement of item within menu, currently it's at the end before close tab block.
* Should it be named longer, something like `Find in Tab` of just `Find` is fine?
* The workaround for focus similar to tab rename is a bit annoying, especially because it required adding a method to `TermControl` but without it find window obviously opens without focus which is bad.

## Validation Steps Performed

Open menu, press menu item try to find things via opened find dialog.

(cherry picked from commit b851b0d3f4)
Service-Card-Id: 83524184
Service-Version: 1.14
2022-06-30 18:08:07 -05:00
Leonard Hecker
a2244246b5 Simplify Utf16Parser (#13096)
This trivial commit simplifies `Utf16Parser::IsLeading/TrailingSurrogate`
methods, by replacing `<bitset>` with a simple, equivalent range check.

(cherry picked from commit 1db47ff8dc)
Service-Card-Id: 83524156
Service-Version: 1.14
2022-06-30 18:08:06 -05:00
Carlos Zamora
988f64ab15 [1.14] Fix keyboard selection and copyOnSelect interaction (#13360)
## Summary of the Pull Request
⚠️This targets release-1.14⚠️
Backport of #13358

This PR fixes a number of interactions between `copyOnSelect` and keyboard selection. Sometimes the selection just wouldn't be cleared or copied appropriately. 

I wrote a whole flowchart of expected behavior with copy on select:
- enable `copyOnSelect`
   - make a selection with the mouse
      -  right-click should copy the text --> clear the selection --> paste
   - use keyboard selection to quick-edit the existing selection
      -  `copy` action should clear the selection
      -  right-click should copy the text --> clear the selection --> paste
2022-06-30 18:07:15 -05:00
Carlos Zamora
b796060c55 [1.14] Properly fix keyboard sln at top/bot (#13372)
A port of commit 0c5a1e9 from #13358.
This fixes an oversight from #13353. That ended up not fixing when trying to move past the top boundary.
This is also a better fix overall. By moving the fix to `_MoveByChar`, we have consistency between all the `_MoveByX` functions in that they automatically clamp to be within the scroll area.
2022-06-30 16:03:06 -05:00
Carlos Zamora
7506a3ab2d [1.14] Fix moving selection past scroll area (#13353)
## Summary of the Pull Request
1.14 port of #13318

Introduced in #10824, this fixes a bug where you could use keyboard selection to move below the scroll area. Instead, we now clamp movement to the mutable viewport (aka the scrollable area). Specifically, we only clamp the y-coordinate to make the experience similar to that of mouse selection.

## Validation Steps Performed
 (no output) try to move past bottom of viewport
 (with output, at bottom of scroll area) try to move past viewport
 (with output, NOT at bottom of scroll area) try to move past viewport
 try to move past top of viewport
2022-06-22 11:16:49 -05:00
Mike Griese
997b4acce5 Prevent ConPTY from de-snapping the terminal (#13164)
This is a big hammer to put out this fire. We're keeping the hiding around for now, cause we think that's likely the one that the internal tests use that we really care about here. If we need to bring this back, we can.

* [x] Closes #13158
* [x] Closes #13162
* [x] Validated these both manually
* [x] `[Native]::ShowWindow([Native]::GetConsoleWindow(), 6)` still works

(cherry picked from commit 11b810e403)
Service-Card-Id: 82371517
Service-Version: 1.14
2022-05-25 15:02:42 -05:00
Ian O'Neill
287db8a483 Don't attempt to split settings tabs (#13172)
Prevents a null pointer dereference when attempting to split a settings tab, due to it not being a terminal tab.

* [x] Closes #13166

## Validation Steps Performed
Manually tested.

(cherry picked from commit 6439b4d807)
Service-Card-Id: 82395540
Service-Version: 1.14
2022-05-25 15:02:41 -05:00
Dustin L. Howett
07f7717112 Remove location-specific suffixes from the zh- lang specifiers (#13148)
This only impacts the UI. We can take a workitem to rename the loc data
later. When the user specifies zh-Hans/zh-Hant, the resource mapper does
the right thing.

Related to #8984

(cherry picked from commit 78852e04ec)
Service-Card-Id: 82315897
Service-Version: 1.14
2022-05-25 15:02:40 -05:00
Mike Griese
39c71d6421 Debounce window state changes caused by the PTY (#13147)
Use a throttled update to update our window state. Throttling should prevent scenarios where the Terminal window state and PTY window state get de-sync'd, and cause the window to minimize/restore constantly in a loop.  "Should" is doing a lot of work in this sentence.

A 200ms delay was chosen because it's the typical animation timeout in Windows. This does result in a delay between the PTY requesting a change to the window state and the Terminal realizing it, but should mitigate issues where the Terminal and PTY get desync'd.

I think we're overall not super confident that this fixes the root causes of the issue. Rather, we're hopeful that a small amount of throttling here should leave time for the Terminal and pty to sync back up. We're comfortable enough with that as a bandaid for 1.14 preview, to see how this behaves in the wild.

(cherry picked from commit c5fad74c54)
Service-Card-Id: 82315892
Service-Version: 1.14
2022-05-23 18:05:01 -05:00
Mike Griese
c0e6c259fc Fix the SUI being in the wrong Theme color (#13145)
ThemeResources are a persistent pain.

Regressed in #13083. See also #12775 et. al.

We can't just put those here though as StaticResources, because XAML will evaluate their values when the App is first loaded, and we'll always use the value from the OS theme, regarless of the requested theme. Kinda the same thing we've had to do with TabViewBackground in the past.

* [x] Fixes something we noticed right before shipping

(cherry picked from commit bb03b00ebf)
Service-Card-Id: 82303612
Service-Version: 1.14
2022-05-23 13:26:21 -05:00
Mike Griese
6d636056a0 Add the background back to showTabsInTitlebar: false's tab row. (#13144)
We're doing it this way because ThemeResources are tricky. We
default in XAML to using the appropriate ThemeResource background
color for our TabRow. When tabs in the titlebar are _disabled_,
this will ensure that the tab row has the correct theme-dependent
value. When tabs in the titlebar are _enabled_ (the default),
we'll switch the BG to Transparent, to let the Titlebar Control's
background be used as the BG for the tab row.

We can't do it the other way around (default to Transparent, only
switch to a color when disabling tabs in the titlebar), because
looking up the correct ThemeResource from and App dictionary is a
capital-H Hard problem.

* [x] Closes #13143
* [x] I work here
* [x] validated manually:
  - [x] showTabsInTitlebar: false, true
  - [x] useAcrylicInTabRow: false, true
  - [x] theme: light, dark
* [x] Need to check if this is regressed the same in 1.13. I suspect it is.

(cherry picked from commit 4c333536b4)
Service-Card-Id: 82298858
Service-Version: 1.14
2022-05-23 13:26:19 -05:00
Mike Griese
20a6c7078b Fis ShowHide for DefTerm (#13129)
Well this one feels dumb.

Make sure to also initially set the visibility of ConPTY windows created for DefTerm connections.

* [x] Closes #13066 for real.
* [x] tested manually.

(cherry picked from commit d82af9367f)
Service-Card-Id: 82146739
Service-Version: 1.14
2022-05-19 18:39:15 -05:00
Mike Griese
eec6a882d6 Fix ShowWindow(GetConsoleWindow()) (#13118)
A bad merge, that actually revealed a horrible bug.

There was a secret conflict between the code in #12526 and #12515. 69b77ca was a bad merge that hid just how bad the issue was. Fixing the one line `nullptr`->`this` in `InteractivityFactory` resulted in a window that would flash uncontrollably, as it minimized and restored itself in a loop. Great.

This can seemingly be fixed by making sure that the conpty window is initially created with the owner already set, rather than relying on a `SetParent` call in post. This does pose some complications for the #1256 future we're approaching. However, this is a blocking bug _now_, and we can figure out the tearout/`SetParent` thing in post.

* fixes #13066.
* Tested with the script in that issue.
* Window doesn't flash uncontrollably.
* `gci | ogv` still works right
* I work here.
* Opening a new tab doesn't spontaneously cause the window to minimize
* Restoring from minimized doesn't yeet focus to an invisible window
* Opening a new tab doesn't yeet focus to an invisible window
* There _is_ a viable way to call `GetAncestor` s.t. it returns the Terminal's hwnd in Terminal, and the console's in Conhost

The `SW_SHOWNOACTIVATE` change is also quite load bearing. With just `SW_NORMAL`, the pseudo window (which is invisible!) gets activated whenever the terminal window is restored from minimized. That's BAD.

There's actually more to this as well.

Calling `SetParent` on a window that is `WS_VISIBLE` will cause the OS to hide the window, make it a _child_ window, then call `SW_SHOW` on the window to re-show it. `SW_SHOW`, however, will cause the OS to also set that window as the _foreground_ window, which would result in the pty's hwnd stealing the foreground away from the owning terminal window. That's bad.

`SetWindowLongPtr` seems to do the job of changing who the window owner is, without all the other side effects of reparenting the window.

Without `SetParent`, however, the pty HWND is no longer a descendant of the Terminal HWND, so that means `GA_ROOT` can no longer be used to find the owner's hwnd. For even more insanity, without `WS_POPUP`, none of the values of `GetAncestor` will actually get the terminal HWND. So, now we also need `WS_POPUP` on the pty hwnd. To get at the Terminal hwnd, you'll need

```c++
GetAncestor(GetConsoleWindow(), GA_ROOTOWNER)
```

(cherry picked from commit 77215d9d77)
Service-Card-Id: 82170678
Service-Version: 1.14
2022-05-19 18:39:14 -05:00
James Holderness
bc9e43a19d Fix handling of cursor position reports in passthrough mode (#13109)
## Summary of the Pull Request

When the conpty passthrough mode is enabled, it often needs to send `DSR-CPR` queries (cursor position reports) to the client terminal to obtain the current cursor position. However, the code that originally handled the responses to these queries got broken by the refactoring of the `ConGetSet` API. This PR is an attempt to correct that regression.

## References

The conpty passthrough mode was introduced in PR #11264.
The refactoring that broke the cursor position handling was in PR #12703.

## PR Checklist
* [x] Closes #13106
* [x] CLA signed.
* [ ] 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

## Detailed Description of the Pull Request / Additional comments

Prior to the `ConGetSet` refactoring, the code that handled `DSR-CPR` responses (`InteractDispatch::MoveCursor`) would pass the cursor position to `ConGetSet::SetCursorPosition`, which in turn would forward it to the `SetConsoleCursorPositionImpl` API, and from there to the `VtIo` class.

After the refactor, all of those intermediate steps were removed - the cursor was simply updated directly in `InteractDispatch::MoveCursor`, and the `VtIo` call was moved from `SetConsoleCursorPositionImpl` to `InteractDispatch` (since that was the only place it was actually required).

However, when the conpty passthrough mode was introduced - which happened in parallel - it relied on the `SetConsoleCursorPositionImpl` API being called from `InteractDispatch` in order to handle its own `DSR-CPR` responses, and that's why things stopped working when the two PRs merged.

So what I've done now is made `InteractDispatch::MoveCursor` method call `SetConsoleCursorPositionImpl` again (although without the intermediate `ConGetSet` overhead), and moved the `VtIo::SetCursorPosition` call back into `SetConsoleCursorPositionImpl`.

This is not ideal, and there are still a bunch of problems with the `DSR-CPR` handling in passthrough mode, but it's at least as good as it was before.

## Validation Steps Performed

I've just manually tested various shells with passthrough mode enabled, and confirmed that they're working better now. There are still issues, but nothing that wasn't already a problem in the initial implementation, at least as far as I can tell.

(cherry picked from commit e1086de512)
Service-Card-Id: 82005205
Service-Version: 1.14
2022-05-17 08:03:28 -07:00
Leonard Hecker
858359e62e AtlasEngine: Stop resizing buffers on scroll (#13100)
This regressed in ad2358d.
We're interested in the size of the viewport only, but it can shift up/down
during scrolling. In these situations we shouldn't resize our buffers of course.

## Validation Steps Performed
* Scroll
* Not setting `ApiInvalidations::Size` 

(cherry picked from commit fa6b066747)
Service-Card-Id: 82005202
Service-Version: 1.14
2022-05-17 08:03:27 -07:00
Carlos Zamora
5fbd5392e7 Add experimental.useBackgroundImageForWindow to schema (#13114)
Adds the `experimental.useBackgroundImageForWindow` global setting introduced in #12893 to the schema.

(cherry picked from commit b699f9275f)
Service-Card-Id: 82002294
Service-Version: 1.14
2022-05-17 08:03:26 -07:00
Carlos Zamora
28284e824f Revert "Hide the window from DWM until we're finished with initialization (#12979)" (#13098)
This reverts commit 14098d71f2.

## Summary of the Pull Request
@zadjii-msft found that this is causing persisted windows on a secondary monitor to shrink a little each time. We're choosing to revert this commit until that gets resolved.

## References
#12979

(cherry picked from commit 6ffc3dc7a8)
Service-Card-Id: 81910920
Service-Version: 1.14
2022-05-13 13:09:59 -07:00
Leonard Hecker
61e6927f34 Fix various issues with useBackgroundImageForWindow (#13090)
Fixes the following issues:
* `desktopWallpaper` not working
* switching tabs/panes causes the background to flicker
* settings preview having a transparent background

## PR Checklist
* [x] Closes #13002
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
Tested the 3 cases above. 

(cherry picked from commit 0630b18eff)
Service-Card-Id: 81868221
Service-Version: 1.14
2022-05-12 16:50:45 -07:00
Carlos Zamora
95693e9079 PGO: train 1.14 separately 2022-05-12 14:43:05 -07:00
Carlos Zamora
eb40b51b79 Fix the 'RunMakeKillTabs' PGO test (#13089)
## Summary of the Pull Request
For some reason, the PGO tests (specifically the `RunMakeKillTabs` test) started to fail after #12979 merged. After closer inspection, the test was actually improperly written. We should be using <kbd>ctrl+shift+t</kbd> to open new tabs, not <kbd>alt+shift+t</kbd>. Presumably, the <kbd>alt</kbd> was copied over from the previous test, because they look _very_ similar.

So I went ahead and fixed the test, and it now (1) tests what it's intended to test and (2) doesn't fail. Why did #12979 cause the tests to fail? idk, but it works now.

## References
#10071 - Introduce PGO Tests

## Validation Steps Performed
Ran PGO tests locally and confirmed that it works.
Ran PGO pipeline and confirmed that it works.

(cherry picked from commit 17d1e2437c)
Service-Card-Id: 81863976
Service-Version: 1.14
2022-05-12 14:40:21 -07:00
James Holderness
521d968a75 Restore virtual viewport position after resize with reflow (#13087)
When the buffer is resized with a reflow, we were previously calculating
the new virtual bottom based on the position of last non-space
character. If the viewport was largely blank when resized, this could
result in the new virtual bottom being higher than it should be.

This PR attempts to address that problem by restoring the virtual bottom
to a position that is the same distance from the cursor row as it was
prior to the resize.

This was a regression introduced in PR #12972.

We still take the last non-space row into account when determining the
virtual bottom, because if the content of the screen is forced to wrap,
the virtual bottom will need to be lower (relative to the cursor) than
it was before.

We also need to check that we don't overflow the bottom of the buffer,
which can occur when the viewport is at the bottom of the buffer, and
the cursor position is pushed down as a result of content wrapping above
it.

I've manually confirmed that this fixes the problem reported in issue
#13078, and I've also extended the existing `RefreshWithReflow` unit
test to cover that particular scenario.

Closes #13078

(cherry picked from commit c2f830843a)
Service-Card-Id: 81864034
Service-Version: 1.14
2022-05-12 14:40:20 -07:00
363 changed files with 5517 additions and 7183 deletions

View File

@@ -410,10 +410,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InteractivityOneCore", "src
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererWddmCon", "src\renderer\wddmcon\lib\wddmcon.vcxproj", "{75C6F576-18E9-4566-978A-F0A301CAC090}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Audio", "Audio", "{40BD8415-DD93-4200-8D82-498DDDC08CC8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MidiAudio", "src\audio\midi\lib\midi.vcxproj", "{3C67784E-1453-49C2-9660-483E2CC7F7AD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AuditMode|Any CPU = AuditMode|Any CPU
@@ -3453,46 +3449,6 @@ Global
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x64.Build.0 = Release|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x86.ActiveCfg = Release|Win32
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x86.Build.0 = Release|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x64.ActiveCfg = AuditMode|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x64.Build.0 = AuditMode|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x86.Build.0 = AuditMode|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|Any CPU.ActiveCfg = Debug|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|ARM.ActiveCfg = Debug|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|ARM64.Build.0 = Debug|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x64.ActiveCfg = Debug|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x64.Build.0 = Debug|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x86.ActiveCfg = Debug|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x86.Build.0 = Debug|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x64.Build.0 = Fuzzing|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x86.Build.0 = Fuzzing|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|Any CPU.ActiveCfg = Release|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|ARM.ActiveCfg = Release|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|ARM64.ActiveCfg = Release|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|ARM64.Build.0 = Release|ARM64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x64.ActiveCfg = Release|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x64.Build.0 = Release|x64
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x86.ActiveCfg = Release|Win32
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -3596,8 +3552,6 @@ Global
{8222900C-8B6C-452A-91AC-BE95DB04B95F} = {05500DEF-2294-41E3-AF9A-24E580B82836}
{06EC74CB-9A12-428C-B551-8537EC964726} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
{75C6F576-18E9-4566-978A-F0A301CAC090} = {05500DEF-2294-41E3-AF9A-24E580B82836}
{40BD8415-DD93-4200-8D82-498DDDC08CC8} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{3C67784E-1453-49C2-9660-483E2CC7F7AD} = {40BD8415-DD93-4200-8D82-498DDDC08CC8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}

View File

@@ -111,10 +111,10 @@ repository.
---
## Windows Terminal Roadmap
## Windows Terminal 2.0 Roadmap
The plan for the Windows Terminal [is described here](/doc/roadmap-2022.md) and
will be updated as the project proceeds.
The plan for delivering Windows Terminal 2.0 [is described
here](/doc/terminal-v2-roadmap.md) and will be updated as the project proceeds.
## Project Build Status

View File

@@ -4,5 +4,5 @@
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
<!-- This cannot be included in another project that depends on XAML (as it would be a duplicate package ID) -->
<package id="Microsoft.UI.Xaml" version="2.7.0" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.3" targetFramework="native" />
</packages>

View File

@@ -9,7 +9,7 @@
<PropertyGroup>
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
<PGOBranch>main</PGOBranch>
<PGOBranch>release-1.14</PGOBranch>
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>

View File

@@ -30,7 +30,7 @@ jobs:
If ($Arch -Eq "x86") { $Arch = "Win32" }
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
- steps: restore-nuget-steps.yml
- template: restore-nuget-steps.yml
- task: UniversalPackages@0
displayName: Download terminal-internal Universal Package
inputs:

View File

@@ -18,14 +18,14 @@
This version should be tracked in all project packages.config files for projects that depend on Xaml.
-->
<TerminalMUXVersion>2.7.2-prerelease.220406002</TerminalMUXVersion>
<TerminalMUXVersion>2.7.3-prerelease.220816001</TerminalMUXVersion>
<!--
For the Windows 11-specific build, we're targeting the public version of Microsoft.UI.Xaml.
This version emits a package dependency instead of embedding the dependency in our own package.
This version should be tracked in build/packages.config.
-->
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.1</TerminalMUXVersion>
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.3</TerminalMUXVersion>
</PropertyGroup>
</Project>

View File

@@ -17,7 +17,7 @@
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2022</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>15</VersionMinor>
<VersionMinor>14</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

View File

@@ -10,13 +10,13 @@
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.6.220404001" targetFramework="native" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
<package id="Microsoft.UI.Xaml" version="2.7.2-prerelease.220406002" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.3-prerelease.220816001" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" developmentDependency="true" />
<!-- Managed packages -->
<package id="Appium.WebDriver" version="3.0.0.2" targetFramework="net45" />
<package id="Castle.Core" version="4.1.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net45" />
<package id="Selenium.Support" version="3.5.0" targetFramework="net45" />
<package id="Selenium.WebDriver" version="3.5.0" targetFramework="net45" />
</packages>

View File

@@ -318,7 +318,6 @@
"moveFocus",
"movePane",
"swapPane",
"markMode",
"moveTab",
"multipleActions",
"newTab",
@@ -2011,6 +2010,10 @@
"description": "Controls what happens when the application emits a BEL character. When set to \"all\", the Terminal will play a sound, flash the taskbar icon (if the terminal window is not in focus) and flash the window. An array of specific behaviors can also be used. Supported array values include `audible`, `window` and `taskbar`. When set to \"none\", nothing will happen.",
"$ref": "#/$defs/BellStyle"
},
"bellSound": {
"description": "Sets the sound played when the application emits a BEL. When set to an array, the terminal will pick one of those sounds at random.",
"$ref": "#/$defs/BellSound"
},
"closeOnExit": {
"default": "graceful",
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",

View File

@@ -22,61 +22,21 @@ Below is the schedule for when milestones will be included in release builds of
| Milestone End Date | Milestone Name | Preview Release Blog Post |
| ------------------ | -------------- | ------------------------- |
| 2020-06-18 | [1.1] in Windows Terminal Preview | [Windows Terminal Preview 1.1 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-1-release/) |
| 2020-07-31 | [1.2] in Windows Terminal Preview<br>[1.1] in Windows Terminal | [Windows Terminal Preview 1.2 Release] |
| 2020-08-31 | [1.3] in Windows Terminal Preview<br>[1.2] in Windows Terminal | [Windows Terminal Preview 1.3 Release] |
| 2020-09-30 | [1.4] in Windows Terminal Preview<br>[1.3] in Windows Terminal | [Windows Terminal Preview 1.4 Release] |
| 2020-11-30 | [1.5] in Windows Terminal Preview<br>[1.4] in Windows Terminal | [Windows Terminal Preview 1.5 Release] |
| 2021-01-31 | [1.6] in Windows Terminal Preview<br>[1.5] in Windows Terminal | [Windows Terminal Preview 1.6 Release] |
| 2021-03-01 | [1.7] in Windows Terminal Preview<br>[1.6] in Windows Terminal | [Windows Terminal Preview 1.7 Release] |
| 2021-04-14 | [1.8] in Windows Terminal Preview<br>[1.7] in Windows Terminal | [Windows Terminal Preview 1.8 Release] |
| 2021-05-31 | [1.9] in Windows Terminal Preview<br>[1.8] in Windows Terminal | [Windows Terminal Preview 1.9 Release] |
| 2021-07-14 | [1.10] in Windows Terminal Preview<br>[1.9] in Windows Terminal | [Windows Terminal Preview 1.10 Release] |
| 2021-08-31 | [1.11] in Windows Terminal Preview<br>[1.10] in Windows Terminal | [Windows Terminal Preview 1.11 Release] |
| 2021-10-20 | [1.12] in Windows Terminal Preview<br>[1.11] in Windows Terminal | [Windows Terminal Preview 1.12 Release] |
| 2022-02-03 | [1.13] in Windows Terminal Preview<br>[1.12] in Windows Terminal | [Windows Terminal Preview 1.13 Release] |
| 2022-05-24 | [1.14] in Windows Terminal Preview<br>[1.13] in Windows Terminal | [Windows Terminal Preview 1.14 Release] |
| | [1.15] in Windows Terminal Preview<br>[1.14] in Windows Terminal | |
| | [1.16] in Windows Terminal Preview<br>[1.15] in Windows Terminal | |
| | [1.17] in Windows Terminal Preview<br>[1.16] in Windows Terminal | |
| 2020-07-31 | [1.2] in Windows Terminal Preview<br>[1.1] in Windows Terminal | [Windows Terminal Preview 1.2 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-2-release/) |
| 2020-08-31 | [1.3] in Windows Terminal Preview<br>[1.2] in Windows Terminal | [Windows Terminal Preview 1.3 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-3-release/) |
| 2020-09-30 | [1.4] in Windows Terminal Preview<br>[1.3] in Windows Terminal | [Windows Terminal Preview 1.4 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-4-release/) |
| 2020-11-30 | [1.5] in Windows Terminal Preview<br>[1.4] in Windows Terminal | [Windows Terminal Preview 1.5 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-5-release/) |
| 2021-01-31 | [1.6] in Windows Terminal Preview<br>[1.5] in Windows Terminal | [Windows Terminal Preview 1.6 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-6-release/) |
| 2021-03-01 | [1.7] in Windows Terminal Preview<br>[1.6] in Windows Terminal | [Windows Terminal Preview 1.7 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-7-release/) |
| 2021-04-14 | [1.8] in Windows Terminal Preview<br>[1.7] in Windows Terminal | [Windows Terminal Preview 1.8 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-8-release/) |
| 2021-05-31 | [1.9] in Windows Terminal Preview<br>[1.8] in Windows Terminal | [Windows Terminal Preview 1.9 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-9-release/) |
| 2021-07-14 | [1.10] in Windows Terminal Preview<br>[1.9] in Windows Terminal | [Windows Terminal Preview 1.10 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-10-release/) |
| 2021-08-31 | [1.11] in Windows Terminal Preview<br>[1.10] in Windows Terminal | [Windows Terminal Preview 1.11 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-11-release/) |
| 2021-10-20 | [1.12] in Windows Terminal Preview<br>[1.11] in Windows Terminal | [Windows Terminal Preview 1.12 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-12-release/) |
| | [1.13] in Windows Terminal Preview<br>[1.12] in Windows Terminal | |
| | [1.14] in Windows Terminal Preview<br>[1.13] in Windows Terminal | |
### Release outline
Below is a VERY vague outline of the remaining calendar year that was drafted late May 2022. This was drafted for internal planning purposes, as a guide. It is not meant to represent official dates. More often than not, releases are synced to official features landing, rather than arbitrary dates. Drift from this initial draft is entirely expected.
```mermaid
gantt
title Proposed Terminal Releases 1.14-1.18
dateFormat YYYY-MM-DD
axisFormat %d %b
section Terminal 1.14
Lock down & bake :done, 2022-05-06, 2w
Release 1.14 :milestone, 2022-05-24
section Terminal 1.15
Features :done, a1, 2022-05-06, 4w
Bugfix :active, a2, after a1 , 1w
Lock down & bake :after a2 , 1w
Release 1.15 :milestone, 2022-06-21, 0
1.15 becomes Stable :milestone, after b3, 0
section Terminal 1.16
Features :b1, after a2, 4w
Bugfix :b2, after b1 , 2w
Lock down & bake :b3, after b2 , 2w
Release 1.16 :milestone, after b3, 0
1.16 becomes Stable :milestone, after c3, 0
section Terminal 1.17
Features :c1, after b2, 4w
Bugfix :c2, after c1 , 2w
Lock down & bake :c3, after c2 , 2w
Release 1.17 :milestone, after c3, 0
1.17 becomes Stable :milestone, after d3, 0
section Terminal 1.18
Features :d1, after c2, 4w
Bugfix :d2, after d1 , 2w
Lock down & bake :d3, after d2 , 2w
Release 1.18 :milestone, after d3, 0
```
## Issue Triage & Prioritization
Incoming issues/asks/etc. are triaged several times a week, labeled appropriately, and assigned to a milestone in priority order:
@@ -102,9 +62,7 @@ Incoming issues/asks/etc. are triaged several times a week, labeled appropriatel
[1.12]: https://github.com/microsoft/terminal/milestone/38
[1.13]: https://github.com/microsoft/terminal/milestone/39
[1.14]: https://github.com/microsoft/terminal/milestone/41
[1.15]: https://github.com/microsoft/terminal/milestone/47
[1.16]: https://github.com/microsoft/terminal/milestone/48
[1.17]: https://github.com/microsoft/terminal/milestone/49
[22H1]: https://github.com/microsoft/terminal/milestone/43
[22H2]: https://github.com/microsoft/terminal/milestone/44
@@ -112,17 +70,3 @@ Incoming issues/asks/etc. are triaged several times a week, labeled appropriatel
[Backlog]: https://github.com/microsoft/terminal/milestone/45
[Terminal v2 Roadmap]: https://github.com/microsoft/terminal/tree/main/doc/terminal-v2-roadmap.md
[Windows Terminal Preview 1.2 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-2-release/
[Windows Terminal Preview 1.3 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-3-release/
[Windows Terminal Preview 1.4 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-4-release/
[Windows Terminal Preview 1.5 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-5-release/
[Windows Terminal Preview 1.6 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-6-release/
[Windows Terminal Preview 1.7 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-7-release/
[Windows Terminal Preview 1.8 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-8-release/
[Windows Terminal Preview 1.9 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-9-release/
[Windows Terminal Preview 1.10 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-10-release/
[Windows Terminal Preview 1.11 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-11-release/
[Windows Terminal Preview 1.12 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-12-release/
[Windows Terminal Preview 1.13 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-13-release/
[Windows Terminal Preview 1.14 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-14-release/

View File

@@ -1,125 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "MidiAudio.hpp"
#include "../terminal/parser/stateMachine.hpp"
namespace
{
class MidiOut
{
public:
static constexpr auto NOTE_OFF = 0x80;
static constexpr auto NOTE_ON = 0x90;
static constexpr auto PROGRAM_CHANGE = 0xC0;
// We're using a square wave as an approximation of the sound that the
// original VT525 terminals might have produced. This is probably not
// quite right, but it works reasonably well.
static constexpr auto SQUARE_WAVE_SYNTH = 80;
MidiOut() noexcept
{
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
{
midiOutOpen(&handle, MIDI_MAPPER, NULL, NULL, CALLBACK_NULL);
OutputMessage(PROGRAM_CHANGE, SQUARE_WAVE_SYNTH);
}
}
~MidiOut() noexcept
{
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
{
midiOutClose(handle);
}
}
void OutputMessage(const int b1, const int b2, const int b3 = 0, const int b4 = 0) noexcept
{
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
{
midiOutShortMsg(handle, MAKELONG(MAKEWORD(b1, b2), MAKEWORD(b3, b4)));
}
}
MidiOut(const MidiOut&) = delete;
MidiOut(MidiOut&&) = delete;
MidiOut& operator=(const MidiOut&) = delete;
MidiOut& operator=(MidiOut&&) = delete;
private:
HMIDIOUT handle = nullptr;
};
}
using namespace std::chrono_literals;
MidiAudio::~MidiAudio() noexcept
{
try
{
#pragma warning(suppress : 26447)
// We acquire the lock here so the class isn't destroyed while in use.
// If this throws, we'll catch it, so the C26447 warning is bogus.
_inUseMutex.lock();
}
catch (...)
{
// If the lock fails, we'll just have to live with the consequences.
}
}
void MidiAudio::Initialize()
{
_shutdownFuture = _shutdownPromise.get_future();
}
void MidiAudio::Shutdown()
{
// Once the shutdown promise is set, any note that is playing will stop
// immediately, and the Unlock call will exit the thread ASAP.
_shutdownPromise.set_value();
}
void MidiAudio::Lock()
{
_inUseMutex.lock();
}
void MidiAudio::Unlock()
{
// We need to check the shutdown status before releasing the mutex,
// because after that the class could be destroyed.
const auto shutdownStatus = _shutdownFuture.wait_for(0s);
_inUseMutex.unlock();
// If the wait didn't timeout, that means the shutdown promise was set,
// so we need to exit the thread ASAP by throwing an exception.
if (shutdownStatus != std::future_status::timeout)
{
throw Microsoft::Console::VirtualTerminal::StateMachine::ShutdownException{};
}
}
void MidiAudio::PlayNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) noexcept
try
{
// The MidiOut is a local static because we can only have one instance,
// and we only want to construct it when it's actually needed.
static MidiOut midiOut;
if (velocity)
{
midiOut.OutputMessage(MidiOut::NOTE_ON, noteNumber, velocity);
}
// By waiting on the shutdown future with the duration of the note, we'll
// either be paused for the appropriate amount of time, or we'll break out
// of the wait early if we've been shutdown.
_shutdownFuture.wait_for(duration);
if (velocity)
{
midiOut.OutputMessage(MidiOut::NOTE_OFF, noteNumber, velocity);
}
}
CATCH_LOG()

View File

@@ -1,36 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- MidiAudio.hpp
Abstract:
This modules provide basic MIDI support with blocking sound output.
*/
#pragma once
#include <future>
#include <mutex>
class MidiAudio
{
public:
MidiAudio() = default;
MidiAudio(const MidiAudio&) = delete;
MidiAudio(MidiAudio&&) = delete;
MidiAudio& operator=(const MidiAudio&) = delete;
MidiAudio& operator=(MidiAudio&&) = delete;
~MidiAudio() noexcept;
void Initialize();
void Shutdown();
void Lock();
void Unlock();
void PlayNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) noexcept;
private:
std::promise<void> _shutdownPromise;
std::future<void> _shutdownFuture;
std::mutex _inUseMutex;
};

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{3c67784e-1453-49c2-9660-483e2cc7f7ad}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>midi</RootNamespace>
<ProjectName>MidiAudio</ProjectName>
<TargetName>MidiAudio</TargetName>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(SolutionDir)src\common.build.pre.props" />
<Import Project="$(SolutionDir)src\common.nugetversions.props" />
<ItemGroup>
<ClCompile Include="..\MidiAudio.cpp" />
<ClCompile Include="..\precomp.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\MidiAudio.hpp" />
<ClInclude Include="..\precomp.h" />
</ItemGroup>
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<Import Project="$(SolutionDir)src\common.build.post.props" />
<Import Project="$(SolutionDir)src\common.nugetversions.targets" />
</Project>

View File

@@ -1,4 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"

View File

@@ -1,30 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- precomp.h
Abstract:
- Contains external headers to include in the precompile phase of console build process.
- Avoid including internal project headers. Instead include them only in the classes that need them (helps with test project building).
--*/
#pragma once
// clang-format off
// This includes support libraries from the CRT, STL, WIL, and GSL
#include "LibraryIncludes.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define NOMCX
#define NOHELP
#define NOCOMM
#endif
// Windows Header Files:
#include <windows.h>
// clang-format on

View File

@@ -11,8 +11,8 @@
// - attr - the default text attribute
// Return Value:
// - constructed object
ATTR_ROW::ATTR_ROW(const til::CoordType width, const TextAttribute attr) :
_data(gsl::narrow_cast<uint16_t>(width), attr) {}
ATTR_ROW::ATTR_ROW(const uint16_t width, const TextAttribute attr) :
_data(width, attr) {}
// Routine Description:
// - Sets all properties of the ATTR_ROW to default values
@@ -32,9 +32,9 @@ void ATTR_ROW::Reset(const TextAttribute attr)
// - newWidth - The new width of the row.
// Return Value:
// - <none>, throws exceptions on failures.
void ATTR_ROW::Resize(const til::CoordType newWidth)
void ATTR_ROW::Resize(const uint16_t newWidth)
{
_data.resize_trailing_extent(gsl::narrow<uint16_t>(newWidth));
_data.resize_trailing_extent(newWidth);
}
// Routine Description:
@@ -45,9 +45,9 @@ void ATTR_ROW::Resize(const til::CoordType newWidth)
// - the text attribute at column
// Note:
// - will throw on error
TextAttribute ATTR_ROW::GetAttrByColumn(const til::CoordType column) const
TextAttribute ATTR_ROW::GetAttrByColumn(const uint16_t column) const
{
return _data.at(gsl::narrow<uint16_t>(column));
return _data.at(column);
}
// Routine Description:
@@ -74,7 +74,7 @@ std::vector<uint16_t> ATTR_ROW::GetHyperlinks() const
// - attr - Attribute (color) to fill remaining characters with
// Return Value:
// - <none>
bool ATTR_ROW::SetAttrToEnd(const til::CoordType beginIndex, const TextAttribute attr)
bool ATTR_ROW::SetAttrToEnd(const uint16_t beginIndex, const TextAttribute attr)
{
_data.replace(gsl::narrow<uint16_t>(beginIndex), _data.size(), attr);
return true;
@@ -103,9 +103,9 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt
// - newAttr: The attribute to merge into this row.
// Return Value:
// - <none>
void ATTR_ROW::Replace(const til::CoordType beginIndex, const til::CoordType endIndex, const TextAttribute& newAttr)
void ATTR_ROW::Replace(const uint16_t beginIndex, const uint16_t endIndex, const TextAttribute& newAttr)
{
_data.replace(gsl::narrow<uint16_t>(beginIndex), gsl::narrow<uint16_t>(endIndex), newAttr);
_data.replace(beginIndex, endIndex, newAttr);
}
ATTR_ROW::const_iterator ATTR_ROW::begin() const noexcept

View File

@@ -30,7 +30,7 @@ class ATTR_ROW final
public:
using const_iterator = rle_vector::const_iterator;
ATTR_ROW(til::CoordType width, TextAttribute attr);
ATTR_ROW(uint16_t width, TextAttribute attr);
~ATTR_ROW() = default;
@@ -40,13 +40,13 @@ public:
noexcept = default;
ATTR_ROW& operator=(ATTR_ROW&&) noexcept = default;
TextAttribute GetAttrByColumn(til::CoordType column) const;
TextAttribute GetAttrByColumn(uint16_t column) const;
std::vector<uint16_t> GetHyperlinks() const;
bool SetAttrToEnd(til::CoordType beginIndex, TextAttribute attr);
bool SetAttrToEnd(uint16_t beginIndex, TextAttribute attr);
void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith);
void Resize(til::CoordType newWidth);
void Replace(til::CoordType beginIndex, til::CoordType endIndex, const TextAttribute& newAttr);
void Resize(uint16_t newWidth);
void Replace(uint16_t beginIndex, uint16_t endIndex, const TextAttribute& newAttr);
const_iterator begin() const noexcept;
const_iterator end() const noexcept;

View File

@@ -17,7 +17,7 @@
// Note: will through if unable to allocate char/attribute buffers
#pragma warning(push)
#pragma warning(disable : 26447) // small_vector's constructor says it can throw but it should not given how we use it. This suppresses this error for the AuditMode build.
CharRow::CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept :
CharRow::CharRow(size_t rowWidth, ROW* const pParent) noexcept :
_data(rowWidth, value_type()),
_pParent{ FAIL_FAST_IF_NULL(pParent) }
{
@@ -30,9 +30,9 @@ CharRow::CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept :
// - <none>
// Return Value:
// - the size of the row
til::CoordType CharRow::size() const noexcept
size_t CharRow::size() const noexcept
{
return gsl::narrow_cast<til::CoordType>(_data.size());
return _data.size();
}
// Routine Description:
@@ -55,7 +55,7 @@ void CharRow::Reset() noexcept
// - newSize - the new width of the character and attributes rows
// Return Value:
// - S_OK on success, otherwise relevant error code
[[nodiscard]] HRESULT CharRow::Resize(const til::CoordType newSize) noexcept
[[nodiscard]] HRESULT CharRow::Resize(const size_t newSize) noexcept
{
try
{
@@ -93,14 +93,14 @@ typename CharRow::const_iterator CharRow::cend() const noexcept
// - <none>
// Return Value:
// - The calculated left boundary of the internal string.
til::CoordType CharRow::MeasureLeft() const noexcept
size_t CharRow::MeasureLeft() const noexcept
{
auto it = _data.cbegin();
while (it != _data.cend() && it->IsSpace())
{
++it;
}
return gsl::narrow_cast<til::CoordType>(it - _data.cbegin());
return it - _data.cbegin();
}
// Routine Description:
@@ -109,17 +109,17 @@ til::CoordType CharRow::MeasureLeft() const noexcept
// - <none>
// Return Value:
// - The calculated right boundary of the internal string.
til::CoordType CharRow::MeasureRight() const
size_t CharRow::MeasureRight() const
{
auto it = _data.crbegin();
while (it != _data.crend() && it->IsSpace())
{
++it;
}
return gsl::narrow_cast<til::CoordType>(_data.crend() - it);
return _data.crend() - it;
}
void CharRow::ClearCell(const til::CoordType column)
void CharRow::ClearCell(const size_t column)
{
_data.at(column).Reset();
}
@@ -149,7 +149,7 @@ bool CharRow::ContainsText() const noexcept
// Return Value:
// - the attribute
// Note: will throw exception if column is out of bounds
const DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column) const
const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
{
return _data.at(column).DbcsAttr();
}
@@ -161,7 +161,7 @@ const DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column) const
// Return Value:
// - the attribute
// Note: will throw exception if column is out of bounds
DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column)
DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
{
return _data.at(column).DbcsAttr();
}
@@ -173,7 +173,7 @@ DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column)
// Return Value:
// - <none>
// Note: will throw exception if column is out of bounds
void CharRow::ClearGlyph(const til::CoordType column)
void CharRow::ClearGlyph(const size_t column)
{
_data.at(column).EraseChars();
}
@@ -185,9 +185,9 @@ void CharRow::ClearGlyph(const til::CoordType column)
// Return Value:
// - text data at column
// - Note: will throw exception if column is out of bounds
const CharRow::reference CharRow::GlyphAt(const til::CoordType column) const
const CharRow::reference CharRow::GlyphAt(const size_t column) const
{
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
return { const_cast<CharRow&>(*this), column };
}
@@ -198,9 +198,9 @@ const CharRow::reference CharRow::GlyphAt(const til::CoordType column) const
// Return Value:
// - text data at column
// - Note: will throw exception if column is out of bounds
CharRow::reference CharRow::GlyphAt(const til::CoordType column)
CharRow::reference CharRow::GlyphAt(const size_t column)
{
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
return { *this, column };
}
@@ -209,7 +209,7 @@ std::wstring CharRow::GetText() const
std::wstring wstr;
wstr.reserve(_data.size());
for (til::CoordType i = 0; i < gsl::narrow_cast<til::CoordType>(_data.size()); ++i)
for (size_t i = 0; i < _data.size(); ++i)
{
const auto glyph = GlyphAt(i);
if (!DbcsAttrAt(i).IsTrailing())
@@ -231,9 +231,9 @@ std::wstring CharRow::GetText() const
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
// Return Value:
// - the delimiter class for the given char
const DelimiterClass CharRow::DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const
const DelimiterClass CharRow::DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const
{
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
const auto glyph = *GlyphAt(column).begin();
if (glyph <= UNICODE_SPACE)
@@ -265,10 +265,10 @@ const UnicodeStorage& CharRow::GetUnicodeStorage() const noexcept
// Arguments:
// - column - the column to generate the key for
// Return Value:
// - the til::point key for data access from UnicodeStorage for the column
til::point CharRow::GetStorageKey(const til::CoordType column) const noexcept
// - the COORD key for data access from UnicodeStorage for the column
COORD CharRow::GetStorageKey(const size_t column) const noexcept
{
return { column, _pParent->GetId() };
return { gsl::narrow<SHORT>(column), _pParent->GetId() };
}
// Routine Description:

View File

@@ -54,22 +54,22 @@ public:
using const_reverse_iterator = typename boost::container::small_vector_base<value_type>::const_reverse_iterator;
using reference = typename CharRowCellReference;
CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept;
CharRow(size_t rowWidth, ROW* const pParent) noexcept;
til::CoordType size() const noexcept;
[[nodiscard]] HRESULT Resize(const til::CoordType newSize) noexcept;
til::CoordType MeasureLeft() const noexcept;
til::CoordType MeasureRight() const;
size_t size() const noexcept;
[[nodiscard]] HRESULT Resize(const size_t newSize) noexcept;
size_t MeasureLeft() const noexcept;
size_t MeasureRight() const;
bool ContainsText() const noexcept;
const DbcsAttribute& DbcsAttrAt(const til::CoordType column) const;
DbcsAttribute& DbcsAttrAt(const til::CoordType column);
void ClearGlyph(const til::CoordType column);
const DbcsAttribute& DbcsAttrAt(const size_t column) const;
DbcsAttribute& DbcsAttrAt(const size_t column);
void ClearGlyph(const size_t column);
const DelimiterClass DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const;
const DelimiterClass DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const;
// working with glyphs
const reference GlyphAt(const til::CoordType column) const;
reference GlyphAt(const til::CoordType column);
const reference GlyphAt(const size_t column) const;
reference GlyphAt(const size_t column);
// iterators
iterator begin() noexcept;
@@ -82,7 +82,7 @@ public:
UnicodeStorage& GetUnicodeStorage() noexcept;
const UnicodeStorage& GetUnicodeStorage() const noexcept;
til::point GetStorageKey(const til::CoordType column) const noexcept;
COORD GetStorageKey(const size_t column) const noexcept;
void UpdateParent(ROW* const pParent);
@@ -91,7 +91,7 @@ public:
private:
void Reset() noexcept;
void ClearCell(const til::CoordType column);
void ClearCell(const size_t column);
std::wstring GetText() const;
protected:

View File

@@ -25,7 +25,7 @@ class CharRowCellReference final
public:
using const_iterator = const wchar_t*;
CharRowCellReference(CharRow& parent, const til::CoordType index) noexcept :
CharRowCellReference(CharRow& parent, const size_t index) noexcept :
_parent{ parent },
_index{ index }
{
@@ -51,7 +51,7 @@ private:
// what char row the object belongs to
CharRow& _parent;
// the index of the cell in the parent char row
til::CoordType _index;
const size_t _index;
CharRowCell& _cellData();
const CharRowCell& _cellData() const;

View File

@@ -21,16 +21,16 @@ enum class LineRendition
DoubleHeightBottom
};
constexpr til::inclusive_rect ScreenToBufferLine(const til::inclusive_rect& line, const LineRendition lineRendition)
constexpr SMALL_RECT ScreenToBufferLine(const SMALL_RECT& line, const LineRendition lineRendition)
{
// Use shift right to quickly divide the Left and Right by 2 for double width lines.
const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
return { line.Left >> scale, line.Top, line.Right >> scale, line.Bottom };
}
constexpr til::inclusive_rect BufferToScreenLine(const til::inclusive_rect& line, const LineRendition lineRendition)
constexpr SMALL_RECT BufferToScreenLine(const SMALL_RECT& line, const LineRendition lineRendition)
{
// Use shift left to quickly multiply the Left and Right by 2 for double width lines.
const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
return { line.Left << scale, line.Top, (line.Right << scale) + scale, line.Bottom };
}

View File

@@ -531,16 +531,16 @@ OutputCellView OutputCellIterator::s_GenerateView(const OutputCell& cell)
// - Gets the distance between two iterators relative to the input data given in.
// Return Value:
// - The number of items of the input run consumed between these two iterators.
til::CoordType OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
ptrdiff_t OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
{
return gsl::narrow_cast<til::CoordType>(_pos - other._pos);
return _pos - other._pos;
}
// Routine Description:
// - Gets the distance between two iterators relative to the number of cells inserted.
// Return Value:
// - The number of cells in the backing buffer filled between these two iterators.
til::CoordType OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
ptrdiff_t OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
{
return gsl::narrow_cast<til::CoordType>(_distance - other._distance);
return _distance - other._distance;
}

View File

@@ -29,7 +29,7 @@ class OutputCellIterator final
public:
using iterator_category = std::input_iterator_tag;
using value_type = OutputCellView;
using difference_type = til::CoordType;
using difference_type = ptrdiff_t;
using pointer = OutputCellView*;
using reference = OutputCellView&;
@@ -48,9 +48,9 @@ public:
operator bool() const noexcept;
til::CoordType GetCellDistance(OutputCellIterator other) const noexcept;
til::CoordType GetInputDistance(OutputCellIterator other) const noexcept;
friend til::CoordType operator-(OutputCellIterator one, OutputCellIterator two) = delete;
ptrdiff_t GetCellDistance(OutputCellIterator other) const noexcept;
ptrdiff_t GetInputDistance(OutputCellIterator other) const noexcept;
friend ptrdiff_t operator-(OutputCellIterator one, OutputCellIterator two) = delete;
OutputCellIterator& operator++();
OutputCellIterator operator++(int);

View File

@@ -21,11 +21,14 @@ OutputCellRect::OutputCellRect() noexcept :
// Arguments:
// - rows - Rows in the rectangle (height)
// - cols - Columns in the rectangle (width)
OutputCellRect::OutputCellRect(const til::CoordType rows, const til::CoordType cols) :
OutputCellRect::OutputCellRect(const size_t rows, const size_t cols) :
_rows(rows),
_cols(cols)
{
_storage.resize(gsl::narrow<size_t>(rows * cols));
size_t totalCells;
THROW_IF_FAILED(SizeTMult(rows, cols, &totalCells));
_storage.resize(totalCells);
}
// Routine Description:
@@ -34,7 +37,7 @@ OutputCellRect::OutputCellRect(const til::CoordType rows, const til::CoordType c
// - row - The Y position or row index in the buffer.
// Return Value:
// - Read/write span of OutputCells
gsl::span<OutputCell> OutputCellRect::GetRow(const til::CoordType row)
gsl::span<OutputCell> OutputCellRect::GetRow(const size_t row)
{
return gsl::span<OutputCell>(_FindRowOffset(row), _cols);
}
@@ -45,7 +48,7 @@ gsl::span<OutputCell> OutputCellRect::GetRow(const til::CoordType row)
// - row - The Y position or row index in the buffer.
// Return Value:
// - Read-only iterator of OutputCells
OutputCellIterator OutputCellRect::GetRowIter(const til::CoordType row) const
OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
{
const gsl::span<const OutputCell> view(_FindRowOffset(row), _cols);
@@ -59,9 +62,9 @@ OutputCellIterator OutputCellRect::GetRowIter(const til::CoordType row) const
// - row - The Y position or row index in the buffer.
// Return Value:
// - Pointer to the location in the rectangle that represents the start of the requested row.
OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row)
OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
{
return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
return &_storage.at(row * _cols);
}
// Routine Description:
@@ -71,16 +74,16 @@ OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row)
// - row - The Y position or row index in the buffer.
// Return Value:
// - Pointer to the location in the rectangle that represents the start of the requested row.
const OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row) const
const OutputCell* OutputCellRect::_FindRowOffset(const size_t row) const
{
return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
return &_storage.at(row * _cols);
}
// Routine Description:
// - Gets the height of the rectangle
// Return Value:
// - Height
til::CoordType OutputCellRect::Height() const noexcept
size_t OutputCellRect::Height() const noexcept
{
return _rows;
}
@@ -89,7 +92,7 @@ til::CoordType OutputCellRect::Height() const noexcept
// - Gets the width of the rectangle
// Return Value:
// - Width
til::CoordType OutputCellRect::Width() const noexcept
size_t OutputCellRect::Width() const noexcept
{
return _cols;
}

View File

@@ -30,20 +30,20 @@ class OutputCellRect final
{
public:
OutputCellRect() noexcept;
OutputCellRect(const til::CoordType rows, const til::CoordType cols);
OutputCellRect(const size_t rows, const size_t cols);
gsl::span<OutputCell> GetRow(const til::CoordType row);
OutputCellIterator GetRowIter(const til::CoordType row) const;
gsl::span<OutputCell> GetRow(const size_t row);
OutputCellIterator GetRowIter(const size_t row) const;
til::CoordType Height() const noexcept;
til::CoordType Width() const noexcept;
size_t Height() const noexcept;
size_t Width() const noexcept;
private:
std::vector<OutputCell> _storage;
OutputCell* _FindRowOffset(const til::CoordType row);
const OutputCell* _FindRowOffset(const til::CoordType row) const;
OutputCell* _FindRowOffset(const size_t row);
const OutputCell* _FindRowOffset(const size_t row) const;
til::CoordType _cols;
til::CoordType _rows;
size_t _cols;
size_t _rows;
};

View File

@@ -38,7 +38,7 @@ OutputCellView::OutputCellView(const std::wstring_view view,
// - Reports how many columns we expect the Chars() text data to consume
// Return Value:
// - Count of column cells on the screen
til::CoordType OutputCellView::Columns() const noexcept
size_t OutputCellView::Columns() const noexcept
{
if (DbcsAttr().IsSingle())
{

View File

@@ -31,7 +31,7 @@ public:
const TextAttributeBehavior behavior) noexcept;
const std::wstring_view& Chars() const noexcept;
til::CoordType Columns() const noexcept;
size_t Columns() const noexcept;
DbcsAttribute DbcsAttr() const noexcept;
TextAttribute TextAttr() const noexcept;
TextAttributeBehavior TextAttrBehavior() const noexcept;

View File

@@ -16,7 +16,7 @@
// - pParent - the text buffer that this row belongs to
// Return Value:
// - constructed object
ROW::ROW(const til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
ROW::ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
_id{ rowId },
_rowWidth{ rowWidth },
_charRow{ rowWidth, this },
@@ -58,7 +58,7 @@ bool ROW::Reset(const TextAttribute Attr)
// - width - the new width, in cells
// Return Value:
// - S_OK if successful, otherwise relevant error
[[nodiscard]] HRESULT ROW::Resize(const til::CoordType width)
[[nodiscard]] HRESULT ROW::Resize(const unsigned short width)
{
RETURN_IF_FAILED(_charRow.Resize(width));
try
@@ -78,7 +78,7 @@ bool ROW::Reset(const TextAttribute Attr)
// - column - 0-indexed column index
// Return Value:
// - <none>
void ROW::ClearColumn(const til::CoordType column)
void ROW::ClearColumn(const size_t column)
{
THROW_HR_IF(E_INVALIDARG, column >= _charRow.size());
_charRow.ClearCell(column);
@@ -103,7 +103,7 @@ const UnicodeStorage& ROW::GetUnicodeStorage() const noexcept
// - limitRight - right inclusive column ID for the last write in this row. (optional, will just write to the end of row if nullopt)
// Return Value:
// - iterator to first cell that was not written to this row.
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap, std::optional<til::CoordType> limitRight)
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap, std::optional<size_t> limitRight)
{
THROW_HR_IF(E_INVALIDARG, index >= _charRow.size());
THROW_HR_IF(E_INVALIDARG, limitRight.value_or(0) >= _charRow.size());

View File

@@ -32,9 +32,9 @@ class TextBuffer;
class ROW final
{
public:
ROW(const til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
til::CoordType size() const noexcept { return _rowWidth; }
size_t size() const noexcept { return _rowWidth; }
void SetWrapForced(const bool wrap) noexcept { _wrapForced = wrap; }
bool WasWrapForced() const noexcept { return _wrapForced; }
@@ -51,19 +51,19 @@ public:
LineRendition GetLineRendition() const noexcept { return _lineRendition; }
void SetLineRendition(const LineRendition lineRendition) noexcept { _lineRendition = lineRendition; }
til::CoordType GetId() const noexcept { return _id; }
void SetId(const til::CoordType id) noexcept { _id = id; }
SHORT GetId() const noexcept { return _id; }
void SetId(const SHORT id) noexcept { _id = id; }
bool Reset(const TextAttribute Attr);
[[nodiscard]] HRESULT Resize(const til::CoordType width);
[[nodiscard]] HRESULT Resize(const unsigned short width);
void ClearColumn(const til::CoordType column);
void ClearColumn(const size_t column);
std::wstring GetText() const { return _charRow.GetText(); }
UnicodeStorage& GetUnicodeStorage() noexcept;
const UnicodeStorage& GetUnicodeStorage() const noexcept;
OutputCellIterator WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap = std::nullopt, std::optional<til::CoordType> limitRight = std::nullopt);
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap = std::nullopt, std::optional<size_t> limitRight = std::nullopt);
#ifdef UNIT_TESTING
friend constexpr bool operator==(const ROW& a, const ROW& b) noexcept;
@@ -74,8 +74,8 @@ private:
CharRow _charRow;
ATTR_ROW _attrRow;
LineRendition _lineRendition;
til::CoordType _id;
til::CoordType _rowWidth;
SHORT _id;
unsigned short _rowWidth;
// Occurs when the user runs out of text in a given row and we're forced to wrap the cursor to the next line
bool _wrapForced;
// Occurs when the user runs out of text to support a double byte character and we're forced to the next line

View File

@@ -357,11 +357,6 @@ void TextAttribute::SetReverseVideo(bool isReversed) noexcept
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO, isReversed);
}
ExtendedAttributes TextAttribute::GetExtendedAttributes() const noexcept
{
return _extendedAttrs;
}
// Routine Description:
// - swaps foreground and background color
void TextAttribute::Invert() noexcept

View File

@@ -109,7 +109,10 @@ public:
void SetOverlined(bool isOverlined) noexcept;
void SetReverseVideo(bool isReversed) noexcept;
ExtendedAttributes GetExtendedAttributes() const noexcept;
constexpr ExtendedAttributes GetExtendedAttributes() const noexcept
{
return _extendedAttrs;
}
bool IsHyperlink() const noexcept;
@@ -161,6 +164,13 @@ public:
{
return WI_IsAnyFlagSet(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL | COMMON_LVB_GRID_LVERTICAL | COMMON_LVB_GRID_RVERTICAL | COMMON_LVB_UNDERSCORE);
}
constexpr bool HasAnyExtendedAttributes() const noexcept
{
return GetExtendedAttributes() != ExtendedAttributes::Normal ||
IsAnyGridLineEnabled() ||
GetHyperlinkId() != 0 ||
IsReverseVideo();
}
private:
static std::array<TextColor, 16> s_legacyForegroundColorMap;

View File

@@ -49,8 +49,6 @@ enum class ColorAlias : size_t
{
DefaultForeground,
DefaultBackground,
FrameForeground,
FrameBackground,
ENUM_COUNT // must be the last element in the enum class
};
@@ -74,13 +72,10 @@ public:
static constexpr BYTE BRIGHT_CYAN = 14;
static constexpr BYTE BRIGHT_WHITE = 15;
// Entries 256 to 260 are reserved for XTerm compatibility.
static constexpr size_t DEFAULT_FOREGROUND = 261;
static constexpr size_t DEFAULT_BACKGROUND = 262;
static constexpr size_t FRAME_FOREGROUND = 263;
static constexpr size_t FRAME_BACKGROUND = 264;
static constexpr size_t CURSOR_COLOR = 265;
static constexpr size_t TABLE_SIZE = 266;
static constexpr size_t DEFAULT_FOREGROUND = 256;
static constexpr size_t DEFAULT_BACKGROUND = 257;
static constexpr size_t CURSOR_COLOR = 258;
static constexpr size_t TABLE_SIZE = 259;
constexpr TextColor() noexcept :
_meta{ ColorType::IsDefault },

View File

@@ -47,7 +47,7 @@ void UnicodeStorage::Erase(const key_type key) noexcept
// - rowMap - A map of the old row IDs to the new row IDs.
// - width - The width of the new row. Remove any items that are beyond the row width.
// - Use nullopt if we're not resizing the width of the row, just renumbering the rows.
void UnicodeStorage::Remap(const std::unordered_map<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width)
void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width)
{
// Make a temporary map to hold all the new row positioning
std::unordered_map<key_type, mapped_type> newMap;
@@ -87,7 +87,7 @@ void UnicodeStorage::Remap(const std::unordered_map<til::CoordType, til::CoordTy
const auto newRowId = mapIter->second;
// Generate a new coordinate with the same X as the old one, but a new Y value.
const auto newCoord = til::point{ oldCoord.X, newRowId };
const auto newCoord = COORD{ oldCoord.X, newRowId };
// Put the adjusted coordinate into the map with the original value.
newMap.emplace(newCoord, pair.second);

View File

@@ -20,11 +20,11 @@ Author(s):
#include <til/bit.h>
#include <til/hash.h>
// std::unordered_map needs help to know how to hash a til::point
// std::unordered_map needs help to know how to hash a COORD
namespace std
{
template<>
struct hash<til::point>
struct hash<COORD>
{
// Routine Description:
// - hashes a coord. coord will be hashed by storing the x and y values consecutively in the lower
@@ -33,9 +33,9 @@ namespace std
// - coord - the coord to hash
// Return Value:
// - the hashed coord
constexpr size_t operator()(const til::point coord) const noexcept
constexpr size_t operator()(const COORD& coord) const noexcept
{
return til::hash(til::bit_cast<uint64_t>(coord));
return til::hash(til::bit_cast<uint32_t>(coord));
}
};
}
@@ -43,7 +43,7 @@ namespace std
class UnicodeStorage final
{
public:
using key_type = typename til::point;
using key_type = typename COORD;
using mapped_type = typename std::vector<wchar_t>;
UnicodeStorage() noexcept;
@@ -54,7 +54,7 @@ public:
void Erase(const key_type key) noexcept;
void Remap(const std::unordered_map<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width);
void Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width);
private:
std::unordered_map<key_type, mapped_type> _map;

View File

@@ -13,6 +13,7 @@
// - ulSize - The height of the cursor within this buffer
Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
_parentBuffer{ parentBuffer },
_cPosition{ 0 },
_fHasMoved(false),
_fIsVisible(true),
_fIsOn(true),
@@ -22,6 +23,7 @@ Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
_fIsConversionArea(false),
_fIsPopupShown(false),
_fDelayedEolWrap(false),
_coordDelayedAt{ 0 },
_fDeferCursorRedraw(false),
_fHaveDeferredCursorRedraw(false),
_ulSize(ulSize),
@@ -33,7 +35,7 @@ Cursor::~Cursor()
{
}
til::point Cursor::GetPosition() const noexcept
COORD Cursor::GetPosition() const noexcept
{
return _cPosition;
}
@@ -190,58 +192,59 @@ void Cursor::_RedrawCursorAlways() noexcept
CATCH_LOG();
}
void Cursor::SetPosition(const til::point cPosition) noexcept
void Cursor::SetPosition(const COORD cPosition) noexcept
{
_RedrawCursor();
_cPosition = cPosition;
_cPosition.X = cPosition.X;
_cPosition.Y = cPosition.Y;
_RedrawCursor();
ResetDelayEOLWrap();
}
void Cursor::SetXPosition(const til::CoordType NewX) noexcept
void Cursor::SetXPosition(const int NewX) noexcept
{
_RedrawCursor();
_cPosition.X = NewX;
_cPosition.X = gsl::narrow<SHORT>(NewX);
_RedrawCursor();
ResetDelayEOLWrap();
}
void Cursor::SetYPosition(const til::CoordType NewY) noexcept
void Cursor::SetYPosition(const int NewY) noexcept
{
_RedrawCursor();
_cPosition.Y = NewY;
_cPosition.Y = gsl::narrow<SHORT>(NewY);
_RedrawCursor();
ResetDelayEOLWrap();
}
void Cursor::IncrementXPosition(const til::CoordType DeltaX) noexcept
void Cursor::IncrementXPosition(const int DeltaX) noexcept
{
_RedrawCursor();
_cPosition.X += DeltaX;
_cPosition.X += gsl::narrow<SHORT>(DeltaX);
_RedrawCursor();
ResetDelayEOLWrap();
}
void Cursor::IncrementYPosition(const til::CoordType DeltaY) noexcept
void Cursor::IncrementYPosition(const int DeltaY) noexcept
{
_RedrawCursor();
_cPosition.Y += DeltaY;
_cPosition.Y += gsl::narrow<SHORT>(DeltaY);
_RedrawCursor();
ResetDelayEOLWrap();
}
void Cursor::DecrementXPosition(const til::CoordType DeltaX) noexcept
void Cursor::DecrementXPosition(const int DeltaX) noexcept
{
_RedrawCursor();
_cPosition.X -= DeltaX;
_cPosition.X -= gsl::narrow<SHORT>(DeltaX);
_RedrawCursor();
ResetDelayEOLWrap();
}
void Cursor::DecrementYPosition(const til::CoordType DeltaY) noexcept
void Cursor::DecrementYPosition(const int DeltaY) noexcept
{
_RedrawCursor();
_cPosition.Y -= DeltaY;
_cPosition.Y -= gsl::narrow<SHORT>(DeltaY);
_RedrawCursor();
ResetDelayEOLWrap();
}
@@ -281,7 +284,7 @@ void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept
_cursorType = OtherCursor._cursorType;
}
void Cursor::DelayEOLWrap(const til::point coordDelayedAt) noexcept
void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
{
_coordDelayedAt = coordDelayedAt;
_fDelayedEolWrap = true;
@@ -289,11 +292,11 @@ void Cursor::DelayEOLWrap(const til::point coordDelayedAt) noexcept
void Cursor::ResetDelayEOLWrap() noexcept
{
_coordDelayedAt = {};
_coordDelayedAt = { 0 };
_fDelayedEolWrap = false;
}
til::point Cursor::GetDelayedAtPosition() const noexcept
COORD Cursor::GetDelayedAtPosition() const noexcept
{
return _coordDelayedAt;
}

View File

@@ -47,7 +47,7 @@ public:
bool IsPopupShown() const noexcept;
bool GetDelay() const noexcept;
ULONG GetSize() const noexcept;
til::point GetPosition() const noexcept;
COORD GetPosition() const noexcept;
const CursorType GetType() const noexcept;
@@ -66,19 +66,19 @@ public:
void SetSize(const ULONG ulSize) noexcept;
void SetStyle(const ULONG ulSize, const CursorType type) noexcept;
void SetPosition(const til::point cPosition) noexcept;
void SetXPosition(const til::CoordType NewX) noexcept;
void SetYPosition(const til::CoordType NewY) noexcept;
void IncrementXPosition(const til::CoordType DeltaX) noexcept;
void IncrementYPosition(const til::CoordType DeltaY) noexcept;
void DecrementXPosition(const til::CoordType DeltaX) noexcept;
void DecrementYPosition(const til::CoordType DeltaY) noexcept;
void SetPosition(const COORD cPosition) noexcept;
void SetXPosition(const int NewX) noexcept;
void SetYPosition(const int NewY) noexcept;
void IncrementXPosition(const int DeltaX) noexcept;
void IncrementYPosition(const int DeltaY) noexcept;
void DecrementXPosition(const int DeltaX) noexcept;
void DecrementYPosition(const int DeltaY) noexcept;
void CopyProperties(const Cursor& OtherCursor) noexcept;
void DelayEOLWrap(const til::point coordDelayedAt) noexcept;
void DelayEOLWrap(const COORD coordDelayedAt) noexcept;
void ResetDelayEOLWrap() noexcept;
til::point GetDelayedAtPosition() const noexcept;
COORD GetDelayedAtPosition() const noexcept;
bool IsDelayedEOLWrap() const noexcept;
void SetType(const CursorType type) noexcept;
@@ -90,7 +90,7 @@ private:
// NOTE: If you are adding a property here, go add it to CopyProperties.
til::point _cPosition; // current position on screen (in screen buffer coords).
COORD _cPosition; // current position on screen (in screen buffer coords).
bool _fHasMoved;
bool _fIsVisible; // whether cursor is visible (set only through the API)
@@ -102,7 +102,7 @@ private:
bool _fIsPopupShown; // if a popup is being shown, turn off, stop blinking.
bool _fDelayedEolWrap; // don't wrap at EOL till the next char comes in.
til::point _coordDelayedAt; // coordinate the EOL wrap was delayed at.
COORD _coordDelayedAt; // coordinate the EOL wrap was delayed at.
bool _fDeferCursorRedraw; // whether we should defer redrawing the cursor or not
bool _fHaveDeferredCursorRedraw; // have we been asked to redraw the cursor while it was being deferred?

View File

@@ -35,6 +35,7 @@ Abstract:
#include <intsafe.h>
// private dependencies
#include "../inc/operators.hpp"
#include "../inc/unicode.hpp"
#pragma warning(pop)

View File

@@ -50,7 +50,7 @@ Search::Search(IUiaData& uiaData,
const std::wstring& str,
const Direction direction,
const Sensitivity sensitivity,
const til::point anchor) :
const COORD anchor) :
_direction(direction),
_sensitivity(sensitivity),
_needle(s_CreateNeedleFromString(str)),
@@ -124,7 +124,7 @@ void Search::Color(const TextAttribute attr) const
// been called and returned true.
// Return Value:
// - pair containing [start, end] coord positions of text found by search
std::pair<til::point, til::point> Search::GetFoundLocation() const noexcept
std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
{
return { _coordSelStart, _coordSelEnd };
}
@@ -140,7 +140,7 @@ std::pair<til::point, til::point> Search::GetFoundLocation() const noexcept
// - direction - The intended direction of the search
// Return Value:
// - Coordinate to start the search from.
til::point Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
{
const auto& textBuffer = uiaData.GetTextBuffer();
const auto textBufferEndPosition = uiaData.GetTextBufferEndPosition();
@@ -187,10 +187,10 @@ til::point Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction d
// - end - If we found it, this is filled with the coordinate of the last character of the needle.
// Return Value:
// - True if we found it. False if not.
bool Search::_FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const
bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const
{
start = {};
end = {};
start = { 0 };
end = { 0 };
auto bufferPos = pos;
@@ -269,7 +269,7 @@ wchar_t Search::_ApplySensitivity(const wchar_t wch) const noexcept
// - Helper to increment a coordinate in respect to the associated screen buffer
// Arguments
// - coord - Updated by function to increment one position (will wrap X and Y direction)
void Search::_IncrementCoord(til::point& coord) const noexcept
void Search::_IncrementCoord(COORD& coord) const noexcept
{
_uiaData.GetTextBuffer().GetSize().IncrementInBoundsCircular(coord);
}
@@ -278,7 +278,7 @@ void Search::_IncrementCoord(til::point& coord) const noexcept
// - Helper to decrement a coordinate in respect to the associated screen buffer
// Arguments
// - coord - Updated by function to decrement one position (will wrap X and Y direction)
void Search::_DecrementCoord(til::point& coord) const noexcept
void Search::_DecrementCoord(COORD& coord) const noexcept
{
_uiaData.GetTextBuffer().GetSize().DecrementInBoundsCircular(coord);
}
@@ -314,7 +314,7 @@ void Search::_UpdateNextPosition()
{
if (_direction == Direction::Forward)
{
_coordNext = {};
_coordNext = { 0 };
}
else
{

View File

@@ -49,33 +49,33 @@ public:
const std::wstring& str,
const Direction dir,
const Sensitivity sensitivity,
const til::point anchor);
const COORD anchor);
bool FindNext();
void Select() const;
void Color(const TextAttribute attr) const;
std::pair<til::point, til::point> GetFoundLocation() const noexcept;
std::pair<COORD, COORD> GetFoundLocation() const noexcept;
private:
wchar_t _ApplySensitivity(const wchar_t wch) const noexcept;
bool _FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const;
bool _FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const;
bool _CompareChars(const std::wstring_view one, const std::wstring_view two) const noexcept;
void _UpdateNextPosition();
void _IncrementCoord(til::point& coord) const noexcept;
void _DecrementCoord(til::point& coord) const noexcept;
void _IncrementCoord(COORD& coord) const noexcept;
void _DecrementCoord(COORD& coord) const noexcept;
static til::point s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
static COORD s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);
bool _reachedEnd = false;
til::point _coordNext;
til::point _coordSelStart;
til::point _coordSelEnd;
COORD _coordNext = { 0 };
COORD _coordSelStart = { 0 };
COORD _coordSelEnd = { 0 };
const til::point _coordAnchor;
const COORD _coordAnchor;
const std::vector<std::vector<wchar_t>> _needle;
const Direction _direction;
const Sensitivity _sensitivity;

View File

@@ -30,7 +30,7 @@ using PointTree = interval_tree::IntervalTree<til::point, size_t>;
// Return Value:
// - constructed object
// Note: may throw exception
TextBuffer::TextBuffer(const til::size screenBufferSize,
TextBuffer::TextBuffer(const COORD screenBufferSize,
const TextAttribute defaultAttributes,
const UINT cursorSize,
const bool isActiveBuffer,
@@ -47,10 +47,10 @@ TextBuffer::TextBuffer(const til::size screenBufferSize,
_currentPatternId{ 0 }
{
// initialize ROWs
_storage.reserve(gsl::narrow<size_t>(screenBufferSize.Y));
for (til::CoordType i = 0; i < screenBufferSize.Y; ++i)
_storage.reserve(static_cast<size_t>(screenBufferSize.Y));
for (size_t i = 0; i < static_cast<size_t>(screenBufferSize.Y); ++i)
{
_storage.emplace_back(i, screenBufferSize.X, _currentAttributes, this);
_storage.emplace_back(static_cast<SHORT>(i), screenBufferSize.X, _currentAttributes, this);
}
_UpdateSize();
@@ -74,9 +74,9 @@ void TextBuffer::CopyProperties(const TextBuffer& OtherBuffer) noexcept
// - <none>
// Return Value:
// - Total number of rows in the buffer
til::CoordType TextBuffer::TotalRowCount() const noexcept
UINT TextBuffer::TotalRowCount() const noexcept
{
return gsl::narrow_cast<til::CoordType>(_storage.size());
return gsl::narrow<UINT>(_storage.size());
}
// Routine Description:
@@ -86,11 +86,13 @@ til::CoordType TextBuffer::TotalRowCount() const noexcept
// - Number of rows down from the first row of the buffer.
// Return Value:
// - const reference to the requested row. Asserts if out of bounds.
const ROW& TextBuffer::GetRowByOffset(const til::CoordType index) const noexcept
const ROW& TextBuffer::GetRowByOffset(const size_t index) const
{
const size_t totalRows = TotalRowCount();
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
return til::at(_storage, offsetIndex);
const auto offsetIndex = (_firstRow + index) % totalRows;
return _storage.at(offsetIndex);
}
// Routine Description:
@@ -100,11 +102,13 @@ const ROW& TextBuffer::GetRowByOffset(const til::CoordType index) const noexcept
// - Number of rows down from the first row of the buffer.
// Return Value:
// - reference to the requested row. Asserts if out of bounds.
ROW& TextBuffer::GetRowByOffset(const til::CoordType index) noexcept
ROW& TextBuffer::GetRowByOffset(const size_t index)
{
const size_t totalRows = TotalRowCount();
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
return til::at(_storage, offsetIndex);
const auto offsetIndex = (_firstRow + index) % totalRows;
return _storage.at(offsetIndex);
}
// Routine Description:
@@ -113,7 +117,7 @@ ROW& TextBuffer::GetRowByOffset(const til::CoordType index) noexcept
// - at - X,Y position in buffer for iterator start position
// Return Value:
// - Read-only iterator of text data only.
TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at) const
TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at) const
{
return TextBufferTextIterator(GetCellDataAt(at));
}
@@ -124,7 +128,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at) const
// - at - X,Y position in buffer for iterator start position
// Return Value:
// - Read-only iterator of cell data.
TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at) const
TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at) const
{
return TextBufferCellIterator(*this, at);
}
@@ -136,7 +140,7 @@ TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at) const
// - at - X,Y position in buffer for iterator start position
// Return Value:
// - Read-only iterator of text data only.
TextBufferTextIterator TextBuffer::GetTextLineDataAt(const til::point at) const
TextBufferTextIterator TextBuffer::GetTextLineDataAt(const COORD at) const
{
return TextBufferTextIterator(GetCellLineDataAt(at));
}
@@ -148,9 +152,9 @@ TextBufferTextIterator TextBuffer::GetTextLineDataAt(const til::point at) const
// - at - X,Y position in buffer for iterator start position
// Return Value:
// - Read-only iterator of cell data.
TextBufferCellIterator TextBuffer::GetCellLineDataAt(const til::point at) const
TextBufferCellIterator TextBuffer::GetCellLineDataAt(const COORD at) const
{
til::inclusive_rect limit;
SMALL_RECT limit;
limit.Top = at.Y;
limit.Bottom = at.Y;
limit.Left = 0;
@@ -167,7 +171,7 @@ TextBufferCellIterator TextBuffer::GetCellLineDataAt(const til::point at) const
// - limit - boundaries for the iterator to operate within
// Return Value:
// - Read-only iterator of text data only.
TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at, const Viewport limit) const
TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at, const Viewport limit) const
{
return TextBufferTextIterator(GetCellDataAt(at, limit));
}
@@ -180,7 +184,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at, const View
// - limit - boundaries for the iterator to operate within
// Return Value:
// - Read-only iterator of cell data.
TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at, const Viewport limit) const
TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at, const Viewport limit) const
{
return TextBufferCellIterator(*this, at, limit);
}
@@ -333,7 +337,7 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt)
// Return Value:
// - The final position of the iterator
OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
const til::point target,
const COORD target,
const std::optional<bool> wrap)
{
// Make mutable copy so we can walk.
@@ -370,9 +374,9 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
// Return Value:
// - The iterator, but advanced to where we stopped writing. Use to find input consumed length or cells written length.
OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
const til::point target,
const COORD target,
const std::optional<bool> wrap,
std::optional<til::CoordType> limitRight)
std::optional<size_t> limitRight)
{
// If we're not in bounds, exit early.
if (!GetSize().IsInBounds(target))
@@ -386,7 +390,7 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
// Take the cell distance written and notify that it needs to be repainted.
const auto written = newIt.GetCellDistance(givenIt);
const auto paint = Viewport::FromDimensions(target, { written, 1 });
const auto paint = Viewport::FromDimensions(target, { gsl::narrow<SHORT>(written), 1 });
TriggerRedraw(paint);
return newIt;
@@ -463,7 +467,7 @@ bool TextBuffer::InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttr
// - <none> - Always sets to wrap
//Return Value:
// - <none>
void TextBuffer::_SetWrapOnCurrentRow() noexcept
void TextBuffer::_SetWrapOnCurrentRow()
{
_AdjustWrapOnCurrentRow(true);
}
@@ -475,10 +479,10 @@ void TextBuffer::_SetWrapOnCurrentRow() noexcept
// - fSet - True if this row has a wrap. False otherwise.
//Return Value:
// - <none>
void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet) noexcept
void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet)
{
// The vertical position of the cursor represents the current row we're manipulating.
const auto uiCurrentRowOffset = GetCursor().GetPosition().Y;
const UINT uiCurrentRowOffset = GetCursor().GetPosition().Y;
// Set the wrap status as appropriate
GetRowByOffset(uiCurrentRowOffset).SetWrapForced(fSet);
@@ -497,7 +501,7 @@ bool TextBuffer::IncrementCursor()
// Cursor position is stored as logical array indices (starts at 0) for the window
// Buffer Size is specified as the "length" of the array. It would say 80 for valid values of 0-79.
// So subtract 1 from buffer size in each direction to find the index of the final column in the buffer
const auto iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
const short iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
// Move the cursor one position to the right
GetCursor().IncrementXPosition(1);
@@ -600,17 +604,17 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
// - The viewport
//Return value:
// - Coordinate position (relative to the text buffer)
til::point TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
{
const auto viewport = viewOptional.has_value() ? viewOptional.value() : GetSize();
til::point coordEndOfText;
COORD coordEndOfText = { 0 };
// Search the given viewport by starting at the bottom.
coordEndOfText.Y = viewport.BottomInclusive();
const auto& currRow = GetRowByOffset(coordEndOfText.Y);
// The X position of the end of the valid text is the Right draw boundary (which is one beyond the final valid character)
coordEndOfText.X = currRow.GetCharRow().MeasureRight() - 1;
coordEndOfText.X = gsl::narrow<short>(currRow.GetCharRow().MeasureRight()) - 1;
// If the X coordinate turns out to be -1, the row was empty, we need to search backwards for the real end of text.
const auto viewportTop = viewport.Top();
@@ -621,13 +625,13 @@ til::point TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::C
const auto& backupRow = GetRowByOffset(coordEndOfText.Y);
// We need to back up to the previous row if this line is empty, AND there are more rows
coordEndOfText.X = backupRow.GetCharRow().MeasureRight() - 1;
coordEndOfText.X = gsl::narrow<short>(backupRow.GetCharRow().MeasureRight()) - 1;
fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop);
}
// don't allow negative results
coordEndOfText.Y = std::max(coordEndOfText.Y, 0);
coordEndOfText.X = std::max(coordEndOfText.X, 0);
coordEndOfText.Y = std::max(coordEndOfText.Y, 0i16);
coordEndOfText.X = std::max(coordEndOfText.X, 0i16);
return coordEndOfText;
}
@@ -639,7 +643,7 @@ til::point TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::C
// Return Value:
// - Coordinate position in screen coordinates of the character just before the cursor.
// - NOTE: Will return 0,0 if already in the top left corner
til::point TextBuffer::_GetPreviousFromCursor() const noexcept
COORD TextBuffer::_GetPreviousFromCursor() const
{
auto coordPosition = GetCursor().GetPosition();
@@ -664,7 +668,7 @@ til::point TextBuffer::_GetPreviousFromCursor() const noexcept
return coordPosition;
}
const til::CoordType TextBuffer::GetFirstRowIndex() const noexcept
const SHORT TextBuffer::GetFirstRowIndex() const noexcept
{
return _firstRow;
}
@@ -676,15 +680,15 @@ const Viewport TextBuffer::GetSize() const noexcept
void TextBuffer::_UpdateSize()
{
_size = Viewport::FromDimensions({ _storage.at(0).size(), gsl::narrow<til::CoordType>(_storage.size()) });
_size = Viewport::FromDimensions({ 0, 0 }, { gsl::narrow<SHORT>(_storage.at(0).size()), gsl::narrow<SHORT>(_storage.size()) });
}
void TextBuffer::_SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept
void TextBuffer::_SetFirstRowIndex(const SHORT FirstRowIndex) noexcept
{
_firstRow = FirstRowIndex;
}
void TextBuffer::ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta)
void TextBuffer::ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta)
{
// If we don't have to move anything, leave early.
if (delta == 0)
@@ -821,9 +825,9 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
const auto fillChar = L' ';
auto fillAttrs = GetCurrentAttributes();
fillAttrs.SetStandardErase();
const auto fillOffset = GetLineWidth(rowIndex);
const auto fillLength = gsl::narrow<size_t>(GetSize().Width() - fillOffset);
const OutputCellIterator fillData{ fillChar, fillAttrs, fillLength };
const size_t fillOffset = GetLineWidth(rowIndex);
const auto fillLength = GetSize().Width() - fillOffset;
const auto fillData = OutputCellIterator{ fillChar, fillAttrs, fillLength };
row.WriteCells(fillData, fillOffset, false);
// We also need to make sure the cursor is clamped within the new width.
GetCursor().SetPosition(ClampPositionWithinLine(cursorPosition));
@@ -832,7 +836,7 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
}
}
void TextBuffer::ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept
void TextBuffer::ResetLineRenditionRange(const size_t startRow, const size_t endRow)
{
for (auto row = startRow; row < endRow; row++)
{
@@ -840,40 +844,40 @@ void TextBuffer::ResetLineRenditionRange(const til::CoordType startRow, const ti
}
}
LineRendition TextBuffer::GetLineRendition(const til::CoordType row) const noexcept
LineRendition TextBuffer::GetLineRendition(const size_t row) const
{
return GetRowByOffset(row).GetLineRendition();
}
bool TextBuffer::IsDoubleWidthLine(const til::CoordType row) const noexcept
bool TextBuffer::IsDoubleWidthLine(const size_t row) const
{
return GetLineRendition(row) != LineRendition::SingleWidth;
}
til::CoordType TextBuffer::GetLineWidth(const til::CoordType row) const noexcept
SHORT TextBuffer::GetLineWidth(const size_t row) const
{
// Use shift right to quickly divide the width by 2 for double width lines.
const auto scale = IsDoubleWidthLine(row) ? 1 : 0;
const SHORT scale = IsDoubleWidthLine(row) ? 1 : 0;
return GetSize().Width() >> scale;
}
til::point TextBuffer::ClampPositionWithinLine(const til::point position) const noexcept
COORD TextBuffer::ClampPositionWithinLine(const COORD position) const
{
const auto rightmostColumn = GetLineWidth(position.Y) - 1;
const SHORT rightmostColumn = GetLineWidth(position.Y) - 1;
return { std::min(position.X, rightmostColumn), position.Y };
}
til::point TextBuffer::ScreenToBufferPosition(const til::point position) const noexcept
COORD TextBuffer::ScreenToBufferPosition(const COORD position) const
{
// Use shift right to quickly divide the X pos by 2 for double width lines.
const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
return { position.X >> scale, position.Y };
}
til::point TextBuffer::BufferToScreenPosition(const til::point position) const noexcept
COORD TextBuffer::BufferToScreenPosition(const COORD position) const
{
// Use shift left to quickly multiply the X pos by 2 for double width lines.
const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
return { position.X << scale, position.Y };
}
@@ -896,7 +900,7 @@ void TextBuffer::Reset()
// - newSize - new size of screen.
// Return Value:
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const til::size newSize) noexcept
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const COORD newSize) noexcept
{
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
@@ -905,12 +909,12 @@ void TextBuffer::Reset()
const auto currentSize = GetSize().Dimensions();
const auto attributes = GetCurrentAttributes();
til::CoordType TopRow = 0; // new top row of the screen buffer
SHORT TopRow = 0; // new top row of the screen buffer
if (newSize.Y <= GetCursor().GetPosition().Y)
{
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
}
const auto TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
// rotate rows until the top row is at index 0
for (auto i = 0; i < TopRowIndex; i++)
@@ -930,7 +934,7 @@ void TextBuffer::Reset()
// add rows if we're growing
while (_storage.size() < static_cast<size_t>(newSize.Y))
{
_storage.emplace_back(gsl::narrow_cast<til::CoordType>(_storage.size()), newSize.X, attributes, this);
_storage.emplace_back(static_cast<short>(_storage.size()), newSize.X, attributes, this);
}
// Now that we've tampered with the row placement, refresh all the row IDs.
@@ -979,7 +983,7 @@ void TextBuffer::TriggerRedraw(const Viewport& viewport)
}
}
void TextBuffer::TriggerRedrawCursor(const til::point position)
void TextBuffer::TriggerRedrawCursor(const COORD position)
{
if (_isActiveBuffer)
{
@@ -1003,7 +1007,7 @@ void TextBuffer::TriggerScroll()
}
}
void TextBuffer::TriggerScroll(const til::point delta)
void TextBuffer::TriggerScroll(const COORD delta)
{
if (_isActiveBuffer)
{
@@ -1028,10 +1032,10 @@ void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
// any high unicode (UnicodeStorage) runs while we're already looping through the rows.
// Arguments:
// - newRowWidth - Optional new value for the row width.
void TextBuffer::_RefreshRowIDs(std::optional<til::CoordType> newRowWidth)
void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
{
std::unordered_map<til::CoordType, til::CoordType> rowMap;
til::CoordType i = 0;
std::unordered_map<SHORT, SHORT> rowMap;
SHORT i = 0;
for (auto& it : _storage)
{
// Build a map so we can update Unicode Storage
@@ -1061,7 +1065,7 @@ void TextBuffer::_RefreshRowIDs(std::optional<til::CoordType> newRowWidth)
// - <none>
// Return Value:
// - reference to the first row.
ROW& TextBuffer::_GetFirstRow() noexcept
ROW& TextBuffer::_GetFirstRow()
{
return GetRowByOffset(0);
}
@@ -1095,23 +1099,23 @@ ROW& TextBuffer::_GetPrevRowNoWrap(const ROW& Row)
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
// Return Value:
// - the delimiter class for the given char
DelimiterClass TextBuffer::_GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const
const DelimiterClass TextBuffer::_GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const
{
return GetRowByOffset(pos.Y).GetCharRow().DelimiterClassAt(pos.X, wordDelimiters);
}
// Method Description:
// - Get the til::point for the beginning of the word you are on
// - Get the COORD for the beginning of the word you are on
// Arguments:
// - target - a til::point on the word you are currently on
// - target - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// - accessibilityMode - when enabled, we continue expanding left until we are at the beginning of a readable word.
// Otherwise, expand left until a character of a new delimiter class is found
// (or a row boundary is encountered)
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
// Return Value:
// - The til::point for the first character on the "word" (inclusive)
til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
// - The COORD for the first character on the "word" (inclusive)
const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
{
// Consider a buffer with this text in it:
// " word other "
@@ -1126,7 +1130,7 @@ til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_
#pragma warning(suppress : 26496)
auto copy{ target };
const auto bufferSize{ GetSize() };
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
if (target == bufferSize.Origin())
{
// can't expand left
@@ -1136,12 +1140,12 @@ til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_
{
// GH#7664: Treat EndExclusive as EndInclusive so
// that it actually points to a space in the buffer
copy = bufferSize.BottomRightInclusive();
copy = { bufferSize.RightInclusive(), bufferSize.BottomInclusive() };
}
else if (bufferSize.CompareInBounds(target, limit, true) >= 0)
else if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
{
// if at/past the limit --> clamp to limit
copy = limitOptional.value_or(bufferSize.BottomRightInclusive());
copy = limitOptional->to_win32_coord();
}
if (accessibilityMode)
@@ -1155,13 +1159,13 @@ til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_
}
// Method Description:
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (accessibility definition) you are on
// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (accessibility definition) you are on
// Arguments:
// - target - a til::point on the word you are currently on
// - target - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// Return Value:
// - The til::point for the first character on the current/previous READABLE "word" (inclusive)
til::point TextBuffer::_GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const
// - The COORD for the first character on the current/previous READABLE "word" (inclusive)
const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const
{
auto result = target;
const auto bufferSize = GetSize();
@@ -1200,13 +1204,13 @@ til::point TextBuffer::_GetWordStartForAccessibility(const til::point target, co
}
// Method Description:
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (selection definition) you are on
// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (selection definition) you are on
// Arguments:
// - target - a til::point on the word you are currently on
// - target - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// Return Value:
// - The til::point for the first character on the current word or delimiter run (stopped by the left margin)
til::point TextBuffer::_GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const
// - The COORD for the first character on the current word or delimiter run (stopped by the left margin)
const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const
{
auto result = target;
const auto bufferSize = GetSize();
@@ -1229,17 +1233,17 @@ til::point TextBuffer::_GetWordStartForSelection(const til::point target, const
}
// Method Description:
// - Get the til::point for the beginning of the NEXT word
// - Get the COORD for the beginning of the NEXT word
// Arguments:
// - target - a til::point on the word you are currently on
// - target - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// - accessibilityMode - when enabled, we continue expanding right until we are at the beginning of the next READABLE word
// Otherwise, expand right until a character of a new delimiter class is found
// (or a row boundary is encountered)
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
// Return Value:
// - The til::point for the last character on the "word" (inclusive)
til::point TextBuffer::GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
// - The COORD for the last character on the "word" (inclusive)
const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
{
// Consider a buffer with this text in it:
// " word other "
@@ -1253,15 +1257,15 @@ til::point TextBuffer::GetWordEnd(const til::point target, const std::wstring_vi
// Already at/past the limit. Can't move forward.
const auto bufferSize{ GetSize() };
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
if (bufferSize.CompareInBounds(target, limit, true) >= 0)
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
{
return target;
}
if (accessibilityMode)
{
return _GetWordEndForAccessibility(target, wordDelimiters, limit);
return _GetWordEndForAccessibility(target, wordDelimiters, limit.to_win32_coord());
}
else
{
@@ -1270,14 +1274,14 @@ til::point TextBuffer::GetWordEnd(const til::point target, const std::wstring_vi
}
// Method Description:
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the next READABLE word
// - Helper method for GetWordEnd(). Get the COORD for the beginning of the next READABLE word
// Arguments:
// - target - a til::point on the word you are currently on
// - target - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// - limit - the last "valid" position in the text buffer (to improve performance)
// Return Value:
// - The til::point for the first character of the next readable "word". If no next word, return one past the end of the buffer
til::point TextBuffer::_GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const
// - The COORD for the first character of the next readable "word". If no next word, return one past the end of the buffer
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const
{
const auto bufferSize{ GetSize() };
auto result{ target };
@@ -1321,13 +1325,13 @@ til::point TextBuffer::_GetWordEndForAccessibility(const til::point target, cons
}
// Method Description:
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the NEXT word
// - Helper method for GetWordEnd(). Get the COORD for the beginning of the NEXT word
// Arguments:
// - target - a til::point on the word you are currently on
// - target - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// Return Value:
// - The til::point for the last character of the current word or delimiter run (stopped by right margin)
til::point TextBuffer::_GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const
// - The COORD for the last character of the current word or delimiter run (stopped by right margin)
const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const
{
const auto bufferSize = GetSize();
@@ -1376,7 +1380,7 @@ void TextBuffer::_PruneHyperlinks()
// we have found all hyperlink references in the first row and put them in refs,
// now we need to search the rest of the buffer (i.e. all the rows except the first)
// to see if those references are anywhere else
for (til::CoordType i = 1; i < total; ++i)
for (size_t i = 1; i != total; ++i)
{
const auto nextRowRefs = GetRowByOffset(i).GetAttrRow().GetHyperlinks();
for (auto id : nextRowRefs)
@@ -1404,22 +1408,22 @@ void TextBuffer::_PruneHyperlinks()
// Method Description:
// - Update pos to be the position of the first character of the next word. This is used for accessibility
// Arguments:
// - pos - a til::point on the word you are currently on
// - pos - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
// Return Value:
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
// - pos - The til::point for the first character on the "word" (inclusive)
bool TextBuffer::MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
// - pos - The COORD for the first character on the "word" (inclusive)
bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
{
// move to the beginning of the next word
// NOTE: _GetWordEnd...() returns the exclusive position of the "end of the word"
// This is also the inclusive start of the next word.
const auto bufferSize{ GetSize() };
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit) };
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit.to_win32_coord()) };
if (bufferSize.CompareInBounds(copy, limit, true) >= 0)
if (bufferSize.CompareInBounds(copy, limit.to_win32_coord(), true) >= 0)
{
return false;
}
@@ -1431,12 +1435,12 @@ bool TextBuffer::MoveToNextWord(til::point& pos, const std::wstring_view wordDel
// Method Description:
// - Update pos to be the position of the first character of the previous word. This is used for accessibility
// Arguments:
// - pos - a til::point on the word you are currently on
// - pos - a COORD on the word you are currently on
// - wordDelimiters - what characters are we considering for the separation of words
// Return Value:
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
// - pos - The til::point for the first character on the "word" (inclusive)
bool TextBuffer::MoveToPreviousWord(til::point& pos, std::wstring_view wordDelimiters) const
// - pos - The COORD for the first character on the "word" (inclusive)
bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters) const
{
// move to the beginning of the current word
auto copy{ GetWordStart(pos, wordDelimiters, true) };
@@ -1455,51 +1459,51 @@ bool TextBuffer::MoveToPreviousWord(til::point& pos, std::wstring_view wordDelim
// Method Description:
// - Update pos to be the beginning of the current glyph/character. This is used for accessibility
// Arguments:
// - pos - a til::point on the word you are currently on
// - pos - a COORD on the word you are currently on
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
// Return Value:
// - pos - The til::point for the first cell of the current glyph (inclusive)
til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
// - pos - The COORD for the first cell of the current glyph (inclusive)
const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
{
auto resultPos = pos;
auto resultPos = pos.to_win32_coord();
const auto bufferSize = GetSize();
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
// Clamp pos to limit
if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
{
resultPos = limit;
resultPos = limit.to_win32_coord();
}
// limit is exclusive, so we need to move back to be within valid bounds
if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
{
bufferSize.DecrementInBounds(resultPos, true);
}
return resultPos;
return til::point{ resultPos };
}
// Method Description:
// - Update pos to be the end of the current glyph/character.
// Arguments:
// - pos - a til::point on the word you are currently on
// - pos - a COORD on the word you are currently on
// - accessibilityMode - this is being used for accessibility; make the end exclusive.
// Return Value:
// - pos - The til::point for the last cell of the current glyph (exclusive)
til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
// - pos - The COORD for the last cell of the current glyph (exclusive)
const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
{
auto resultPos = pos;
auto resultPos = pos.to_win32_coord();
const auto bufferSize = GetSize();
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
// Clamp pos to limit
if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
{
resultPos = limit;
resultPos = limit.to_win32_coord();
}
if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
{
bufferSize.IncrementInBounds(resultPos, true);
}
@@ -1509,24 +1513,24 @@ til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode,
{
bufferSize.IncrementInBounds(resultPos, true);
}
return resultPos;
return til::point{ resultPos };
}
// Method Description:
// - Update pos to be the beginning of the next glyph/character. This is used for accessibility
// Arguments:
// - pos - a til::point on the word you are currently on
// - pos - a COORD on the word you are currently on
// - allowExclusiveEnd - allow result to be the exclusive limit (one past limit)
// - limit - boundaries for the iterator to operate within
// Return Value:
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
// - pos - The til::point for the first cell of the current glyph (inclusive)
// - pos - The COORD for the first cell of the current glyph (inclusive)
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::optional<til::point> limitOptional) const
{
const auto bufferSize = GetSize();
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
const auto distanceToLimit{ bufferSize.CompareInBounds(pos, limit, true) };
const auto distanceToLimit{ bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) };
if (distanceToLimit >= 0)
{
// Corner Case: we're on/past the limit
@@ -1543,7 +1547,7 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
}
// Try to move forward, but if we hit the buffer boundary, we fail to move.
auto iter{ GetCellDataAt(pos, bufferSize) };
auto iter{ GetCellDataAt(pos.to_win32_coord(), bufferSize) };
const bool success{ ++iter };
// Move again if we're on a wide glyph
@@ -1552,24 +1556,24 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
++iter;
}
pos = iter.Pos();
pos = til::point{ iter.Pos() };
return success;
}
// Method Description:
// - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
// Arguments:
// - pos - a til::point on the word you are currently on
// - pos - a COORD on the word you are currently on
// Return Value:
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
// - pos - The til::point for the first cell of the previous glyph (inclusive)
// - pos - The COORD for the first cell of the previous glyph (inclusive)
bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional) const
{
auto resultPos = pos;
auto resultPos = pos.to_win32_coord();
const auto bufferSize = GetSize();
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
if (bufferSize.CompareInBounds(pos, limit, true) > 0)
if (bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) > 0)
{
// we're past the end
// clamp us to the limit
@@ -1584,7 +1588,7 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
bufferSize.DecrementInBounds(resultPos, true);
}
pos = resultPos;
pos = til::point{ resultPos };
return success;
}
@@ -1602,9 +1606,9 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
// the buffer rather than the screen.
// Return Value:
// - the delimiter class for the given char
const std::vector<til::inclusive_rect> TextBuffer::GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const
const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const
{
std::vector<til::inclusive_rect> textRects;
std::vector<SMALL_RECT> textRects;
const auto bufferSize = GetSize();
@@ -1615,11 +1619,11 @@ const std::vector<til::inclusive_rect> TextBuffer::GetTextRects(til::point start
std::make_tuple(start, end) :
std::make_tuple(end, start);
const auto textRectSize = 1 + lowerCoord.Y - higherCoord.Y;
const auto textRectSize = base::ClampedNumeric<short>(1) + lowerCoord.Y - higherCoord.Y;
textRects.reserve(textRectSize);
for (auto row = higherCoord.Y; row <= lowerCoord.Y; row++)
{
til::inclusive_rect textRow;
SMALL_RECT textRow;
textRow.Top = row;
textRow.Bottom = row;
@@ -1657,12 +1661,12 @@ const std::vector<til::inclusive_rect> TextBuffer::GetTextRects(til::point start
// - selectionRow: the selection row to be expanded
// Return Value:
// - modifies selectionRow's Left and Right values to expand properly
void TextBuffer::_ExpandTextRow(til::inclusive_rect& textRow) const
void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
{
const auto bufferSize = GetSize();
// expand left side of rect
til::point targetPoint{ textRow.Left, textRow.Top };
COORD targetPoint{ textRow.Left, textRow.Top };
if (GetCellDataAt(targetPoint)->DbcsAttr().IsTrailing())
{
if (targetPoint.X == bufferSize.Left())
@@ -1704,7 +1708,7 @@ void TextBuffer::_ExpandTextRow(til::inclusive_rect& textRow) const
// - The text, background color, and foreground color data of the selected region of the text buffer.
const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
const bool trimTrailingWhitespace,
const std::vector<til::inclusive_rect>& selectionRects,
const std::vector<SMALL_RECT>& selectionRects,
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors,
const bool formatWrappedRows) const
{
@@ -1721,9 +1725,9 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
}
// for each row in the selection
for (size_t i = 0; i < rows; i++)
for (UINT i = 0; i < rows; i++)
{
const auto iRow = selectionRects.at(i).Top;
const UINT iRow = selectionRects.at(i).Top;
const auto highlight = Viewport::FromInclusive(selectionRects.at(i));
@@ -2239,22 +2243,22 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
const auto cOldCursorPos = oldCursor.GetPosition();
const auto cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
const auto cOldRowsTotal = cOldLastChar.Y + 1;
const short cOldRowsTotal = cOldLastChar.Y + 1;
til::point cNewCursorPos;
COORD cNewCursorPos = { 0 };
auto fFoundCursorPos = false;
auto foundOldMutable = false;
auto foundOldVisible = false;
auto hr = S_OK;
// Loop through all the rows of the old buffer and reprint them into the new buffer
til::CoordType iOldRow = 0;
short iOldRow = 0;
for (; iOldRow < cOldRowsTotal; iOldRow++)
{
// Fetch the row and its "right" which is the last printable character.
const auto& row = oldBuffer.GetRowByOffset(iOldRow);
const auto cOldColsTotal = oldBuffer.GetLineWidth(iOldRow);
const auto& charRow = row.GetCharRow();
auto iRight = charRow.MeasureRight();
auto iRight = gsl::narrow_cast<short>(charRow.MeasureRight());
// If we're starting a new row, try and preserve the line rendition
// from the row in the original buffer.
@@ -2292,7 +2296,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
// Loop through every character in the current row (up to
// the "right" boundary, which is one past the final valid
// character)
til::CoordType iOldCol = 0;
short iOldCol = 0;
const auto copyRight = iRight;
for (; iOldCol < copyRight; iOldCol++)
{
@@ -2435,7 +2439,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
const auto coordNewCursor = newCursor.GetPosition();
if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
{
if (newBuffer.GetRowByOffset(coordNewCursor.Y - 1).WasWrapForced())
if (newBuffer.GetRowByOffset(gsl::narrow_cast<size_t>(coordNewCursor.Y) - 1).WasWrapForced())
{
hr = newBuffer.NewlineCursor() ? hr : E_OUTOFMEMORY;
}
@@ -2689,17 +2693,17 @@ void TextBuffer::CopyPatterns(const TextBuffer& OtherBuffer)
// - The lastRow to search
// Return value:
// - An interval tree containing the patterns found
PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const
PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) const
{
PointTree::interval_vector intervals;
std::wstring concatAll;
const auto rowSize = GetRowByOffset(0).size();
concatAll.reserve(gsl::narrow_cast<size_t>(rowSize) * gsl::narrow_cast<size_t>(lastRow - firstRow + 1));
concatAll.reserve(rowSize * (lastRow - firstRow + 1));
// to deal with text that spans multiple lines, we will first concatenate
// all the text into one string and find the patterns in that string
for (til::CoordType i = firstRow; i <= lastRow; ++i)
for (auto i = firstRow; i <= lastRow; ++i)
{
auto& row = GetRowByOffset(i);
concatAll += row.GetText();
@@ -2714,21 +2718,21 @@ PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::Coor
auto words_begin = std::wsregex_iterator(concatAll.begin(), concatAll.end(), regexObj);
auto words_end = std::wsregex_iterator();
til::CoordType lenUpToThis = 0;
size_t lenUpToThis = 0;
for (auto i = words_begin; i != words_end; ++i)
{
// record the locations -
// when we find a match, the prefix is text that is between this
// match and the previous match, so we use the size of the prefix
// along with the size of the match to determine the locations
til::CoordType prefixSize = 0;
size_t prefixSize = 0;
for (const auto parsedGlyph : Utf16Parser::Parse(i->prefix().str()))
{
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
prefixSize += IsGlyphFullWidth(glyph) ? 2 : 1;
}
const auto start = lenUpToThis + prefixSize;
til::CoordType matchSize = 0;
size_t matchSize = 0;
for (const auto parsedGlyph : Utf16Parser::Parse(i->str()))
{
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
@@ -2737,8 +2741,8 @@ PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::Coor
const auto end = start + matchSize;
lenUpToThis = end;
const til::point startCoord{ start % rowSize, start / rowSize };
const til::point endCoord{ end % rowSize, end / rowSize };
const til::point startCoord{ gsl::narrow<SHORT>(start % rowSize), gsl::narrow<SHORT>(start / rowSize) };
const til::point endCoord{ gsl::narrow<SHORT>(end % rowSize), gsl::narrow<SHORT>(end / rowSize) };
// store the intervals
// NOTE: these intervals are relative to the VIEWPORT not the buffer

View File

@@ -68,7 +68,7 @@ namespace Microsoft::Console::Render
class TextBuffer final
{
public:
TextBuffer(const til::size screenBufferSize,
TextBuffer(const COORD screenBufferSize,
const TextAttribute defaultAttributes,
const UINT cursorSize,
const bool isActiveBuffer,
@@ -79,27 +79,27 @@ public:
void CopyProperties(const TextBuffer& OtherBuffer) noexcept;
// row manipulation
const ROW& GetRowByOffset(const til::CoordType index) const noexcept;
ROW& GetRowByOffset(const til::CoordType index) noexcept;
const ROW& GetRowByOffset(const size_t index) const;
ROW& GetRowByOffset(const size_t index);
TextBufferCellIterator GetCellDataAt(const til::point at) const;
TextBufferCellIterator GetCellLineDataAt(const til::point at) const;
TextBufferCellIterator GetCellDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
TextBufferTextIterator GetTextDataAt(const til::point at) const;
TextBufferTextIterator GetTextLineDataAt(const til::point at) const;
TextBufferTextIterator GetTextDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
TextBufferCellIterator GetCellDataAt(const COORD at) const;
TextBufferCellIterator GetCellLineDataAt(const COORD at) const;
TextBufferCellIterator GetCellDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
TextBufferTextIterator GetTextDataAt(const COORD at) const;
TextBufferTextIterator GetTextLineDataAt(const COORD at) const;
TextBufferTextIterator GetTextDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
// Text insertion functions
OutputCellIterator Write(const OutputCellIterator givenIt);
OutputCellIterator Write(const OutputCellIterator givenIt,
const til::point target,
const COORD target,
const std::optional<bool> wrap = true);
OutputCellIterator WriteLine(const OutputCellIterator givenIt,
const til::point target,
const COORD target,
const std::optional<bool> setWrap = std::nullopt,
const std::optional<til::CoordType> limitRight = std::nullopt);
const std::optional<size_t> limitRight = std::nullopt);
bool InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
bool InsertCharacter(const std::wstring_view chars, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
@@ -109,36 +109,36 @@ public:
// Scroll needs access to this to quickly rotate around the buffer.
bool IncrementCircularBuffer(const bool inVtMode = false);
til::point GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
COORD GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
Cursor& GetCursor() noexcept;
const Cursor& GetCursor() const noexcept;
const til::CoordType GetFirstRowIndex() const noexcept;
const SHORT GetFirstRowIndex() const noexcept;
const Microsoft::Console::Types::Viewport GetSize() const noexcept;
void ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta);
void ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta);
til::CoordType TotalRowCount() const noexcept;
UINT TotalRowCount() const noexcept;
[[nodiscard]] TextAttribute GetCurrentAttributes() const noexcept;
void SetCurrentAttributes(const TextAttribute& currentAttributes) noexcept;
void SetCurrentLineRendition(const LineRendition lineRendition);
void ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept;
LineRendition GetLineRendition(const til::CoordType row) const noexcept;
bool IsDoubleWidthLine(const til::CoordType row) const noexcept;
void ResetLineRenditionRange(const size_t startRow, const size_t endRow);
LineRendition GetLineRendition(const size_t row) const;
bool IsDoubleWidthLine(const size_t row) const;
til::CoordType GetLineWidth(const til::CoordType row) const noexcept;
til::point ClampPositionWithinLine(const til::point position) const noexcept;
til::point ScreenToBufferPosition(const til::point position) const noexcept;
til::point BufferToScreenPosition(const til::point position) const noexcept;
SHORT GetLineWidth(const size_t row) const;
COORD ClampPositionWithinLine(const COORD position) const;
COORD ScreenToBufferPosition(const COORD position) const;
COORD BufferToScreenPosition(const COORD position) const;
void Reset();
[[nodiscard]] HRESULT ResizeTraditional(const til::size newSize) noexcept;
[[nodiscard]] HRESULT ResizeTraditional(const COORD newSize) noexcept;
const UnicodeStorage& GetUnicodeStorage() const noexcept;
UnicodeStorage& GetUnicodeStorage() noexcept;
@@ -149,23 +149,23 @@ public:
Microsoft::Console::Render::Renderer& GetRenderer() noexcept;
void TriggerRedraw(const Microsoft::Console::Types::Viewport& viewport);
void TriggerRedrawCursor(const til::point position);
void TriggerRedrawCursor(const COORD position);
void TriggerRedrawAll();
void TriggerScroll();
void TriggerScroll(const til::point delta);
void TriggerScroll(const COORD delta);
void TriggerNewTextNotification(const std::wstring_view newText);
til::point GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
til::point GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
bool MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
bool MoveToPreviousWord(til::point& pos, const std::wstring_view wordDelimiters) const;
const COORD GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
const COORD GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
bool MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
bool MoveToPreviousWord(COORD& pos, const std::wstring_view wordDelimiters) const;
til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
const til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
const til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false, std::optional<til::point> limitOptional = std::nullopt) const;
bool MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional = std::nullopt) const;
const std::vector<til::inclusive_rect> GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const;
const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const;
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
@@ -184,7 +184,7 @@ public:
const TextAndColor GetText(const bool includeCRLF,
const bool trimTrailingWhitespace,
const std::vector<til::inclusive_rect>& textRects,
const std::vector<SMALL_RECT>& textRects,
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors = nullptr,
const bool formatWrappedRows = false) const;
@@ -200,8 +200,8 @@ public:
struct PositionInformation
{
til::CoordType mutableViewportTop{ 0 };
til::CoordType visibleViewportTop{ 0 };
short mutableViewportTop{ 0 };
short visibleViewportTop{ 0 };
};
static HRESULT Reflow(TextBuffer& oldBuffer,
@@ -212,7 +212,7 @@ public:
const size_t AddPatternRecognizer(const std::wstring_view regexString);
void ClearPatternRecognizers() noexcept;
void CopyPatterns(const TextBuffer& OtherBuffer);
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const;
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const size_t firstRow, const size_t lastRow) const;
private:
void _UpdateSize();
@@ -220,7 +220,7 @@ private:
std::vector<ROW> _storage;
Cursor _cursor;
til::CoordType _firstRow; // indexes top row (not necessarily 0)
SHORT _firstRow; // indexes top row (not necessarily 0)
TextAttribute _currentAttributes;
@@ -234,29 +234,29 @@ private:
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
uint16_t _currentHyperlinkId;
void _RefreshRowIDs(std::optional<til::CoordType> newRowWidth);
void _RefreshRowIDs(std::optional<SHORT> newRowWidth);
void _SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept;
void _SetFirstRowIndex(const SHORT FirstRowIndex) noexcept;
til::point _GetPreviousFromCursor() const noexcept;
COORD _GetPreviousFromCursor() const;
void _SetWrapOnCurrentRow() noexcept;
void _AdjustWrapOnCurrentRow(const bool fSet) noexcept;
void _SetWrapOnCurrentRow();
void _AdjustWrapOnCurrentRow(const bool fSet);
// Assist with maintaining proper buffer state for Double Byte character sequences
bool _PrepareForDoubleByteSequence(const DbcsAttribute dbcsAttribute);
bool _AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribute);
ROW& _GetFirstRow() noexcept;
ROW& _GetFirstRow();
ROW& _GetPrevRowNoWrap(const ROW& row);
void _ExpandTextRow(til::inclusive_rect& selectionRow) const;
void _ExpandTextRow(SMALL_RECT& selectionRow) const;
DelimiterClass _GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const;
til::point _GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const;
til::point _GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
til::point _GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const;
til::point _GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const;
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const;
const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
void _PruneHyperlinks();

View File

@@ -19,7 +19,7 @@ using namespace Microsoft::Console::Types;
// Arguments:
// - buffer - Text buffer to seek through
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos) :
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos) :
TextBufferCellIterator(buffer, pos, buffer.GetSize())
{
}
@@ -30,7 +30,7 @@ TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::po
// - buffer - Pointer to screen buffer to seek through
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
// - limits - Viewport limits to restrict the iterator within the buffer bounds (smaller than the buffer itself)
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Viewport limits) :
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Viewport limits) :
_buffer(buffer),
_pos(pos),
_pRow(s_GetRow(buffer, pos)),
@@ -126,7 +126,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator+=(const ptrdiff_t& move
const auto oldX = _pos.X;
const auto oldY = _pos.Y;
// Under MSVC writing the individual members of a til::point generates worse assembly
// Under MSVC writing the individual members of a COORD generates worse assembly
// compared to having them be local variables. This causes a performance impact.
auto newX = oldX;
auto newY = oldY;
@@ -289,7 +289,7 @@ ptrdiff_t TextBufferCellIterator::operator-(const TextBufferCellIterator& it)
// - Sets the coordinate position that this iterator will inspect within the text buffer on dereference.
// Arguments:
// - newPos - The new coordinate position.
void TextBufferCellIterator::_SetPos(const til::point newPos)
void TextBufferCellIterator::_SetPos(const COORD newPos)
{
if (newPos.Y != _pos.Y)
{
@@ -317,7 +317,7 @@ void TextBufferCellIterator::_SetPos(const til::point newPos)
// - pos - Position inside screen buffer bounds to retrieve row
// Return Value:
// - Pointer to the underlying CharRow structure
const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept
const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const COORD pos)
{
return &buffer.GetRowByOffset(pos.Y);
}
@@ -354,7 +354,7 @@ const OutputCellView* TextBufferCellIterator::operator->() const noexcept
return &_view;
}
til::point TextBufferCellIterator::Pos() const noexcept
COORD TextBufferCellIterator::Pos() const noexcept
{
return _pos;
}

View File

@@ -25,8 +25,8 @@ class TextBuffer;
class TextBufferCellIterator
{
public:
TextBufferCellIterator(const TextBuffer& buffer, til::point pos);
TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Microsoft::Console::Types::Viewport limits);
TextBufferCellIterator(const TextBuffer& buffer, COORD pos);
TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Microsoft::Console::Types::Viewport limits);
operator bool() const noexcept;
@@ -47,12 +47,12 @@ public:
const OutputCellView& operator*() const noexcept;
const OutputCellView* operator->() const noexcept;
til::point Pos() const noexcept;
COORD Pos() const noexcept;
protected:
void _SetPos(const til::point newPos);
void _SetPos(const COORD newPos);
void _GenerateView();
static const ROW* s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept;
static const ROW* s_GetRow(const TextBuffer& buffer, const COORD pos);
OutputCellView _view;
@@ -61,7 +61,7 @@ protected:
const TextBuffer& _buffer;
const Microsoft::Console::Types::Viewport _bounds;
bool _exceeded;
til::point _pos;
COORD _pos;
#if UNIT_TESTING
friend class TextBufferIteratorTests;

View File

@@ -36,9 +36,9 @@ namespace
struct TestBuffer
{
til::size size;
COORD size;
std::vector<TestRow> rows;
til::point cursor;
COORD cursor;
};
struct TestCase
@@ -737,7 +737,7 @@ class ReflowTests
{
auto buffer = std::make_unique<TextBuffer>(testBuffer.size, TextAttribute{ 0x7 }, 0, false, renderer);
til::CoordType i{};
size_t i{};
for (const auto& testRow : testBuffer.rows)
{
auto& row{ buffer->GetRowByOffset(i) };
@@ -745,7 +745,7 @@ class ReflowTests
auto& charRow{ row.GetCharRow() };
row.SetWrapForced(testRow.wrap);
til::CoordType j{};
size_t j{};
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
{
// Yes, we're about to manually create a buffer. It is unpleasant.
@@ -771,7 +771,7 @@ class ReflowTests
return buffer;
}
static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const til::size newSize)
static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const COORD newSize)
{
auto buffer = std::make_unique<TextBuffer>(newSize, TextAttribute{ 0x7 }, 0, false, renderer);
TextBuffer::Reflow(originalBuffer, *buffer, std::nullopt, std::nullopt);
@@ -783,7 +783,7 @@ class ReflowTests
VERIFY_ARE_EQUAL(testBuffer.cursor, buffer.GetCursor().GetPosition());
VERIFY_ARE_EQUAL(testBuffer.size, buffer.GetSize().Dimensions());
til::CoordType i{};
size_t i{};
for (const auto& testRow : testBuffer.rows)
{
NoThrowString indexString;
@@ -794,7 +794,7 @@ class ReflowTests
indexString.Format(L"[Row %d]", i);
VERIFY_ARE_EQUAL(testRow.wrap, row.WasWrapForced(), indexString);
til::CoordType j{};
size_t j{};
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
{
indexString.Format(L"[Cell %d, %d; Text line index %d]", it - charRow.begin(), i, j);

View File

@@ -18,7 +18,7 @@ class UnicodeStorageTests
TEST_METHOD(CanOverwriteEmoji)
{
UnicodeStorage storage;
const til::point coord{ 1, 3 };
const COORD coord{ 1, 3 };
const std::vector<wchar_t> newMoon{ 0xD83C, 0xDF11 };
const std::vector<wchar_t> fullMoon{ 0xD83C, 0xDF15 };

View File

@@ -37,6 +37,7 @@ Abstract:
// private dependencies
#include "../host/conddkrefs.h"
#include "../inc/operators.hpp"
#include "../inc/unicode.hpp"
#pragma warning(pop)

View File

@@ -1,7 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<PropertyGroup Label="NuGet Dependencies">
<TerminalMUX>true</TerminalMUX>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\wap-common.build.pre.props" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
<PropertyGroup Label="Configuration">
<!--
These two properties are very important!
@@ -135,6 +140,10 @@
<!-- 16.3.0 - remove non-resources.pri PRI files since we just forced them back in. -->
<AppxPackagePayload Remove="@(AppxPackagePayload)" Condition="'%(Extension)' == '.pri' and '%(Filename)' != 'resources'" />
<AppxUploadPackagePayload Remove="@(AppxUploadPackagePayload)" Condition="'%(Extension)' == '.pri' and '%(Filename)' != 'resources'" />
<!-- Remove all of the xaml files, because we are using embedded xbf payloads (saves about 500kb on disk!) -->
<AppxPackagePayload Remove="@(AppxPackagePayload)" Condition="'%(Extension)' == '.xaml'" />
<AppxUploadPackagePayload Remove="@(AppxUploadPackagePayload)" Condition="'%(Extension)' == '.xaml'" />
</ItemGroup>
</Target>
@@ -160,13 +169,7 @@
</Target>
<!-- This is required to get the package dependency in the AppXManifest. -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\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.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -100,7 +100,6 @@
<com:ProxyStub Id="DEC4804D-56D1-4F73-9FBE-6828E7C85C56" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
</com:ComInterface>
</com:Extension>
<com:Extension Category="windows.comServer">

View File

@@ -189,7 +189,6 @@
<com:ProxyStub Id="1833E661-CC81-4DD0-87C6-C2F74BD39EFA" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
</com:ComInterface>
</com:Extension>
<com:Extension Category="windows.comServer">

View File

@@ -189,7 +189,6 @@
<com:ProxyStub Id="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
</com:ComInterface>
</com:Extension>
<com:Extension Category="windows.comServer">

View File

@@ -230,7 +230,7 @@ HRESULT HwndTerminal::Initialize()
RECT windowRect;
GetWindowRect(_hwnd.get(), &windowRect);
const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
const COORD windowSize{ gsl::narrow<short>(windowRect.right - windowRect.left), gsl::narrow<short>(windowRect.bottom - windowRect.top) };
// Fist set up the dx engine with the window size in pixels.
// Then, using the font, get the number of characters that can fit.
@@ -239,7 +239,7 @@ HRESULT HwndTerminal::Initialize()
_renderEngine = std::move(dxEngine);
_terminal->Create({ 80, 25 }, 1000, *_renderer);
_terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
_terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
localPointerToThread->EnablePainting();
@@ -343,7 +343,7 @@ IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() noexcept
return _uiaProvider.Get();
}
HRESULT HwndTerminal::Refresh(const til::size windowSize, _Out_ til::size* dimensions)
HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
{
RETURN_HR_IF_NULL(E_INVALIDARG, dimensions);
@@ -357,7 +357,8 @@ HRESULT HwndTerminal::Refresh(const til::size windowSize, _Out_ til::size* dimen
_renderer->TriggerRedrawAll();
// Convert our new dimensions to characters
const auto viewInPixels = Viewport::FromDimensions(windowSize);
const auto viewInPixels = Viewport::FromDimensions({ 0, 0 },
{ gsl::narrow<short>(windowSize.cx), gsl::narrow<short>(windowSize.cy) });
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
// If this function succeeds with S_FALSE, then the terminal didn't
@@ -434,7 +435,7 @@ void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data)
/// <param name="height">New height of the terminal in pixels</param>
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
/// <returns>HRESULT of the attempted resize.</returns>
HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
{
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
@@ -447,7 +448,7 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType
static_cast<int>(height),
0));
const til::size windowSize{ width, height };
const SIZE windowSize{ width, height };
return publicTerminal->Refresh(windowSize, dimensions);
}
@@ -458,19 +459,19 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType
/// <param name="dimensionsInCharacters">New terminal size in row and column count.</param>
/// <param name="dimensionsInPixels">Out parameter with the new size of the renderer.</param>
/// <returns>HRESULT of the attempted resize.</returns>
HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensionsInCharacters, _Out_ til::size* dimensionsInPixels)
HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensionsInCharacters, _Out_ SIZE* dimensionsInPixels)
{
RETURN_HR_IF_NULL(E_INVALIDARG, dimensionsInPixels);
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto viewInCharacters = Viewport::FromDimensions(dimensionsInCharacters);
const auto viewInCharacters = Viewport::FromDimensions({ 0, 0 }, { (dimensionsInCharacters.X), (dimensionsInCharacters.Y) });
const auto viewInPixels = publicTerminal->_renderEngine->GetViewportInPixels(viewInCharacters);
dimensionsInPixels->cx = viewInPixels.Width();
dimensionsInPixels->cy = viewInPixels.Height();
til::size unused;
COORD unused{ 0, 0 };
return TerminalTriggerResize(terminal, viewInPixels.Width(), viewInPixels.Height(), &unused);
}
@@ -483,7 +484,7 @@ HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ ti
/// <param name="height">Height of the terminal area to calculate.</param>
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
/// <returns>HRESULT of the calculation.</returns>
HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
{
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
@@ -547,11 +548,11 @@ try
if (multiClickMapper == 3)
{
_terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Line);
_terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Line);
}
else if (multiClickMapper == 2)
{
_terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Word);
_terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Word);
}
else
{
@@ -592,13 +593,13 @@ try
if (distanceSquared >= maxDistanceSquared)
{
_terminal->SetSelectionAnchor(touchdownPoint / fontSize);
_terminal->SetSelectionAnchor((touchdownPoint / fontSize).to_win32_coord());
// stop tracking the touchdown point
_singleClickTouchdownPos = std::nullopt;
}
}
this->_terminal->SetSelectionEnd(cursorPosition / fontSize);
this->_terminal->SetSelectionEnd((cursorPosition / fontSize).to_win32_coord());
this->_renderer->TriggerSelection();
return S_OK;
@@ -700,7 +701,9 @@ try
wheelDelta = HIWORD(wParam);
// If it's a *WHEEL event, it's in screen coordinates, not window (?!)
ScreenToClient(_hwnd.get(), cursorPosition.as_win32_point());
auto coordsToTransform = cursorPosition.to_win32_point();
ScreenToClient(_hwnd.get(), &coordsToTransform);
cursorPosition = til::point{ coordsToTransform };
}
const TerminalInput::MouseButtonState state{
@@ -709,7 +712,7 @@ try
WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)
};
return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta, state);
return _terminal->SendMouseEvent((cursorPosition / fontSize).to_win32_coord(), uMsg, getControlKeyState(), wheelDelta, state);
}
catch (...)
{
@@ -777,7 +780,7 @@ void _stdcall DestroyTerminal(void* terminal)
}
// Updates the terminal font type, size, color, as well as the background/foreground colors to a specified theme.
void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi)
void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi)
{
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
{
@@ -807,8 +810,8 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
RECT windowRect;
GetWindowRect(publicTerminal->_hwnd.get(), &windowRect);
til::size dimensions;
const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
COORD dimensions = {};
const SIZE windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
publicTerminal->Refresh(windowSize, &dimensions);
}
@@ -981,21 +984,21 @@ void HwndTerminal::_StringPaste(const wchar_t* const pData) noexcept
CATCH_LOG();
}
til::size HwndTerminal::GetFontSize() const noexcept
COORD HwndTerminal::GetFontSize() const noexcept
{
return _actualFont.GetSize();
}
til::rect HwndTerminal::GetBounds() const noexcept
RECT HwndTerminal::GetBounds() const noexcept
{
til::rect windowRect;
GetWindowRect(_hwnd.get(), windowRect.as_win32_rect());
RECT windowRect;
GetWindowRect(_hwnd.get(), &windowRect);
return windowRect;
}
til::rect HwndTerminal::GetPadding() const noexcept
RECT HwndTerminal::GetPadding() const noexcept
{
return {};
return { 0 };
}
double HwndTerminal::GetScaleFactor() const noexcept
@@ -1003,7 +1006,7 @@ double HwndTerminal::GetScaleFactor() const noexcept
return static_cast<double>(_currentDpi) / static_cast<double>(USER_DEFAULT_SCREEN_DPI);
}
void HwndTerminal::ChangeViewport(const til::inclusive_rect& NewWindow)
void HwndTerminal::ChangeViewport(const SMALL_RECT NewWindow)
{
_terminal->UserScrollViewport(NewWindow.Top);
}

View File

@@ -27,16 +27,16 @@ extern "C" {
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
__declspec(dllexport) void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data);
__declspec(dllexport) void _stdcall TerminalRegisterScrollCallback(void* terminal, void __stdcall callback(int, int, int));
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
__declspec(dllexport) const wchar_t* _stdcall TerminalGetSelection(void* terminal);
__declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal);
__declspec(dllexport) void _stdcall DestroyTerminal(void* terminal);
__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
__declspec(dllexport) void _stdcall TerminalRegisterWriteCallback(void* terminal, const void __stdcall callback(wchar_t*));
__declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
__declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD flags, WORD scanCode);
@@ -60,7 +60,7 @@ public:
HRESULT Initialize();
void Teardown() noexcept;
void SendOutput(std::wstring_view data);
HRESULT Refresh(const til::size windowSize, _Out_ til::size* dimensions);
HRESULT Refresh(const SIZE windowSize, _Out_ COORD* dimensions);
void RegisterScrollCallback(std::function<void(int, int, int)> callback);
void RegisterWriteCallback(const void _stdcall callback(wchar_t*));
::Microsoft::Console::Types::IUiaData* GetUiaData() const noexcept;
@@ -91,9 +91,9 @@ private:
std::optional<til::point> _singleClickTouchdownPos;
friend HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
friend void _stdcall TerminalClearSelection(void* terminal);
@@ -101,7 +101,7 @@ private:
friend bool _stdcall TerminalIsSelectionActive(void* terminal);
friend void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode, WORD flags);
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
friend void _stdcall TerminalBlinkCursor(void* terminal);
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
friend void _stdcall TerminalSetFocus(void* terminal);
@@ -128,10 +128,10 @@ private:
void _SendCharEvent(wchar_t ch, WORD scanCode, WORD flags) noexcept;
// Inherited via IControlAccessibilityInfo
til::size GetFontSize() const noexcept override;
til::rect GetBounds() const noexcept override;
COORD GetFontSize() const noexcept override;
RECT GetBounds() const noexcept override;
double GetScaleFactor() const noexcept override;
void ChangeViewport(const til::inclusive_rect& NewWindow) override;
void ChangeViewport(const SMALL_RECT NewWindow) override;
HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept override;
til::rect GetPadding() const noexcept override;
RECT GetPadding() const noexcept override;
};

View File

@@ -97,7 +97,7 @@ HRESULT OpenTerminalHere::GetTitle(IShellItemArray* /*psiItemArray*/,
return SHStrDup(resource.data(), ppszName);
}
HRESULT OpenTerminalHere::GetState(IShellItemArray* psiItemArray,
HRESULT OpenTerminalHere::GetState(IShellItemArray* /*psiItemArray*/,
BOOL /*fOkToBeSlow*/,
EXPCMDSTATE* pCmdState)
{
@@ -106,25 +106,10 @@ HRESULT OpenTerminalHere::GetState(IShellItemArray* psiItemArray,
// E_PENDING and this object will be called back on a background thread with
// fOkToBeSlow == TRUE
// We however don't need to bother with any of that.
// If no item was selected when the context menu was opened and Explorer
// is not at a valid path (e.g. This PC or Quick Access), we should hide
// the verb from the context menu.
if (psiItemArray == nullptr)
{
const auto path = this->_GetPathFromExplorer();
*pCmdState = path.empty() ? ECS_HIDDEN : ECS_ENABLED;
}
else
{
winrt::com_ptr<IShellItem> psi;
psiItemArray->GetItemAt(0, psi.put());
SFGAOF attributes;
const bool isFileSystemItem = (psi->GetAttributes(SFGAO_FILESYSTEM, &attributes) == S_OK);
*pCmdState = isFileSystemItem ? ECS_ENABLED : ECS_HIDDEN;
}
// We however don't need to bother with any of that, so we'll just return
// ECS_ENABLED.
*pCmdState = ECS_ENABLED;
return S_OK;
}

View File

@@ -278,55 +278,6 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}
void TerminalPage::_HandleScrollToMark(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<ScrollToMarkArgs>())
{
_ApplyToActiveControls([&realArgs](auto& control) {
control.ScrollToMark(realArgs.Direction());
});
}
args.Handled(true);
}
void TerminalPage::_HandleAddMark(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<AddMarkArgs>())
{
_ApplyToActiveControls([realArgs](auto& control) {
Control::ScrollMark mark;
if (realArgs.Color())
{
mark.Color.Color = realArgs.Color().Value();
mark.Color.HasValue = true;
}
else
{
mark.Color.HasValue = false;
}
control.AddMark(mark);
});
}
args.Handled(true);
}
void TerminalPage::_HandleClearMark(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_ApplyToActiveControls([](auto& control) {
control.ClearMark();
});
args.Handled(true);
}
void TerminalPage::_HandleClearAllMarks(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_ApplyToActiveControls([](auto& control) {
control.ClearAllMarks();
});
args.Handled(true);
}
void TerminalPage::_HandleFindMatch(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
@@ -1092,24 +1043,4 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}
}
void TerminalPage::_HandleMarkMode(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& control{ _GetActiveControl() })
{
control.ToggleMarkMode();
args.Handled(true);
}
}
void TerminalPage::_HandleToggleBlockSelection(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& control{ _GetActiveControl() })
{
const auto handled = control.ToggleBlockSelection();
args.Handled(handled);
}
}
}

View File

@@ -292,7 +292,7 @@ namespace winrt::TerminalApp::implementation
_root->Maximized(true);
}
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode))
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode) && !IsQuakeWindow())
{
_root->SetFullscreen(true);
}

View File

@@ -111,7 +111,15 @@ namespace winrt::Microsoft::TerminalApp::implementation
void DebugTapConnection::_OutputHandler(const hstring str)
{
_TerminalOutputHandlers(til::visualize_control_codes(str));
auto output = til::visualize_control_codes(str);
// To make the output easier to read, we introduce a line break whenever
// an LF control is encountered. But at this point, the LF would have
// been converted to U+240A (␊), so that's what we need to search for.
for (size_t lfPos = 0; (lfPos = output.find(L'\u240A', lfPos)) != std::wstring::npos;)
{
output.insert(++lfPos, L"\r\n");
}
_TerminalOutputHandlers(output);
}
// Called by the DebugInputTapConnection to print user input

View File

@@ -119,6 +119,7 @@
</resheader>
<data name="AppName" xml:space="preserve">
<value>Terminal</value>
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppNameDev" xml:space="preserve">
<value>Terminal Dev</value>
@@ -126,9 +127,11 @@
</data>
<data name="AppNamePre" xml:space="preserve">
<value>Terminal Preview</value>
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppStoreName" xml:space="preserve">
<value>Windows Terminal</value>
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppStoreNameDev" xml:space="preserve">
<value>Windows Terminal Dev</value>
@@ -136,9 +139,11 @@
</data>
<data name="AppStoreNamePre" xml:space="preserve">
<value>Windows Terminal Preview</value>
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppShortName" xml:space="preserve">
<value>Terminal</value>
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppShortNameDev" xml:space="preserve">
<value>Terminal Dev</value>
@@ -146,6 +151,7 @@
</data>
<data name="AppShortNamePre" xml:space="preserve">
<value>Terminal Preview</value>
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>The New Windows Terminal</value>

View File

@@ -60,7 +60,8 @@
FontSize="12">
<ToolTipService.ToolTip>
<ToolTip Placement="Mouse">
<TextBlock IsTextSelectionEnabled="False">
<TextBlock IsTextSelectionEnabled="False"
TextWrapping="Wrap">
<Run x:Uid="NewTabRun" /> <LineBreak />
<Run x:Uid="NewPaneRun"
FontStyle="Italic" /> <LineBreak />

View File

@@ -20,6 +20,7 @@
<PropertyGroup Label="NuGet Dependencies">
<TerminalCppWinrt>true</TerminalCppWinrt>
<TerminalXamlApplicationToolkit>true</TerminalXamlApplicationToolkit>
<TerminalMUX>true</TerminalMUX>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
@@ -407,13 +408,6 @@
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\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.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<!--
By default, the PRI file will contain resource paths beginning with the
project name. Since we enabled XBF embedding, this *also* includes App.xbf.

View File

@@ -1107,8 +1107,8 @@ namespace winrt::TerminalApp::implementation
L".",
L"Azure",
nullptr,
settings.InitialRows(),
settings.InitialCols(),
::base::saturated_cast<uint32_t>(settings.InitialRows()),
::base::saturated_cast<uint32_t>(settings.InitialCols()),
winrt::guid());
if constexpr (Feature_VtPassthroughMode::IsEnabled())
@@ -1158,8 +1158,8 @@ namespace winrt::TerminalApp::implementation
newWorkingDirectory,
settings.StartingTitle(),
envMap.GetView(),
settings.InitialRows(),
settings.InitialCols(),
::base::saturated_cast<uint32_t>(settings.InitialRows()),
::base::saturated_cast<uint32_t>(settings.InitialCols()),
winrt::guid());
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
@@ -3274,6 +3274,9 @@ namespace winrt::TerminalApp::implementation
// Request a summon of this window to the foreground
_SummonWindowRequestedHandlers(*this, nullptr);
const IInspectable unused{ nullptr };
_SetAsDefaultDismissHandler(unused, unused);
return S_OK;
}
CATCH_RETURN()

View File

@@ -15,6 +15,7 @@
<PropertyGroup Label="NuGet Dependencies">
<TerminalCppWinrt>true</TerminalCppWinrt>
<TerminalXamlApplicationToolkit>true</TerminalXamlApplicationToolkit>
<TerminalMUX>true</TerminalMUX>
</PropertyGroup>
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
@@ -92,14 +93,6 @@
</Reference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\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.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>

View File

@@ -9,7 +9,7 @@ using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Terminal::TerminalConnection;
static til::point GetConsoleScreenSize(HANDLE outputHandle)
static COORD GetConsoleScreenSize(HANDLE outputHandle)
{
CONSOLE_SCREEN_BUFFER_INFOEX csbiex{};
csbiex.cbSize = sizeof(csbiex);

View File

@@ -75,8 +75,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
if (settings)
{
_initialRows = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows));
_initialCols = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols));
_initialRows = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows);
_initialCols = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols);
}
}

View File

@@ -32,8 +32,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
private:
til::CoordType _initialRows{};
til::CoordType _initialCols{};
uint32_t _initialRows{};
uint32_t _initialCols{};
enum class AzureState
{

View File

@@ -53,7 +53,12 @@ CATCH_RETURN()
HRESULT CTerminalHandoff::s_StopListening()
{
std::unique_lock lock{ _mtx };
return s_StopListeningLocked();
}
// See s_StopListening()
HRESULT CTerminalHandoff::s_StopListeningLocked()
{
RETURN_HR_IF_NULL(E_NOT_VALID_STATE, _pfnHandoff);
_pfnHandoff = nullptr;
@@ -101,14 +106,16 @@ HRESULT CTerminalHandoff::EstablishPtyHandoff(HANDLE in, HANDLE out, HANDLE sign
{
try
{
// Stash a local copy of _pfnHandoff before we stop listening.
std::unique_lock lock{ _mtx };
// s_StopListeningLocked sets _pfnHandoff to nullptr.
// localPfnHandoff is tested for nullness below.
#pragma warning(suppress : 26429) // Symbol '...' is never tested for nullness, it can be marked as not_null (f.23).
auto localPfnHandoff = _pfnHandoff;
// Because we are REGCLS_SINGLEUSE... we need to `CoRevokeClassObject` after we handle this ONE call.
// COM does not automatically clean that up for us. We must do it.
s_StopListening();
std::unique_lock lock{ _mtx };
LOG_IF_FAILED(s_StopListeningLocked());
// Report an error if no one registered a handoff function before calling this.
THROW_HR_IF_NULL(E_NOT_VALID_STATE, localPfnHandoff);

View File

@@ -43,6 +43,9 @@ struct __declspec(uuid(__CLSID_CTerminalHandoff))
static HRESULT s_StartListening(NewHandoffFunction pfnHandoff);
static HRESULT s_StopListening();
private:
static HRESULT s_StopListeningLocked();
};
// Disable warnings from the CoCreatableClass macro as the value it provides for

View File

@@ -293,7 +293,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
_transitionToState(ConnectionState::Connecting);
const til::size dimensions{ gsl::narrow<til::CoordType>(_initialCols), gsl::narrow<til::CoordType>(_initialRows) };
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
// If we do not have pipes already, then this is a fresh connection... not an inbound one that is a received
// handoff from an already-started PTY process.
@@ -309,7 +309,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
}
}
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(til::unwrap_coord_size(dimensions), flags, &_inPipe, &_outPipe, &_hPC));
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, flags, &_inPipe, &_outPipe, &_hPC));
if (_initialParentHwnd != 0)
{
@@ -338,7 +338,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), til::unwrap_coord_size(dimensions)));
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), dimensions));
THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
if (_initialVisibility)

View File

@@ -67,8 +67,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
void _indicateExitWithStatus(unsigned int status) noexcept;
void _ClientTerminated() noexcept;
til::CoordType _initialRows{};
til::CoordType _initialCols{};
uint32_t _initialRows{};
uint32_t _initialCols{};
uint64_t _initialParentHwnd{ 0 };
hstring _commandline{};
hstring _startingDirectory{};

View File

@@ -37,28 +37,6 @@ constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds(
namespace winrt::Microsoft::Terminal::Control::implementation
{
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const til::color& c)
{
Core::OptionalColor result;
result.Color = c;
result.HasValue = true;
return result;
}
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const std::optional<til::color>& c)
{
Core::OptionalColor result;
if (c.has_value())
{
result.Color = *c;
result.HasValue = true;
}
else
{
result.HasValue = false;
}
return result;
}
// Helper static function to ensure that all ambiguous-width glyphs are reported as narrow.
// See microsoft/terminal#2066 for more info.
static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */)
@@ -115,6 +93,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto pfnTitleChanged = std::bind(&ControlCore::_terminalTitleChanged, this, std::placeholders::_1);
_terminal->SetTitleChangedCallback(pfnTitleChanged);
auto pfnTabColorChanged = std::bind(&ControlCore::_terminalTabColorChanged, this, std::placeholders::_1);
_terminal->SetTabColorChangedCallback(pfnTabColorChanged);
auto pfnScrollPositionChanged = std::bind(&ControlCore::_terminalScrollPositionChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
_terminal->SetScrollPositionChangedCallback(pfnScrollPositionChanged);
@@ -127,9 +108,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto pfnShowWindowChanged = std::bind(&ControlCore::_terminalShowWindowChanged, this, std::placeholders::_1);
_terminal->SetShowWindowCallback(pfnShowWindowChanged);
auto pfnPlayMidiNote = std::bind(&ControlCore::_terminalPlayMidiNote, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
_terminal->SetPlayMidiNoteCallback(pfnPlayMidiNote);
// MSFT 33353327: Initialize the renderer in the ctor instead of Initialize().
// We need the renderer to be ready to accept new engines before the SwapChainPanel is ready to go.
// If we wait, a screen reader may try to get the AutomationPeer (aka the UIA Engine), and we won't be able to attach
@@ -148,7 +126,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread));
_renderer->SetBackgroundColorChangedCallback([this]() { _rendererBackgroundColorChanged(); });
_renderer->SetFrameColorChangedCallback([this]() { _rendererTabColorChanged(); });
_renderer->SetRendererEnteredErrorStateCallback([weakThis = get_weak()]() {
if (auto strongThis{ weakThis.get() })
@@ -195,11 +172,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
});
_updatePatternLocations = std::make_shared<ThrottledFuncTrailing<>>(
_dispatcher,
// NOTE: Calling UpdatePatternLocations from a background
// thread is a workaround for us to hit GH#12607 less often.
_updatePatternLocations = std::make_unique<til::throttled_func_trailing<>>(
UpdatePatternLocationsInterval,
[weakThis = get_weak()]() {
if (auto core{ weakThis.get() }; !core->_IsClosing())
if (auto core{ weakThis.get() })
{
core->UpdatePatternLocations();
}
@@ -226,8 +204,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
_renderer->TriggerTeardown();
}
_shutdownMidiAudio();
}
bool ControlCore::Initialize(const double actualWidth,
@@ -272,8 +248,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// and react accordingly.
_updateFont(true);
const til::size windowSize{ static_cast<til::CoordType>(windowWidth),
static_cast<til::CoordType>(windowHeight) };
const COORD windowSize{ static_cast<short>(windowWidth),
static_cast<short>(windowHeight) };
// First set up the dx engine with the window size in pixels.
// Then, using the font, get the number of characters that can fit.
@@ -417,19 +393,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
vkey != VK_SNAPSHOT &&
keyDown)
{
if (_terminal->IsInMarkMode() && modifiers.IsCtrlPressed() && vkey == 'A')
{
auto lock = _terminal->LockForWriting();
_terminal->SelectAll();
_renderer->TriggerSelection();
return true;
}
// try to update the selection
if (const auto updateSlnParams{ _terminal->ConvertKeyEventToUpdateSelectionParams(modifiers, vkey) })
if (const auto updateSlnParams{ ::Terminal::ConvertKeyEventToUpdateSelectionParams(modifiers, vkey) })
{
auto lock = _terminal->LockForWriting();
_terminal->UpdateSelection(updateSlnParams->first, updateSlnParams->second, modifiers);
_terminal->UpdateSelection(updateSlnParams->first, updateSlnParams->second);
_renderer->TriggerSelection();
return true;
}
@@ -466,7 +434,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const short wheelDelta,
const TerminalInput::MouseButtonState state)
{
return _terminal->SendMouseEvent(viewportPos, uiButton, states, wheelDelta, state);
return _terminal->SendMouseEvent(viewportPos.to_win32_coord(), uiButton, states, wheelDelta, state);
}
void ControlCore::UserScrollViewport(const int viewTop)
@@ -478,7 +446,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// itself - it was initiated by the mouse wheel, or the scrollbar.
_terminal->UserScrollViewport(viewTop);
_updatePatternLocations->Run();
(*_updatePatternLocations)();
}
void ControlCore::AdjustOpacity(const double adjustment)
@@ -590,12 +558,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_lastHoveredCell = terminalPosition;
uint16_t newId{ 0u };
// we can't use auto here because we're pre-declaring newInterval.
decltype(_terminal->GetHyperlinkIntervalFromPosition({})) newInterval{ std::nullopt };
decltype(_terminal->GetHyperlinkIntervalFromPosition(COORD{})) newInterval{ std::nullopt };
if (terminalPosition.has_value())
{
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
newId = _terminal->GetHyperlinkIdAtPosition(*terminalPosition);
newInterval = _terminal->GetHyperlinkIntervalFromPosition(*terminalPosition);
newId = _terminal->GetHyperlinkIdAtPosition(terminalPosition->to_win32_coord());
newInterval = _terminal->GetHyperlinkIntervalFromPosition(terminalPosition->to_win32_coord());
}
// If the hyperlink ID changed or the interval changed, trigger a redraw all
@@ -625,7 +593,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
// Lock for the duration of our reads.
auto lock = _terminal->LockForReading();
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }) };
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }.to_win32_coord()) };
}
winrt::hstring ControlCore::HoveredUriText() const
@@ -633,7 +601,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
if (_lastHoveredCell.has_value())
{
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(*_lastHoveredCell) };
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(_lastHoveredCell->to_win32_coord()) };
}
return {};
}
@@ -680,9 +648,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Inform the renderer of our opacity
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());
// Trigger a redraw to repaint the window background and tab colors.
_renderer->TriggerRedrawAll(true, true);
_updateAntiAliasingMode();
if (sizeChanged)
@@ -803,7 +768,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool ControlCore::_setFontSizeUnderLock(int fontSize)
{
// Make sure we have a non-zero font size
const auto newSize = std::max(fontSize, 1);
const auto newSize = std::max<short>(gsl::narrow_cast<short>(fontSize), 1);
const auto fontFace = _settings->FontFace();
const auto fontWeight = _settings->FontWeight();
_actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false };
@@ -859,8 +824,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - <none>
void ControlCore::_refreshSizeUnderLock()
{
auto cx = gsl::narrow_cast<til::CoordType>(_panelWidth * _compositionScale);
auto cy = gsl::narrow_cast<til::CoordType>(_panelHeight * _compositionScale);
auto cx = gsl::narrow_cast<short>(_panelWidth * _compositionScale);
auto cy = gsl::narrow_cast<short>(_panelHeight * _compositionScale);
// Don't actually resize so small that a single character wouldn't fit
// in either dimension. The buffer really doesn't like being size 0.
@@ -928,17 +893,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_refreshSizeUnderLock();
}
void ControlCore::SetSelectionAnchor(const til::point position)
void ControlCore::SetSelectionAnchor(const til::point& position)
{
auto lock = _terminal->LockForWriting();
_terminal->SetSelectionAnchor(position);
_terminal->SetSelectionAnchor(position.to_win32_coord());
}
// Method Description:
// - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
// Arguments:
// - position: the point in terminal coordinates (in cells, not pixels)
void ControlCore::SetEndSelectionPoint(const til::point position)
void ControlCore::SetEndSelectionPoint(const til::point& position)
{
if (!_terminal->IsSelectionActive())
{
@@ -955,7 +920,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
};
// save location (for rendering) + render
_terminal->SetSelectionEnd(terminalPosition);
_terminal->SetSelectionEnd(terminalPosition.to_win32_coord());
_renderer->TriggerSelection();
}
@@ -969,13 +934,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Method Description:
// - Given a copy-able selection, get the selected text from the buffer and send it to the
// Windows Clipboard (CascadiaWin32:main.cpp).
// - CopyOnSelect does NOT clear the selection
// Arguments:
// - singleLine: collapse all of the text to one line
// - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr
// if we should defer which formats are copied to the global setting
// - clearSelection: if true, clear the selection. Used for CopyOnSelect.
bool ControlCore::CopySelectionToClipboard(bool singleLine,
const Windows::Foundation::IReference<CopyFormat>& formats)
const Windows::Foundation::IReference<CopyFormat>& formats,
bool clearSelection)
{
// no selection --> nothing to copy
if (!_terminal->IsSelectionActive())
@@ -1015,7 +981,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bgColor) :
"";
if (!_settings->CopyOnSelect())
if (clearSelection)
{
_terminal->ClearSelection();
_renderer->TriggerSelection();
@@ -1037,28 +1003,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_renderer->TriggerSelection();
}
bool ControlCore::ToggleBlockSelection()
const bool ControlCore::IsInQuickEditMode() const noexcept
{
auto lock = _terminal->LockForWriting();
if (_terminal->IsSelectionActive())
{
_terminal->SetBlockSelection(!_terminal->IsBlockSelection());
_renderer->TriggerSelection();
return true;
}
return false;
}
void ControlCore::ToggleMarkMode()
{
auto lock = _terminal->LockForWriting();
_terminal->ToggleMarkMode();
_renderer->TriggerSelection();
}
bool ControlCore::IsInMarkMode() const
{
return _terminal->IsInMarkMode();
return _terminal->IsInQuickEditMode();
}
// Method Description:
@@ -1204,6 +1151,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_TitleChangedHandlers(*this, winrt::make<TitleChangedEventArgs>(winrt::hstring{ wstr }));
}
// Method Description:
// - Called for the Terminal's TabColorChanged callback. This will re-raise
// a new winrt TypedEvent that can be listened to.
// - The listeners to this event will re-query the control for the current
// value of TabColor().
// Arguments:
// - <unused>
// Return Value:
// - <none>
void ControlCore::_terminalTabColorChanged(const std::optional<til::color> /*color*/)
{
// Raise a TabColorChanged event
_TabColorChangedHandlers(*this, nullptr);
}
// Method Description:
// - Update the position and size of the scrollbar to match the given
// viewport top, viewport height, and buffer size.
@@ -1218,10 +1180,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const int viewHeight,
const int bufferSize)
{
if (!_initializedTerminal)
{
return;
}
// Clear the regex pattern tree so the renderer does not try to render them while scrolling
// We're **NOT** taking the lock here unlike _scrollbarChangeHandler because
// we are already under lock (since this usually happens as a result of writing).
@@ -1242,7 +1200,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
// Additionally, start the throttled update of where our links are.
_updatePatternLocations->Run();
(*_updatePatternLocations)();
}
void ControlCore::_terminalCursorPositionChanged()
@@ -1266,66 +1224,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
// Method Description:
// - Plays a single MIDI note, blocking for the duration.
// Arguments:
// - noteNumber - The MIDI note number to be played (0 - 127).
// - velocity - The force with which the note should be played (0 - 127).
// - duration - How long the note should be sustained (in microseconds).
void ControlCore::_terminalPlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration)
{
// We create the audio instance on demand, and lock it for the duration
// of the note output so it can't be destroyed while in use.
auto& midiAudio = _getMidiAudio();
midiAudio.Lock();
// We then unlock the terminal, so the UI doesn't hang while we're busy.
auto& terminalLock = _terminal->GetReadWriteLock();
terminalLock.unlock();
// This call will block for the duration, unless shutdown early.
midiAudio.PlayNote(noteNumber, velocity, duration);
// Once complete, we reacquire the terminal lock and unlock the audio.
// If the terminal has shutdown in the meantime, the Unlock call
// will throw an exception, forcing the thread to exit ASAP.
terminalLock.lock();
midiAudio.Unlock();
}
// Method Description:
// - Returns the MIDI audio instance, created on demand.
// Arguments:
// - <none>
// Return Value:
// - a reference to the MidiAudio instance.
MidiAudio& ControlCore::_getMidiAudio()
{
if (!_midiAudio)
{
_midiAudio = std::make_unique<MidiAudio>();
_midiAudio->Initialize();
}
return *_midiAudio;
}
// Method Description:
// - Shuts down the MIDI audio system if previously instantiated.
// Arguments:
// - <none>
// Return Value:
// - <none>
void ControlCore::_shutdownMidiAudio()
{
if (_midiAudio)
{
// We lock the terminal here to make sure the shutdown promise is
// set before the audio is unlocked in the thread that is playing.
auto lock = _terminal->LockForWriting();
_midiAudio->Shutdown();
}
}
bool ControlCore::HasSelection() const
{
return _terminal->IsSelectionActive();
@@ -1468,11 +1366,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_BackgroundColorChangedHandlers(*this, nullptr);
}
void ControlCore::_rendererTabColorChanged()
{
_TabColorChangedHandlers(*this, nullptr);
}
void ControlCore::BlinkAttributeTick()
{
auto lock = _terminal->LockForWriting();
@@ -1526,7 +1419,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
auto lock = _terminal->LockForReading();
return _terminal->GetCursorPosition().to_core_point();
return _terminal->GetViewportRelativeCursorPosition().to_core_point();
}
// This one's really pushing the boundary of what counts as "encapsulation".
@@ -1578,7 +1471,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
// If shift is pressed and there is a selection we extend it using
// the selection mode (expand the "end" selection point)
_terminal->SetSelectionEnd(terminalPosition, mode);
_terminal->SetSelectionEnd(terminalPosition.to_win32_coord(), mode);
selectionNeedsToBeCopied = true;
}
else if (mode != ::Terminal::SelectionExpansion::Char || shiftEnabled)
@@ -1586,7 +1479,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// If we are handling a double / triple-click or shift+single click
// we establish selection using the selected mode
// (expand both "start" and "end" selection points)
_terminal->MultiClickSelection(terminalPosition, mode);
_terminal->MultiClickSelection(terminalPosition.to_win32_coord(), mode);
selectionNeedsToBeCopied = true;
}
@@ -1616,18 +1509,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
void ControlCore::_connectionOutputHandler(const hstring& hstr)
{
try
{
_terminal->Write(hstr);
_terminal->Write(hstr);
// Start the throttled update of where our hyperlinks are.
_updatePatternLocations->Run();
}
catch (...)
{
// We're expecting to receive an exception here if the terminal
// is closed while we're blocked playing a MIDI note.
}
// Start the throttled update of where our hyperlinks are.
(*_updatePatternLocations)();
}
// Method Description:
@@ -1859,13 +1744,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - This is related to work done for GH#2988.
void ControlCore::GotFocus()
{
_terminal->FocusChanged(true);
_focusChanged(true);
}
// See GotFocus.
void ControlCore::LostFocus()
{
_terminal->FocusChanged(false);
_focusChanged(false);
}
void ControlCore::_focusChanged(bool focused)
{
// GH#13461 - temporarily turn off read-only mode, send the focus event,
// then turn it back on. Even in focus mode, focus events are fine to
// send. We don't want to pop a warning every time the control is
// focused.
const auto previous = std::exchange(_isReadOnly, false);
const auto restore = wil::scope_exit([&]() { _isReadOnly = previous; });
_terminal->FocusChanged(focused);
}
bool ControlCore::_isBackgroundTransparent()
@@ -1897,140 +1793,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
_owningHwnd = owner;
}
Windows::Foundation::Collections::IVector<Control::ScrollMark> ControlCore::ScrollMarks() const
{
auto internalMarks{ _terminal->GetScrollMarks() };
auto v = winrt::single_threaded_observable_vector<Control::ScrollMark>();
for (const auto& mark : internalMarks)
{
Control::ScrollMark m{};
// sneaky: always evaluate the color of the mark to a real value
// before shoving it into the optional. If the mark doesn't have a
// specific color set, we'll use the value from the color table
// that's appropriate for this category of mark. If we do have a
// color set, then great we'll use that. The TermControl can then
// always use the value in the Mark regardless if it was actually
// set or not.
m.Color = OptionalFromColor(_terminal->GetColorForMark(mark));
m.Start = mark.start.to_core_point();
m.End = mark.end.to_core_point();
v.Append(m);
}
return v;
}
void ControlCore::AddMark(const Control::ScrollMark& mark)
{
::Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark m{};
if (mark.Color.HasValue)
{
m.color = til::color{ mark.Color.Color };
}
if (HasSelection())
{
m.start = til::point{ _terminal->GetSelectionAnchor() };
m.end = til::point{ _terminal->GetSelectionEnd() };
}
else
{
m.start = m.end = til::point{ _terminal->GetTextBuffer().GetCursor().GetPosition() };
}
// The version of this that only accepts a ScrollMark will automatically
// set the start & end to the cursor position.
_terminal->AddMark(m, m.start, m.end);
}
void ControlCore::ClearMark() { _terminal->ClearMark(); }
void ControlCore::ClearAllMarks() { _terminal->ClearAllMarks(); }
void ControlCore::ScrollToMark(const Control::ScrollToMarkDirection& direction)
{
const auto currentOffset = ScrollOffset();
const auto& marks{ _terminal->GetScrollMarks() };
std::optional<DispatchTypes::ScrollMark> tgt;
switch (direction)
{
case ScrollToMarkDirection::Last:
{
int highest = currentOffset;
for (const auto& mark : marks)
{
const auto newY = mark.start.y;
if (newY > highest)
{
tgt = mark;
highest = newY;
}
}
break;
}
case ScrollToMarkDirection::First:
{
int lowest = currentOffset;
for (const auto& mark : marks)
{
const auto newY = mark.start.y;
if (newY < lowest)
{
tgt = mark;
lowest = newY;
}
}
break;
}
case ScrollToMarkDirection::Next:
{
int minDistance = INT_MAX;
for (const auto& mark : marks)
{
const auto delta = mark.start.y - currentOffset;
if (delta > 0 && delta < minDistance)
{
tgt = mark;
minDistance = delta;
}
}
break;
}
case ScrollToMarkDirection::Previous:
default:
{
int minDistance = INT_MAX;
for (const auto& mark : marks)
{
const auto delta = currentOffset - mark.start.y;
if (delta > 0 && delta < minDistance)
{
tgt = mark;
minDistance = delta;
}
}
break;
}
}
if (tgt.has_value())
{
UserScrollViewport(tgt->start.y);
}
else
{
if (direction == ScrollToMarkDirection::Last || direction == ScrollToMarkDirection::Next)
{
UserScrollViewport(BufferHeight());
}
else if (direction == ScrollToMarkDirection::First || direction == ScrollToMarkDirection::Previous)
{
UserScrollViewport(0);
}
}
}
}

View File

@@ -17,7 +17,6 @@
#include "ControlCore.g.h"
#include "ControlSettings.h"
#include "../../audio/midi/MidiAudio.hpp"
#include "../../renderer/base/Renderer.hpp"
#include "../../cascadia/TerminalCore/Terminal.hpp"
#include "../buffer/out/search.h"
@@ -80,11 +79,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SendInput(const winrt::hstring& wstr);
void PasteText(const winrt::hstring& hstr);
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats, bool clearSelection = true);
void SelectAll();
bool ToggleBlockSelection();
void ToggleMarkMode();
bool IsInMarkMode() const;
const bool IsInQuickEditMode() const noexcept;
void GotFocus();
void LostFocus();
@@ -119,13 +116,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
int BufferHeight() const;
bool BracketedPasteEnabled() const noexcept;
Windows::Foundation::Collections::IVector<Control::ScrollMark> ScrollMarks() const;
void AddMark(const Control::ScrollMark& mark);
void ClearMark();
void ClearAllMarks();
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
#pragma endregion
#pragma region ITerminalInput
@@ -159,8 +149,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool HasSelection() const;
bool CopyOnSelect() const;
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
void SetSelectionAnchor(const til::point position);
void SetEndSelectionPoint(const til::point position);
void SetSelectionAnchor(const til::point& position);
void SetEndSelectionPoint(const til::point& position);
void Search(const winrt::hstring& text,
const bool goForward,
@@ -261,7 +251,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
winrt::Windows::System::DispatcherQueue _dispatcher{ nullptr };
std::shared_ptr<ThrottledFuncTrailing<>> _tsfTryRedrawCanvas;
std::shared_ptr<ThrottledFuncTrailing<>> _updatePatternLocations;
std::unique_ptr<til::throttled_func_trailing<>> _updatePatternLocations;
std::shared_ptr<ThrottledFuncTrailing<Control::ScrollPositionChangedArgs>> _updateScrollBar;
winrt::fire_and_forget _asyncCloseConnection();
@@ -276,27 +266,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _terminalCopyToClipboard(std::wstring_view wstr);
void _terminalWarningBell();
void _terminalTitleChanged(std::wstring_view wstr);
void _terminalTabColorChanged(const std::optional<til::color> color);
void _terminalScrollPositionChanged(const int viewTop,
const int viewHeight,
const int bufferSize);
void _terminalCursorPositionChanged();
void _terminalTaskbarProgressChanged();
void _terminalShowWindowChanged(bool showOrHide);
void _terminalPlayMidiNote(const int noteNumber,
const int velocity,
const std::chrono::microseconds duration);
#pragma endregion
std::unique_ptr<MidiAudio> _midiAudio;
MidiAudio& _getMidiAudio();
void _shutdownMidiAudio();
#pragma region RendererCallbacks
void _rendererWarning(const HRESULT hr);
void _renderEngineSwapChainChanged();
void _rendererBackgroundColorChanged();
void _rendererTabColorChanged();
#pragma endregion
void _raiseReadOnlyWarning();
@@ -306,6 +288,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _setOpacity(const double opacity);
bool _isBackgroundTransparent();
void _focusChanged(bool focused);
inline bool _IsClosing() const noexcept
{

View File

@@ -22,6 +22,7 @@ namespace Microsoft.Terminal.Control
IsRightButtonDown = 0x4
};
enum ClearBufferType
{
Screen,
@@ -65,10 +66,7 @@ namespace Microsoft.Terminal.Control
void SendInput(String text);
void PasteText(String text);
void SelectAll();
Boolean ToggleBlockSelection();
void ToggleMarkMode();
void ClearBuffer(ClearBufferType clearType);
Boolean IsInMarkMode();
void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition);
void ClearHoveredCell();

View File

@@ -142,13 +142,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Method Description:
// - Given a copy-able selection, get the selected text from the buffer and send it to the
// Windows Clipboard (CascadiaWin32:main.cpp).
// - CopyOnSelect does NOT clear the selection
// Arguments:
// - singleLine: collapse all of the text to one line
// - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr
// if we should defer which formats are copied to the global setting
// - clearSelection: if true, clear the selection after copying it. Used for CopyOnSelect.
bool ControlInteractivity::CopySelectionToClipboard(bool singleLine,
const Windows::Foundation::IReference<CopyFormat>& formats)
const Windows::Foundation::IReference<CopyFormat>& formats,
bool clearSelection)
{
if (_core)
{
@@ -164,7 +165,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Mark the current selection as copied
_selectionNeedsToBeCopied = false;
return _core->CopySelectionToClipboard(singleLine, formats);
return _core->CopySelectionToClipboard(singleLine, formats, clearSelection);
}
return false;
@@ -257,14 +258,26 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown))
{
// CopyOnSelect right click always pastes
if (_core->CopyOnSelect() || !_core->HasSelection())
if (_core->CopyOnSelect())
{
// CopyOnSelect:
// 1. keyboard selection? --> copy the new content first
// 2. right click always pastes!
if (_core->IsInQuickEditMode())
{
CopySelectionToClipboard(shiftEnabled, nullptr);
}
RequestPasteTextFromClipboard();
}
else if (_core->HasSelection())
{
// copy selected text
CopySelectionToClipboard(shiftEnabled, nullptr);
}
else
{
CopySelectionToClipboard(shiftEnabled, nullptr);
// no selection --> paste
RequestPasteTextFromClipboard();
}
}
}
@@ -383,7 +396,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
isLeftMouseRelease &&
_selectionNeedsToBeCopied)
{
CopySelectionToClipboard(false, nullptr);
// IMPORTANT!
// Set clearSelection to false here!
// Otherwise, the selection will be cleared immediately after you make it.
CopySelectionToClipboard(false, nullptr, /*clearSelection*/ false);
}
_singleClickTouchdownPos = std::nullopt;
@@ -615,7 +631,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Get the size of the font, which is in pixels
const til::size fontSize{ _core->GetFont().GetSize() };
// Convert the location in pixels to characters within the current viewport.
return pixelPosition / fontSize;
return til::point{ pixelPosition / fontSize };
}
bool ControlInteractivity::_sendMouseEventHelper(const til::point terminalPosition,

View File

@@ -80,7 +80,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
#pragma endregion
bool CopySelectionToClipboard(bool singleLine,
const Windows::Foundation::IReference<CopyFormat>& formats);
const Windows::Foundation::IReference<CopyFormat>& formats,
bool clearSelection = true);
void RequestPasteTextFromClipboard();
void SetEndSelectionPoint(const Core::Point pixelPosition);
bool ManglePathsForWsl();
@@ -123,7 +124,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// terminal.
bool _selectionNeedsToBeCopied;
std::optional<til::point> _lastHoveredCell{ std::nullopt };
std::optional<COORD> _lastHoveredCell{ std::nullopt };
// Track the last hyperlink ID we hovered over
uint16_t _lastHoveredId{ 0 };

View File

@@ -56,7 +56,6 @@ namespace Microsoft.Terminal.Control
// Experimental Settings
Boolean ForceFullRepaintRendering { get; };
Boolean SoftwareRendering { get; };
Boolean ShowMarks { get; };
Boolean UseBackgroundImageForWindow { get; };
};
}

View File

@@ -3,32 +3,6 @@
namespace Microsoft.Terminal.Control
{
enum MarkCategory
{
Prompt = 0,
Error = 1,
Warning = 2,
Info = 3
};
struct ScrollMark
{
// There are other members of DispatchTypes::ScrollMark, but these are
// all we need to expose up and set downwards currently. Additional
// members can be bubbled as necessary.
Microsoft.Terminal.Core.Point Start;
Microsoft.Terminal.Core.Point End; // exclusive
Microsoft.Terminal.Core.OptionalColor Color;
};
enum ScrollToMarkDirection
{
Previous,
Next,
First,
Last
};
// These are properties of the TerminalCore that should be queryable by the
// rest of the app.
interface ICoreState
@@ -53,11 +27,5 @@ namespace Microsoft.Terminal.Control
UInt64 OwningHwnd;
void AddMark(ScrollMark mark);
void ClearMark();
void ClearAllMarks();
void ScrollToMark(ScrollToMarkDirection direction);
IVector<ScrollMark> ScrollMarks { get; };
};
}

View File

@@ -146,14 +146,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
#pragma endregion
#pragma region IControlAccessibilityInfo
til::size InteractivityAutomationPeer::GetFontSize() const noexcept
COORD InteractivityAutomationPeer::GetFontSize() const noexcept
{
return { til::math::rounding, _interactivity->Core().FontSize() };
return til::size{ til::math::rounding, _interactivity->Core().FontSize() }.to_win32_coord();
}
til::rect InteractivityAutomationPeer::GetBounds() const noexcept
RECT InteractivityAutomationPeer::GetBounds() const noexcept
{
return _controlBounds;
return _controlBounds.to_win32_rect();
}
HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
@@ -164,9 +164,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return S_OK;
}
til::rect InteractivityAutomationPeer::GetPadding() const noexcept
RECT InteractivityAutomationPeer::GetPadding() const noexcept
{
return _controlPadding;
return _controlPadding.to_win32_rect();
}
double InteractivityAutomationPeer::GetScaleFactor() const noexcept
@@ -174,7 +174,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
}
void InteractivityAutomationPeer::ChangeViewport(const til::inclusive_rect& NewWindow)
void InteractivityAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow)
{
_interactivity->UpdateScrollbar(NewWindow.Top);
}

View File

@@ -63,11 +63,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
#pragma region IControlAccessibilityInfo Pattern
// Inherited via IControlAccessibilityInfo
virtual til::size GetFontSize() const noexcept override;
virtual til::rect GetBounds() const noexcept override;
virtual til::rect GetPadding() const noexcept override;
virtual COORD GetFontSize() const noexcept override;
virtual RECT GetBounds() const noexcept override;
virtual RECT GetPadding() const noexcept override;
virtual double GetScaleFactor() const noexcept override;
virtual void ChangeViewport(const til::inclusive_rect& NewWindow) override;
virtual void ChangeViewport(SMALL_RECT NewWindow) override;
virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override;
#pragma endregion

View File

@@ -124,7 +124,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
[weakThis = get_weak()](const auto& update) {
if (auto control{ weakThis.get() }; !control->_IsClosing())
{
control->_throttledUpdateScrollbar(update);
control->_isInternalScrollBarUpdate = true;
auto scrollBar = control->ScrollBar();
if (update.newValue)
{
scrollBar.Value(*update.newValue);
}
scrollBar.Maximum(update.newMaximum);
scrollBar.Minimum(update.newMinimum);
scrollBar.ViewportSize(update.newViewportSize);
// scroll one full screen worth at a time when the scroll bar is clicked
scrollBar.LargeChange(std::max(update.newViewportSize - 1, 0.));
control->_isInternalScrollBarUpdate = false;
}
});
@@ -135,57 +148,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_ApplyUISettings();
}
void TermControl::_throttledUpdateScrollbar(const ScrollBarUpdate& update)
{
// Assumptions:
// * we're already not closing
// * caller already checked weak ptr to make sure we're still alive
_isInternalScrollBarUpdate = true;
auto scrollBar = ScrollBar();
if (update.newValue)
{
scrollBar.Value(*update.newValue);
}
scrollBar.Maximum(update.newMaximum);
scrollBar.Minimum(update.newMinimum);
scrollBar.ViewportSize(update.newViewportSize);
// scroll one full screen worth at a time when the scroll bar is clicked
scrollBar.LargeChange(std::max(update.newViewportSize - 1, 0.));
_isInternalScrollBarUpdate = false;
if (_showMarksInScrollbar)
{
// Update scrollbar marks
ScrollBarCanvas().Children().Clear();
const auto marks{ _core.ScrollMarks() };
const auto fullHeight{ ScrollBarCanvas().ActualHeight() };
const auto totalBufferRows{ update.newMaximum + update.newViewportSize };
for (const auto m : marks)
{
Windows::UI::Xaml::Shapes::Rectangle r;
Media::SolidColorBrush brush{};
// Sneaky: technically, a mark doesn't need to have a color set,
// it might want to just use the color from the palette for that
// kind of mark. Fortunately, ControlCore is kind enough to
// pre-evaluate that for us, and shove the real value into the
// Color member, regardless if the mark has a literal value set.
brush.Color(static_cast<til::color>(m.Color.Color));
r.Fill(brush);
r.Width(16.0f / 3.0f); // pip width - 1/3rd of the scrollbar width.
r.Height(2);
const auto markRow = m.Start.Y;
const auto fractionalHeight = markRow / totalBufferRows;
const auto relativePos = fractionalHeight * fullHeight;
ScrollBarCanvas().Children().Append(r);
Windows::UI::Xaml::Controls::Canvas::SetTop(r, relativePos);
}
}
}
// Method Description:
// - Loads the search box from the xaml UI and focuses it.
void TermControl::CreateSearchBoxControl()
@@ -442,13 +404,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
newMargin.Right,
newMargin.Bottom });
}
_showMarksInScrollbar = settings.ShowMarks();
// Clear out all the current marks
ScrollBarCanvas().Children().Clear();
// When we hot reload the settings, the core will send us a scrollbar
// update. If we enabled scrollbar marks, then great, when we handle
// that message, we'll redraw them.
}
// Method Description:
@@ -682,7 +637,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// clever way around asking the core for this.
til::point TermControl::GetFontSize() const
{
return { til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
return til::point{ til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
}
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
@@ -1182,7 +1137,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
// Manually show the cursor when a key is pressed. Restarting
// the timer prevents flickering.
_core.CursorOn(!_core.IsInMarkMode());
_core.CursorOn(true);
_cursorTimer->Start();
}
@@ -1653,7 +1608,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
if (_cursorTimer)
{
// When the terminal focuses, show the cursor immediately
_core.CursorOn(!_core.IsInMarkMode());
_core.CursorOn(true);
_cursorTimer->Start();
}
@@ -1904,16 +1859,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_core.SelectAll();
}
bool TermControl::ToggleBlockSelection()
{
return _core.ToggleBlockSelection();
}
void TermControl::ToggleMarkMode()
{
_core.ToggleMarkMode();
}
void TermControl::Close()
{
if (!_IsClosing())
@@ -2019,7 +1964,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// The family is only used to determine if the font is truetype or
// not, but DX doesn't use that info at all.
// The Codepage is additionally not actually used by the DX engine at all.
FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, fontSize }, CP_UTF8, false };
FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, gsl::narrow_cast<short>(fontSize) }, CP_UTF8, false };
FontInfoDesired desiredFont = { actualFont };
// Create a DX engine and initialize it with our font and DPI. We'll
@@ -2908,17 +2853,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return _core.OwningHwnd();
}
void TermControl::AddMark(const Control::ScrollMark& mark)
{
_core.AddMark(mark);
}
void TermControl::ClearMark() { _core.ClearMark(); }
void TermControl::ClearAllMarks() { _core.ClearAllMarks(); }
void TermControl::ScrollToMark(const Control::ScrollToMarkDirection& direction) { _core.ScrollToMark(direction); }
Windows::Foundation::Collections::IVector<Control::ScrollMark> TermControl::ScrollMarks() const
{
return _core.ScrollMarks();
}
}

View File

@@ -38,8 +38,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
void PasteTextFromClipboard();
void SelectAll();
bool ToggleBlockSelection();
void ToggleMarkMode();
void Close();
Windows::Foundation::Size CharacterDimensions() const;
Windows::Foundation::Size MinimumSize();
@@ -67,13 +65,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
uint64_t OwningHwnd();
void OwningHwnd(uint64_t owner);
Windows::Foundation::Collections::IVector<Control::ScrollMark> ScrollMarks() const;
void AddMark(const Control::ScrollMark& mark);
void ClearMark();
void ClearAllMarks();
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
#pragma endregion
void ScrollViewport(int viewTop);
@@ -202,7 +193,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
std::optional<Windows::UI::Xaml::DispatcherTimer> _blinkTimer;
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
bool _showMarksInScrollbar{ false };
inline bool _IsClosing() const noexcept
{
@@ -295,7 +285,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
void _coreFoundMatch(const IInspectable& sender, const Control::FoundResultsArgs& args);
void _throttledUpdateScrollbar(const ScrollBarUpdate& update);
};
}

View File

@@ -51,8 +51,6 @@ namespace Microsoft.Terminal.Control
Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference<CopyFormat> formats);
void PasteTextFromClipboard();
void SelectAll();
Boolean ToggleBlockSelection();
void ToggleMarkMode();
void ClearBuffer(ClearBufferType clearType);
void Close();
Windows.Foundation.Size CharacterDimensions { get; };

View File

@@ -1243,30 +1243,6 @@
Style="{StaticResource ForkedScrollbarTemplate}"
ValueChanged="_ScrollbarChangeHandler"
ViewportSize="10" />
<Grid x:Name="ScrollMarksGrid"
Grid.Column="1"
Width="{StaticResource ScrollBarSize}"
HorizontalAlignment="Right"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="0"
Height="{StaticResource ScrollBarSize}" />
<Canvas x:Name="ScrollBarCanvas"
Grid.Row="1"
Width="{StaticResource ScrollBarSize}"
HorizontalAlignment="Right"
VerticalAlignment="Stretch" />
<Border Grid.Row="2"
Height="{StaticResource ScrollBarSize}" />
</Grid>
</Grid>
<local:TSFInputControl x:Name="TSFInputControl"

View File

@@ -147,14 +147,9 @@
<PRIResource Include="Resources\en-US\Resources.resw" />
<OCResourceDirectory Include="Resources" />
</ItemGroup>
<ItemGroup Condition="'$(WindowsTerminalBranding)'=='' or '$(WindowsTerminalBranding)'=='Dev' or '$(WindowsTerminalBranding)'=='Preview'">
<!-- GH#13252 Only vend this dependency for Dev and Preview builds. -->
<SDKReference Include="Microsoft.Midi.GmDls, Version=10.0.22000.0" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
<ProjectReference Include="..\..\types\lib\types.vcxproj" />
<ProjectReference Include="..\..\audio\midi\lib\midi.vcxproj" />
<ProjectReference Include="..\..\buffer\out\lib\bufferout.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\renderer\base\lib\base.vcxproj" />
<ProjectReference Include="..\..\renderer\atlas\atlas.vcxproj" />

View File

@@ -45,7 +45,6 @@
#include <winrt/Windows.UI.Xaml.Input.h>
#include <winrt/Windows.UI.Xaml.Interop.h>
#include <winrt/Windows.ui.xaml.markup.h>
#include <winrt/Windows.ui.xaml.shapes.h>
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
#include <winrt/Windows.Storage.h>

View File

@@ -24,15 +24,6 @@ namespace Microsoft.Terminal.Core
UInt8 A;
};
// Yes, this is also just an IReference<Color>. However, IReference has some
// weird ownership semantics that just make it a pain for something as
// simple as "maybe this color doesn't have a value set".
struct OptionalColor
{
Boolean HasValue;
Microsoft.Terminal.Core.Color Color;
};
// TerminalCore declares its own Color struct to avoid depending on
// Windows.UI. Windows.Foundation.Point also exists, but it's composed of
// floating-point coordinates, when we almost always need integer coordinates.

View File

@@ -26,9 +26,6 @@ namespace Microsoft.Terminal.Core
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> TabColor;
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> StartingTabColor;
Boolean AutoMarkPrompts;
};
}

View File

@@ -17,10 +17,10 @@ namespace Microsoft::Terminal::Core
ITerminalInput& operator=(ITerminalInput&&) = default;
virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0;
virtual bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
[[nodiscard]] virtual HRESULT UserResize(const til::size size) noexcept = 0;
[[nodiscard]] virtual HRESULT UserResize(const COORD size) noexcept = 0;
virtual void UserScrollViewport(const int viewTop) = 0;
virtual int GetScrollOffset() = 0;

View File

@@ -45,12 +45,11 @@ Terminal::Terminal() :
_snapOnInput{ true },
_altGrAliasing{ true },
_blockSelection{ false },
_markMode{ false },
_quickEditMode{ false },
_selection{ std::nullopt },
_taskbarState{ 0 },
_taskbarProgress{ 0 },
_trimBlockSelection{ false },
_autoMarkPrompts{ false }
_trimBlockSelection{ false }
{
auto passAlongInput = [&](std::deque<std::unique_ptr<IInputEvent>>& inEventsToWrite) {
if (!_pfnWriteInput)
@@ -67,12 +66,12 @@ Terminal::Terminal() :
_renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, RGB(0, 0, 0));
}
void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Renderer& renderer)
void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& renderer)
{
_mutableViewport = Viewport::FromDimensions({ 0, 0 }, viewportSize);
_scrollbackLines = scrollbackLines;
const til::size bufferSize{ viewportSize.X,
Utils::ClampToShortMax(viewportSize.Y + scrollbackLines, 1) };
const COORD bufferSize{ viewportSize.X,
Utils::ClampToShortMax(viewportSize.Y + scrollbackLines, 1) };
const TextAttribute attr{};
const UINT cursorSize = 12;
_mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, renderer);
@@ -98,8 +97,8 @@ void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Re
void Terminal::CreateFromSettings(ICoreSettings settings,
Renderer& renderer)
{
const til::size viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
Utils::ClampToShortMax(settings.InitialRows(), 1) };
const COORD viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
Utils::ClampToShortMax(settings.InitialRows(), 1) };
// TODO:MSFT:20642297 - Support infinite scrollback here, if HistorySize is -1
Create(viewportSize, Utils::ClampToShortMax(settings.HistorySize(), 0), renderer);
@@ -122,17 +121,16 @@ void Terminal::UpdateSettings(ICoreSettings settings)
_suppressApplicationTitle = settings.SuppressApplicationTitle();
_startingTitle = settings.StartingTitle();
_trimBlockSelection = settings.TrimBlockSelection();
_autoMarkPrompts = settings.AutoMarkPrompts();
_terminalInput->ForceDisableWin32InputMode(settings.ForceVTInput());
if (settings.TabColor() == nullptr)
{
_renderSettings.SetColorTableEntry(TextColor::FRAME_BACKGROUND, INVALID_COLOR);
_tabColor = std::nullopt;
}
else
{
_renderSettings.SetColorTableEntry(TextColor::FRAME_BACKGROUND, til::color{ settings.TabColor().Value() });
_tabColor = settings.TabColor().Value();
}
if (!_startingTabColor && settings.StartingTabColor())
@@ -140,6 +138,11 @@ void Terminal::UpdateSettings(ICoreSettings settings)
_startingTabColor = settings.StartingTabColor().Value();
}
if (_pfnTabColorChanged)
{
_pfnTabColorChanged(GetTabColor());
}
// TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we
// have a smaller scrollback. We should do this carefully - if the new buffer
// size is smaller than where the mutable viewport currently is, we'll want
@@ -213,11 +216,6 @@ void Terminal::UpdateAppearance(const ICoreAppearance& appearance)
}
_defaultCursorShape = cursorShape;
// Tell the control that the scrollbar has somehow changed. Used as a
// workaround to force the control to redraw any scrollbar marks whose color
// may have changed.
_NotifyScrollEvent();
}
void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
@@ -250,7 +248,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
// - S_OK if we successfully resized the terminal, S_FALSE if there was
// nothing to do (the viewportSize is the same as our current size), or an
// appropriate HRESULT for failing to resize.
[[nodiscard]] HRESULT Terminal::UserResize(const til::size viewportSize) noexcept
[[nodiscard]] HRESULT Terminal::UserResize(const COORD viewportSize) noexcept
{
const auto oldDimensions = _GetMutableViewport().Dimensions();
if (viewportSize == oldDimensions)
@@ -265,7 +263,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
if (_inAltBuffer())
{
// stash this resize for the future.
_deferredResize = viewportSize;
_deferredResize = til::size{ viewportSize };
_altBuffer->GetCursor().StartDeferDrawing();
// we're capturing `this` here because when we exit, we want to EndDefer on the (newly created) active buffer.
@@ -280,19 +278,19 @@ std::wstring_view Terminal::GetWorkingDirectory()
// Since the _mutableViewport is no longer the size of the actual
// viewport, then update our _altBufferSize tracker we're using to help
// us out here.
_altBufferSize = viewportSize;
_altBufferSize = til::size{ viewportSize };
return S_OK;
}
const auto dx = viewportSize.X - oldDimensions.X;
const auto newBufferHeight = std::clamp(viewportSize.Y + _scrollbackLines, 0, SHRT_MAX);
const auto dx = ::base::ClampSub(viewportSize.X, oldDimensions.X);
const short newBufferHeight = ::base::ClampAdd(viewportSize.Y, _scrollbackLines);
til::size bufferSize{ viewportSize.X, newBufferHeight };
COORD bufferSize{ viewportSize.X, newBufferHeight };
// This will be used to determine where the viewport should be in the new buffer.
const auto oldViewportTop = _mutableViewport.Top();
auto newViewportTop = oldViewportTop;
auto newVisibleTop = _VisibleStartIndex();
auto newVisibleTop = ::base::saturated_cast<short>(_VisibleStartIndex());
// If the original buffer had _no_ scroll offset, then we should be at the
// bottom in the new buffer as well. Track that case now.
@@ -336,7 +334,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
oldRows.mutableViewportTop = oldViewportTop;
oldRows.visibleViewportTop = newVisibleTop;
const std::optional oldViewStart{ oldViewportTop };
const std::optional<short> oldViewStart{ oldViewportTop };
RETURN_IF_FAILED(TextBuffer::Reflow(*_mainBuffer.get(),
*newTextBuffer.get(),
_mutableViewport,
@@ -390,7 +388,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
const auto maxRow = std::max(newLastChar.Y, newCursorPos.Y);
const auto proposedTopFromLastLine = maxRow - viewportSize.Y + 1;
const short proposedTopFromLastLine = ::base::ClampAdd(::base::ClampSub(maxRow, viewportSize.Y), 1);
const auto proposedTopFromScrollback = newViewportTop;
auto proposedTop = std::max(proposedTopFromLastLine,
@@ -440,7 +438,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
// Make sure the proposed viewport is within the bounds of the buffer.
// First make sure the top is >=0
proposedTop = std::max(0, proposedTop);
proposedTop = std::max(static_cast<short>(0), proposedTop);
// If the new bottom would be below the bottom of the buffer, then slide the
// top up so that we'll still fit within the buffer.
@@ -459,7 +457,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
// Make sure that we don't scroll past the mutableViewport at the bottom of the buffer
newVisibleTop = std::min(newVisibleTop, _mutableViewport.Top());
// Make sure we don't scroll past the top of the scrollback
newVisibleTop = std::max(newVisibleTop, 0);
newVisibleTop = std::max<short>(newVisibleTop, 0);
// If the old scrolloffset was 0, then we weren't scrolled back at all
// before, and shouldn't be now either.
@@ -562,7 +560,7 @@ bool Terminal::ShouldSendAlternateScroll(const unsigned int uiButton,
// - Given a coord, get the URI at that location
// Arguments:
// - The position
std::wstring Terminal::GetHyperlinkAtPosition(const til::point position)
std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
{
auto attr = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr();
if (attr.IsHyperlink())
@@ -578,8 +576,8 @@ std::wstring Terminal::GetHyperlinkAtPosition(const til::point position)
const auto end = result->stop;
std::wstring uri;
const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start));
const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end));
const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start.to_win32_coord()));
const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end.to_win32_coord()));
for (auto iter = startIter; iter != endIter; ++iter)
{
uri += iter->Chars();
@@ -595,7 +593,7 @@ std::wstring Terminal::GetHyperlinkAtPosition(const til::point position)
// - The position of the text
// Return value:
// - The hyperlink ID
uint16_t Terminal::GetHyperlinkIdAtPosition(const til::point position)
uint16_t Terminal::GetHyperlinkIdAtPosition(const COORD position)
{
return _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr().GetHyperlinkId();
}
@@ -606,9 +604,9 @@ uint16_t Terminal::GetHyperlinkIdAtPosition(const til::point position)
// - The position
// Return value:
// - The interval representing the start and end coordinates
std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const til::point position)
std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const COORD position)
{
const auto results = _patternIntervalTree.findOverlapping({ position.X + 1, position.Y }, position);
const auto results = _patternIntervalTree.findOverlapping(til::point{ position.X + 1, position.Y }, til::point{ position });
if (results.size() > 0)
{
for (const auto& result : results)
@@ -723,14 +721,16 @@ bool Terminal::SendKeyEvent(const WORD vkey,
// Return Value:
// - true if we translated the key event, and it should not be processed any further.
// - false if we did not translate the key, and it should be processed into a character.
bool Terminal::SendMouseEvent(til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
{
// GH#6401: VT applications should be able to receive mouse events from outside the
// terminal buffer. This is likely to happen when the user drags the cursor offscreen.
// We shouldn't throw away perfectly good events when they're offscreen, so we just
// clamp them to be within the range [(0, 0), (W, H)].
_GetMutableViewport().ToOrigin().Clamp(viewportPos);
return _terminalInput->HandleMouse(viewportPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
#pragma warning(suppress : 26496) // analysis can't tell we're assigning through a reference below
auto clampedPos{ viewportPos };
_GetMutableViewport().ToOrigin().Clamp(clampedPos);
return _terminalInput->HandleMouse(til::point{ clampedPos }, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
}
// Method Description:
@@ -757,22 +757,6 @@ bool Terminal::SendCharEvent(const wchar_t ch, const WORD scanCode, const Contro
vkey = _VirtualKeyFromCharacter(ch);
}
// GH#1527: When the user has auto mark prompts enabled, we're going to try
// and heuristically detect if this was the line the prompt was on.
// * If the key was an Enter keypress (Terminal.app also marks ^C keypresses
// as prompts. That's omitted for now.)
// * AND we're not in the alt buffer
//
// Then treat this line like it's a prompt mark.
if (_autoMarkPrompts && vkey == VK_RETURN && !_inAltBuffer())
{
DispatchTypes::ScrollMark mark;
mark.category = DispatchTypes::MarkCategory::Prompt;
// Don't set the color - we'll automatically use the DEFAULT_FOREGROUND
// color for any MarkCategory::Prompt marks without one set.
AddMark(mark);
}
// Unfortunately, the UI doesn't give us both a character down and a
// character up event, only a character received event. So fake sending both
// to the terminal input translator. Unless it's in win32-input-mode, it'll
@@ -805,8 +789,8 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
{
const auto vis = _VisibleStartIndex();
auto invalidate = [=](const PointTree::interval& interval) {
til::point startCoord{ interval.start.x, interval.start.y + vis };
til::point endCoord{ interval.stop.x, interval.stop.y + vis };
COORD startCoord{ gsl::narrow<SHORT>(interval.start.x), gsl::narrow<SHORT>(interval.start.y + vis) };
COORD endCoord{ gsl::narrow<SHORT>(interval.stop.x), gsl::narrow<SHORT>(interval.stop.y + vis) };
_InvalidateFromCoords(startCoord, endCoord);
};
tree.visit_all(invalidate);
@@ -816,30 +800,30 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
// - Given start and end coords, invalidates all the regions between them
// Arguments:
// - The start and end coords
void Terminal::_InvalidateFromCoords(const til::point start, const til::point end)
void Terminal::_InvalidateFromCoords(const COORD start, const COORD end)
{
if (start.Y == end.Y)
{
til::inclusive_rect region{ start.X, start.Y, end.X, end.Y };
SMALL_RECT region{ start.X, start.Y, end.X, end.Y };
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
}
else
{
const auto rowSize = _activeBuffer().GetRowByOffset(0).size();
const auto rowSize = gsl::narrow<SHORT>(_activeBuffer().GetRowByOffset(0).size());
// invalidate the first line
til::inclusive_rect region{ start.X, start.Y, rowSize - 1, start.Y };
SMALL_RECT region{ start.X, start.Y, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(start.Y) };
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
if ((end.Y - start.Y) > 1)
{
// invalidate the lines in between the first and last line
region = til::inclusive_rect{ 0, start.Y + 1, rowSize - 1, end.Y - 1 };
region = SMALL_RECT{ 0, start.Y + 1, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(end.Y - 1) };
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
}
// invalidate the last line
region = til::inclusive_rect{ 0, end.Y, end.X, end.Y };
region = SMALL_RECT{ 0, end.Y, end.X, end.Y };
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
}
}
@@ -984,25 +968,16 @@ WORD Terminal::_TakeVirtualKeyFromLastKeyEvent(const WORD scanCode) noexcept
#endif
}
// Method Description:
// - Get a reference to the the terminal's read/write lock.
// Return Value:
// - a ticket_lock which can be used to manually lock or unlock the terminal.
til::ticket_lock& Terminal::GetReadWriteLock() noexcept
{
return _readWriteLock;
}
Viewport Terminal::_GetMutableViewport() const noexcept
{
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
// viewport's size hasn't been updated yet. In that case, use the
// temporarily stashed _altBufferSize instead.
return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize) :
return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize.to_win32_coord()) :
_mutableViewport;
}
til::CoordType Terminal::GetBufferHeight() const noexcept
short Terminal::GetBufferHeight() const noexcept
{
return _GetMutableViewport().BottomExclusive();
}
@@ -1036,8 +1011,8 @@ Viewport Terminal::_GetVisibleViewport() const noexcept
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
// viewport's size hasn't been updated yet. In that case, use the
// temporarily stashed _altBufferSize instead.
const til::point origin{ 0, _VisibleStartIndex() };
const auto size{ _inAltBuffer() ? _altBufferSize :
const COORD origin{ 0, gsl::narrow<short>(_VisibleStartIndex()) };
const auto size{ _inAltBuffer() ? _altBufferSize.to_win32_coord() :
_mutableViewport.Dimensions() };
return Viewport::FromDimensions(origin,
size);
@@ -1081,7 +1056,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
{
// If "wch" was a surrogate character, we just consumed 2 code units above.
// -> Increment "i" by 1 in that case and thus by 2 in total in this iteration.
proposedCursorPosition.X += cellDistance;
proposedCursorPosition.X += gsl::narrow<SHORT>(cellDistance);
i += inputDistance - 1;
}
else
@@ -1120,7 +1095,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
cursor.EndDeferDrawing();
}
void Terminal::_AdjustCursorPosition(const til::point proposedPosition)
void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
{
#pragma warning(suppress : 26496) // cpp core checks wants this const but it's modified below.
auto proposedCursorPosition = proposedPosition;
@@ -1129,7 +1104,7 @@ void Terminal::_AdjustCursorPosition(const til::point proposedPosition)
// If we're about to scroll past the bottom of the buffer, instead cycle the
// buffer.
til::CoordType rowsPushedOffTopOfBuffer = 0;
SHORT rowsPushedOffTopOfBuffer = 0;
const auto newRows = std::max(0, proposedCursorPosition.Y - bufferSize.Height() + 1);
if (proposedCursorPosition.Y >= bufferSize.Height())
{
@@ -1184,7 +1159,7 @@ void Terminal::_AdjustCursorPosition(const til::point proposedPosition)
// In the alt buffer, we never need to adjust _mutableViewport, which is the viewport of the main buffer.
if (newViewTop != _mutableViewport.Top())
{
_mutableViewport = Viewport::FromDimensions({ 0, newViewTop },
_mutableViewport = Viewport::FromDimensions({ 0, gsl::narrow<short>(newViewTop) },
_mutableViewport.Dimensions());
updatedViewport = true;
}
@@ -1221,21 +1196,10 @@ void Terminal::_AdjustCursorPosition(const til::point proposedPosition)
if (rowsPushedOffTopOfBuffer != 0)
{
if (_scrollMarks.size() > 0)
{
for (auto& mark : _scrollMarks)
{
mark.start.y -= rowsPushedOffTopOfBuffer;
}
_scrollMarks.erase(std::remove_if(_scrollMarks.begin(),
_scrollMarks.end(),
[](const VirtualTerminal::DispatchTypes::ScrollMark& m) { return m.start.y < 0; }),
_scrollMarks.end());
}
// We have to report the delta here because we might have circled the text buffer.
// That didn't change the viewport and therefore the TriggerScroll(void)
// method can't detect the delta on its own.
til::point delta{ 0, -rowsPushedOffTopOfBuffer };
COORD delta{ 0, gsl::narrow_cast<short>(-rowsPushedOffTopOfBuffer) };
_activeBuffer().TriggerScroll(delta);
}
}
@@ -1309,6 +1273,11 @@ void Terminal::SetTitleChangedCallback(std::function<void(std::wstring_view)> pf
_pfnTitleChanged.swap(pfn);
}
void Terminal::SetTabColorChangedCallback(std::function<void(const std::optional<til::color>)> pfn) noexcept
{
_pfnTabColorChanged.swap(pfn);
}
void Terminal::SetCopyToClipboardCallback(std::function<void(std::wstring_view)> pfn) noexcept
{
_pfnCopyToClipboard.swap(pfn);
@@ -1343,15 +1312,6 @@ void Terminal::SetShowWindowCallback(std::function<void(bool)> pfn) noexcept
_pfnShowWindowChanged.swap(pfn);
}
// Method Description:
// - Allows setting a callback for playing MIDI notes.
// Arguments:
// - pfn: a function callback that takes a note number, a velocity level, and a duration
void Terminal::SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept
{
_pfnPlayMidiNote.swap(pfn);
}
// Method Description:
// - Sets the cursor to be currently on. On/Off is tracked independently of
// cursor visibility (hidden/visible). On/off is controlled by the cursor
@@ -1369,7 +1329,7 @@ void Terminal::SetCursorOn(const bool isOn)
bool Terminal::IsCursorBlinkingAllowed() const noexcept
{
const auto& cursor = _activeBuffer().GetCursor();
return !_markMode && cursor.IsBlinkingAllowed();
return cursor.IsBlinkingAllowed();
}
// Method Description:
@@ -1398,18 +1358,10 @@ void Terminal::ClearPatternTree() noexcept
// Method Description:
// - Returns the tab color
// If the starting color exists, its value is preferred
// If the starting color exits, it's value is preferred
const std::optional<til::color> Terminal::GetTabColor() const noexcept
{
if (_startingTabColor.has_value())
{
return _startingTabColor;
}
else
{
const auto tabColor = _renderSettings.GetColorAlias(ColorAlias::FrameBackground);
return tabColor == INVALID_COLOR ? std::nullopt : std::optional<til::color>{ tabColor };
}
return _startingTabColor.has_value() ? _startingTabColor : _tabColor;
}
// Method Description:
@@ -1484,11 +1436,6 @@ void Terminal::ApplyScheme(const Scheme& colorScheme)
_renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, til::color{ colorScheme.CursorColor });
_renderSettings.MakeAdjustedColorArray();
// Tell the control that the scrollbar has somehow changed. Used as a
// workaround to force the control to redraw any scrollbar marks whose color
// may have changed.
_NotifyScrollEvent();
}
bool Terminal::_inAltBuffer() const noexcept
@@ -1516,100 +1463,11 @@ void Terminal::_updateUrlDetection()
}
}
void Terminal::AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark,
const til::point& start,
const til::point& end)
// Method Description:
// - Returns the position of the cursor relative to the active viewport
til::point Terminal::GetViewportRelativeCursorPosition() const noexcept
{
if (_inAltBuffer())
{
return;
}
DispatchTypes::ScrollMark m = mark;
m.start = start;
m.end = end;
_scrollMarks.push_back(m);
// Tell the control that the scrollbar has somehow changed. Used as a
// workaround to force the control to redraw any scrollbar marks
_NotifyScrollEvent();
}
void Terminal::ClearMark()
{
// Look for one where the cursor is, or where the selection is if we have
// one. Any mark that intersects the cursor/selection, on either side
// (inclusive), will get cleared.
const til::point cursor{ _activeBuffer().GetCursor().GetPosition() };
til::point start{ cursor };
til::point end{ cursor };
if (IsSelectionActive())
{
start = til::point{ GetSelectionAnchor() };
end = til::point{ GetSelectionEnd() };
}
_scrollMarks.erase(std::remove_if(_scrollMarks.begin(),
_scrollMarks.end(),
[&start, &end](const auto& m) {
return (m.start >= start && m.start <= end) ||
(m.end >= start && m.end <= end);
}),
_scrollMarks.end());
// Tell the control that the scrollbar has somehow changed. Used as a
// workaround to force the control to redraw any scrollbar marks
_NotifyScrollEvent();
}
void Terminal::ClearAllMarks()
{
_scrollMarks.clear();
// Tell the control that the scrollbar has somehow changed. Used as a
// workaround to force the control to redraw any scrollbar marks
_NotifyScrollEvent();
}
const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark>& Terminal::GetScrollMarks() const
{
// TODO: GH#11000 - when the marks are stored per-buffer, get rid of this.
// We want to return _no_ marks when we're in the alt buffer, to effectively
// hide them. We need to return a reference, so we can't just ctor an empty
// list here just for when we're in the alt buffer.
static std::vector<DispatchTypes::ScrollMark> _altBufferMarks{};
return _inAltBuffer() ? _altBufferMarks : _scrollMarks;
}
til::color Terminal::GetColorForMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) const
{
if (mark.color.has_value())
{
return *mark.color;
}
switch (mark.category)
{
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Prompt:
{
return _renderSettings.GetColorAlias(ColorAlias::DefaultForeground);
}
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Error:
{
return _renderSettings.GetColorTableEntry(TextColor::BRIGHT_RED);
}
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Warning:
{
return _renderSettings.GetColorTableEntry(TextColor::BRIGHT_YELLOW);
}
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Success:
{
return _renderSettings.GetColorTableEntry(TextColor::BRIGHT_GREEN);
}
default:
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Info:
{
return _renderSettings.GetColorAlias(ColorAlias::DefaultForeground);
}
}
const til::point absoluteCursorPosition{ GetCursorPosition() };
const auto viewport{ _GetMutableViewport() };
return absoluteCursorPosition - til::point{ viewport.Origin() };
}

View File

@@ -69,8 +69,8 @@ public:
Terminal& operator=(const Terminal&) = default;
Terminal& operator=(Terminal&&) = default;
void Create(til::size viewportSize,
til::CoordType scrollbackLines,
void Create(COORD viewportSize,
SHORT scrollbackLines,
Microsoft::Console::Render::Renderer& renderer);
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
@@ -84,6 +84,8 @@ public:
bool IsXtermBracketedPasteModeEnabled() const;
std::wstring_view GetWorkingDirectory();
til::point GetViewportRelativeCursorPosition() const noexcept;
// Write comes from the PTY and goes to our parser to be stored in the output buffer
void Write(std::wstring_view stringView);
@@ -92,9 +94,8 @@ public:
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForReading();
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForWriting();
til::ticket_lock& GetReadWriteLock() noexcept;
til::CoordType GetBufferHeight() const noexcept;
short GetBufferHeight() const noexcept;
int ViewStartIndex() const noexcept;
int ViewEndIndex() const noexcept;
@@ -102,11 +103,6 @@ public:
RenderSettings& GetRenderSettings() noexcept { return _renderSettings; };
const RenderSettings& GetRenderSettings() const noexcept { return _renderSettings; };
const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark>& GetScrollMarks() const;
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark,
const til::point& start,
const til::point& end);
#pragma region ITerminalApi
// These methods are defined in TerminalApi.cpp
void PrintString(const std::wstring_view string) override;
@@ -123,36 +119,28 @@ public:
void LineFeed(const bool withReturn) override;
void SetWindowTitle(const std::wstring_view title) override;
CursorType GetUserDefaultCursorStyle() const override;
bool ResizeWindow(const til::CoordType width, const til::CoordType height) override;
bool ResizeWindow(const size_t width, const size_t height) override;
void SetConsoleOutputCP(const unsigned int codepage) override;
unsigned int GetConsoleOutputCP() const override;
void EnableXtermBracketedPasteMode(const bool enabled) override;
void CopyToClipboard(std::wstring_view content) override;
void SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) override;
void SetWorkingDirectory(std::wstring_view uri) override;
void PlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) override;
void ShowWindow(bool showOrHide) override;
void UseAlternateScreenBuffer() override;
void UseMainScreenBuffer() override;
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) override;
bool IsConsolePty() const override;
bool IsVtInputEnabled() const override;
void NotifyAccessibilityChange(const til::rect& changedRect) override;
#pragma endregion
void ClearMark();
void ClearAllMarks();
til::color GetColorForMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) const;
#pragma region ITerminalInput
// These methods are defined in Terminal.cpp
bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
[[nodiscard]] HRESULT UserResize(const til::size viewportSize) noexcept override;
[[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
void UserScrollViewport(const int viewTop) override;
int GetScrollOffset() noexcept override;
@@ -162,14 +150,14 @@ public:
void FocusChanged(const bool focused) noexcept override;
std::wstring GetHyperlinkAtPosition(const til::point position);
uint16_t GetHyperlinkIdAtPosition(const til::point position);
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const til::point position);
std::wstring GetHyperlinkAtPosition(const COORD position);
uint16_t GetHyperlinkIdAtPosition(const COORD position);
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const COORD position);
#pragma endregion
#pragma region IBaseData(base to IRenderData and IUiaData)
Microsoft::Console::Types::Viewport GetViewport() noexcept override;
til::point GetTextBufferEndPosition() const noexcept override;
COORD GetTextBufferEndPosition() const noexcept override;
const TextBuffer& GetTextBuffer() const noexcept override;
const FontInfo& GetFontInfo() const noexcept override;
@@ -179,7 +167,7 @@ public:
#pragma region IRenderData
// These methods are defined in TerminalRenderData.cpp
til::point GetCursorPosition() const noexcept override;
COORD GetCursorPosition() const noexcept override;
bool IsCursorVisible() const noexcept override;
bool IsCursorOn() const noexcept override;
ULONG GetCursorHeight() const noexcept override;
@@ -190,7 +178,7 @@ public:
const bool IsGridLineDrawingAllowed() noexcept override;
const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
const std::vector<size_t> GetPatternId(const til::point location) const noexcept override;
const std::vector<size_t> GetPatternId(const COORD location) const noexcept override;
#pragma endregion
#pragma region IUiaData
@@ -199,23 +187,23 @@ public:
const bool IsSelectionActive() const noexcept override;
const bool IsBlockSelection() const noexcept override;
void ClearSelection() override;
void SelectNewRegion(const til::point coordStart, const til::point coordEnd) override;
const til::point GetSelectionAnchor() const noexcept override;
const til::point GetSelectionEnd() const noexcept override;
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
const COORD GetSelectionAnchor() const noexcept override;
const COORD GetSelectionEnd() const noexcept override;
const std::wstring_view GetConsoleTitle() const noexcept override;
void ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute) override;
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
const bool IsUiaDataInitialized() const noexcept override;
#pragma endregion
void SetWriteInputCallback(std::function<void(std::wstring_view)> pfn) noexcept;
void SetWarningBellCallback(std::function<void()> pfn) noexcept;
void SetTitleChangedCallback(std::function<void(std::wstring_view)> pfn) noexcept;
void SetTabColorChangedCallback(std::function<void(const std::optional<til::color>)> pfn) noexcept;
void SetCopyToClipboardCallback(std::function<void(std::wstring_view)> pfn) noexcept;
void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
void SetCursorPositionChangedCallback(std::function<void()> pfn) noexcept;
void TaskbarProgressChangedCallback(std::function<void()> pfn) noexcept;
void SetShowWindowCallback(std::function<void(bool)> pfn) noexcept;
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
void SetCursorOn(const bool isOn);
bool IsCursorBlinkingAllowed() const noexcept;
@@ -249,17 +237,16 @@ public:
Viewport,
Buffer
};
void MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode);
void SetSelectionAnchor(const til::point position);
void SetSelectionEnd(const til::point position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
void MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode);
void SetSelectionAnchor(const COORD position);
void SetSelectionEnd(const COORD position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
void SetBlockSelection(const bool isEnabled) noexcept;
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods);
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode);
void SelectAll();
bool IsInMarkMode() const;
void ToggleMarkMode();
bool IsInQuickEditMode() const noexcept;
using UpdateSelectionParams = std::optional<std::pair<SelectionDirection, SelectionExpansion>>;
UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const;
static UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey);
const TextBuffer::TextAndColor RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace);
#pragma endregion
@@ -283,9 +270,9 @@ private:
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
std::function<void()> _pfnCursorPositionChanged;
std::function<void(const std::optional<til::color>)> _pfnTabColorChanged;
std::function<void()> _pfnTaskbarProgressChanged;
std::function<void(bool)> _pfnShowWindowChanged;
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
RenderSettings _renderSettings;
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
@@ -293,6 +280,7 @@ private:
std::optional<std::wstring> _title;
std::wstring _startingTitle;
std::optional<til::color> _tabColor;
std::optional<til::color> _startingTabColor;
CursorType _defaultCursorShape;
@@ -302,7 +290,6 @@ private:
bool _suppressApplicationTitle;
bool _bracketedPasteMode;
bool _trimBlockSelection;
bool _autoMarkPrompts;
size_t _taskbarState;
size_t _taskbarProgress;
@@ -316,26 +303,26 @@ private:
FontInfo _fontInfo{ DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false };
#pragma region Text Selection
// a selection is represented as a range between two COORDs (start and end)
// the pivot is the til::point that remains selected when you extend a selection in any direction
// the pivot is the COORD that remains selected when you extend a selection in any direction
// this is particularly useful when a word selection is extended over its starting point
// see TerminalSelection.cpp for more information
struct SelectionAnchors
{
til::point start;
til::point end;
til::point pivot;
COORD start;
COORD end;
COORD pivot;
};
std::optional<SelectionAnchors> _selection;
bool _blockSelection;
std::wstring _wordDelimiters;
SelectionExpansion _multiClickSelectionMode;
bool _markMode;
bool _quickEditMode;
#pragma endregion
std::unique_ptr<TextBuffer> _mainBuffer;
std::unique_ptr<TextBuffer> _altBuffer;
Microsoft::Console::Types::Viewport _mutableViewport;
til::CoordType _scrollbackLines;
SHORT _scrollbackLines;
bool _detectURLs{ false };
til::size _altBufferSize;
@@ -359,7 +346,7 @@ private:
interval_tree::IntervalTree<til::point, size_t> _patternIntervalTree;
void _InvalidatePatternTree(interval_tree::IntervalTree<til::point, size_t>& tree);
void _InvalidateFromCoords(const til::point start, const til::point end);
void _InvalidateFromCoords(const COORD start, const COORD end);
// Since virtual keys are non-zero, you assume that this field is empty/invalid if it is.
struct KeyEventCodes
@@ -369,8 +356,6 @@ private:
};
std::optional<KeyEventCodes> _lastKeyEventCodes;
std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark> _scrollMarks;
static WORD _ScanCodeFromVirtualKey(const WORD vkey) noexcept;
static WORD _VirtualKeyFromScanCode(const WORD scanCode) noexcept;
static WORD _VirtualKeyFromCharacter(const wchar_t ch) noexcept;
@@ -387,7 +372,7 @@ private:
void _WriteBuffer(const std::wstring_view& stringView);
void _AdjustCursorPosition(const til::point proposedPosition);
void _AdjustCursorPosition(const COORD proposedPosition);
void _NotifyScrollEvent() noexcept;
@@ -399,14 +384,14 @@ private:
#pragma region TextSelection
// These methods are defined in TerminalSelection.cpp
std::vector<til::inclusive_rect> _GetSelectionRects() const noexcept;
std::pair<til::point, til::point> _PivotSelection(const til::point targetPos, bool& targetStart) const;
std::pair<til::point, til::point> _ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const;
til::point _ConvertToBufferCell(const til::point viewportPos) const;
void _MoveByChar(SelectionDirection direction, til::point& pos);
void _MoveByWord(SelectionDirection direction, til::point& pos);
void _MoveByViewport(SelectionDirection direction, til::point& pos);
void _MoveByBuffer(SelectionDirection direction, til::point& pos);
std::vector<SMALL_RECT> _GetSelectionRects() const noexcept;
std::pair<COORD, COORD> _PivotSelection(const COORD targetPos, bool& targetStart) const;
std::pair<COORD, COORD> _ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const;
COORD _ConvertToBufferCell(const COORD viewportPos) const;
void _MoveByChar(SelectionDirection direction, COORD& pos);
void _MoveByWord(SelectionDirection direction, COORD& pos);
void _MoveByViewport(SelectionDirection direction, COORD& pos);
void _MoveByBuffer(SelectionDirection direction, COORD& pos);
#pragma endregion
#ifdef UNIT_TESTING

View File

@@ -45,7 +45,7 @@ void Terminal::SetViewportPosition(const til::point position)
if (!_inAltBuffer())
{
const auto dimensions = _GetMutableViewport().Dimensions();
_mutableViewport = Viewport::FromDimensions(position, dimensions);
_mutableViewport = Viewport::FromDimensions(position.to_win32_coord(), dimensions);
Terminal::_NotifyScrollEvent();
}
}
@@ -106,7 +106,7 @@ CursorType Terminal::GetUserDefaultCursorStyle() const
return _defaultCursorShape;
}
bool Terminal::ResizeWindow(const til::CoordType /*width*/, const til::CoordType /*height*/)
bool Terminal::ResizeWindow(const size_t /*width*/, const size_t /*height*/)
{
// TODO: This will be needed to support various resizing sequences. See also GH#1860.
return false;
@@ -188,15 +188,10 @@ void Terminal::SetWorkingDirectory(std::wstring_view uri)
_workingDirectory = uri;
}
void Terminal::PlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration)
{
_pfnPlayMidiNote(noteNumber, velocity, duration);
}
void Terminal::UseAlternateScreenBuffer()
{
// the new alt buffer is exactly the size of the viewport.
_altBufferSize = _mutableViewport.Dimensions();
_altBufferSize = til::size{ _mutableViewport.Dimensions() };
const auto cursorSize = _mainBuffer->GetCursor().GetSize();
@@ -204,7 +199,7 @@ void Terminal::UseAlternateScreenBuffer()
_mainBuffer->ClearPatternRecognizers();
// Create a new alt buffer
_altBuffer = std::make_unique<TextBuffer>(_altBufferSize,
_altBuffer = std::make_unique<TextBuffer>(_altBufferSize.to_win32_coord(),
TextAttribute{},
cursorSize,
true,
@@ -275,7 +270,7 @@ void Terminal::UseMainScreenBuffer()
if (_deferredResize.has_value())
{
LOG_IF_FAILED(UserResize(_deferredResize.value()));
LOG_IF_FAILED(UserResize(_deferredResize.value().to_win32_coord()));
_deferredResize = std::nullopt;
}
@@ -298,12 +293,6 @@ void Terminal::UseMainScreenBuffer()
CATCH_LOG();
}
void Terminal::AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark)
{
const til::point cursorPos{ _activeBuffer().GetCursor().GetPosition() };
AddMark(mark, cursorPos, cursorPos);
}
// Method Description:
// - Reacts to a client asking us to show or hide the window.
// Arguments:

View File

@@ -43,9 +43,9 @@ using namespace Microsoft::Terminal::Core;
// - Helper to determine the selected region of the buffer. Used for rendering.
// Return Value:
// - A vector of rectangles representing the regions to select, line by line. They are absolute coordinates relative to the buffer origin.
std::vector<til::inclusive_rect> Terminal::_GetSelectionRects() const noexcept
std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const noexcept
{
std::vector<til::inclusive_rect> result;
std::vector<SMALL_RECT> result;
if (!IsSelectionActive())
{
@@ -66,7 +66,7 @@ std::vector<til::inclusive_rect> Terminal::_GetSelectionRects() const noexcept
// - None
// Return Value:
// - None
const til::point Terminal::GetSelectionAnchor() const noexcept
const COORD Terminal::GetSelectionAnchor() const noexcept
{
return _selection->start;
}
@@ -77,7 +77,7 @@ const til::point Terminal::GetSelectionAnchor() const noexcept
// - None
// Return Value:
// - None
const til::point Terminal::GetSelectionEnd() const noexcept
const COORD Terminal::GetSelectionEnd() const noexcept
{
return _selection->end;
}
@@ -96,12 +96,17 @@ const bool Terminal::IsBlockSelection() const noexcept
return _blockSelection;
}
bool Terminal::IsInQuickEditMode() const noexcept
{
return _quickEditMode;
}
// Method Description:
// - Perform a multi-click selection at viewportPos expanding according to the expansionMode
// Arguments:
// - viewportPos: the (x,y) coordinate on the visible viewport
// - expansionMode: the SelectionExpansion to dictate the boundaries of the selection anchors
void Terminal::MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode)
void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode)
{
// set the selection pivot to expand the selection using SetSelectionEnd()
_selection = SelectionAnchors{};
@@ -119,7 +124,7 @@ void Terminal::MultiClickSelection(const til::point viewportPos, SelectionExpans
// - Record the position of the beginning of a selection
// Arguments:
// - position: the (x,y) coordinate on the visible viewport
void Terminal::SetSelectionAnchor(const til::point viewportPos)
void Terminal::SetSelectionAnchor(const COORD viewportPos)
{
_selection = SelectionAnchors{};
_selection->pivot = _ConvertToBufferCell(viewportPos);
@@ -136,7 +141,7 @@ void Terminal::SetSelectionAnchor(const til::point viewportPos)
// Arguments:
// - viewportPos: the (x,y) coordinate on the visible viewport
// - newExpansionMode: overwrites the _multiClickSelectionMode for this function call. Used for ShiftClick
void Terminal::SetSelectionEnd(const til::point viewportPos, std::optional<SelectionExpansion> newExpansionMode)
void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionExpansion> newExpansionMode)
{
if (!_selection.has_value())
{
@@ -180,7 +185,7 @@ void Terminal::SetSelectionEnd(const til::point viewportPos, std::optional<Selec
// - targetStart: if true, target will be the new start. Otherwise, target will be the new end.
// Return Value:
// - the new start/end for a selection
std::pair<til::point, til::point> Terminal::_PivotSelection(const til::point targetPos, bool& targetStart) const
std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& targetStart) const
{
if (targetStart = _activeBuffer().GetSize().CompareInBounds(targetPos, _selection->pivot) <= 0)
{
@@ -202,7 +207,7 @@ std::pair<til::point, til::point> Terminal::_PivotSelection(const til::point tar
// - anchors: a pair of selection anchors representing a desired selection
// Return Value:
// - the new start/end for a selection
std::pair<til::point, til::point> Terminal::_ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const
std::pair<COORD, COORD> Terminal::_ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const
{
auto start = anchors.first;
auto end = anchors.second;
@@ -235,41 +240,13 @@ void Terminal::SetBlockSelection(const bool isEnabled) noexcept
_blockSelection = isEnabled;
}
bool Terminal::IsInMarkMode() const
Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey)
{
return _markMode;
}
void Terminal::ToggleMarkMode()
{
if (_markMode)
{
// Exit Mark Mode
ClearSelection();
}
else
{
// Enter Mark Mode
// NOTE: directly set cursor state. We already should have locked before calling this function.
_activeBuffer().GetCursor().SetIsOn(false);
const auto cursorPos{ _activeBuffer().GetCursor().GetPosition() };
_selection = SelectionAnchors{};
_selection->start = cursorPos;
_selection->end = cursorPos;
_selection->pivot = cursorPos;
_markMode = true;
_blockSelection = false;
}
}
Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const
{
if ((_markMode || mods.IsShiftPressed()) && !mods.IsAltPressed())
if (mods.IsShiftPressed() && !mods.IsAltPressed())
{
if (mods.IsCtrlPressed())
{
// Ctrl + Shift + _
// (Mark Mode) Ctrl + _
switch (vkey)
{
case VK_LEFT:
@@ -285,7 +262,6 @@ Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams
else
{
// Shift + _
// (Mark Mode) Just the vkeys
switch (vkey)
{
case VK_HOME:
@@ -310,22 +286,14 @@ Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams
return std::nullopt;
}
// Method Description:
// - updates the selection endpoints based on a direction and expansion mode. Primarily used for keyboard selection.
// Arguments:
// - direction: the direction to move the selection endpoint in
// - mode: the type of movement to be performed (i.e. move by word)
// - mods: the key modifiers pressed when performing this update
void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods)
void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion mode)
{
// 1. Figure out which endpoint to update
// If we're in mark mode, shift dictates whether you are moving the end or not.
// Otherwise, we're updating an existing selection, so one of the endpoints is the pivot,
// signifying that the other endpoint is the one we want to move.
const auto movingEnd{ _markMode ? mods.IsShiftPressed() : _selection->start == _selection->pivot };
// One of the endpoints is the pivot, signifying that the other endpoint is the one we want to move.
const auto movingEnd{ _selection->start == _selection->pivot };
auto targetPos{ movingEnd ? _selection->end : _selection->start };
// 2. Perform the movement
// 2 Perform the movement
switch (mode)
{
case SelectionExpansion::Char:
@@ -344,28 +312,14 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion
// 3. Actually modify the selection
// NOTE: targetStart doesn't matter here
if (_markMode)
{
// [Mark Mode]
// - moveSelectionEnd --> just move end (i.e. shift + arrow keys)
// - !moveSelectionEnd --> move all three (i.e. just use arrow keys)
_selection->end = targetPos;
if (!movingEnd)
{
_selection->start = targetPos;
_selection->pivot = targetPos;
}
}
else
{
auto targetStart = false;
std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart);
}
auto targetStart = false;
_quickEditMode = true;
std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart);
// 4. Scroll (if necessary)
if (const auto viewport = _GetVisibleViewport(); !viewport.IsInBounds(targetPos))
if (const auto visibleViewport = _GetVisibleViewport(); !visibleViewport.IsInBounds(targetPos))
{
if (const auto amtAboveView = viewport.Top() - targetPos.Y; amtAboveView > 0)
if (const auto amtAboveView = visibleViewport.Top() - targetPos.Y; amtAboveView > 0)
{
// anchor is above visible viewport, scroll by that amount
_scrollOffset += amtAboveView;
@@ -373,7 +327,7 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion
else
{
// anchor is below visible viewport, scroll by that amount
const auto amtBelowView = targetPos.Y - viewport.BottomInclusive();
const auto amtBelowView = targetPos.Y - visibleViewport.BottomInclusive();
_scrollOffset -= amtBelowView;
}
_NotifyScrollEvent();
@@ -390,39 +344,41 @@ void Terminal::SelectAll()
_selection->pivot = _selection->end;
}
void Terminal::_MoveByChar(SelectionDirection direction, til::point& pos)
void Terminal::_MoveByChar(SelectionDirection direction, COORD& pos)
{
switch (direction)
{
case SelectionDirection::Left:
_activeBuffer().GetSize().DecrementInBounds(pos);
pos = _activeBuffer().GetGlyphStart(pos);
pos = _activeBuffer().GetGlyphStart(til::point{ pos }).to_win32_coord();
break;
case SelectionDirection::Right:
_activeBuffer().GetSize().IncrementInBounds(pos);
pos = _activeBuffer().GetGlyphEnd(pos);
pos = _activeBuffer().GetGlyphEnd(til::point{ pos }).to_win32_coord();
break;
case SelectionDirection::Up:
{
const auto bufferSize{ _activeBuffer().GetSize() };
pos = { pos.X, std::clamp(pos.Y - 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
const auto newY{ base::ClampSub<short, short>(pos.Y, 1).RawValue() };
pos = newY < bufferSize.Top() ? bufferSize.Origin() : COORD{ pos.X, newY };
break;
}
case SelectionDirection::Down:
{
const auto bufferSize{ _activeBuffer().GetSize() };
pos = { pos.X, std::clamp(pos.Y + 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
const auto mutableBottom{ _GetMutableViewport().BottomInclusive() };
const auto newY{ base::ClampAdd<short, short>(pos.Y, 1).RawValue() };
pos = newY > mutableBottom ? COORD{ bufferSize.RightInclusive(), mutableBottom } : COORD{ pos.X, newY };
break;
}
}
}
void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
{
switch (direction)
{
case SelectionDirection::Left:
{
const auto wordStartPos{ _activeBuffer().GetWordStart(pos, _wordDelimiters) };
if (_activeBuffer().GetSize().CompareInBounds(_selection->pivot, pos) < 0)
{
@@ -443,9 +399,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
pos = wordStartPos;
}
break;
}
case SelectionDirection::Right:
{
const auto wordEndPos{ _activeBuffer().GetWordEnd(pos, _wordDelimiters) };
if (_activeBuffer().GetSize().CompareInBounds(pos, _selection->pivot) < 0)
{
@@ -466,7 +420,6 @@ void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
pos = wordEndPos;
}
break;
}
case SelectionDirection::Up:
_MoveByChar(direction, pos);
pos = _activeBuffer().GetWordStart(pos, _wordDelimiters);
@@ -478,7 +431,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
}
}
void Terminal::_MoveByViewport(SelectionDirection direction, til::point& pos)
void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos)
{
const auto bufferSize{ _activeBuffer().GetSize() };
switch (direction)
@@ -492,22 +445,22 @@ void Terminal::_MoveByViewport(SelectionDirection direction, til::point& pos)
case SelectionDirection::Up:
{
const auto viewportHeight{ _GetMutableViewport().Height() };
const auto newY{ pos.Y - viewportHeight };
pos = newY < bufferSize.Top() ? bufferSize.Origin() : til::point{ pos.X, newY };
const auto newY{ base::ClampSub<short, short>(pos.Y, viewportHeight) };
pos = newY < bufferSize.Top() ? bufferSize.Origin() : COORD{ pos.X, newY };
break;
}
case SelectionDirection::Down:
{
const auto viewportHeight{ _GetMutableViewport().Height() };
const auto mutableBottom{ _GetMutableViewport().BottomInclusive() };
const auto newY{ pos.Y + viewportHeight };
pos = newY > mutableBottom ? til::point{ bufferSize.RightInclusive(), mutableBottom } : til::point{ pos.X, newY };
const auto newY{ base::ClampAdd<short, short>(pos.Y, viewportHeight) };
pos = newY > mutableBottom ? COORD{ bufferSize.RightInclusive(), mutableBottom } : COORD{ pos.X, newY };
break;
}
}
}
void Terminal::_MoveByBuffer(SelectionDirection direction, til::point& pos)
void Terminal::_MoveByBuffer(SelectionDirection direction, COORD& pos)
{
const auto bufferSize{ _activeBuffer().GetSize() };
switch (direction)
@@ -529,7 +482,7 @@ void Terminal::_MoveByBuffer(SelectionDirection direction, til::point& pos)
void Terminal::ClearSelection()
{
_selection = std::nullopt;
_markMode = false;
_quickEditMode = false;
}
// Method Description:
@@ -564,10 +517,10 @@ const TextBuffer::TextAndColor Terminal::RetrieveSelectedTextFromBuffer(bool sin
// - viewportPos: a coordinate on the viewport
// Return Value:
// - the corresponding location on the buffer
til::point Terminal::_ConvertToBufferCell(const til::point viewportPos) const
COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
{
const auto yPos = _VisibleStartIndex() + viewportPos.Y;
til::point bufferPos = { viewportPos.X, yPos };
const auto yPos = base::ClampedNumeric<short>(_VisibleStartIndex()) + viewportPos.Y;
COORD bufferPos = { viewportPos.X, yPos };
_activeBuffer().GetSize().Clamp(bufferPos);
return bufferPos;
}
@@ -579,7 +532,7 @@ til::point Terminal::_ConvertToBufferCell(const til::point viewportPos) const
// - coordSelectionStart - Not used
// - coordSelectionEnd - Not used
// - attr - Not used.
void Terminal::ColorSelection(const til::point, const til::point, const TextAttribute)
void Terminal::ColorSelection(const COORD, const COORD, const TextAttribute)
{
THROW_HR(E_NOTIMPL);
}

View File

@@ -14,12 +14,13 @@ Viewport Terminal::GetViewport() noexcept
return _GetVisibleViewport();
}
til::point Terminal::GetTextBufferEndPosition() const noexcept
COORD Terminal::GetTextBufferEndPosition() const noexcept
{
// We use the end line of mutableViewport as the end
// of the text buffer, it always moves with the written
// text
return { _GetMutableViewport().Width() - 1, ViewEndIndex() };
COORD endPosition{ _GetMutableViewport().Width() - 1, gsl::narrow<short>(ViewEndIndex()) };
return endPosition;
}
const TextBuffer& Terminal::GetTextBuffer() const noexcept
@@ -37,7 +38,7 @@ void Terminal::SetFontInfo(const FontInfo& fontInfo)
_fontInfo = fontInfo;
}
til::point Terminal::GetCursorPosition() const noexcept
COORD Terminal::GetCursorPosition() const noexcept
{
const auto& cursor = _activeBuffer().GetCursor();
return cursor.GetPosition();
@@ -103,10 +104,10 @@ const std::wstring Microsoft::Terminal::Core::Terminal::GetHyperlinkCustomId(uin
// - The location
// Return value:
// - The pattern IDs of the location
const std::vector<size_t> Terminal::GetPatternId(const til::point location) const noexcept
const std::vector<size_t> Terminal::GetPatternId(const COORD location) const noexcept
{
// Look through our interval tree for this location
const auto intervals = _patternIntervalTree.findOverlapping({ location.X + 1, location.Y }, location);
const auto intervals = _patternIntervalTree.findOverlapping(til::point{ location.X + 1, location.Y }, til::point{ location });
if (intervals.size() == 0)
{
return {};
@@ -146,7 +147,7 @@ catch (...)
return {};
}
void Terminal::SelectNewRegion(const til::point coordStart, const til::point coordEnd)
void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
{
#pragma warning(push)
#pragma warning(disable : 26496) // cpp core checks wants these const, but they're decremented below.
@@ -177,8 +178,8 @@ void Terminal::SelectNewRegion(const til::point coordStart, const til::point coo
_NotifyScrollEvent();
}
realCoordStart.Y -= _VisibleStartIndex();
realCoordEnd.Y -= _VisibleStartIndex();
realCoordStart.Y -= gsl::narrow<short>(_VisibleStartIndex());
realCoordEnd.Y -= gsl::narrow<short>(_VisibleStartIndex());
SetSelectionAnchor(realCoordStart);
SetSelectionEnd(realCoordEnd, SelectionExpansion::Char);

View File

@@ -36,22 +36,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
static constexpr std::wstring_view SelectionBackgroundColorTag{ L"SelectionBackground" };
static const std::array<hstring, 16> TableColorNames = {
RS_(L"ColorScheme_Black/Header"),
RS_(L"ColorScheme_Red/Header"),
RS_(L"ColorScheme_Green/Header"),
RS_(L"ColorScheme_Yellow/Header"),
RS_(L"ColorScheme_Blue/Header"),
RS_(L"ColorScheme_Purple/Header"),
RS_(L"ColorScheme_Cyan/Header"),
RS_(L"ColorScheme_White/Header"),
RS_(L"ColorScheme_BrightBlack/Header"),
RS_(L"ColorScheme_BrightRed/Header"),
RS_(L"ColorScheme_BrightGreen/Header"),
RS_(L"ColorScheme_BrightYellow/Header"),
RS_(L"ColorScheme_BrightBlue/Header"),
RS_(L"ColorScheme_BrightPurple/Header"),
RS_(L"ColorScheme_BrightCyan/Header"),
RS_(L"ColorScheme_BrightWhite/Header")
RS_(L"ColorScheme_Black/Text"),
RS_(L"ColorScheme_Red/Text"),
RS_(L"ColorScheme_Green/Text"),
RS_(L"ColorScheme_Yellow/Text"),
RS_(L"ColorScheme_Blue/Text"),
RS_(L"ColorScheme_Purple/Text"),
RS_(L"ColorScheme_Cyan/Text"),
RS_(L"ColorScheme_White/Text"),
RS_(L"ColorScheme_BrightBlack/Text"),
RS_(L"ColorScheme_BrightRed/Text"),
RS_(L"ColorScheme_BrightGreen/Text"),
RS_(L"ColorScheme_BrightYellow/Text"),
RS_(L"ColorScheme_BrightBlue/Text"),
RS_(L"ColorScheme_BrightPurple/Text"),
RS_(L"ColorScheme_BrightCyan/Text"),
RS_(L"ColorScheme_BrightWhite/Text")
};
static const std::array<std::wstring, 9> InBoxSchemes = {
@@ -187,7 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
if (std::find(std::begin(InBoxSchemes), std::end(InBoxSchemes), schemeName) != std::end(InBoxSchemes))
{
// load disclaimer for in-box profiles
disclaimer = RS_(L"ColorScheme_DeleteButtonDisclaimerInBox");
disclaimer = RS_(L"ColorScheme_DeleteButtonDisclaimerInBox/Text");
}
DeleteButtonDisclaimer().Text(disclaimer);

View File

@@ -93,7 +93,7 @@
<Grid.RowDefinitions>
<!-- profile name -->
<RowDefinition Height="20" />
<RowDefinition Height="*" />
<!-- author and version -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
@@ -109,25 +109,20 @@
<TextBlock Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Height="20"
AutomationProperties.AccessibilityView="Raw"
Text="{x:Bind Name}" />
<TextBlock Grid.Row="1"
Grid.Column="1"
Height="20"
AutomationProperties.AccessibilityView="Raw"
Style="{ThemeResource SecondaryTextBlockStyle}"
Text="{x:Bind Author}"
Visibility="{x:Bind local:Converters.StringNotEmptyToVisibility(Author)}" />
Text="{x:Bind Author}" />
<TextBlock Grid.Row="1"
Grid.Column="2"
Height="20"
AutomationProperties.AccessibilityView="Raw"
Style="{ThemeResource SecondaryTextBlockStyle}"
Text="{x:Bind Version}"
Visibility="{x:Bind local:Converters.StringNotEmptyToVisibility(Version)}" />
Text="{x:Bind Version}" />
</Grid>
</DataTemplate>

View File

@@ -179,7 +179,7 @@
</Frame>
<!-- Explicitly set the background color on grid to prevent the navigation animation from overflowing it -->
<Grid Grid.Row="1"
Height="55"
Height="80"
BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}"
BorderThickness="0,1,0,0">
<Grid.ColumnDefinitions>
@@ -196,14 +196,14 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
Orientation="Horizontal">
<Button x:Name="SaveButton"
x:Uid="Settings_SaveSettingsButton"
Click="SaveButton_Click"
Style="{StaticResource AccentButtonStyle}" />
<Button x:Name="ResetButton"
x:Uid="Settings_ResetSettingsButton"
Margin="10,0,0,0"
Click="ResetButton_Click" />
<Button x:Name="SaveButton"
x:Uid="Settings_SaveSettingsButton"
Margin="10,0,0,0"
Click="SaveButton_Click"
Style="{StaticResource AccentButtonStyle}" />
</StackPanel>
</Grid>
</Grid>

View File

@@ -34,6 +34,7 @@
</PropertyGroup>
<PropertyGroup Label="NuGet Dependencies">
<TerminalCppWinrt>true</TerminalCppWinrt>
<TerminalMUX>true</TerminalMUX>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
@@ -353,12 +354,5 @@
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\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.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -8,10 +8,11 @@
using namespace ::winrt::Microsoft::Terminal::TerminalConnection;
using namespace ::winrt::Windows::Foundation;
static constexpr std::wstring_view PreviewText{ L"Windows Terminal\r\nCopyright (c) Microsoft Corporation\r\n\nC:\\Windows\\Terminal> " };
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
PreviewConnection::PreviewConnection(const winrt::hstring previewString) noexcept :
_previewString{ previewString }
PreviewConnection::PreviewConnection() noexcept
{
}
@@ -20,7 +21,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// First send a sequence to disable cursor blinking
_TerminalOutputHandlers(L"\x1b[?12l");
// Send the preview text
_TerminalOutputHandlers(_previewString);
_TerminalOutputHandlers(PreviewText);
}
void PreviewConnection::Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) noexcept

View File

@@ -19,7 +19,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
class PreviewConnection : public winrt::implements<PreviewConnection, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection>
{
public:
PreviewConnection(const winrt::hstring previewString) noexcept;
PreviewConnection() noexcept;
void Initialize(const Windows::Foundation::Collections::ValueSet& settings) noexcept;
void Start() noexcept;
@@ -31,8 +31,5 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
WINRT_CALLBACK(TerminalOutput, winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputHandler);
TYPED_EVENT(StateChanged, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection, IInspectable);
private:
const winrt::hstring _previewString;
};
}

View File

@@ -14,12 +14,10 @@
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Navigation;
static const winrt::hstring PreviewText{ L"Windows Terminal\r\nCopyright (c) Microsoft Corporation\r\n\nC:\\Windows\\Terminal> " };
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Profiles_Appearance::Profiles_Appearance() :
_previewControl{ Control::TermControl(Model::TerminalSettings{}, nullptr, make<PreviewConnection>(PreviewText)) }
_previewControl{ Control::TermControl(Model::TerminalSettings{}, nullptr, make<PreviewConnection>()) }
{
InitializeComponent();

View File

@@ -139,43 +139,43 @@
<value>Background</value>
<comment>This is the header for a control that lets the user select the background color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_Black.Header" xml:space="preserve">
<data name="ColorScheme_Black.Text" xml:space="preserve">
<value>Black</value>
<comment>This is the header for a control that lets the user select the black color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_Blue.Header" xml:space="preserve">
<data name="ColorScheme_Blue.Text" xml:space="preserve">
<value>Blue</value>
<comment>This is the header for a control that lets the user select the blue color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightBlack.Header" xml:space="preserve">
<data name="ColorScheme_BrightBlack.Text" xml:space="preserve">
<value>Bright black</value>
<comment>This is the header for a control that lets the user select the bright black color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightBlue.Header" xml:space="preserve">
<data name="ColorScheme_BrightBlue.Text" xml:space="preserve">
<value>Bright blue</value>
<comment>This is the header for a control that lets the user select the bright blue color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightCyan.Header" xml:space="preserve">
<data name="ColorScheme_BrightCyan.Text" xml:space="preserve">
<value>Bright cyan</value>
<comment>This is the header for a control that lets the user select the bright cyan color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightGreen.Header" xml:space="preserve">
<data name="ColorScheme_BrightGreen.Text" xml:space="preserve">
<value>Bright green</value>
<comment>This is the header for a control that lets the user select the bright green color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightPurple.Header" xml:space="preserve">
<data name="ColorScheme_BrightPurple.Text" xml:space="preserve">
<value>Bright purple</value>
<comment>This is the header for a control that lets the user select the bright purple color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightRed.Header" xml:space="preserve">
<data name="ColorScheme_BrightRed.Text" xml:space="preserve">
<value>Bright red</value>
<comment>This is the header for a control that lets the user select the bright red color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightWhite.Header" xml:space="preserve">
<data name="ColorScheme_BrightWhite.Text" xml:space="preserve">
<value>Bright white</value>
<comment>This is the header for a control that lets the user select the bright white color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_BrightYellow.Header" xml:space="preserve">
<data name="ColorScheme_BrightYellow.Text" xml:space="preserve">
<value>Bright yellow</value>
<comment>This is the header for a control that lets the user select the bright yellow color for text displayed on the screen.</comment>
</data>
@@ -183,7 +183,7 @@
<value>Cursor color</value>
<comment>This is the header for a control that lets the user select the text cursor's color displayed on the screen.</comment>
</data>
<data name="ColorScheme_Cyan.Header" xml:space="preserve">
<data name="ColorScheme_Cyan.Text" xml:space="preserve">
<value>Cyan</value>
<comment>This is the header for a control that lets the user select the cyan color for text displayed on the screen.</comment>
</data>
@@ -191,11 +191,11 @@
<value>Foreground</value>
<comment>This is the header for a control that lets the user select the foreground color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_Green.Header" xml:space="preserve">
<data name="ColorScheme_Green.Text" xml:space="preserve">
<value>Green</value>
<comment>This is the header for a control that lets the user select the green color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_Purple.Header" xml:space="preserve">
<data name="ColorScheme_Purple.Text" xml:space="preserve">
<value>Purple</value>
<comment>This is the header for a control that lets the user select the purple color for text displayed on the screen.</comment>
</data>
@@ -203,15 +203,15 @@
<value>Selection background</value>
<comment>This is the header for a control that lets the user select the background color for selected text displayed on the screen.</comment>
</data>
<data name="ColorScheme_Red.Header" xml:space="preserve">
<data name="ColorScheme_Red.Text" xml:space="preserve">
<value>Red</value>
<comment>This is the header for a control that lets the user select the red color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_White.Header" xml:space="preserve">
<data name="ColorScheme_White.Text" xml:space="preserve">
<value>White</value>
<comment>This is the header for a control that lets the user select the white color for text displayed on the screen.</comment>
</data>
<data name="ColorScheme_Yellow.Header" xml:space="preserve">
<data name="ColorScheme_Yellow.Text" xml:space="preserve">
<value>Yellow</value>
<comment>This is the header for a control that lets the user select the yellow color for text displayed on the screen.</comment>
</data>
@@ -1194,7 +1194,7 @@
<value>Rename</value>
<comment>Text label for a button that can be used to begin the renaming process.</comment>
</data>
<data name="ColorScheme_DeleteButtonDisclaimerInBox" xml:space="preserve">
<data name="ColorScheme_DeleteButtonDisclaimerInBox.Text" xml:space="preserve">
<value>This color scheme cannot be deleted or renamed because it is included by default.</value>
<comment>Disclaimer presented next to the delete button when it is disabled.</comment>
</data>

View File

@@ -39,10 +39,6 @@ static constexpr std::string_view ScrollUpKey{ "scrollUp" };
static constexpr std::string_view ScrollUpPageKey{ "scrollUpPage" };
static constexpr std::string_view ScrollToTopKey{ "scrollToTop" };
static constexpr std::string_view ScrollToBottomKey{ "scrollToBottom" };
static constexpr std::string_view ScrollToMarkKey{ "scrollToMark" };
static constexpr std::string_view AddMarkKey{ "addMark" };
static constexpr std::string_view ClearMarkKey{ "clearMark" };
static constexpr std::string_view ClearAllMarksKey{ "clearAllMarks" };
static constexpr std::string_view SendInputKey{ "sendInput" };
static constexpr std::string_view SetColorSchemeKey{ "setColorScheme" };
static constexpr std::string_view SetTabColorKey{ "setTabColor" };
@@ -80,8 +76,6 @@ static constexpr std::string_view QuitKey{ "quit" };
static constexpr std::string_view AdjustOpacityKey{ "adjustOpacity" };
static constexpr std::string_view RestoreLastClosedKey{ "restoreLastClosed" };
static constexpr std::string_view SelectAllKey{ "selectAll" };
static constexpr std::string_view MarkModeKey{ "markMode" };
static constexpr std::string_view ToggleBlockSelectionKey{ "toggleBlockSelection" };
static constexpr std::string_view ActionKey{ "action" };
@@ -358,10 +352,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::ScrollUpPage, RS_(L"ScrollUpPageCommandKey") },
{ ShortcutAction::ScrollToTop, RS_(L"ScrollToTopCommandKey") },
{ ShortcutAction::ScrollToBottom, RS_(L"ScrollToBottomCommandKey") },
{ ShortcutAction::ScrollToMark, RS_(L"ScrollToPreviousMarkCommandKey") },
{ ShortcutAction::AddMark, RS_(L"AddMarkCommandKey") },
{ ShortcutAction::ClearMark, RS_(L"ClearMarkCommandKey") },
{ ShortcutAction::ClearAllMarks, RS_(L"ClearAllMarksCommandKey") },
{ ShortcutAction::SendInput, L"" },
{ ShortcutAction::SetColorScheme, L"" },
{ ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") },
@@ -398,8 +388,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::AdjustOpacity, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::RestoreLastClosed, RS_(L"RestoreLastClosedCommandKey") },
{ ShortcutAction::SelectAll, RS_(L"SelectAllCommandKey") },
{ ShortcutAction::MarkMode, RS_(L"MarkModeCommandKey") },
{ ShortcutAction::ToggleBlockSelection, RS_(L"ToggleBlockSelectionCommandKey") },
};
}();

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