mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
Compare commits
18 Commits
dev/migrie
...
v0.5.2761.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b22f77b76d | ||
|
|
e035c8fe93 | ||
|
|
5b33c6692b | ||
|
|
42e281deed | ||
|
|
f4e19e07ab | ||
|
|
d85689c1a8 | ||
|
|
c0ee499c71 | ||
|
|
3bae3c102a | ||
|
|
b61f1d3aea | ||
|
|
776b9a5103 | ||
|
|
f081a95db0 | ||
|
|
9461df9fa3 | ||
|
|
a5a8b41303 | ||
|
|
8195efa225 | ||
|
|
d745063feb | ||
|
|
495a29cc3e | ||
|
|
906c6e7882 | ||
|
|
88d7502c73 |
@@ -54,6 +54,14 @@ steps:
|
||||
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'Source Index PDBs'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
errorActionPreference: silentlyContinue
|
||||
|
||||
- task: VSTest@2
|
||||
displayName: 'Run Unit Tests'
|
||||
inputs:
|
||||
@@ -81,7 +89,7 @@ steps:
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
|
||||
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy *.appx/*.msix to Artifacts (Non-PR builds only)'
|
||||
inputs:
|
||||
@@ -101,3 +109,4 @@ steps:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)/appx'
|
||||
ArtifactName: 'appx-$(BuildConfiguration)'
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
|
||||
85
build/scripts/Index-Pdbs.ps1
Normal file
85
build/scripts/Index-Pdbs.ps1
Normal file
@@ -0,0 +1,85 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true, Position=0)][string]$SearchDir,
|
||||
[Parameter(Mandatory=$true, Position=1)][string]$SourceRoot,
|
||||
[Parameter(Mandatory=$true, Position=2)][string]$CommitId,
|
||||
[string]$Organization = "microsoft",
|
||||
[string]$Repo = "terminal",
|
||||
[switch]$recursive
|
||||
)
|
||||
|
||||
$debuggerPath = (Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" -name WindowsDebuggersRoot10).WindowsDebuggersRoot10
|
||||
$srcsrvPath = Join-Path $debuggerPath "x64\srcsrv"
|
||||
$srctoolExe = Join-Path $srcsrvPath "srctool.exe"
|
||||
$pdbstrExe = Join-Path $srcsrvPath "pdbstr.exe"
|
||||
|
||||
$fileTable = @{}
|
||||
foreach ($gitFile in & git ls-files)
|
||||
{
|
||||
$fileTable[$gitFile] = $gitFile
|
||||
}
|
||||
|
||||
$mappedFiles = New-Object System.Collections.ArrayList
|
||||
|
||||
foreach ($file in (Get-ChildItem -r:$recursive "$SearchDir\*.pdb"))
|
||||
{
|
||||
Write-Verbose "Found $file"
|
||||
|
||||
$ErrorActionPreference = "Continue" # Azure Pipelines defaults to "Stop", continue past errors in this script.
|
||||
|
||||
$allFiles = & $srctoolExe -r "$file"
|
||||
|
||||
# If the pdb didn't have enough files then skip it (the srctool output has a blank line even when there's no info
|
||||
# so check for less than 2 lines)
|
||||
if ($allFiles.Length -lt 2)
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
for ($i = 0; $i -lt $allFiles.Length; $i++)
|
||||
{
|
||||
if ($allFiles[$i].StartsWith($SourceRoot, [StringComparison]::OrdinalIgnoreCase))
|
||||
{
|
||||
$relative = $allFiles[$i].Substring($SourceRoot.Length).TrimStart("\")
|
||||
$relative = $relative.Replace("\", "/")
|
||||
|
||||
# Git urls are case-sensitive but the PDB might contain a lowercased version of the file path.
|
||||
# Look up the relative url in the output of "ls-files". If it's not there then it's not something
|
||||
# in git, so don't index it.
|
||||
$relative = $fileTable[$relative]
|
||||
if ($relative)
|
||||
{
|
||||
$mapping = $allFiles[$i] + "*$relative"
|
||||
$mappedFiles.Add($mapping)
|
||||
|
||||
Write-Verbose "Mapped path $($i): $mapping"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pdbstrFile = Join-Path "$env:TEMP" "pdbstr.txt"
|
||||
|
||||
Write-Verbose "pdbstr.txt = $pdbstrFile"
|
||||
|
||||
@"
|
||||
SRCSRV: ini ------------------------------------------------
|
||||
VERSION=2
|
||||
VERCTRL=http
|
||||
SRCSRV: variables ------------------------------------------
|
||||
ORGANIZATION=$Organization
|
||||
REPO=$Repo
|
||||
COMMITID=$CommitId
|
||||
HTTP_ALIAS=https://raw.githubusercontent.com/%ORGANIZATION%/%REPO%/%COMMITID%/
|
||||
HTTP_EXTRACT_TARGET=%HTTP_ALIAS%%var2%
|
||||
SRCSRVTRG=%HTTP_EXTRACT_TARGET%
|
||||
SRC_INDEX=public
|
||||
SRCSRV: source files ---------------------------------------
|
||||
$($mappedFiles -join "`r`n")
|
||||
SRCSRV: end ------------------------------------------------
|
||||
"@ | Set-Content $pdbstrFile
|
||||
|
||||
& $pdbstrExe -p:"$file" -w -s:srcsrv -i:$pdbstrFile
|
||||
}
|
||||
|
||||
# Return with exit 0 to override any weird error code from other tools
|
||||
Exit 0
|
||||
BIN
res/Cascadia.ttf
BIN
res/Cascadia.ttf
Binary file not shown.
@@ -18,4 +18,4 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
|
||||
### Fonts Included
|
||||
|
||||
* Cascadia Code
|
||||
* from microsoft/cascadia-code@5f91b87e12c9af709fa406c22a79145879edc3d2
|
||||
* from microsoft/cascadia-code@d3b1adacf2691dfadf8ebd8a08936d3ad8a062d0
|
||||
|
||||
@@ -147,11 +147,11 @@ const UnicodeStorage& ROW::GetUnicodeStorage() const noexcept
|
||||
// Arguments:
|
||||
// - it - custom console iterator to use for seeking input data. bool() false when it becomes invalid while seeking.
|
||||
// - index - column in row to start writing at
|
||||
// - setWrap - set the wrap flags if we hit the end of the row while writing and there's still more data in the iterator.
|
||||
// - wrap - change the wrap flag if we hit the end of the row while writing and there's still more data in the iterator.
|
||||
// - 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 size_t index, const bool setWrap, std::optional<size_t> 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());
|
||||
@@ -202,10 +202,15 @@ OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, co
|
||||
++it;
|
||||
}
|
||||
|
||||
// If we're asked to set the wrap status and we just filled the last column with some text, set wrap status on the row.
|
||||
if (setWrap && fillingLastColumn)
|
||||
// If we're asked to (un)set the wrap status and we just filled the last column with some text...
|
||||
// NOTE:
|
||||
// - wrap = std::nullopt --> don't change the wrap value
|
||||
// - wrap = true --> we're filling cells as a steam, consider this a wrap
|
||||
// - wrap = false --> we're filling cells as a block, unwrap
|
||||
if (wrap.has_value() && fillingLastColumn)
|
||||
{
|
||||
_charRow.SetWrapForced(true);
|
||||
// set wrap status on the row to parameter's value.
|
||||
_charRow.SetWrapForced(wrap.value());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||
|
||||
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const bool setWrap, std::optional<size_t> 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);
|
||||
|
||||
friend bool operator==(const ROW& a, const ROW& b) noexcept;
|
||||
|
||||
|
||||
@@ -318,10 +318,12 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt)
|
||||
// Arguments:
|
||||
// - givenIt - Iterator representing output cell data to write
|
||||
// - target - the row/column to start writing the text to
|
||||
// - wrap - change the wrap flag if we hit the end of the row while writing and there's still more data
|
||||
// Return Value:
|
||||
// - The final position of the iterator
|
||||
OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
const COORD target)
|
||||
const COORD target,
|
||||
const std::optional<bool> wrap)
|
||||
{
|
||||
// Make mutable copy so we can walk.
|
||||
auto it = givenIt;
|
||||
@@ -336,7 +338,8 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
while (it && size.IsInBounds(lineTarget))
|
||||
{
|
||||
// Attempt to write as much data as possible onto this line.
|
||||
it = WriteLine(it, lineTarget, true);
|
||||
// NOTE: if wrap = true/false, we want to set the line's wrap to true/false (respectively) if we reach the end of the line
|
||||
it = WriteLine(it, lineTarget, wrap);
|
||||
|
||||
// Move to the next line down.
|
||||
lineTarget.X = 0;
|
||||
@@ -351,13 +354,13 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
// Arguments:
|
||||
// - givenIt - The iterator that will dereference into cell data to insert
|
||||
// - target - Coordinate targeted within output buffer
|
||||
// - setWrap - Whether we should try to set the wrap flag if we write up to the end of the line and have more data
|
||||
// - wrap - change the wrap flag if we hit the end of the row while writing and there's still more data in the iterator.
|
||||
// - limitRight - Optionally restrict the right boundary for writing (e.g. stop writing earlier than the end of line)
|
||||
// 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 COORD target,
|
||||
const bool setWrap,
|
||||
const std::optional<bool> wrap,
|
||||
std::optional<size_t> limitRight)
|
||||
{
|
||||
// If we're not in bounds, exit early.
|
||||
@@ -368,7 +371,7 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
||||
|
||||
// Get the row and write the cells
|
||||
ROW& row = GetRowByOffset(target.Y);
|
||||
const auto newIt = row.WriteCells(givenIt, target.X, setWrap, limitRight);
|
||||
const auto newIt = row.WriteCells(givenIt, target.X, wrap, limitRight);
|
||||
|
||||
// Take the cell distance written and notify that it needs to be repainted.
|
||||
const auto written = newIt.GetCellDistance(givenIt);
|
||||
|
||||
@@ -89,11 +89,12 @@ public:
|
||||
OutputCellIterator Write(const OutputCellIterator givenIt);
|
||||
|
||||
OutputCellIterator Write(const OutputCellIterator givenIt,
|
||||
const COORD target);
|
||||
const COORD target,
|
||||
const std::optional<bool> wrap = true);
|
||||
|
||||
OutputCellIterator WriteLine(const OutputCellIterator givenIt,
|
||||
const COORD target,
|
||||
const bool setWrap = false,
|
||||
const std::optional<bool> setWrap = std::nullopt,
|
||||
const std::optional<size_t> limitRight = std::nullopt);
|
||||
|
||||
bool InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||
|
||||
@@ -19,16 +19,6 @@ namespace winrt::TerminalApp::implementation
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::Maximize()
|
||||
{
|
||||
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateMaximized", false);
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::RestoreDown()
|
||||
{
|
||||
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false);
|
||||
}
|
||||
|
||||
// These event handlers simply forward each buttons click events up to the
|
||||
// events we've exposed.
|
||||
void MinMaxCloseControl::_MinimizeClick(winrt::Windows::Foundation::IInspectable const& sender,
|
||||
@@ -48,6 +38,21 @@ namespace winrt::TerminalApp::implementation
|
||||
_closeClickHandlers(*this, e);
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::SetWindowVisualState(WindowVisualState visualState)
|
||||
{
|
||||
switch (visualState)
|
||||
{
|
||||
case WindowVisualState::WindowVisualStateMaximized:
|
||||
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(MaximizeButton(), L"WindowStateMaximized", false);
|
||||
break;
|
||||
case WindowVisualState::WindowVisualStateNormal:
|
||||
case WindowVisualState::WindowVisualStateIconified:
|
||||
default:
|
||||
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MinMaxCloseControl, MinimizeClick, _minimizeClickHandlers, TerminalApp::MinMaxCloseControl, RoutedEventArgs);
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MinMaxCloseControl, MaximizeClick, _maximizeClickHandlers, TerminalApp::MinMaxCloseControl, RoutedEventArgs);
|
||||
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MinMaxCloseControl, CloseClick, _closeClickHandlers, TerminalApp::MinMaxCloseControl, RoutedEventArgs);
|
||||
|
||||
@@ -18,8 +18,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
MinMaxCloseControl();
|
||||
|
||||
void Maximize();
|
||||
void RestoreDown();
|
||||
void SetWindowVisualState(WindowVisualState visualState);
|
||||
|
||||
void _MinimizeClick(winrt::Windows::Foundation::IInspectable const& sender,
|
||||
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "..\TitlebarControl.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass MinMaxCloseControl : Windows.UI.Xaml.Controls.StackPanel
|
||||
{
|
||||
MinMaxCloseControl();
|
||||
|
||||
void Maximize();
|
||||
void RestoreDown();
|
||||
void SetWindowVisualState(WindowVisualState visualState);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MinimizeClick;
|
||||
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MaximizeClick;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- cppwinrt.build.pre.props depends on these settings: -->
|
||||
<!-- build a dll, not exe (Application) -->
|
||||
@@ -21,7 +22,6 @@
|
||||
<ItemGroup>
|
||||
<!-- DON'T PUT XAML FILES HERE! Put them in TerminalAppLib.vcxproj -->
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- Only put headers for winrt types in here. Don't put other header files
|
||||
@@ -60,31 +60,25 @@
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj">
|
||||
<Project>{18D09A24-8240-42D6-8CB6-236EEE820263}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
<!-- The midl compiler however, _will_ aggregate our winmd dependencies
|
||||
somehow. So make sure to only include top-level dependencies here (don't
|
||||
include Settings and Connection, since Control will include them for us) -->
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||||
|
||||
<!-- Reference TerminalAppLib here, so we can use it's TerminalApp.winmd as
|
||||
our TerminalApp.winmd. This didn't work correctly in VS2017, you'd need to
|
||||
manually reference the lib -->
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj" >
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj">
|
||||
<Private>true</Private>
|
||||
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- A small helper for paths to the compiled cppwinrt projects -->
|
||||
<_BinRoot Condition="'$(Platform)' != 'Win32'">$(OpenConsoleDir)$(Platform)\$(Configuration)\</_BinRoot>
|
||||
<_BinRoot Condition="'$(Platform)' == 'Win32'">$(OpenConsoleDir)$(Configuration)\</_BinRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
DON'T REDIRECT OUR OUTPUT.
|
||||
@@ -99,18 +93,28 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>User32.lib;WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
|
||||
<!-- TerminalAppLib contains a DllMain that we need to force the use of. -->
|
||||
<AdditionalOptions Condition="'$(Platform)'=='Win32'">/INCLUDE:_DllMain@12</AdditionalOptions>
|
||||
<AdditionalOptions Condition="'$(Platform)'!='Win32'">/INCLUDE:DllMain</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<!-- Import this set of targets that fixes a VS bug that manifests when using
|
||||
the TerminalAppLib project -->
|
||||
<Import Project="FixVisualStudioBug.targets" />
|
||||
|
||||
</Project>
|
||||
<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.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
@@ -59,12 +59,10 @@ namespace winrt::TerminalApp::implementation
|
||||
::GetWindowPlacement(_window, &placement);
|
||||
if (placement.showCmd == SW_SHOWNORMAL)
|
||||
{
|
||||
MinMaxCloseControl().Maximize();
|
||||
::PostMessage(_window, WM_SYSCOMMAND, SC_MAXIMIZE | flag, lParam);
|
||||
}
|
||||
else if (placement.showCmd == SW_SHOWMAXIMIZED)
|
||||
{
|
||||
MinMaxCloseControl().RestoreDown();
|
||||
::PostMessage(_window, WM_SYSCOMMAND, SC_RESTORE | flag, lParam);
|
||||
}
|
||||
}
|
||||
@@ -92,4 +90,9 @@ namespace winrt::TerminalApp::implementation
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
|
||||
void TitlebarControl::SetWindowVisualState(WindowVisualState visualState)
|
||||
{
|
||||
MinMaxCloseControl().SetWindowVisualState(visualState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ namespace winrt::TerminalApp::implementation
|
||||
Windows::UI::Xaml::UIElement Content();
|
||||
void Content(Windows::UI::Xaml::UIElement content);
|
||||
|
||||
void SetWindowVisualState(WindowVisualState visualState);
|
||||
|
||||
void Root_SizeChanged(const IInspectable& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e);
|
||||
|
||||
void Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
|
||||
@@ -3,9 +3,17 @@
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
enum WindowVisualState
|
||||
{
|
||||
WindowVisualStateNormal = 0,
|
||||
WindowVisualStateMaximized,
|
||||
WindowVisualStateIconified
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass TitlebarControl : Windows.UI.Xaml.Controls.Grid
|
||||
{
|
||||
TitlebarControl(UInt64 parentWindowHandle);
|
||||
void SetWindowVisualState(WindowVisualState visualState);
|
||||
|
||||
Windows.UI.Xaml.UIElement Content;
|
||||
Windows.UI.Xaml.Controls.Border DragBar { get; };
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
"commandline": "powershell.exe",
|
||||
"hidden": false,
|
||||
"startingDirectory": "%USERPROFILE%",
|
||||
"background": "#012456",
|
||||
"closeOnExit": true,
|
||||
"colorScheme": "Campbell",
|
||||
"colorScheme": "Campbell Powershell",
|
||||
"cursorColor": "#FFFFFF",
|
||||
"cursorShape": "bar",
|
||||
"fontFace": "Consolas",
|
||||
@@ -46,8 +45,7 @@
|
||||
"icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
|
||||
"padding": "8, 8, 8, 8",
|
||||
"snapOnInput": true,
|
||||
"useAcrylic": true,
|
||||
"acrylicOpacity": 0.75
|
||||
"useAcrylic": false
|
||||
}
|
||||
],
|
||||
"schemes":
|
||||
@@ -73,6 +71,27 @@
|
||||
"brightCyan": "#61D6D6",
|
||||
"brightWhite": "#F2F2F2"
|
||||
},
|
||||
{
|
||||
"name": "Campbell Powershell",
|
||||
"foreground": "#CCCCCC",
|
||||
"background": "#012456",
|
||||
"black": "#0C0C0C",
|
||||
"red": "#C50F1F",
|
||||
"green": "#13A10E",
|
||||
"yellow": "#C19C00",
|
||||
"blue": "#0037DA",
|
||||
"purple": "#881798",
|
||||
"cyan": "#3A96DD",
|
||||
"white": "#CCCCCC",
|
||||
"brightBlack": "#767676",
|
||||
"brightRed": "#E74856",
|
||||
"brightGreen": "#16C60C",
|
||||
"brightYellow": "#F9F1A5",
|
||||
"brightBlue": "#3B78FF",
|
||||
"brightPurple": "#B4009E",
|
||||
"brightCyan": "#61D6D6",
|
||||
"brightWhite": "#F2F2F2"
|
||||
},
|
||||
{
|
||||
"name": "Vintage",
|
||||
"foreground": "#C0C0C0",
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
#include <wil/cppwinrt.h>
|
||||
|
||||
#include <unknwn.h>
|
||||
|
||||
#include <hstring.h>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview7" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.2.190611001-prerelease" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
</packages>
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -35,7 +38,7 @@
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="init.cpp"/>
|
||||
<ClCompile Include="init.cpp" />
|
||||
<ClCompile Include="AzureConnection.cpp" Condition="'$(Platform)'!='ARM64'" />
|
||||
<ClCompile Include="AzureConnection-ARM64.cpp" Condition="'$(Platform)'=='ARM64'" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
@@ -90,5 +93,14 @@
|
||||
<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\vcpkg-cpprestsdk.2.10.0\build\native\vcpkg-cpprestsdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\vcpkg-cpprestsdk.2.10.0\build\native\vcpkg-cpprestsdk.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
@@ -15,6 +15,7 @@
|
||||
<ClCompile Include="ConhostConnection.cpp" />
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="AzureConnection.cpp" />
|
||||
<ClCompile Include="init.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
<package id="vcpkg-cpprestsdk" version="2.10.0" targetFramework="native" />
|
||||
</packages>
|
||||
</packages>
|
||||
@@ -15,6 +15,8 @@
|
||||
// Must be included before any WinRT headers.
|
||||
#include <unknwn.h>
|
||||
|
||||
#include <wil/cppwinrt.h>
|
||||
|
||||
#include "winrt/Windows.Foundation.h"
|
||||
#include "winrt/Windows.Security.Credentials.h"
|
||||
#include "winrt/Windows.Foundation.Collections.h"
|
||||
|
||||
@@ -638,41 +638,29 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
}
|
||||
|
||||
const auto modifiers = _GetPressedModifierKeys();
|
||||
|
||||
// AltGr key combinations don't always contain any meaningful,
|
||||
// pretranslated unicode character during WM_KEYDOWN.
|
||||
// E.g. on a German keyboard AltGr+Q should result in a "@" character,
|
||||
// but actually results in "Q" with Alt and Ctrl modifier states.
|
||||
// By returning false though, we can abort handling this WM_KEYDOWN
|
||||
// event and let the WM_CHAR handler kick in, which will be
|
||||
// provided with an appropriate unicode character.
|
||||
//
|
||||
// GH#2235: Make sure to handle AltGr before trying keybindings,
|
||||
// so Ctrl+Alt keybindings won't eat an AltGr keypress.
|
||||
if (modifiers.IsAltGrPressed())
|
||||
{
|
||||
_HandleVoidKeyEvent();
|
||||
e.Handled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto vkey = static_cast<WORD>(e.OriginalKey());
|
||||
const auto scanCode = e.KeyStatus().ScanCode;
|
||||
bool handled = false;
|
||||
|
||||
auto bindings = _settings.KeyBindings();
|
||||
if (bindings)
|
||||
// GH#2235: Terminal::Settings hasn't been modified to differentiate between AltGr and Ctrl+Alt yet.
|
||||
// -> Don't check for key bindings if this is an AltGr key combination.
|
||||
if (!modifiers.IsAltGrPressed())
|
||||
{
|
||||
handled = bindings.TryKeyChord({
|
||||
modifiers.IsCtrlPressed(),
|
||||
modifiers.IsAltPressed(),
|
||||
modifiers.IsShiftPressed(),
|
||||
vkey,
|
||||
});
|
||||
auto bindings = _settings.KeyBindings();
|
||||
if (bindings)
|
||||
{
|
||||
handled = bindings.TryKeyChord({
|
||||
modifiers.IsCtrlPressed(),
|
||||
modifiers.IsAltPressed(),
|
||||
modifiers.IsShiftPressed(),
|
||||
vkey,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
handled = _TrySendKeyEvent(vkey, modifiers);
|
||||
handled = _TrySendKeyEvent(vkey, scanCode, modifiers);
|
||||
}
|
||||
|
||||
// Manually prevent keyboard navigation with tab. We want to send tab to
|
||||
@@ -686,17 +674,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
e.Handled(handled);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Some key events cannot be handled (e.g. AltGr combinations) and are
|
||||
// delegated to the character handler. Just like with _TrySendKeyEvent(),
|
||||
// the character handler counts on us though to:
|
||||
// - Clears the current selection.
|
||||
// - Makes the cursor briefly visible during typing.
|
||||
void TermControl::_HandleVoidKeyEvent()
|
||||
{
|
||||
_TrySendKeyEvent(0, {});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Send this particular key event to the terminal.
|
||||
// See Terminal::SendKeyEvent for more information.
|
||||
@@ -705,14 +682,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
// Arguments:
|
||||
// - vkey: The vkey of the key pressed.
|
||||
// - states: The Microsoft::Terminal::Core::ControlKeyStates representing the modifier key states.
|
||||
bool TermControl::_TrySendKeyEvent(WORD vkey, const ControlKeyStates modifiers)
|
||||
bool TermControl::_TrySendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates modifiers)
|
||||
{
|
||||
_terminal->ClearSelection();
|
||||
|
||||
// If the terminal translated the key, mark the event as handled.
|
||||
// This will prevent the system from trying to get the character out
|
||||
// of it and sending us a CharacterRecieved event.
|
||||
const auto handled = vkey ? _terminal->SendKeyEvent(vkey, modifiers) : true;
|
||||
const auto handled = vkey ? _terminal->SendKeyEvent(vkey, scanCode, modifiers) : true;
|
||||
|
||||
if (_cursorTimer.has_value())
|
||||
{
|
||||
|
||||
@@ -184,8 +184,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
static Windows::UI::Xaml::Thickness _ParseThicknessFromPadding(const hstring padding);
|
||||
|
||||
::Microsoft::Terminal::Core::ControlKeyStates _GetPressedModifierKeys() const;
|
||||
void _HandleVoidKeyEvent();
|
||||
bool _TrySendKeyEvent(WORD vkey, ::Microsoft::Terminal::Core::ControlKeyStates modifiers);
|
||||
bool _TrySendKeyEvent(const WORD vkey, const WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers);
|
||||
|
||||
const COORD _GetTerminalPosition(winrt::Windows::Foundation::Point cursorPosition);
|
||||
const unsigned int _NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<PropertyGroup>
|
||||
<!-- cppwinrt.build.pre.props depends on these settings: -->
|
||||
@@ -86,4 +89,18 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
</Project>
|
||||
<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.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
@@ -17,6 +17,7 @@
|
||||
<ClCompile Include="XamlUiaTextRange.cpp" />
|
||||
<ClCompile Include="TermControlUiaProvider.cpp" />
|
||||
<ClCompile Include="UiaTextRange.cpp" />
|
||||
<ClCompile Include="init.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -37,4 +38,4 @@
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
</packages>
|
||||
@@ -18,6 +18,8 @@
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
#include <wil/cppwinrt.h>
|
||||
|
||||
#include <unknwn.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Microsoft::Terminal::Core
|
||||
public:
|
||||
virtual ~ITerminalInput() {}
|
||||
|
||||
virtual bool SendKeyEvent(const WORD vkey, const ControlKeyStates states) = 0;
|
||||
virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states) = 0;
|
||||
|
||||
// void SendMouseEvent(uint row, uint col, KeyModifiers modifiers);
|
||||
[[nodiscard]] virtual HRESULT UserResize(const COORD size) noexcept = 0;
|
||||
|
||||
@@ -205,7 +205,7 @@ void Terminal::Write(std::wstring_view stringView)
|
||||
// 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::SendKeyEvent(const WORD vkey, const ControlKeyStates states)
|
||||
bool Terminal::SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states)
|
||||
{
|
||||
if (_snapOnInput && _scrollOffset != 0)
|
||||
{
|
||||
@@ -222,14 +222,7 @@ bool Terminal::SendKeyEvent(const WORD vkey, const ControlKeyStates states)
|
||||
wchar_t ch = UNICODE_NULL;
|
||||
if (states.IsAltPressed() && vkey != VK_SPACE)
|
||||
{
|
||||
ch = static_cast<wchar_t>(LOWORD(MapVirtualKey(vkey, MAPVK_VK_TO_CHAR)));
|
||||
// MapVirtualKey will give us the capitalized version of the char.
|
||||
// However, if shift isn't pressed, we want to send the lowercase version.
|
||||
// (See GH#637)
|
||||
if (!states.IsShiftPressed())
|
||||
{
|
||||
ch = towlower(ch);
|
||||
}
|
||||
ch = _CharacterFromKeyEvent(vkey, scanCode, states);
|
||||
}
|
||||
|
||||
if (states.IsCtrlPressed())
|
||||
@@ -260,12 +253,54 @@ bool Terminal::SendKeyEvent(const WORD vkey, const ControlKeyStates states)
|
||||
|
||||
const bool manuallyHandled = ch != UNICODE_NULL;
|
||||
|
||||
KeyEvent keyEv{ true, 0, vkey, 0, ch, states.Value() };
|
||||
KeyEvent keyEv{ true, 0, vkey, scanCode, ch, states.Value() };
|
||||
const bool translated = _terminalInput->HandleKey(&keyEv);
|
||||
|
||||
return translated && manuallyHandled;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the keyboard's scan code for the given virtual key code.
|
||||
// Arguments:
|
||||
// - vkey: The virtual key code.
|
||||
// Return Value:
|
||||
// - The keyboard's scan code.
|
||||
WORD Terminal::_ScanCodeFromVirtualKey(const WORD vkey) noexcept
|
||||
{
|
||||
return LOWORD(MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Translates the specified virtual key code and keyboard state to the corresponding character.
|
||||
// Arguments:
|
||||
// - vkey: The virtual key code that initiated this keyboard event.
|
||||
// - scanCode: The scan code that initiated this keyboard event.
|
||||
// - states: The current keyboard state.
|
||||
// Return Value:
|
||||
// - The character that would result from this virtual key code and keyboard state.
|
||||
wchar_t Terminal::_CharacterFromKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states) noexcept
|
||||
{
|
||||
const auto sc = scanCode != 0 ? scanCode : _ScanCodeFromVirtualKey(vkey);
|
||||
|
||||
// We might want to use GetKeyboardState() instead of building our own keyState.
|
||||
// The question is whether that's necessary though. For now it seems to work fine as it is.
|
||||
BYTE keyState[256] = {};
|
||||
keyState[VK_SHIFT] = states.IsShiftPressed() ? 0x80 : 0;
|
||||
keyState[VK_CONTROL] = states.IsCtrlPressed() ? 0x80 : 0;
|
||||
keyState[VK_MENU] = states.IsAltPressed() ? 0x80 : 0;
|
||||
|
||||
// Technically ToUnicodeEx() can produce arbitrarily long sequences of diacritics etc.
|
||||
// Since we only handle the case of a single UTF-16 code point, we can set the buffer size to 2 though.
|
||||
constexpr size_t bufferSize = 2;
|
||||
wchar_t buffer[bufferSize];
|
||||
|
||||
// wFlags: If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer)
|
||||
const auto result = ToUnicodeEx(vkey, sc, keyState, buffer, bufferSize, 0b100, nullptr);
|
||||
|
||||
// TODO:GH#2853 We're only handling single UTF-16 code points right now, since that's the only thing KeyEvent supports.
|
||||
return result == 1 || result == -1 ? buffer[0] : 0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Aquire a read lock on the terminal.
|
||||
// Return Value:
|
||||
@@ -381,6 +416,18 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
|
||||
}
|
||||
}
|
||||
|
||||
// If we're about to try to place the cursor past the right edge of the buffer, move it down a row
|
||||
// This is another patch that GH#780 should supersede. This is really correcting for other bad situations
|
||||
// like bisecting (writing only the leading half because there's no room for the trailing) a wide character
|
||||
// into the buffer. However, it's not really all-up correctable without implementing a full WriteStream here.
|
||||
// Also, this particular code RIGHT HERE shouldn't need to know anything about the cursor or the cells advanced
|
||||
// which also will be solved by GH#780 (hopefully).
|
||||
if (proposedCursorPosition.X > bufferSize.RightInclusive())
|
||||
{
|
||||
proposedCursorPosition.X = 0;
|
||||
proposedCursorPosition.Y++;
|
||||
}
|
||||
|
||||
// If we're about to scroll past the bottom of the buffer, instead cycle the buffer.
|
||||
const auto newRows = proposedCursorPosition.Y - bufferSize.Height() + 1;
|
||||
if (newRows > 0)
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
|
||||
#pragma region ITerminalInput
|
||||
// These methods are defined in Terminal.cpp
|
||||
bool SendKeyEvent(const WORD vkey, const Microsoft::Terminal::Core::ControlKeyStates states) override;
|
||||
bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states) override;
|
||||
[[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
|
||||
void UserScrollViewport(const int viewTop) override;
|
||||
int GetScrollOffset() override;
|
||||
@@ -207,6 +207,9 @@ private:
|
||||
// underneath them, while others would prefer to anchor it in place.
|
||||
// Either way, we sohould make this behavior controlled by a setting.
|
||||
|
||||
static WORD _ScanCodeFromVirtualKey(const WORD vkey) noexcept;
|
||||
static wchar_t _CharacterFromKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states) noexcept;
|
||||
|
||||
int _ViewStartIndex() const noexcept;
|
||||
int _VisibleStartIndex() const noexcept;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<ProjectName>TerminalCore</ProjectName>
|
||||
<TargetName>TerminalCore</TargetName>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<RootNamespace>Microsoft.Terminal.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<!-- ============================ References ============================ -->
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<PropertyGroup>
|
||||
<!-- cppwinrt.build.pre.props depends on these settings: -->
|
||||
@@ -47,7 +50,6 @@
|
||||
<None Include="packages.config" />
|
||||
<None Include="TerminalSettings.def" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
DON'T REDIRECT OUR OUTPUT.
|
||||
@@ -58,4 +60,18 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
</Project>
|
||||
<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.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
@@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
</packages>
|
||||
@@ -19,4 +19,5 @@
|
||||
#endif
|
||||
|
||||
#include <unknwn.h>
|
||||
#include <wil/cppwinrt.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
|
||||
@@ -48,12 +48,12 @@ namespace TerminalCoreUnitTests
|
||||
// Verify that Alt+a generates a lowercase a on the input
|
||||
expectedinput = L"\x1b"
|
||||
"a";
|
||||
VERIFY_IS_TRUE(term.SendKeyEvent(L'A', ControlKeyStates::LeftAltPressed));
|
||||
VERIFY_IS_TRUE(term.SendKeyEvent(L'A', 0, ControlKeyStates::LeftAltPressed));
|
||||
|
||||
// Verify that Alt+shift+a generates a uppercase a on the input
|
||||
expectedinput = L"\x1b"
|
||||
"A";
|
||||
VERIFY_IS_TRUE(term.SendKeyEvent(L'A', ControlKeyStates::LeftAltPressed | ControlKeyStates::ShiftPressed));
|
||||
VERIFY_IS_TRUE(term.SendKeyEvent(L'A', 0, ControlKeyStates::LeftAltPressed | ControlKeyStates::ShiftPressed));
|
||||
}
|
||||
|
||||
void InputTest::AltSpace()
|
||||
@@ -61,6 +61,6 @@ namespace TerminalCoreUnitTests
|
||||
// Make sure we don't handle Alt+Space. The system will use this to
|
||||
// bring up the system menu for restore, min/maximimize, size, move,
|
||||
// close
|
||||
VERIFY_IS_FALSE(term.SendKeyEvent(L' ', ControlKeyStates::LeftAltPressed));
|
||||
VERIFY_IS_FALSE(term.SendKeyEvent(L' ', 0, ControlKeyStates::LeftAltPressed));
|
||||
}
|
||||
}
|
||||
|
||||
92
src/cascadia/UnitTests_TerminalCore/TerminalApiTests.cpp
Normal file
92
src/cascadia/UnitTests_TerminalCore/TerminalApiTests.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
#include "precomp.h"
|
||||
#include <WexTestClass.h>
|
||||
|
||||
#include "../cascadia/TerminalCore/Terminal.hpp"
|
||||
#include "../cascadia/UnitTests_TerminalCore/MockTermSettings.h"
|
||||
#include "../renderer/inc/DummyRenderTarget.hpp"
|
||||
#include "consoletaeftemplates.hpp"
|
||||
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
|
||||
using namespace Microsoft::Terminal::Core;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
|
||||
namespace TerminalCoreUnitTests
|
||||
{
|
||||
class TerminalApiTests
|
||||
{
|
||||
TEST_CLASS(TerminalApiTests);
|
||||
|
||||
struct Baton
|
||||
{
|
||||
HANDLE ev;
|
||||
std::wstring text;
|
||||
Terminal* pTerm;
|
||||
};
|
||||
|
||||
TEST_METHOD(PrintStringOfEmojiBisectingFinalColumn)
|
||||
{
|
||||
Terminal term;
|
||||
DummyRenderTarget emptyRT;
|
||||
term.Create({ 100, 100 }, 0, emptyRT);
|
||||
|
||||
std::wstring textToPrint;
|
||||
textToPrint.push_back(L'A'); // A is half-width, push it in.
|
||||
|
||||
// Put a ton of copies of a full-width emoji here.
|
||||
const wchar_t* emoji = L"\xD83D\xDE00"; // 1F600 is wide in https://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt
|
||||
for (size_t i = 0; i < 120; ++i)
|
||||
{
|
||||
textToPrint = textToPrint.append(emoji);
|
||||
}
|
||||
|
||||
Baton b;
|
||||
b.ev = CreateEventW(nullptr, TRUE, FALSE, L"It is an event");
|
||||
b.text = textToPrint;
|
||||
b.pTerm = &term;
|
||||
|
||||
Log::Comment(L"Launching thread to write data.");
|
||||
|
||||
HANDLE hThread = CreateThread(
|
||||
nullptr, 0, [](LPVOID c) -> DWORD {
|
||||
Baton& b = *reinterpret_cast<Baton*>(c);
|
||||
Log::Comment(L"Writing data.");
|
||||
b.pTerm->PrintString(b.text);
|
||||
Log::Comment(L"Setting event.");
|
||||
SetEvent(b.ev);
|
||||
return 0;
|
||||
},
|
||||
(LPVOID)&b,
|
||||
0,
|
||||
nullptr);
|
||||
|
||||
Log::Comment(L"Waiting for the write.");
|
||||
switch (WaitForSingleObject(b.ev, 2000))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
Log::Comment(L"Didn't get stuck. Success.");
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
Log::Comment(L"Wait timed out. It got stuck.");
|
||||
Log::Result(WEX::Logging::TestResults::Failed);
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
Log::Comment(L"Wait failed for some reason. We didn't expect this.");
|
||||
Log::Result(WEX::Logging::TestResults::Failed);
|
||||
break;
|
||||
default:
|
||||
Log::Comment(L"Wait return code that no one expected. Fail.");
|
||||
Log::Result(WEX::Logging::TestResults::Failed);
|
||||
break;
|
||||
}
|
||||
|
||||
TerminateThread(hThread, 0);
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
<ClCompile Include="precomp.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalApiTests.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\buffer\out\lib\bufferout.vcxproj">
|
||||
|
||||
@@ -263,8 +263,6 @@ void NonClientIslandWindow::_UpdateDragRegion()
|
||||
// - Hit test the frame for resizing and moving.
|
||||
// Arguments:
|
||||
// - ptMouse: the mouse point being tested, in absolute (NOT WINDOW) coordinates.
|
||||
// - titlebarIsCaption: If true, we want to treat the titlebar area as
|
||||
// HTCAPTION, otherwise we'll return HTNOWHERE for the titlebar.
|
||||
// Return Value:
|
||||
// - one of the values from
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-nchittest#return-value
|
||||
@@ -272,13 +270,7 @@ void NonClientIslandWindow::_UpdateDragRegion()
|
||||
// NOTE:
|
||||
// - Largely taken from code on:
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/dwm/customframe
|
||||
// NOTE[2]: Concerning `titlebarIsCaption`
|
||||
// - We want HTNOWHERE as the return value for WM_NCHITTEST, so that we can get
|
||||
// mouse presses in the titlebar area. If we return HTCAPTION there, we won't
|
||||
// get any mouse WMs. However, when we're handling the mouse events, we need
|
||||
// to know if the mouse was in that are or not, so we'll return HTCAPTION in
|
||||
// that handler, to differentiate from the rest of the window.
|
||||
[[nodiscard]] LRESULT NonClientIslandWindow::HitTestNCA(POINT ptMouse, const bool titlebarIsCaption) const noexcept
|
||||
[[nodiscard]] LRESULT NonClientIslandWindow::HitTestNCA(POINT ptMouse) const noexcept
|
||||
{
|
||||
// Get the window rectangle.
|
||||
RECT rcWindow = BaseWindow::GetWindowRect();
|
||||
@@ -319,7 +311,7 @@ void NonClientIslandWindow::_UpdateDragRegion()
|
||||
|
||||
// clang-format off
|
||||
// Hit test (HTTOPLEFT, ... HTBOTTOMRIGHT)
|
||||
const auto topHt = fOnResizeBorder ? HTTOP : (titlebarIsCaption ? HTCAPTION : HTNOWHERE);
|
||||
const auto topHt = fOnResizeBorder ? HTTOP : HTCAPTION;
|
||||
LRESULT hitTests[3][3] = {
|
||||
{ HTTOPLEFT, topHt, HTTOPRIGHT },
|
||||
{ HTLEFT, HTNOWHERE, HTRIGHT },
|
||||
@@ -520,7 +512,7 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
// Handle hit testing in the NCA if not handled by DwmDefWindowProc.
|
||||
if (lRet == 0)
|
||||
{
|
||||
lRet = HitTestNCA({ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }, false);
|
||||
lRet = HitTestNCA({ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) });
|
||||
if (lRet != HTNOWHERE)
|
||||
{
|
||||
return lRet;
|
||||
@@ -598,22 +590,18 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_NCLBUTTONUP:
|
||||
case WM_NCMBUTTONDOWN:
|
||||
case WM_NCMBUTTONUP:
|
||||
case WM_NCRBUTTONDOWN:
|
||||
case WM_NCRBUTTONUP:
|
||||
case WM_NCXBUTTONDOWN:
|
||||
case WM_NCXBUTTONUP:
|
||||
{
|
||||
POINT point1 = {};
|
||||
::GetCursorPos(&point1);
|
||||
|
||||
const auto region = HitTestNCA(point1, true);
|
||||
if (region == HTCAPTION)
|
||||
{
|
||||
// If we clicked in the titlebar, raise an event so the app host can
|
||||
// dispatch an appropriate event.
|
||||
_DragRegionClickedHandlers();
|
||||
|
||||
const auto longParam = MAKELPARAM(point1.x, point1.y);
|
||||
::SetActiveWindow(_window.get());
|
||||
::PostMessage(_window.get(), WM_SYSCOMMAND, SC_MOVE | HTCAPTION, longParam);
|
||||
}
|
||||
// If we clicked in the titlebar, raise an event so the app host can
|
||||
// dispatch an appropriate event.
|
||||
_DragRegionClickedHandlers();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -679,6 +667,17 @@ bool NonClientIslandWindow::_HandleWindowPosChanging(WINDOWPOS* const windowPos)
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto windowStyle = GetWindowStyle(_window.get());
|
||||
const auto isMaximized = WI_IsFlagSet(windowStyle, WS_MAXIMIZE);
|
||||
const auto isIconified = WI_IsFlagSet(windowStyle, WS_ICONIC);
|
||||
|
||||
if (_titlebar)
|
||||
{
|
||||
_titlebar.SetWindowVisualState(isMaximized ? winrt::TerminalApp::WindowVisualState::WindowVisualStateMaximized :
|
||||
isIconified ? winrt::TerminalApp::WindowVisualState::WindowVisualStateIconified :
|
||||
winrt::TerminalApp::WindowVisualState::WindowVisualStateNormal);
|
||||
}
|
||||
|
||||
// Figure out the suggested dimensions
|
||||
RECT rcSuggested;
|
||||
rcSuggested.left = windowPos->x;
|
||||
@@ -726,9 +725,6 @@ bool NonClientIslandWindow::_HandleWindowPosChanging(WINDOWPOS* const windowPos)
|
||||
}
|
||||
}
|
||||
|
||||
const auto windowStyle = GetWindowStyle(_window.get());
|
||||
const auto isMaximized = WI_IsFlagSet(windowStyle, WS_MAXIMIZE);
|
||||
|
||||
// If we're about to maximize the window, determine how much we're about to
|
||||
// overhang by, and adjust for that.
|
||||
// We need to do this because maximized windows will typically overhang the
|
||||
|
||||
@@ -55,7 +55,7 @@ private:
|
||||
|
||||
RECT GetDragAreaRect() const noexcept;
|
||||
|
||||
[[nodiscard]] LRESULT HitTestNCA(POINT ptMouse, const bool titlebarIsCaption) const noexcept;
|
||||
[[nodiscard]] LRESULT HitTestNCA(POINT ptMouse) const noexcept;
|
||||
|
||||
[[nodiscard]] HRESULT _UpdateFrameMargins() const noexcept;
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -77,16 +78,13 @@
|
||||
<!-- Dependencies -->
|
||||
<ItemGroup>
|
||||
<!-- Even though we do have proper recursive dependencies, we want to keep some of these here
|
||||
so that the AppX Manifest contains their activatable classes. -->
|
||||
so that the AppX Manifest contains their activatable classes. -->
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\TerminalApp.vcxproj" />
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
This ItemGroup and the Globals PropertyGroup below it are required in order
|
||||
to enable F5 debugging for the unpackaged application
|
||||
@@ -102,26 +100,27 @@
|
||||
<!-- DON'T REDIRECT OUR OUTPUT -->
|
||||
<NoOutputRedirection>true</NoOutputRedirection>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.1-rc\build\native\Microsoft.VCRTForwarders.140.targets')" />
|
||||
|
||||
<!-- Override GetPackagingOutputs to roll up all our dependencies.
|
||||
This ensures that when the WAP packaging project asks what files go into
|
||||
the package, we tell it.
|
||||
@@ -143,11 +142,12 @@
|
||||
ContinueOnError="$(_ContinueOnError)">
|
||||
<Output TaskParameter="TargetOutputs" ItemName="_PackagingOutputsFromOtherProjects"/>
|
||||
</MSBuild>
|
||||
|
||||
<ItemGroup>
|
||||
<PackagingOutputs Include="@(_PackagingOutputsFromOtherProjects)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)\build\rules\GenerateSxsManifestsFromWinmds.targets" />
|
||||
</Project>
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview7" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.2.190611001-prerelease" targetFramework="native" />
|
||||
<package id="Microsoft.VCRTForwarders.140" version="1.0.1-rc" targetFramework="native" />
|
||||
</packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -38,6 +38,9 @@ Abstract:
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
#include <wil/cppwinrt.h>
|
||||
|
||||
// Needed just for XamlIslands to work at all:
|
||||
#include <winrt/Windows.system.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
@@ -290,7 +290,10 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
||||
try
|
||||
{
|
||||
const OutputCellIterator it(character, lengthToWrite);
|
||||
const auto done = screenInfo.Write(it, startingCoordinate);
|
||||
|
||||
// when writing to the buffer, specifically unset wrap if we get to the last column.
|
||||
// a fill operation should UNSET wrap in that scenario. See GH #1126 for more details.
|
||||
const auto done = screenInfo.Write(it, startingCoordinate, false);
|
||||
cellsModified = done.GetInputDistance(it);
|
||||
|
||||
// Notify accessibility
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="..\..\common.build.pre.props" />
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\precomp.h" />
|
||||
@@ -65,6 +68,9 @@
|
||||
<ItemGroup>
|
||||
<Manifest Include="openconsole.exe.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
@@ -88,4 +94,18 @@
|
||||
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
|
||||
<Import Project="..\..\common.build.exe.props" />
|
||||
<Import Project="..\..\common.build.post.props" />
|
||||
<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.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
@@ -38,4 +38,10 @@
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="openconsole.exe.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
src/host/exe/packages.config
Normal file
6
src/host/exe/packages.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
</packages>
|
||||
@@ -58,4 +58,125 @@ class FillOutputTests
|
||||
&charsWritten));
|
||||
VERIFY_ARE_EQUAL(1u, charsWritten);
|
||||
}
|
||||
|
||||
TEST_METHOD(UnsetWrap)
|
||||
{
|
||||
// WARNING: If this test suddenly decides to start failing,
|
||||
// this is because the wrap registry key is not set.
|
||||
// TODO GH #2859: Get/Set Registry Key for Wrap
|
||||
|
||||
HANDLE hConsole = GetStdOutputHandle();
|
||||
DWORD charsWritten = 0;
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFOEX sbiex = { 0 };
|
||||
sbiex.cbSize = sizeof(sbiex);
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hConsole, &sbiex));
|
||||
|
||||
const auto consoleWidth = sbiex.dwSize.X;
|
||||
|
||||
std::wstring input(consoleWidth + 2, L'a');
|
||||
std::wstring filled(consoleWidth, L'b');
|
||||
|
||||
// Write until a wrap occurs
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(WriteConsoleW(hConsole,
|
||||
input.data(),
|
||||
gsl::narrow_cast<DWORD>(input.size()),
|
||||
&charsWritten,
|
||||
nullptr));
|
||||
|
||||
// Verify wrap occurred
|
||||
std::unique_ptr<wchar_t[]> bufferText = std::make_unique<wchar_t[]>(consoleWidth);
|
||||
DWORD readSize = 0;
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterW(hConsole,
|
||||
bufferText.get(),
|
||||
consoleWidth,
|
||||
{ 0, 0 },
|
||||
&readSize));
|
||||
|
||||
WEX::Common::String expected(input.c_str(), readSize);
|
||||
WEX::Common::String actual(bufferText.get(), readSize);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
bufferText = std::make_unique<wchar_t[]>(2);
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterW(hConsole,
|
||||
bufferText.get(),
|
||||
2,
|
||||
{ 0, 1 },
|
||||
&readSize));
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, readSize);
|
||||
expected = WEX::Common::String(input.c_str(), readSize);
|
||||
actual = WEX::Common::String(bufferText.get(), readSize);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
// Fill Console Line with 'b's
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(FillConsoleOutputCharacterW(hConsole,
|
||||
L'b',
|
||||
consoleWidth,
|
||||
{ 2, 0 },
|
||||
&charsWritten));
|
||||
|
||||
// Verify first line is full of 'a's then 'b's
|
||||
bufferText = std::make_unique<wchar_t[]>(consoleWidth);
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterW(hConsole,
|
||||
bufferText.get(),
|
||||
consoleWidth,
|
||||
{ 0, 0 },
|
||||
&readSize));
|
||||
|
||||
expected = WEX::Common::String(input.c_str(), 2);
|
||||
actual = WEX::Common::String(bufferText.get(), 2);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
expected = WEX::Common::String(filled.c_str(), consoleWidth - 2);
|
||||
actual = WEX::Common::String(&bufferText[2], readSize - 2);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
// Verify second line is still has 'a's that wrapped over
|
||||
bufferText = std::make_unique<wchar_t[]>(2);
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterW(hConsole,
|
||||
bufferText.get(),
|
||||
static_cast<SHORT>(2),
|
||||
{ 0, 0 },
|
||||
&readSize));
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, readSize);
|
||||
expected = WEX::Common::String(input.c_str(), 2);
|
||||
actual = WEX::Common::String(bufferText.get(), readSize);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
// Resize to be smaller by 2
|
||||
sbiex.srWindow.Right -= 2;
|
||||
sbiex.dwSize.X -= 2;
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleScreenBufferInfoEx(hConsole, &sbiex));
|
||||
|
||||
// Verify first line is full of 'a's then 'b's
|
||||
bufferText = std::make_unique<wchar_t[]>(consoleWidth - 2);
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterW(hConsole,
|
||||
bufferText.get(),
|
||||
consoleWidth - static_cast<SHORT>(2),
|
||||
{ 0, 0 },
|
||||
&readSize));
|
||||
|
||||
expected = WEX::Common::String(input.c_str(), 2);
|
||||
actual = WEX::Common::String(bufferText.get(), 2);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
expected = WEX::Common::String(filled.c_str(), consoleWidth - 4);
|
||||
actual = WEX::Common::String(&bufferText[2], readSize - 2);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
// Verify second line is still has 'a's ('b's didn't wrap over)
|
||||
bufferText = std::make_unique<wchar_t[]>(static_cast<SHORT>(2));
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterW(hConsole,
|
||||
bufferText.get(),
|
||||
static_cast<SHORT>(2),
|
||||
{ 0, 0 },
|
||||
&readSize));
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, readSize);
|
||||
expected = WEX::Common::String(input.c_str(), 2);
|
||||
actual = WEX::Common::String(bufferText.get(), readSize);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -183,7 +183,7 @@ class PtyTests
|
||||
|
||||
if (pStartupInfo)
|
||||
{
|
||||
size_t attrListSize{};
|
||||
SIZE_T attrListSize{};
|
||||
|
||||
pStartupInfo->StartupInfo.cb = sizeof(STARTUPINFOEXW);
|
||||
|
||||
|
||||
@@ -1378,12 +1378,25 @@ void DoSrvPrivateAllowCursorBlinking(SCREEN_INFORMATION& screenInfo, const bool
|
||||
coordDestination.X = 0;
|
||||
coordDestination.Y = viewport.Top + 1;
|
||||
|
||||
Status = NTSTATUS_FROM_HRESULT(ServiceLocator::LocateGlobals().api.ScrollConsoleScreenBufferWImpl(screenInfo,
|
||||
srScroll,
|
||||
coordDestination,
|
||||
srScroll,
|
||||
UNICODE_SPACE,
|
||||
screenInfo.GetAttributes().GetLegacyAttributes()));
|
||||
// Here we previously called to ScrollConsoleScreenBufferWImpl to
|
||||
// perform the scrolling operation. However, that function only
|
||||
// accepts a WORD for the fill attributes. That means we'd lose
|
||||
// 256/RGB fidelity for fill attributes. So instead, we'll just call
|
||||
// ScrollRegion ourselves, with the same params that
|
||||
// ScrollConsoleScreenBufferWImpl would have.
|
||||
// See microsoft/terminal#832, #2702 for more context.
|
||||
try
|
||||
{
|
||||
LockConsole();
|
||||
auto Unlock = wil::scope_exit([&] { UnlockConsole(); });
|
||||
ScrollRegion(screenInfo,
|
||||
srScroll,
|
||||
srScroll,
|
||||
coordDestination,
|
||||
UNICODE_SPACE,
|
||||
screenInfo.GetAttributes());
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
@@ -1406,18 +1419,44 @@ void DoSrvPrivateAllowCursorBlinking(SCREEN_INFORMATION& screenInfo, const bool
|
||||
// Make sure the cursor doesn't move outside the viewport.
|
||||
screenInfo.GetViewport().Clamp(clampedPos);
|
||||
|
||||
// Make sure the cursor stays inside the margins, but only if it started there
|
||||
if (screenInfo.AreMarginsSet() && screenInfo.IsCursorInMargins(cursor.GetPosition()))
|
||||
// Make sure the cursor stays inside the margins
|
||||
if (screenInfo.AreMarginsSet())
|
||||
{
|
||||
try
|
||||
const auto margins = screenInfo.GetAbsoluteScrollMargins().ToInclusive();
|
||||
|
||||
const auto cursorY = cursor.GetPosition().Y;
|
||||
|
||||
const auto lo = margins.Top;
|
||||
const auto hi = margins.Bottom;
|
||||
|
||||
// See microsoft/terminal#2929 - If the cursor is _below_ the top
|
||||
// margin, it should stay below the top margin. If it's _above_ the
|
||||
// bottom, it should stay above the bottom. Cursor movements that stay
|
||||
// outside the margins shouldn't necessarily be affected. For example,
|
||||
// moving up while below the bottom margin shouldn't just jump straight
|
||||
// to the bottom margin. See
|
||||
// ScreenBufferTests::CursorUpDownOutsideMargins for a test of that
|
||||
// behavior.
|
||||
const bool cursorBelowTop = cursorY >= lo;
|
||||
const bool cursorAboveBottom = cursorY <= hi;
|
||||
|
||||
if (cursorBelowTop)
|
||||
{
|
||||
const auto margins = screenInfo.GetAbsoluteScrollMargins().ToInclusive();
|
||||
const auto v = clampedPos.Y;
|
||||
const auto lo = margins.Top;
|
||||
const auto hi = margins.Bottom;
|
||||
clampedPos.Y = std::clamp(v, lo, hi);
|
||||
try
|
||||
{
|
||||
clampedPos.Y = std::max(clampedPos.Y, lo);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
||||
if (cursorAboveBottom)
|
||||
{
|
||||
try
|
||||
{
|
||||
clampedPos.Y = std::min(clampedPos.Y, hi);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
cursor.SetPosition(clampedPos);
|
||||
|
||||
|
||||
@@ -2599,14 +2599,17 @@ OutputCellIterator SCREEN_INFORMATION::Write(const OutputCellIterator it)
|
||||
// Arguments:
|
||||
// - it - Iterator representing output cell data to write.
|
||||
// - target - The position to start writing at
|
||||
// - wrap - change the wrap flag if we hit the end of the row while writing and there's still more data
|
||||
// Return Value:
|
||||
// - the iterator at its final position
|
||||
// Note:
|
||||
// - will throw exception on error.
|
||||
OutputCellIterator SCREEN_INFORMATION::Write(const OutputCellIterator it,
|
||||
const COORD target)
|
||||
const COORD target,
|
||||
const std::optional<bool> wrap)
|
||||
{
|
||||
return _textBuffer->Write(it, target);
|
||||
// NOTE: if wrap = true/false, we want to set the line's wrap to true/false (respectively) if we reach the end of the line
|
||||
return _textBuffer->Write(it, target, wrap);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
||||
@@ -131,7 +131,8 @@ public:
|
||||
OutputCellIterator Write(const OutputCellIterator it);
|
||||
|
||||
OutputCellIterator Write(const OutputCellIterator it,
|
||||
const COORD target);
|
||||
const COORD target,
|
||||
const std::optional<bool> wrap = true);
|
||||
|
||||
OutputCellIterator WriteRect(const OutputCellIterator it,
|
||||
const Microsoft::Console::Types::Viewport viewport);
|
||||
|
||||
@@ -180,6 +180,7 @@ TARGETLIBS = \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
|
||||
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \
|
||||
$(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \
|
||||
$(WINCORE_OBJ_PATH)\console\open\src\host\lib\$(O)\conhostv2.lib \
|
||||
$(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \
|
||||
|
||||
@@ -171,7 +171,7 @@ class ScreenBufferTests
|
||||
TEST_METHOD(DeleteLinesInMargins);
|
||||
TEST_METHOD(ReverseLineFeedInMargins);
|
||||
|
||||
TEST_METHOD(InsertDeleteLines256Colors);
|
||||
TEST_METHOD(ScrollLines256Colors);
|
||||
|
||||
TEST_METHOD(SetOriginMode);
|
||||
|
||||
@@ -182,6 +182,10 @@ class ScreenBufferTests
|
||||
TEST_METHOD(ClearAlternateBuffer);
|
||||
|
||||
TEST_METHOD(InitializeTabStopsInVTMode);
|
||||
|
||||
TEST_METHOD(CursorUpDownAcrossMargins);
|
||||
TEST_METHOD(CursorUpDownOutsideMargins);
|
||||
TEST_METHOD(CursorUpDownExactlyAtMargins);
|
||||
};
|
||||
|
||||
void ScreenBufferTests::SingleAlternateBufferCreationTest()
|
||||
@@ -3994,10 +3998,10 @@ void ScreenBufferTests::ReverseLineFeedInMargins()
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenBufferTests::InsertDeleteLines256Colors()
|
||||
void ScreenBufferTests::ScrollLines256Colors()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Data:insert", L"{false, true}")
|
||||
TEST_METHOD_PROPERTY(L"Data:scrollType", L"{0, 1, 2}")
|
||||
TEST_METHOD_PROPERTY(L"Data:colorStyle", L"{0, 1, 2}")
|
||||
END_TEST_METHOD_PROPERTIES();
|
||||
|
||||
@@ -4007,16 +4011,22 @@ void ScreenBufferTests::InsertDeleteLines256Colors()
|
||||
const int Use256Color = 1;
|
||||
const int UseRGBColor = 2;
|
||||
|
||||
bool insert;
|
||||
// scrollType will be used to control whether we use InsertLines,
|
||||
// DeleteLines, or ReverseIndex to scroll the contents of the buffer.
|
||||
const int InsertLines = 0;
|
||||
const int DeleteLines = 1;
|
||||
const int ReverseLineFeed = 2;
|
||||
|
||||
int scrollType;
|
||||
int colorStyle;
|
||||
VERIFY_SUCCEEDED(TestData::TryGetValue(L"insert", insert), L"whether to insert(true) or delete(false) lines");
|
||||
VERIFY_SUCCEEDED(TestData::TryGetValue(L"scrollType", scrollType), L"controls whether to use InsertLines, DeleteLines ot ReverseLineFeed");
|
||||
VERIFY_SUCCEEDED(TestData::TryGetValue(L"colorStyle", colorStyle), L"controls whether to use the 16 color table, 256 table, or RGB colors");
|
||||
|
||||
// This test is largely taken from repro code from
|
||||
// https://github.com/microsoft/terminal/issues/832#issuecomment-507447272
|
||||
Log::Comment(
|
||||
L"Sets the attributes to a 256/RGB color, then scrolls some lines with"
|
||||
L" DL. Verifies the rows are cleared with the attributes we'd expect.");
|
||||
L" IL/DL/RI. Verifies the rows are cleared with the attributes we'd expect.");
|
||||
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
auto& si = gci.GetActiveOutputBuffer();
|
||||
@@ -4052,8 +4062,22 @@ void ScreenBufferTests::InsertDeleteLines256Colors()
|
||||
// Move to home
|
||||
stateMachine.ProcessString(L"\x1b[H");
|
||||
|
||||
// Insert/Delete 10 lines
|
||||
stateMachine.ProcessString(insert ? L"\x1b[10L" : L"\x1b[10M");
|
||||
// Insert/Delete/Reverse Index 10 lines
|
||||
std::wstring scrollSeq = L"";
|
||||
if (scrollType == InsertLines)
|
||||
{
|
||||
scrollSeq = L"\x1b[10L";
|
||||
}
|
||||
if (scrollType == DeleteLines)
|
||||
{
|
||||
scrollSeq = L"\x1b[10M";
|
||||
}
|
||||
if (scrollType == ReverseLineFeed)
|
||||
{
|
||||
// This is 10 "Reverse Index" commands, which don't accept a parameter.
|
||||
scrollSeq = L"\x1bM\x1bM\x1bM\x1bM\x1bM\x1bM\x1bM\x1bM\x1bM\x1bM";
|
||||
}
|
||||
stateMachine.ProcessString(scrollSeq);
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
|
||||
@@ -4403,3 +4427,170 @@ void ScreenBufferTests::InitializeTabStopsInVTMode()
|
||||
|
||||
VERIFY_IS_TRUE(gci.GetActiveOutputBuffer().AreTabsSet());
|
||||
}
|
||||
|
||||
void ScreenBufferTests::CursorUpDownAcrossMargins()
|
||||
{
|
||||
// Test inspired by: https://github.com/microsoft/terminal/issues/2929
|
||||
// echo -e "\e[6;19r\e[24H\e[99AX\e[1H\e[99BY\e[r"
|
||||
// This does the following:
|
||||
// * sets the top and bottom DECSTBM margins to 6 and 19
|
||||
// * moves to line 24 (i.e. below the bottom margin)
|
||||
// * executes the CUU sequence with a count of 99, to move up 99 lines
|
||||
// * writes out X
|
||||
// * moves to line 1 (i.e. above the top margin)
|
||||
// * executes the CUD sequence with a count of 99, to move down 99 lines
|
||||
// * writes out Y
|
||||
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
auto& si = gci.GetActiveOutputBuffer();
|
||||
auto& tbi = si.GetTextBuffer();
|
||||
auto& stateMachine = si.GetStateMachine();
|
||||
auto& cursor = si.GetTextBuffer().GetCursor();
|
||||
|
||||
VERIFY_IS_TRUE(si.GetViewport().BottomInclusive() > 24);
|
||||
|
||||
// Set some scrolling margins
|
||||
stateMachine.ProcessString(L"\x1b[6;19r");
|
||||
stateMachine.ProcessString(L"\x1b[24H");
|
||||
VERIFY_ARE_EQUAL(23, cursor.GetPosition().Y);
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[99A");
|
||||
VERIFY_ARE_EQUAL(5, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"X");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 0, 5 });
|
||||
VERIFY_ARE_EQUAL(L"X", iter->Chars());
|
||||
}
|
||||
stateMachine.ProcessString(L"\x1b[1H");
|
||||
VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y);
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[99B");
|
||||
VERIFY_ARE_EQUAL(18, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"Y");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 0, 18 });
|
||||
VERIFY_ARE_EQUAL(L"Y", iter->Chars());
|
||||
}
|
||||
stateMachine.ProcessString(L"\x1b[r");
|
||||
}
|
||||
|
||||
void ScreenBufferTests::CursorUpDownOutsideMargins()
|
||||
{
|
||||
// Test inspired by the CursorUpDownAcrossMargins test.
|
||||
// echo -e "\e[6;19r\e[24H\e[1AX\e[1H\e[1BY\e[r"
|
||||
// This does the following:
|
||||
// * sets the top and bottom DECSTBM margins to 6 and 19
|
||||
// * moves to line 24 (i.e. below the bottom margin)
|
||||
// * executes the CUU sequence with a count of 1, to move up 1 lines (still below margins)
|
||||
// * writes out X
|
||||
// * moves to line 1 (i.e. above the top margin)
|
||||
// * executes the CUD sequence with a count of 1, to move down 1 lines (still above margins)
|
||||
// * writes out Y
|
||||
|
||||
// This test is different becasue the end location of the vertical movement
|
||||
// should not be within the margins at all. We should not clamp this
|
||||
// movement to be within the margins.
|
||||
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
auto& si = gci.GetActiveOutputBuffer();
|
||||
auto& tbi = si.GetTextBuffer();
|
||||
auto& stateMachine = si.GetStateMachine();
|
||||
auto& cursor = si.GetTextBuffer().GetCursor();
|
||||
|
||||
VERIFY_IS_TRUE(si.GetViewport().BottomInclusive() > 24);
|
||||
|
||||
// Set some scrolling margins
|
||||
stateMachine.ProcessString(L"\x1b[6;19r");
|
||||
stateMachine.ProcessString(L"\x1b[24H");
|
||||
VERIFY_ARE_EQUAL(23, cursor.GetPosition().Y);
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[1A");
|
||||
VERIFY_ARE_EQUAL(22, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"X");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 0, 22 });
|
||||
VERIFY_ARE_EQUAL(L"X", iter->Chars());
|
||||
}
|
||||
stateMachine.ProcessString(L"\x1b[1H");
|
||||
VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y);
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[1B");
|
||||
VERIFY_ARE_EQUAL(1, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"Y");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 0, 1 });
|
||||
VERIFY_ARE_EQUAL(L"Y", iter->Chars());
|
||||
}
|
||||
stateMachine.ProcessString(L"\x1b[r");
|
||||
}
|
||||
|
||||
void ScreenBufferTests::CursorUpDownExactlyAtMargins()
|
||||
{
|
||||
// Test inspired by the CursorUpDownAcrossMargins test.
|
||||
// echo -e "\e[6;19r\e[19H\e[1B1\e[1A2\e[6H\e[1A3\e[1B4\e[r"
|
||||
// This does the following:
|
||||
// * sets the top and bottom DECSTBM margins to 6 and 19
|
||||
// * moves to line 19 (i.e. on the bottom margin)
|
||||
// * executes the CUD sequence with a count of 1, to move down 1 lines (still on the margin)
|
||||
// * writes out 1
|
||||
// * executes the CUU sequence with a count of 1, to move up 1 lines (now inside margins)
|
||||
// * writes out 2
|
||||
// * moves to line 6 (i.e. on the top margin)
|
||||
// * executes the CUU sequence with a count of 1, to move up 1 lines (still on the margin)
|
||||
// * writes out 3
|
||||
// * executes the CUD sequence with a count of 1, to move down 1 lines (still above margins)
|
||||
// * writes out 4
|
||||
|
||||
// This test is different becasue the starting location for these scroll
|
||||
// operations is _exactly_ on the margins
|
||||
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
auto& si = gci.GetActiveOutputBuffer();
|
||||
auto& tbi = si.GetTextBuffer();
|
||||
auto& stateMachine = si.GetStateMachine();
|
||||
auto& cursor = si.GetTextBuffer().GetCursor();
|
||||
|
||||
VERIFY_IS_TRUE(si.GetViewport().BottomInclusive() > 24);
|
||||
|
||||
// Set some scrolling margins
|
||||
stateMachine.ProcessString(L"\x1b[6;19r");
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[19;1H");
|
||||
VERIFY_ARE_EQUAL(18, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"\x1b[1B");
|
||||
VERIFY_ARE_EQUAL(18, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"1");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 0, 18 });
|
||||
VERIFY_ARE_EQUAL(L"1", iter->Chars());
|
||||
}
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[1A");
|
||||
VERIFY_ARE_EQUAL(17, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"2");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 1, 17 });
|
||||
VERIFY_ARE_EQUAL(L"2", iter->Chars());
|
||||
}
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[6;1H");
|
||||
VERIFY_ARE_EQUAL(5, cursor.GetPosition().Y);
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[1A");
|
||||
VERIFY_ARE_EQUAL(5, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"3");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 0, 5 });
|
||||
VERIFY_ARE_EQUAL(L"3", iter->Chars());
|
||||
}
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[1B");
|
||||
VERIFY_ARE_EQUAL(6, cursor.GetPosition().Y);
|
||||
stateMachine.ProcessString(L"4");
|
||||
{
|
||||
auto iter = tbi.GetCellDataAt({ 1, 6 });
|
||||
VERIFY_ARE_EQUAL(L"4", iter->Chars());
|
||||
}
|
||||
|
||||
stateMachine.ProcessString(L"\x1b[r");
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@ class TextBufferTests
|
||||
|
||||
TEST_METHOD(TestWrapFlag);
|
||||
|
||||
TEST_METHOD(TestWrapThroughWriteLine);
|
||||
|
||||
TEST_METHOD(TestDoubleBytePadFlag);
|
||||
|
||||
void DoBoundaryTest(PWCHAR const pwszInputString,
|
||||
@@ -197,6 +199,78 @@ void TextBufferTests::TestWrapFlag()
|
||||
VERIFY_IS_FALSE(Row.GetCharRow().WasWrapForced());
|
||||
}
|
||||
|
||||
void TextBufferTests::TestWrapThroughWriteLine()
|
||||
{
|
||||
TextBuffer& textBuffer = GetTbi();
|
||||
|
||||
auto VerifyWrap = [&](bool expected) {
|
||||
ROW& Row = textBuffer._GetFirstRow();
|
||||
|
||||
if (expected)
|
||||
{
|
||||
VERIFY_IS_TRUE(Row.GetCharRow().WasWrapForced());
|
||||
}
|
||||
else
|
||||
{
|
||||
VERIFY_IS_FALSE(Row.GetCharRow().WasWrapForced());
|
||||
}
|
||||
};
|
||||
|
||||
// Construct string for testing
|
||||
const auto width = textBuffer.GetSize().Width();
|
||||
std::wstring chars = L"";
|
||||
for (auto i = 0; i < width; i++)
|
||||
{
|
||||
chars.append(L"a");
|
||||
}
|
||||
const auto lineOfText = std::move(chars);
|
||||
|
||||
Log::Comment(L"Case 1 : Implicit wrap (false)");
|
||||
{
|
||||
TextAttribute expectedAttr(FOREGROUND_RED);
|
||||
OutputCellIterator it(lineOfText, expectedAttr);
|
||||
|
||||
textBuffer.WriteLine(it, { 0, 0 });
|
||||
VerifyWrap(false);
|
||||
}
|
||||
|
||||
Log::Comment(L"Case 2 : wrap = true");
|
||||
{
|
||||
TextAttribute expectedAttr(FOREGROUND_RED);
|
||||
OutputCellIterator it(lineOfText, expectedAttr);
|
||||
|
||||
textBuffer.WriteLine(it, { 0, 0 }, true);
|
||||
VerifyWrap(true);
|
||||
}
|
||||
|
||||
Log::Comment(L"Case 3: wrap = nullopt (remain as TRUE)");
|
||||
{
|
||||
TextAttribute expectedAttr(FOREGROUND_RED);
|
||||
OutputCellIterator it(lineOfText, expectedAttr);
|
||||
|
||||
textBuffer.WriteLine(it, { 0, 0 }, std::nullopt);
|
||||
VerifyWrap(true);
|
||||
}
|
||||
|
||||
Log::Comment(L"Case 4: wrap = false");
|
||||
{
|
||||
TextAttribute expectedAttr(FOREGROUND_RED);
|
||||
OutputCellIterator it(lineOfText, expectedAttr);
|
||||
|
||||
textBuffer.WriteLine(it, { 0, 0 }, false);
|
||||
VerifyWrap(false);
|
||||
}
|
||||
|
||||
Log::Comment(L"Case 5: wrap = nullopt (remain as false)");
|
||||
{
|
||||
TextAttribute expectedAttr(FOREGROUND_RED);
|
||||
OutputCellIterator it(lineOfText, expectedAttr);
|
||||
|
||||
textBuffer.WriteLine(it, { 0, 0 }, std::nullopt);
|
||||
VerifyWrap(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TextBufferTests::TestDoubleBytePadFlag()
|
||||
{
|
||||
TextBuffer& textBuffer = GetTbi();
|
||||
|
||||
@@ -121,12 +121,13 @@ class Microsoft::Console::Render::VtRendererTest
|
||||
|
||||
TEST_METHOD(TestResize);
|
||||
|
||||
TEST_METHOD(TestCursorVisibility);
|
||||
|
||||
void Test16Colors(VtEngine* engine);
|
||||
|
||||
std::deque<std::string> qExpectedInput;
|
||||
bool WriteCallback(const char* const pch, size_t const cch);
|
||||
void TestPaint(VtEngine& engine, std::function<void()> pfn);
|
||||
void TestPaintXterm(XtermEngine& engine, std::function<void()> pfn);
|
||||
Viewport SetUpViewport();
|
||||
};
|
||||
|
||||
@@ -173,38 +174,6 @@ void VtRendererTest::TestPaint(VtEngine& engine, std::function<void()> pfn)
|
||||
VERIFY_SUCCEEDED(engine.EndPaint());
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Small helper to do a series of testing wrapped by StartPaint/EndPaint calls
|
||||
// Also expects \x1b[?25l and \x1b[?25h on start/stop, for cursor visibility
|
||||
// Arguments:
|
||||
// - engine: the engine to operate on
|
||||
// - pfn: A function pointer to some test code to run.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void VtRendererTest::TestPaintXterm(XtermEngine& engine, std::function<void()> pfn)
|
||||
{
|
||||
HRESULT hr = engine.StartPaint();
|
||||
pfn();
|
||||
// If we didn't have anything to do on this frame, still execute our
|
||||
// callback, but don't check for the following ?25h
|
||||
if (hr != S_FALSE)
|
||||
{
|
||||
// If the engine has decided that it needs to disble the cursor, it'll
|
||||
// insert ?25l to the front of the buffer (which won't hit this
|
||||
// callback) and write ?25h to the end of the frame
|
||||
if (engine._needToDisableCursor)
|
||||
{
|
||||
qExpectedInput.push_back("\x1b[?25h");
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_SUCCEEDED(engine.EndPaint());
|
||||
|
||||
VERIFY_ARE_EQUAL(qExpectedInput.size(),
|
||||
static_cast<size_t>(0),
|
||||
L"Done painting, there shouldn't be any output we're still expecting");
|
||||
}
|
||||
|
||||
void VtRendererTest::VtSequenceHelperTests()
|
||||
{
|
||||
wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE);
|
||||
@@ -298,7 +267,7 @@ void VtRendererTest::Xterm256TestInvalidate()
|
||||
L"Make sure that scrolling only invalidates part of the viewport, and sends the right sequences"));
|
||||
COORD scrollDelta = { 0, 1 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled one down, only top line is invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -314,7 +283,7 @@ void VtRendererTest::Xterm256TestInvalidate()
|
||||
scrollDelta = { 0, 3 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled three down, only top 3 lines are invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -328,7 +297,7 @@ void VtRendererTest::Xterm256TestInvalidate()
|
||||
|
||||
scrollDelta = { 0, -1 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled one up, only bottom line is invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -343,7 +312,7 @@ void VtRendererTest::Xterm256TestInvalidate()
|
||||
|
||||
scrollDelta = { 0, -3 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled three up, only bottom 3 lines are invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -363,7 +332,7 @@ void VtRendererTest::Xterm256TestInvalidate()
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
scrollDelta = { 0, 2 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled three down, only top 3 lines are invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -557,8 +526,6 @@ void VtRendererTest::Xterm256TestCursor()
|
||||
L"----move to the start of this line (y stays the same)----"));
|
||||
qExpectedInput.push_back("\r");
|
||||
VERIFY_SUCCEEDED(engine->_MoveCursor({ 0, 1 }));
|
||||
|
||||
qExpectedInput.push_back("\x1b[?25h");
|
||||
});
|
||||
|
||||
TestPaint(*engine, [&]() {
|
||||
@@ -629,7 +596,7 @@ void VtRendererTest::XtermTestInvalidate()
|
||||
L"Make sure that invalidating anything only invalidates that portion"));
|
||||
SMALL_RECT invalid = { 1, 1, 1, 1 };
|
||||
VERIFY_SUCCEEDED(engine->Invalidate(&invalid));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
VERIFY_ARE_EQUAL(invalid, engine->_invalidRect.ToExclusive());
|
||||
});
|
||||
|
||||
@@ -637,7 +604,7 @@ void VtRendererTest::XtermTestInvalidate()
|
||||
L"Make sure that scrolling only invalidates part of the viewport, and sends the right sequences"));
|
||||
COORD scrollDelta = { 0, 1 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled one down, only top line is invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -652,7 +619,7 @@ void VtRendererTest::XtermTestInvalidate()
|
||||
|
||||
scrollDelta = { 0, 3 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled three down, only top 3 lines are invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -666,7 +633,7 @@ void VtRendererTest::XtermTestInvalidate()
|
||||
|
||||
scrollDelta = { 0, -1 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled one up, only bottom line is invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -681,7 +648,7 @@ void VtRendererTest::XtermTestInvalidate()
|
||||
|
||||
scrollDelta = { 0, -3 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled three up, only bottom 3 lines are invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -701,7 +668,7 @@ void VtRendererTest::XtermTestInvalidate()
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
scrollDelta = { 0, 2 };
|
||||
VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"---- Scrolled three down, only top 3 lines are invalid. ----"));
|
||||
invalid = view.ToExclusive();
|
||||
@@ -864,8 +831,6 @@ void VtRendererTest::XtermTestCursor()
|
||||
L"----move to the start of this line (y stays the same)----"));
|
||||
qExpectedInput.push_back("\r");
|
||||
VERIFY_SUCCEEDED(engine->_MoveCursor({ 0, 1 }));
|
||||
|
||||
qExpectedInput.push_back("\x1b[?25h");
|
||||
});
|
||||
|
||||
TestPaint(*engine, [&]() {
|
||||
@@ -1130,14 +1095,14 @@ void VtRendererTest::TestWrapping()
|
||||
|
||||
Viewport view = SetUpViewport();
|
||||
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Make sure the cursor is at 0,0"));
|
||||
qExpectedInput.push_back("\x1b[H");
|
||||
VERIFY_SUCCEEDED(engine->_MoveCursor({ 0, 0 }));
|
||||
});
|
||||
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Painting a line that wrapped, then painting another line, and "
|
||||
L"making sure we don't manually move the cursor between those paints."));
|
||||
@@ -1196,9 +1161,125 @@ void VtRendererTest::TestResize()
|
||||
|
||||
VERIFY_SUCCEEDED(engine->UpdateViewport(newView.ToInclusive()));
|
||||
|
||||
TestPaintXterm(*engine, [&]() {
|
||||
TestPaint(*engine, [&]() {
|
||||
VERIFY_ARE_EQUAL(newView, engine->_invalidRect);
|
||||
VERIFY_IS_FALSE(engine->_firstPaint);
|
||||
VERIFY_IS_FALSE(engine->_suppressResizeRepaint);
|
||||
});
|
||||
}
|
||||
|
||||
void VtRendererTest::TestCursorVisibility()
|
||||
{
|
||||
Viewport view = SetUpViewport();
|
||||
wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE);
|
||||
auto engine = std::make_unique<Xterm256Engine>(std::move(hFile), _shutdownEvent, p, view, g_ColorTable, static_cast<WORD>(COLOR_TABLE_SIZE));
|
||||
auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2);
|
||||
engine->SetTestCallback(pfn);
|
||||
|
||||
// Verify the first paint emits a clear
|
||||
qExpectedInput.push_back("\x1b[2J");
|
||||
VERIFY_IS_TRUE(engine->_firstPaint);
|
||||
VERIFY_IS_FALSE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_TRUE(engine->_nextCursorIsVisible);
|
||||
TestPaint(*engine, [&]() {
|
||||
// During StartPaint, we'll mark the cursor as off. make sure that happens.
|
||||
VERIFY_IS_FALSE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_firstPaint);
|
||||
});
|
||||
|
||||
// The cursor wasn't painted in the last frame.
|
||||
VERIFY_IS_FALSE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_nextCursorIsVisible);
|
||||
|
||||
COORD origin{ 0, 0 };
|
||||
|
||||
VERIFY_ARE_NOT_EQUAL(origin, engine->_lastText);
|
||||
|
||||
IRenderEngine::CursorOptions options{};
|
||||
options.coordCursor = origin;
|
||||
|
||||
// Frame 1: Paint the cursor at the home position. At the end of the frame,
|
||||
// the cursor should be on. Because we're moving the cursor with CUP, we
|
||||
// need to disable the cursor during this frame.
|
||||
TestPaint(*engine, [&]() {
|
||||
VERIFY_IS_FALSE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
|
||||
Log::Comment(NoThrowString().Format(L"Make sure the cursor is at 0,0"));
|
||||
qExpectedInput.push_back("\x1b[H");
|
||||
VERIFY_SUCCEEDED(engine->PaintCursor(options));
|
||||
|
||||
VERIFY_IS_TRUE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_TRUE(engine->_needToDisableCursor);
|
||||
|
||||
qExpectedInput.push_back("\x1b[?25h");
|
||||
});
|
||||
|
||||
VERIFY_IS_TRUE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_TRUE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
|
||||
// Frame 2: Paint the cursor again at the home position. At the end of the
|
||||
// frame, the cursor should be on, the same as before. We aren't moving the
|
||||
// cursor during this frame, so _needToDisableCursor will stay false.
|
||||
TestPaint(*engine, [&]() {
|
||||
VERIFY_IS_TRUE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
|
||||
Log::Comment(NoThrowString().Format(L"If we just paint the cursor again at the same position, the cursor should not need to be disabled"));
|
||||
VERIFY_SUCCEEDED(engine->PaintCursor(options));
|
||||
|
||||
VERIFY_IS_TRUE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
});
|
||||
|
||||
VERIFY_IS_TRUE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_TRUE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
|
||||
// Frame 3: Paint the cursor at 2,2. At the end of the frame, the cursor
|
||||
// should be on, the same as before. Because we're moving the cursor with
|
||||
// CUP, we need to disable the cursor during this frame.
|
||||
TestPaint(*engine, [&]() {
|
||||
VERIFY_IS_TRUE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
|
||||
Log::Comment(NoThrowString().Format(L"Move the cursor to 2,2"));
|
||||
qExpectedInput.push_back("\x1b[3;3H");
|
||||
|
||||
options.coordCursor = { 2, 2 };
|
||||
|
||||
VERIFY_SUCCEEDED(engine->PaintCursor(options));
|
||||
|
||||
VERIFY_IS_TRUE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_TRUE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_TRUE(engine->_needToDisableCursor);
|
||||
|
||||
// Because _needToDisableCursor is true, we'll insert a ?25l at the
|
||||
// start of the frame. Unfortunately, we can't test to make sure that
|
||||
// it's there, but we can ensure that the matching ?25h is printed:
|
||||
qExpectedInput.push_back("\x1b[?25h");
|
||||
});
|
||||
|
||||
VERIFY_IS_TRUE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_TRUE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
|
||||
// Frame 4: Don't paint the cursor. At the end of the frame, the cursor
|
||||
// should be off.
|
||||
Log::Comment(NoThrowString().Format(L"Painting without calling PaintCursor will hide the cursor"));
|
||||
TestPaint(*engine, [&]() {
|
||||
VERIFY_IS_TRUE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
|
||||
qExpectedInput.push_back("\x1b[?25l");
|
||||
});
|
||||
|
||||
VERIFY_IS_FALSE(engine->_lastCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_nextCursorIsVisible);
|
||||
VERIFY_IS_FALSE(engine->_needToDisableCursor);
|
||||
}
|
||||
|
||||
@@ -454,7 +454,7 @@ VOID ConIoSrvComm::CleanupForHeadless(const NTSTATUS status)
|
||||
ServiceLocator::LocateGlobals().ntstatusConsoleInputInitStatus = status;
|
||||
|
||||
// Signal that input is ready to go.
|
||||
ServiceLocator::LocateGlobals().hConsoleInputInitEvent.SetEvent();
|
||||
ServiceLocator::LocateGlobals().consoleInputInitializedEvent.SetEvent();
|
||||
|
||||
_fIsInputInitialized = true;
|
||||
}
|
||||
|
||||
@@ -54,10 +54,13 @@ DWORD WINAPI ConsoleInputThreadProcOneCore(LPVOID /*lpParam*/)
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
globals.getConsoleInformation().GetActiveOutputBuffer().RefreshFontWithRenderer();
|
||||
}
|
||||
|
||||
globals.ntstatusConsoleInputInitStatus = Status;
|
||||
globals.hConsoleInputInitEvent.SetEvent();
|
||||
globals.ntstatusConsoleInputInitStatus = Status;
|
||||
globals.consoleInputInitializedEvent.SetEvent();
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Start listening for input (returns on failure only).
|
||||
|
||||
@@ -70,6 +70,7 @@ TARGETLIBS = \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
|
||||
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \
|
||||
$(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \
|
||||
$(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \
|
||||
$(WINCORE_OBJ_PATH)\console\open\src\buffer\out\lib\$(O)\conbufferout.lib \
|
||||
|
||||
6
src/propsheet/packages.config
Normal file
6
src/propsheet/packages.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
</packages>
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="..\common.build.pre.props" />
|
||||
<ItemGroup>
|
||||
<ClCompile Include="console.cpp" />
|
||||
@@ -48,6 +51,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="console.def" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -83,4 +87,18 @@
|
||||
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
|
||||
<Import Project="..\common.build.dll.props" />
|
||||
<Import Project="..\common.build.post.props" />
|
||||
</Project>
|
||||
<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.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
@@ -45,9 +45,6 @@
|
||||
<ClCompile Include="PropSheetHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="readLink.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="registry.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -63,6 +60,12 @@
|
||||
<ClCompile Include="LayoutPage.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ColorControl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalPage.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="globals.h">
|
||||
@@ -95,6 +98,12 @@
|
||||
<ClInclude Include="LayoutPage.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ColorControl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TerminalPage.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="console.rc">
|
||||
@@ -110,5 +119,9 @@
|
||||
<None Include="console.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -22,7 +22,9 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
|
||||
_fUseAsciiOnly(fUseAsciiOnly),
|
||||
_previousLineWrapped(false),
|
||||
_usingUnderLine(false),
|
||||
_needToDisableCursor(false)
|
||||
_needToDisableCursor(false),
|
||||
_lastCursorIsVisible(false),
|
||||
_nextCursorIsVisible(true)
|
||||
{
|
||||
// Set out initial cursor position to -1, -1. This will force our initial
|
||||
// paint to manually move the cursor to 0, 0, not just ignore it.
|
||||
@@ -45,6 +47,11 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
|
||||
|
||||
_trace.TraceLastText(_lastText);
|
||||
|
||||
// Prep us to think that the cursor is not visible this frame. If it _is_
|
||||
// visible, then PaintCursor will be called, and we'll set this to true
|
||||
// during the frame.
|
||||
_nextCursorIsVisible = false;
|
||||
|
||||
if (_firstPaint)
|
||||
{
|
||||
// MSFT:17815688
|
||||
@@ -73,14 +80,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
|
||||
|
||||
if (!_quickReturn)
|
||||
{
|
||||
if (!_WillWriteSingleChar())
|
||||
{
|
||||
// MSFT:TODO:20331739
|
||||
// Make sure to match the cursor visibility in the terminal to the console's
|
||||
// // Turn off cursor
|
||||
// RETURN_IF_FAILED(_HideCursor());
|
||||
}
|
||||
else
|
||||
if (_WillWriteSingleChar())
|
||||
{
|
||||
// Don't re-enable the cursor.
|
||||
_quickReturn = true;
|
||||
@@ -99,22 +99,38 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
|
||||
// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
|
||||
[[nodiscard]] HRESULT XtermEngine::EndPaint() noexcept
|
||||
{
|
||||
// MSFT:TODO:20331739
|
||||
// Make sure to match the cursor visibility in the terminal to the console's
|
||||
// if (!_quickReturn)
|
||||
// {
|
||||
// // Turn on cursor
|
||||
// RETURN_IF_FAILED(_ShowCursor());
|
||||
// }
|
||||
|
||||
// If during the frame we determined that the cursor needed to be disabled,
|
||||
// then insert a cursor off at the start of the buffer, and re-enable
|
||||
// the cursor here.
|
||||
if (_needToDisableCursor)
|
||||
{
|
||||
_buffer.insert(0, "\x1b[25l");
|
||||
// If the cursor was previously visible, let's hide it for this frame,
|
||||
// by prepending a cursor off.
|
||||
if (_lastCursorIsVisible)
|
||||
{
|
||||
_buffer.insert(0, "\x1b[25l");
|
||||
_lastCursorIsVisible = false;
|
||||
}
|
||||
// If the cursor was NOT previously visible, then that's fine! we don't
|
||||
// need to worry, it's already off.
|
||||
}
|
||||
|
||||
// If the cursor is moving from off -> on (including cases where we just
|
||||
// disabled if for this frame), show the cursor at the end of the frame
|
||||
if (_nextCursorIsVisible && !_lastCursorIsVisible)
|
||||
{
|
||||
RETURN_IF_FAILED(_ShowCursor());
|
||||
}
|
||||
// Otherwise, if the cursor previously was visible, and it should be hidden
|
||||
// (on -> off), hide it at the end of the frame.
|
||||
else if (!_nextCursorIsVisible && _lastCursorIsVisible)
|
||||
{
|
||||
RETURN_IF_FAILED(_HideCursor());
|
||||
}
|
||||
|
||||
// Update our tracker of what we thought the last cursor state of the
|
||||
// terminal was.
|
||||
_lastCursorIsVisible = _nextCursorIsVisible;
|
||||
|
||||
RETURN_IF_FAILED(VtEngine::EndPaint());
|
||||
|
||||
@@ -178,6 +194,27 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
|
||||
return VtEngine::_16ColorUpdateDrawingBrushes(colorForeground, colorBackground, isBold, _ColorTable, _cColorTable);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Draws the cursor on the screen
|
||||
// Arguments:
|
||||
// - options - Options that affect the presentation of the cursor
|
||||
// Return Value:
|
||||
// - S_OK or suitable HRESULT error from writing pipe.
|
||||
[[nodiscard]] HRESULT XtermEngine::PaintCursor(const IRenderEngine::CursorOptions& options) noexcept
|
||||
{
|
||||
// PaintCursor is only called when the cursor is in fact visible in a single
|
||||
// frame. When this is called, mark _nextCursorIsVisible as true. At the end
|
||||
// of the frame, we'll decide to either turn the cursor on or not, based
|
||||
// upon the previous state.
|
||||
|
||||
// When this method is not called during a frame, it's because the cursor
|
||||
// was not visible. In that case, at the end of the frame,
|
||||
// _nextCursorIsVisible will still be false (from when we set it during
|
||||
// StartPaint)
|
||||
_nextCursorIsVisible = true;
|
||||
return VtEngine::PaintCursor(options);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Write a VT sequence to move the cursor to the specified coordinates. We
|
||||
// also store the last place we left the cursor for future optimizations.
|
||||
|
||||
@@ -40,6 +40,8 @@ namespace Microsoft::Console::Render
|
||||
[[nodiscard]] HRESULT StartPaint() noexcept override;
|
||||
[[nodiscard]] HRESULT EndPaint() noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
|
||||
|
||||
[[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const COLORREF colorForeground,
|
||||
const COLORREF colorBackground,
|
||||
const WORD legacyColorAttribute,
|
||||
@@ -61,6 +63,8 @@ namespace Microsoft::Console::Render
|
||||
bool _previousLineWrapped;
|
||||
bool _usingUnderLine;
|
||||
bool _needToDisableCursor;
|
||||
bool _lastCursorIsVisible;
|
||||
bool _nextCursorIsVisible;
|
||||
|
||||
[[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept override;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Microsoft::Console::Render
|
||||
const COORD coordTarget) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
|
||||
[[nodiscard]] virtual HRESULT PaintCursor(const CursorOptions& options) noexcept override;
|
||||
|
||||
[[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const COLORREF colorForeground,
|
||||
const COLORREF colorBackground,
|
||||
|
||||
@@ -73,6 +73,7 @@ TARGETLIBS = \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
|
||||
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \
|
||||
$(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \
|
||||
$(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \
|
||||
$(WINCORE_OBJ_PATH)\console\open\src\buffer\out\lib\$(O)\conbufferout.lib \
|
||||
|
||||
@@ -44,6 +44,17 @@ bool OutputStateMachineEngine::ActionExecute(const wchar_t wch)
|
||||
{
|
||||
_dispatch->Execute(wch);
|
||||
_ClearLastChar();
|
||||
|
||||
if (wch == AsciiChars::BEL)
|
||||
{
|
||||
// microsoft/terminal#2952
|
||||
// If we're attached to a terminal, let's also pass the BEL through.
|
||||
if (_pfnFlushToTerminal != nullptr)
|
||||
{
|
||||
_pfnFlushToTerminal();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ TARGETLIBS = \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
|
||||
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \
|
||||
$(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \
|
||||
$(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \
|
||||
$(CONSOLE_OBJ_PATH)\buffer\out\lib\$(O)\conbufferout.lib \
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<RootNamespace>VtPipeTerm</RootNamespace>
|
||||
<ProjectName>VtPipeTerm</ProjectName>
|
||||
<TargetName>VtPipeTerm</TargetName>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
|
||||
6
src/winconpty/packages.config
Normal file
6
src/winconpty/packages.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.0.0-beta2-19367-01" targetFramework="native" developmentDependency="true" />
|
||||
</packages>
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" />
|
||||
<Import Project="$(SolutionDir)src\common.build.pre.props" />
|
||||
<ItemGroup>
|
||||
<ClCompile Include="winconpty.cpp" />
|
||||
@@ -8,6 +11,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="../server/DeviceHandle.cpp" />
|
||||
<ClCompile Include="../server/WinNTControl.cpp" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="winconpty.def" />
|
||||
</ItemGroup>
|
||||
<ItemDefinitionGroup>
|
||||
@@ -25,13 +29,25 @@
|
||||
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
|
||||
<Import Project="$(SolutionDir)src\common.build.dll.props" />
|
||||
<Import Project="$(SolutionDir)src\common.build.post.props" />
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>winconpty.def</ModuleDefinitionFile>
|
||||
|
||||
<!-- Force APISet to the beginning of the link line; GH#922 -->
|
||||
<AdditionalDependencies>onecoreuap_apiset.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
<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.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.0.0-beta2-19367-01\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0-beta2-19367-01\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
</Project>
|
||||
Reference in New Issue
Block a user