Merge remote-tracking branch 'origin/master' into dev/migrie/f/2046-command-palette
# Conflicts: # src/cascadia/inc/cppwinrt_utils.h
This commit is contained in:
commit
75375d721c
2
.github/ISSUE_TEMPLATE/Bug_Report.md
vendored
2
.github/ISSUE_TEMPLATE/Bug_Report.md
vendored
|
@ -26,6 +26,8 @@ This bug tracker is monitored by Windows Terminal development team and other tec
|
|||
**Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**.
|
||||
Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue.
|
||||
|
||||
If this is an application crash, please also provide a Feedback Hub submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal (Preview)" and choose "Share My Feedback" after submission to get the link.
|
||||
|
||||
Please use this form and describe your issue, concisely but precisely, with as much detail as possible.
|
||||
|
||||
-->
|
||||
|
|
|
@ -464,11 +464,8 @@ Global
|
|||
{06EC74CB-9A12-429C-B551-8562EC954747}.Release|x86.ActiveCfg = Release|Win32
|
||||
{06EC74CB-9A12-429C-B551-8562EC954747}.Release|x86.Build.0 = Release|Win32
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.AuditMode|x64.Build.0 = Release|x64
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -482,11 +479,8 @@ Global
|
|||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.Release|x86.ActiveCfg = Release|Win32
|
||||
{531C23E7-4B76-4C08-8AAD-04164CB628C9}.Release|x86.Build.0 = Release|Win32
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.AuditMode|x64.Build.0 = Release|x64
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -500,11 +494,8 @@ Global
|
|||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.Release|x86.ActiveCfg = Release|Win32
|
||||
{531C23E7-4B76-4C08-8BBD-04164CB628C9}.Release|x86.Build.0 = Release|Win32
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.AuditMode|x64.Build.0 = Release|x64
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -516,11 +507,8 @@ Global
|
|||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.Release|x64.Build.0 = Release|x64
|
||||
{8CDB8850-7484-4EC7-B45B-181F85B2EE54}.Release|x86.ActiveCfg = Release|Win32
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.AuditMode|x64.Build.0 = Release|x64
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -534,11 +522,8 @@ Global
|
|||
{12144E07-FE63-4D33-9231-748B8D8C3792}.Release|x86.ActiveCfg = Release|Win32
|
||||
{12144E07-FE63-4D33-9231-748B8D8C3792}.Release|x86.Build.0 = Release|Win32
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.AuditMode|x64.Build.0 = Release|x64
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -552,11 +537,8 @@ Global
|
|||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6AF01638-84CF-4B65-9870-484DFFCAC772}.Release|x86.Build.0 = Release|Win32
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.AuditMode|x64.Build.0 = Release|x64
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -570,11 +552,8 @@ Global
|
|||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.Release|x86.ActiveCfg = Release|Win32
|
||||
{96927B31-D6E8-4ABD-B03E-A5088A30BEBE}.Release|x86.Build.0 = Release|Win32
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.AuditMode|x64.Build.0 = Release|x64
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{F210A4AE-E02A-4BFC-80BB-F50A672FE763}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -624,11 +603,8 @@ Global
|
|||
{18D09A24-8240-42D6-8CB6-236EEE820262}.Release|x86.ActiveCfg = Release|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820262}.Release|x86.Build.0 = Release|Win32
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.AuditMode|ARM64.ActiveCfg = Debug|Win32
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.AuditMode|ARM64.Build.0 = Debug|Win32
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.AuditMode|x64.Build.0 = Release|x64
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.Debug|ARM64.ActiveCfg = Debug|Win32
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.Debug|x64.Build.0 = Debug|x64
|
||||
|
@ -640,11 +616,8 @@ Global
|
|||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C17E1BF3-9D34-4779-9458-A8EF98CC5662}.Release|x86.Build.0 = Release|Win32
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.AuditMode|ARM64.ActiveCfg = Debug|Win32
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.AuditMode|ARM64.Build.0 = Debug|Win32
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.AuditMode|x64.Build.0 = Release|x64
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.Debug|ARM64.ActiveCfg = Debug|Win32
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.Debug|x64.Build.0 = Debug|x64
|
||||
|
@ -656,11 +629,8 @@ Global
|
|||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{099193A0-1E43-4BBC-BA7F-7B351E1342DF}.Release|x86.Build.0 = Release|Win32
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.AuditMode|x64.Build.0 = Release|x64
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -674,11 +644,8 @@ Global
|
|||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.Release|x86.ActiveCfg = Release|Win32
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79}.Release|x86.Build.0 = Release|Win32
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.AuditMode|x64.Build.0 = Release|x64
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -692,11 +659,8 @@ Global
|
|||
{919544AC-D39B-463F-8414-3C3C67CF727C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{919544AC-D39B-463F-8414-3C3C67CF727C}.Release|x86.Build.0 = Release|Win32
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.AuditMode|x64.Build.0 = Release|x64
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{ED82003F-FC5D-4E94-8B36-F480018ED064}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -728,11 +692,8 @@ Global
|
|||
{06EC74CB-9A12-429C-B551-8532EC964726}.Release|x86.ActiveCfg = Release|Win32
|
||||
{06EC74CB-9A12-429C-B551-8532EC964726}.Release|x86.Build.0 = Release|Win32
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.AuditMode|x64.Build.0 = Release|x64
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{ED82003F-FC5D-4E94-8B47-F480018ED064}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -764,11 +725,8 @@ Global
|
|||
{06EC74CB-9A12-429C-B551-8562EC964846}.Release|x86.ActiveCfg = Release|Win32
|
||||
{06EC74CB-9A12-429C-B551-8562EC964846}.Release|x86.Build.0 = Release|Win32
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.AuditMode|x64.Build.0 = Release|x64
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -782,11 +740,8 @@ Global
|
|||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D3B92829-26CB-411A-BDA2-7F5DA3D25DD4}.Release|x86.Build.0 = Release|Win32
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.AuditMode|x64.Build.0 = Release|x64
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{C7A6A5D9-60BE-4AEB-A5F6-AFE352F86CBB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -818,11 +773,8 @@ Global
|
|||
{990F2657-8580-4828-943F-5DD657D11842}.Release|x86.ActiveCfg = Release|Win32
|
||||
{990F2657-8580-4828-943F-5DD657D11842}.Release|x86.Build.0 = Release|Win32
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.AuditMode|x64.Build.0 = Release|x64
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -836,11 +788,8 @@ Global
|
|||
{814DBDDE-894E-4327-A6E1-740504850098}.Release|x86.ActiveCfg = Release|Win32
|
||||
{814DBDDE-894E-4327-A6E1-740504850098}.Release|x86.Build.0 = Release|Win32
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.AuditMode|x64.Build.0 = Release|x64
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{814CBEEE-894E-4327-A6E1-740504850098}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -872,11 +821,8 @@ Global
|
|||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.ActiveCfg = Release|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.Build.0 = Release|Win32
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.AuditMode|x64.Build.0 = Release|x64
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{990F2657-8580-4828-943F-5DD657D11843}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -1061,11 +1007,8 @@ Global
|
|||
{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310}.Release|x86.Build.0 = Release|x86
|
||||
{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310}.Release|x86.Deploy.0 = Release|x86
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -1097,11 +1040,8 @@ Global
|
|||
{EF3E32A7-5FF6-42B4-B6E2-96CD7D033F00}.Release|x86.ActiveCfg = Release|Win32
|
||||
{EF3E32A7-5FF6-42B4-B6E2-96CD7D033F00}.Release|x86.Build.0 = Release|Win32
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -1115,11 +1055,8 @@ Global
|
|||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.ActiveCfg = Release|Win32
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
## Installation
|
||||
|
||||
_(Note: in order to run the Windows Terminal, you'll need to be running at least Windows build 18362 or higher.)_
|
||||
|
||||
### Microsoft Store
|
||||
|
||||
Download the Microsoft Terminal free from the Microsoft Store and it'll be continuously updated. Or, feel free to side-load [releases](https://github.com/microsoft/terminal/releases) from GitHub, but note they won't auto-update.
|
||||
|
|
|
@ -13,17 +13,20 @@ pr:
|
|||
branches:
|
||||
include:
|
||||
- master
|
||||
paths:
|
||||
exclude:
|
||||
- doc/*
|
||||
- samples/*
|
||||
- tools/*
|
||||
|
||||
# 0.0.yyMM.dd##
|
||||
# 0.0.1904.0900
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
jobs:
|
||||
# This is disabled because the build agents were running out of disk space.
|
||||
# We're pursuing that in the background, but the spice must flow in the meantime.
|
||||
# - template: ./templates/build-console-audit-job.yml
|
||||
# parameters:
|
||||
# platform: x64
|
||||
- template: ./templates/build-console-audit-job.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
|
|
|
@ -8,9 +8,9 @@ Settings in the Windows Console Host can be a bit tricky to understand. This is
|
|||
|---------------------------|-----------------------|--------------------------------------|
|
||||
|`FontSize` |Coordinate (REG_DWORD) |Size of font in pixels |
|
||||
|`FontFamily` |REG_DWORD |GDI Font family |
|
||||
|`ScreenBufferSize` |Coordinate (REG_DWORD) |Size of the screen buffer in WxH characters |
|
||||
|`ScreenBufferSize` |Coordinate (REG_DWORD) |Size of the screen buffer in WxH characters\*\* |
|
||||
|`CursorSize` |REG_DWORD |Cursor height as percentage of a single character |
|
||||
|`WindowSize` |Coordinate (REG_DWORD) |Initial size of the window in WxH characters |
|
||||
|`WindowSize` |Coordinate (REG_DWORD) |Initial size of the window in WxH characters\*\* |
|
||||
|`WindowPosition` |Coordinate (REG_DWORD) |Initial position of the window in WxH pixels (if not set, use auto-positioning) |
|
||||
|`WindowAlpha` |REG_DWORD |Opacity of the window (valid range: 0x4D-0xFF) |
|
||||
|`ScreenColors` |REG_DWORD |Default foreground and background colors |
|
||||
|
@ -39,6 +39,10 @@ Settings in the Windows Console Host can be a bit tricky to understand. This is
|
|||
|
||||
*: Only applies to the improved version of the Windows Console Host
|
||||
|
||||
**: WxH stands for Width by Height, it's the fact that things like a Window size
|
||||
store the Width and Height values in the high and low word in the registry's
|
||||
double word values.
|
||||
|
||||
## The Settings Hierarchy
|
||||
|
||||
Settings are persisted to a variety of locations depending on how they are modified and how the Windows Console Host was invoked:
|
||||
|
|
15
doc/bot.md
15
doc/bot.md
|
@ -64,6 +64,12 @@ We'll be using tags, primarily, to help us understand what needs attention, what
|
|||
- If an issue is filed matching a pattern that happens all the time (common duplicate phrase, obvious multiple-issues-in-one pattern)...
|
||||
- Then close the issue automatically informing the opener that they can resolve the problem and reopen the issue. (See Bug/Feature templates for example situations.)
|
||||
|
||||
#### Help ask for Feedback Hub
|
||||
- If an issue is tagged `Needs-Feedback-Hub`
|
||||
- Then reply to the issue with a bit of text on asking the author to send us data with Feedback Hub and give us the link.
|
||||
- And remove the `Needs-Feedback-Hub` tag
|
||||
- And add the `Needs-Author-Feedback` tag
|
||||
|
||||
### PR Management
|
||||
|
||||
#### Codeflow Link *(Disabled)*
|
||||
|
@ -98,5 +104,14 @@ We'll be using tags, primarily, to help us understand what needs attention, what
|
|||
#### Add committed fix tag for completed PRs
|
||||
- When a PR is finished and there's no outstanding work left on a linked issue, add the `Resolution-Fix-Committed` label
|
||||
|
||||
#### Remove Needs-Second from completed PRs
|
||||
- If a PR is closed and it has the `Needs-Second` tag, the bot will remove the tag.
|
||||
|
||||
### Release Management
|
||||
|
||||
When a release is created, if the PR ID number is linked inside the release description, the bot will walk through the related PR and all of its related issues and leave a message.
|
||||
- PR message: "🎉{release name} {release version} has been released which incorporates this pull request.🎉
|
||||
- Issue message: 🎉This issue was addressed in #{pull request ID}, which has now been successfully released as {release name} {release version}.🎉"
|
||||
|
||||
## Admin Panel
|
||||
[Here](https://fabric-cp.azurewebsites.net/bot/)
|
||||
|
|
|
@ -25,7 +25,7 @@ Properties listed below are specific to each unique profile.
|
|||
| `commandline` | _Required_ | String | `powershell.exe` | Executable used in the profile. |
|
||||
| `cursorColor` | _Required_ | String | `#FFFFFF` | Sets the cursor color for the profile. Uses hex color format: `"#rrggbb"`. |
|
||||
| `cursorShape` | _Required_ | String | `bar` | Sets the cursor shape for the profile. Possible values: `"vintage"` ( ▃ ), `"bar"` ( ┃ ), `"underscore"` ( ▁ ), `"filledBox"` ( █ ), `"emptyBox"` ( ▯ ) |
|
||||
| `fontFace` | _Required_ | String | `Consolas` | Name of the font face used in the profile. |
|
||||
| `fontFace` | _Required_ | String | `Consolas` | Name of the font face used in the profile. We will try to fallback to Consolas if this can't be found or is invalid. |
|
||||
| `fontSize` | _Required_ | Integer | `10` | Sets the font size. |
|
||||
| `guid` | _Required_ | String | | Unique identifier of the profile. Written in registry format: `"{00000000-0000-0000-0000-000000000000}"`. |
|
||||
| `historySize` | _Required_ | Integer | `9001` | The number of lines above the ones displayed in the window you can scroll back to. |
|
||||
|
|
255
doc/specs/#976 - VT52 escape sequences.md
Normal file
255
doc/specs/#976 - VT52 escape sequences.md
Normal file
|
@ -0,0 +1,255 @@
|
|||
---
|
||||
author: James Holderness @j4james
|
||||
created on: 2019-07-17
|
||||
last updated: 2019-07-28
|
||||
issue id: 976
|
||||
---
|
||||
|
||||
# VT52 Escape Sequences
|
||||
|
||||
## Abstract
|
||||
|
||||
This spec outlines the work required to split off the existing VT52 commands from the VT100 implementation, and extend the VT52 support to cover all of the core commands.
|
||||
|
||||
## Inspiration
|
||||
|
||||
The existing VT52 commands aren't currently implemented as a separate mode, so they conflict with sequences defined in the VT100 specification. This is blocking us from adding support for the VT100 Index (IND) escape sequence, which is one of the missing commands required to pass the test of cursor movements in Vttest.
|
||||
|
||||
## Solution Design
|
||||
|
||||
The basic idea is to add support for the [DECANM private mode sequence](https://vt100.net/docs/vt100-ug/chapter3.html#DECANM), which can then be used to switch from the default _ANSI_ mode, to a new _VT52_ mode. Once in _VT52_ mode, there is a separate [_Enter ANSI Mode_ sequence](https://vt100.net/docs/vt100-ug/chapter3.html#VT52ANSI) (`ESC <`) to switch back again.
|
||||
|
||||
In terms of implementation, there are a number of areas of the system that would need to be updated.
|
||||
|
||||
### The State Machine
|
||||
|
||||
In order to implement the VT52 compatibility mode correctly, we'll need to introduce a flag in the `StateMachine` class that indicates the mode that is currently active. When in VT52 mode, certain paths in the state diagram should not be followed - for example, you can't have CSI, OSC, or SS3 escape sequences. There would also need to be an additional state to handle VT52 parameters (for the _Direct Cursor Address_ command). These parameters take a different form to the typical VT100 parameters, as they follow the command character instead of preceding it.
|
||||
|
||||
It would probably be best to introduce a new dispatch method in the `IStateMachineEngine` interface to handle the parsed VT52 sequences, since the existing `ActionEscDispatch` does not support parameters (which are required for the _Direct Cursor Address_ command). I think it would also make for a cleaner implementation to have the VT52 commands separate from the VT100 code, and would likely have less impact on the performance that way.
|
||||
|
||||
### The Terminal Input
|
||||
|
||||
The escape sequences generated by the keyboard for function keys, cursor keys, and the numeric keypad, are not the same in VT52 mode as they are in ANSI mode. So there would need to be a flag in the `TerminalInput` class to keep track of the current mode, and thus be able to generate the appropriate sequences for that mode.
|
||||
|
||||
Technically the VT52 keyboard doesn't map directly to a typical PC keyboard, so we can't always work from the specs in deciding what sequences are required for each key. When in doubt, we should probably be trying to match the key sequences generated by XTerm. The sequences below are based on the default XTerm mappings.
|
||||
|
||||
**Function Keys**
|
||||
|
||||
The functions keys <kbd>F1</kbd> to <kbd>F4</kbd> generate a simple ESC prefix instead of SS3 (or CSI). These correspond with the four function keys on the VT100 keypad. In V52 mode they are not affected by modifiers.
|
||||
|
||||
Key | ANSI mode | VT52 mode
|
||||
---------------|-----------|-----------
|
||||
<kbd>F1</kbd> | `SS3 P` | `ESC P`
|
||||
<kbd>F2</kbd> | `SS3 Q` | `ESC Q`
|
||||
<kbd>F3</kbd> | `SS3 R` | `ESC R`
|
||||
<kbd>F4</kbd> | `SS3 S` | `ESC S`
|
||||
|
||||
The function keys <kbd>F5</kbd> to <kbd>F12</kbd> generate the same sequences as they do in ANSI mode, except that they are not affected by modifiers. These correspond with a subset of the top-row functions keys on the VT220, along with the Windows <kbd>Menu</kbd> key mapping to the VT220 <kbd>DO</kbd> key.
|
||||
|
||||
Key | Sequence
|
||||
----------------|-------------
|
||||
<kbd>F5</kbd> | `CSI 1 5 ~`
|
||||
<kbd>F6</kbd> | `CSI 1 7 ~`
|
||||
<kbd>F7</kbd> | `CSI 1 8 ~`
|
||||
<kbd>F8</kbd> | `CSI 1 9 ~`
|
||||
<kbd>F9</kbd> | `CSI 2 0 ~`
|
||||
<kbd>F10</kbd> | `CSI 2 1 ~`
|
||||
<kbd>F11</kbd> | `CSI 2 3 ~`
|
||||
<kbd>F12</kbd> | `CSI 2 4 ~`
|
||||
<kbd>Menu</kbd> | `CSI 2 9 ~`
|
||||
|
||||
**Cursor and Editing Keys**
|
||||
|
||||
The cursor keys generate a simple ESC prefix instead of CSI or SS3. These correspond with the cursor keys on the VT100, except for <kbd>Home</kbd> and <kbd>End</kbd>, which are XTerm extensions. In V52 mode, they are not affected by modifiers, nor are they affected by the DECCKM _Cursor Keys_ mode.
|
||||
|
||||
Key | ANSI mode | VT52 mode
|
||||
-----------------|-----------|-----------
|
||||
<kbd>Up</kbd> | `CSI A` | `ESC A`
|
||||
<kbd>Down</kbd> | `CSI B` | `ESC B`
|
||||
<kbd>Right</kbd> | `CSI C` | `ESC C`
|
||||
<kbd>Left</kbd> | `CSI D` | `ESC D`
|
||||
<kbd>End</kbd> | `CSI F` | `ESC F`
|
||||
<kbd>Home</kbd> | `CSI H` | `ESC H`
|
||||
|
||||
The "editing" keys generate the same sequences as they do in ANSI mode, except that they are not affected by modifiers. These correspond with a subset of the editing keys on the VT220.
|
||||
|
||||
Key | Sequence
|
||||
----------------|-----------
|
||||
<kbd>Ins</kbd> | `CSI 2 ~`
|
||||
<kbd>Del</kbd> | `CSI 3 ~`
|
||||
<kbd>PgUp</kbd> | `CSI 5 ~`
|
||||
<kbd>PgDn</kbd> | `CSI 6 ~`
|
||||
|
||||
**Numeric Keypad**
|
||||
|
||||
With <kbd>Num Lock</kbd> disabled, most of the keys on the numeric keypad function the same as cursor keys or editing keys, but with the addition of a center <kbd>5</kbd> key. As a described above, the cursor keys generate a simple ESC prefix instead of CSI or SS3, while the editing keys remain unchanged (with the exception of modifiers).
|
||||
|
||||
In V52 mode, most modifiers are ignored, except for <kbd>Shift</kbd>, which is the equivalent of enabling <kbd>Num Lock</kbd> (i.e. the keys just generate their corresponding digit characters or `.`). With <kbd>Num Lock</kbd> enabled, it's the other way arround - the digits are generated by default, while <kbd>Shift</kbd> enables the cursor/editing functionality.
|
||||
|
||||
Key | Alias | ANSI mode | VT52 mode
|
||||
-------------|-------|-----------|-----------
|
||||
<kbd>.</kbd> | Del | `CSI 3 ~` | `CSI 3 ~`
|
||||
<kbd>0</kbd> | Ins | `CSI 2 ~` | `CSI 2 ~`
|
||||
<kbd>1</kbd> | End | `CSI F` | `ESC F`
|
||||
<kbd>2</kbd> | Down | `CSI B` | `ESC B`
|
||||
<kbd>3</kbd> | PgDn | `CSI 6 ~` | `CSI 6 ~`
|
||||
<kbd>4</kbd> | Left | `CSI D` | `ESC D`
|
||||
<kbd>4</kbd> | Clear | `CSI E` | `ESC E`
|
||||
<kbd>6</kbd> | Right | `CSI C` | `ESC C`
|
||||
<kbd>7</kbd> | Home | `CSI H` | `ESC H`
|
||||
<kbd>8</kbd> | Up | `CSI A` | `ESC A`
|
||||
<kbd>9</kbd> | PgUp | `CSI 5 ~` | `CSI 5 ~`
|
||||
|
||||
When the DECKPAM _Alternate/Application Keypad Mode_ is set, though, the <kbd>Shift</kbd> modifier has a different affect on the numeric keypad. The sequences generated now correspond with the VT100/V52 numeric keypad keys. In VT52 mode, these sequences are not affected by any other modifiers, and this mode only applies when <kbd>Num Lock</kbd> is disabled.
|
||||
|
||||
Key | Alias | ANSI mode | VT52 mode
|
||||
-------------|-------|-----------|-----------
|
||||
<kbd>.</kbd> | Del | `SS3 2 n` | `ESC ? n`
|
||||
<kbd>0</kbd> | Ins | `SS3 2 p` | `ESC ? p`
|
||||
<kbd>1</kbd> | End | `SS3 2 q` | `ESC ? q `
|
||||
<kbd>2</kbd> | Down | `SS3 2 r` | `ESC ? r`
|
||||
<kbd>3</kbd> | PgDn | `SS3 2 s` | `ESC ? s`
|
||||
<kbd>4</kbd> | Left | `SS3 2 t` | `ESC ? t`
|
||||
<kbd>4</kbd> | Clear | `SS3 2 u` | `ESC ? u`
|
||||
<kbd>6</kbd> | Right | `SS3 2 v` | `ESC ? v`
|
||||
<kbd>7</kbd> | Home | `SS3 2 w` | `ESC ? w`
|
||||
<kbd>8</kbd> | Up | `SS3 2 x` | `ESC ? x`
|
||||
<kbd>9</kbd> | PgUp | `SS3 2 y` | `ESC ? y`
|
||||
|
||||
When the DECKPAM _Alternate/Application Keypad Mode_ is set, the "arithmetic" keys on the numeric keypad are also affected (this includes the <kbd>Enter</kbd> key). The sequences generated again correspond with the VT100/VT52 numeric keys (more or less), but this mapping is active even without the <kbd>Shift</kbd> modifier (and in VT52 mode all other modifiers are ignored too). As above, the mode only applies when <kbd>Num Lock</kbd> is disabled.
|
||||
|
||||
Key | ANSI mode | VT52 mode
|
||||
-----------------|-----------|-----------
|
||||
<kbd>*</kbd> | `SS3 j` | `ESC ? j`
|
||||
<kbd>+</kbd> | `SS3 k` | `ESC ? k`
|
||||
<kbd>-</kbd> | `SS3 m` | `ESC ? m`
|
||||
<kbd>/</kbd> | `SS3 o` | `ESC ? o`
|
||||
<kbd>Enter</kbd> | `SS3 M` | `ESC ? M`
|
||||
|
||||
Note that the DECKPAM _Application Keypad Mode_ is not currently implemented in ANSI mode, so perhaps that needs to be addressed first, before trying to add support for the VT52 _Alternate Keypad Mode_.
|
||||
|
||||
### Changing Modes
|
||||
|
||||
The `_PrivateModeParamsHelper` method in the `AdaptDispatch` class would need to be extended to handle the DECANM mode parameter, and trigger a function to switch to VT52 mode. The typical pattern for this seems to be through a `PrivateXXX` method in the `ConGetSet` interface. Then the `ConhostInternalGetSet` implementation can pass that flag on to the active output buffer's `StateMachine`, and the active input buffer's `TerminalInput` instance.
|
||||
|
||||
Changing back from VT52 mode to ANSI mode would need to be achieved with a separate VT52 command (`ESC <`), since the VT100 CSI mode sequences would no longer be active. This would be handled in the same place as the other VT52 commands, in the `OutputStateMachineEngine`, and then passed on to the mode selection method in the `AdaptDispatch` class described above (essentially the equivalent of the DECANM private mode being set).
|
||||
|
||||
### Additional VT52 Commands
|
||||
|
||||
Most of the missing VT52 functionality can be implemented in terms of existing VT100 methods.
|
||||
|
||||
* The _Cursor Up_ (`ESC A`), _Cursor Down_ (`ESC B`), _Cursor Left_ (`ESC D`), and _Cursor Right_ (`ESC C`) commands are already implemented.
|
||||
* The _Enter Graphics Mode_ (`ESC F`) and _Exit Graphics Mode_ (`ESC G`) commands can probably use the existing `DesignateCharset` method, although this would require a new `VTCharacterSets` option with a corresponding table of characters (see below).
|
||||
* The _Reverse Line Feed_ (`ESC I`) command can use the existing `ReverseLineFeed` method.
|
||||
* The _Erase to End of Display_ (`ESC J`) and _Erase to End of Line_ (`ESC K`) commands can use the existing `EraseInDisplay` and `EraseInLine` methods.
|
||||
* The _Cursor Home_ (`ESC H`) and _Direct Cursor Address_ (`ESC Y`) commands can probably be implemented using the `CursorPosition` method. Technically the _Direct Cursor Address_ has different rules for the boundary conditions (the CUP command clamps out of range coordinates, while the _Direct Cursor Address_ command ignores them, judged individually - one may be ignored while the other is interpreted). Nobody seems to get that right, though, so it's probably not that big a deal.
|
||||
* The _Identify_ (`ESC Z`) command may be the only one that doesn't build on existing functionality, but it should be a fairly trivial addition to the `AdaptDispatch` class. For a terminal emulating VT52, the identifying sequence should be `ESC / Z`.
|
||||
* The _Enter Keypad Mode_ (`ESC =`) and _Exit Keypad Mode_ (`ESC >`) commands can use the existing `SetKeypadMode` method, assuming the `TerminalInput` class already knows to generate different sequences when in VT52 mode (as described in the _Terminal Input_ section above).
|
||||
* The _Enter ANSI Mode_ (`ESC <`) command can just call through to the new mode selection method in the `AdaptDispatch` class as discussed in the _Changing Modes_ section above.
|
||||
|
||||
There are also a few VT52 print commands, but those are not technically part of the core command set, and considering we don't yet support any of the VT102 print commands, I think they can probably be considered out of scope for now. Briefly they are:
|
||||
|
||||
* _Auto Print_ on (`ESC ^`) and off (`ESC _`) commands. In auto print mode, a display line prints after you move the cursor off the line, or during an auto wrap.
|
||||
* _Print Controller_ on (`ESC W`) and off (`ESC X`) commands. When enabled, the terminal transmits received characters to the printer without displaying them.
|
||||
* The _Print Cursor Line_ (`ESC V`) command prints the display line with the cursor.
|
||||
* The _Print Screen_ (`ESC ]`) command prints the screen (or at least the scrolling region).
|
||||
|
||||
I suspect most, if not all of these, would be direct equivalents of the VT102 print commands, if we ever implemented those.
|
||||
|
||||
### Graphic Mode Character Set
|
||||
|
||||
The table below lists suggested mappings for the _Graphics Mode_ character set, based on the descriptions in the [VT102 User Guide](https://vt100.net/docs/vt102-ug/table5-15.html).
|
||||
|
||||
Note that there is only the one _fraction numerator_ character in Unicode, so superscript digits have instead been used for the numerators 3, 5, and 7. There are also not enough _horizontal scan line_ characters (for the _bar at scan x_ characters), so each of them is used twice to cover the full range.
|
||||
|
||||
ASCII Character |Mapped Glyph |Unicode Value |Spec Description
|
||||
----------------|---------------|---------------|----------------
|
||||
_ | |U+0020 |Blank
|
||||
` | |U+0020 |Reserved
|
||||
a |█ |U+2588 |Solid rectangle
|
||||
b |⅟ |U+215F |1/
|
||||
c |³ |U+00B3 |3/
|
||||
d |⁵ |U+2075 |5/
|
||||
e |⁷ |U+2077 |7/
|
||||
f |° |U+00B0 |Degrees
|
||||
g |± |U+00B1 |Plus or minus
|
||||
h |→ |U+2192 |Right arrow
|
||||
i |… |U+2026 |Ellipsis (dots)
|
||||
j |÷ |U+00F7 |Divide by
|
||||
k |↓ |U+2193 |Down arrow
|
||||
l |⎺ |U+23BA |Bar at scan 0
|
||||
m |⎺ |U+23BA |Bar at scan 1
|
||||
n |⎻ |U+23BB |Bar at scan 2
|
||||
o |⎻ |U+23BB |Bar at scan 3
|
||||
p |⎼ |U+23BC |Bar at scan 4
|
||||
q |⎼ |U+23BC |Bar at scan 5
|
||||
r |⎽ |U+23BD |Bar at scan 6
|
||||
s |⎽ |U+23BD |Bar at scan 7
|
||||
t |₀ |U+2080 |Subscript 0
|
||||
u |₁ |U+2081 |Subscript 1
|
||||
v |₂ |U+2082 |Subscript 2
|
||||
w |₃ |U+2083 |Subscript 3
|
||||
x |₄ |U+2084 |Subscript 4
|
||||
y |₅ |U+2085 |Subscript 5
|
||||
z |₆ |U+2086 |Subscript 6
|
||||
{ |₇ |U+2087 |Subscript 7
|
||||
\| |₈ |U+2088 |Subscript 8
|
||||
} |₉ |U+2089 |Subscript 9
|
||||
\~ |¶ |U+00B6 |Paragraph
|
||||
|
||||
### Testing
|
||||
|
||||
A simple unit test will need to be added to the `AdapterTest` class, to confirm that calls to toggle between the ANSI and VT52 modes in the `AdaptDispatch` class are correctly forwarded to the corresponding `PrivateXXX` handler in the `ConGetSet` interface.
|
||||
|
||||
The majority of the testing would be handled in the `StateMachineExternalTest` class though. These tests would confirm that the various VT52 sequences trigger the expected methods in the `ITermDispatch` interface when VT52 Mode is enabled, and also that they don't do anything when in ANSI mode.
|
||||
|
||||
There shouldn't really be any need for additional tests in the `ScreenBufferTests` class, since we're relying on existing VT100 functionality which should already be tested there.
|
||||
|
||||
For fuzzing support, we'll need to add the DECANM option to the `GeneratePrivateModeParamToken` method in the `VTCommandFuzzer` class, and also probably add two additional token generator methods - one specifically for the _Direct Cursor Address_ command, which requires parameters, and another to handle the remaining parameterless commands.
|
||||
|
||||
In terms of manual testing, it can be useful to run the _Test of VT52 mode_ option in Vttest, and confirm that everything looks correct there. It's also worth going through some of the options in the The _Test of keyboard_ section, since those tests aren't only intended for the later VT models - they do cover the VT52 keyboard as well.
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
There is no additional UI associated with this feature.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
This should not impact accessibility any more than the existing escape sequences.
|
||||
|
||||
### Security
|
||||
|
||||
This should not introduce any new security issues.
|
||||
|
||||
### Reliability
|
||||
|
||||
This should not introduce any new reliability issues.
|
||||
|
||||
### Compatibility
|
||||
|
||||
This could be a breaking change for code that relies on the few existing VT52 commands being available without a mode change. However, that functionality is non-standard, and has not been around for that long. There is almost certainly more benefit in being able to implement the missing VT100 functionality than there is in retaining that non-standard behaviour.
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
The additional mode flags and associated processing in the `StateMachine` and `TerminalInput` classes could have some performance impact, but that is unlikely to be significant.
|
||||
|
||||
## Potential Issues
|
||||
|
||||
The only negative impacts I can think of would be the potential for breaking changes, and the possible impact on performance, as discussed in the _Compatibility_ and _Performance_ sections above. But as with any new code, there is always the possibility of new bugs being introduced as well.
|
||||
|
||||
## Future considerations
|
||||
|
||||
As mentioned in the _Inspiration_ section, having the VT52 functionality isolated with a new mode would enable us to implement the VT100 Index (IND) escape sequence, which currently conflicts with the VT52 _Cursor Left_ command.
|
||||
|
||||
## Resources
|
||||
|
||||
* [VT52 Mode Control Sequences](https://vt100.net/docs/vt100-ug/chapter3.html#S3.3.5)
|
||||
* [VT100 ANSI/VT52 Mode (DECANM)](https://vt100.net/docs/vt100-ug/chapter3.html#DECANM)
|
||||
* [VT100 Index Sequence (IND)](https://vt100.net/docs/vt100-ug/chapter3.html#IND)
|
||||
* [VTTEST Test Utility](https://invisible-island.net/vttest/)
|
||||
* [DEC STD 070 Video Systems Reference Manual](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381)
|
||||
|
||||
|
||||
|
|
@ -558,22 +558,37 @@ bool TextBuffer::IncrementCircularBuffer()
|
|||
|
||||
//Routine Description:
|
||||
// - Retrieves the position of the last non-space character on the final line of the text buffer.
|
||||
// - By default, we search the entire buffer to find the last non-space character
|
||||
//Arguments:
|
||||
// - <none>
|
||||
//Return Value:
|
||||
// - Coordinate position in screen coordinates (offset coordinates, not array index coordinates).
|
||||
COORD TextBuffer::GetLastNonSpaceCharacter() const
|
||||
{
|
||||
COORD coordEndOfText;
|
||||
// Always search the whole buffer, by starting at the bottom.
|
||||
coordEndOfText.Y = GetSize().BottomInclusive();
|
||||
return GetLastNonSpaceCharacter(GetSize());
|
||||
}
|
||||
|
||||
//Routine Description:
|
||||
// - Retrieves the position of the last non-space character in the given viewport
|
||||
// - This is basically an optimized version of GetLastNonSpaceCharacter(), and can be called when
|
||||
// - we know the last character is within the given viewport (so we don't need to check the entire buffer)
|
||||
//Arguments:
|
||||
// - The viewport
|
||||
//Return value:
|
||||
// - Coordinate position (relative to the text buffer)
|
||||
COORD TextBuffer::GetLastNonSpaceCharacter(const Microsoft::Console::Types::Viewport viewport) const
|
||||
{
|
||||
COORD coordEndOfText = { 0 };
|
||||
// Search the given viewport by starting at the bottom.
|
||||
coordEndOfText.Y = viewport.BottomInclusive();
|
||||
|
||||
const ROW* pCurrRow = &GetRowByOffset(coordEndOfText.Y);
|
||||
// The X position of the end of the valid text is the Right draw boundary (which is one beyond the final valid character)
|
||||
coordEndOfText.X = static_cast<short>(pCurrRow->GetCharRow().MeasureRight()) - 1;
|
||||
|
||||
// If the X coordinate turns out to be -1, the row was empty, we need to search backwards for the real end of text.
|
||||
bool fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > 0); // this row is empty, and we're not at the top
|
||||
const auto viewportTop = viewport.Top();
|
||||
bool fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop); // this row is empty, and we're not at the top
|
||||
while (fDoBackUp)
|
||||
{
|
||||
coordEndOfText.Y--;
|
||||
|
@ -581,7 +596,7 @@ COORD TextBuffer::GetLastNonSpaceCharacter() const
|
|||
// We need to back up to the previous row if this line is empty, AND there are more rows
|
||||
|
||||
coordEndOfText.X = static_cast<short>(pCurrRow->GetCharRow().MeasureRight()) - 1;
|
||||
fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > 0);
|
||||
fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop);
|
||||
}
|
||||
|
||||
// don't allow negative results
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
bool IncrementCircularBuffer();
|
||||
|
||||
COORD GetLastNonSpaceCharacter() const;
|
||||
COORD GetLastNonSpaceCharacter(const Microsoft::Console::Types::Viewport viewport) const;
|
||||
|
||||
Cursor& GetCursor();
|
||||
const Cursor& GetCursor() const;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<PropertyGroup Label="Version">
|
||||
<!-- These fields are picked up by PackageES -->
|
||||
<VersionMajor>0</VersionMajor>
|
||||
<VersionMinor>2</VersionMinor>
|
||||
<VersionMinor>3</VersionMinor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
|
||||
|
@ -305,4 +305,4 @@
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
|
|
|
@ -327,7 +327,8 @@ namespace winrt::TerminalApp::implementation
|
|||
auto keyBindings = _settings->GetKeybindings();
|
||||
|
||||
const GUID defaultProfileGuid = _settings->GlobalSettings().GetDefaultProfile();
|
||||
for (int profileIndex = 0; profileIndex < _settings->GetProfiles().size(); profileIndex++)
|
||||
auto const profileCount = gsl::narrow_cast<int>(_settings->GetProfiles().size()); // the number of profiles should not change in the loop for this to work
|
||||
for (int profileIndex = 0; profileIndex < profileCount; profileIndex++)
|
||||
{
|
||||
const auto& profile = _settings->GetProfiles()[profileIndex];
|
||||
auto profileMenuItem = Controls::MenuFlyoutItem{};
|
||||
|
@ -818,7 +819,7 @@ namespace winrt::TerminalApp::implementation
|
|||
const auto profiles = _settings->GetProfiles();
|
||||
|
||||
// If we don't have that many profiles, then do nothing.
|
||||
if (realIndex >= profiles.size())
|
||||
if (realIndex >= gsl::narrow<decltype(realIndex)>(profiles.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -905,7 +906,7 @@ namespace winrt::TerminalApp::implementation
|
|||
_UpdateTitle(tab);
|
||||
});
|
||||
|
||||
term.GetControl().GotFocus([this, weakTabPtr](auto&&, auto&&) {
|
||||
term.GotFocus([this, weakTabPtr](auto&&, auto&&) {
|
||||
auto tab = weakTabPtr.lock();
|
||||
if (!tab)
|
||||
{
|
||||
|
@ -1106,7 +1107,7 @@ namespace winrt::TerminalApp::implementation
|
|||
// - Sets focus to the desired tab.
|
||||
void App::_SelectTab(const int tabIndex)
|
||||
{
|
||||
if (tabIndex >= 0 && tabIndex < _tabs.size())
|
||||
if (tabIndex >= 0 && tabIndex < gsl::narrow_cast<decltype(tabIndex)>(_tabs.size()))
|
||||
{
|
||||
_SetFocusedTabIndex(tabIndex);
|
||||
}
|
||||
|
@ -1253,12 +1254,12 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
if (tabIndexFromControl == focusedTabIndex)
|
||||
{
|
||||
if (focusedTabIndex >= _tabs.size())
|
||||
auto const tabCount = gsl::narrow_cast<decltype(focusedTabIndex)>(_tabs.size());
|
||||
if (focusedTabIndex >= tabCount)
|
||||
{
|
||||
focusedTabIndex = static_cast<int>(_tabs.size()) - 1;
|
||||
focusedTabIndex = tabCount - 1;
|
||||
}
|
||||
|
||||
if (focusedTabIndex < 0)
|
||||
else if (focusedTabIndex < 0)
|
||||
{
|
||||
focusedTabIndex = 0;
|
||||
}
|
||||
|
@ -1499,20 +1500,18 @@ namespace winrt::TerminalApp::implementation
|
|||
{
|
||||
const auto* const profile = _settings->FindProfile(profileGuid);
|
||||
TerminalConnection::ITerminalConnection connection{ nullptr };
|
||||
// The Azure connection has a boost dependency, and boost does not support ARM64
|
||||
// so we make sure that we do not try to compile the Azure connection code if we are in ARM64 (we would get build errors otherwise)
|
||||
|
||||
GUID connectionType{ 0 };
|
||||
if (profile->HasConnectionType())
|
||||
{
|
||||
connectionType = profile->GetConnectionType();
|
||||
}
|
||||
#ifndef _M_ARM64
|
||||
if (connectionType == AzureConnectionType)
|
||||
|
||||
if (profile->HasConnectionType() && profile->GetConnectionType() == AzureConnectionType && TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
|
||||
{
|
||||
connection = TerminalConnection::AzureConnection(settings.InitialRows(), settings.InitialCols());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
connection = TerminalConnection::ConhostConnection(settings.Commandline(), settings.StartingDirectory(), settings.InitialRows(), settings.InitialCols(), winrt::guid());
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "CascadiaSettings.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
#include "winrt/Microsoft.Terminal.TerminalConnection.h"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
using namespace ::TerminalApp;
|
||||
|
@ -239,26 +240,13 @@ void CascadiaSettings::_CreateDefaultProfiles()
|
|||
powershellProfile.SetDefaultBackground(POWERSHELL_BLUE);
|
||||
powershellProfile.SetUseAcrylic(false);
|
||||
|
||||
// The Azure connection has a boost dependency, and boost does not support ARM64
|
||||
// so we don't create a default profile for the Azure cloud shell if we're in ARM64
|
||||
#ifndef _M_ARM64
|
||||
auto azureCloudShellProfile{ _CreateDefaultProfile(L"Azure Cloud Shell") };
|
||||
azureCloudShellProfile.SetCommandline(L"Azure");
|
||||
azureCloudShellProfile.SetStartingDirectory(DEFAULT_STARTING_DIRECTORY);
|
||||
azureCloudShellProfile.SetColorScheme({ L"Solarized Dark" });
|
||||
azureCloudShellProfile.SetAcrylicOpacity(0.85);
|
||||
azureCloudShellProfile.SetUseAcrylic(true);
|
||||
azureCloudShellProfile.SetCloseOnExit(false);
|
||||
azureCloudShellProfile.SetConnectionType(AzureConnectionType);
|
||||
#endif
|
||||
|
||||
// If the user has installed PowerShell Core, we add PowerShell Core as a default.
|
||||
// PowerShell Core default folder is "%PROGRAMFILES%\PowerShell\[Version]\".
|
||||
std::filesystem::path psCoreCmdline{};
|
||||
if (_isPowerShellCoreInstalled(psCoreCmdline))
|
||||
{
|
||||
auto pwshProfile{ _CreateDefaultProfile(L"PowerShell Core") };
|
||||
pwshProfile.SetCommandline(psCoreCmdline);
|
||||
pwshProfile.SetCommandline(std::move(psCoreCmdline));
|
||||
pwshProfile.SetStartingDirectory(DEFAULT_STARTING_DIRECTORY);
|
||||
pwshProfile.SetColorScheme({ L"Campbell" });
|
||||
|
||||
|
@ -274,9 +262,20 @@ void CascadiaSettings::_CreateDefaultProfiles()
|
|||
|
||||
_profiles.emplace_back(powershellProfile);
|
||||
_profiles.emplace_back(cmdProfile);
|
||||
#ifndef _M_ARM64
|
||||
_profiles.emplace_back(azureCloudShellProfile);
|
||||
#endif
|
||||
|
||||
if (winrt::Microsoft::Terminal::TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
|
||||
{
|
||||
auto azureCloudShellProfile{ _CreateDefaultProfile(L"Azure Cloud Shell") };
|
||||
azureCloudShellProfile.SetCommandline(L"Azure");
|
||||
azureCloudShellProfile.SetStartingDirectory(DEFAULT_STARTING_DIRECTORY);
|
||||
azureCloudShellProfile.SetColorScheme({ L"Vintage" });
|
||||
azureCloudShellProfile.SetAcrylicOpacity(0.6);
|
||||
azureCloudShellProfile.SetUseAcrylic(true);
|
||||
azureCloudShellProfile.SetCloseOnExit(false);
|
||||
azureCloudShellProfile.SetConnectionType(AzureConnectionType);
|
||||
_profiles.emplace_back(azureCloudShellProfile);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_AppendWslProfiles(_profiles);
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
Json::Value ToJson() const;
|
||||
static std::unique_ptr<CascadiaSettings> FromJson(const Json::Value& json);
|
||||
|
||||
static std::wstring GetSettingsPath();
|
||||
static std::wstring GetSettingsPath(const bool useRoamingPath = false);
|
||||
|
||||
const Profile* FindProfile(GUID profileGuid) const noexcept;
|
||||
|
||||
|
|
|
@ -261,25 +261,77 @@ void CascadiaSettings::_WriteSettings(const std::string_view content)
|
|||
// from reading the file
|
||||
std::optional<std::string> CascadiaSettings::_ReadSettings()
|
||||
{
|
||||
auto pathToSettingsFile{ CascadiaSettings::GetSettingsPath() };
|
||||
const auto hFile = CreateFileW(pathToSettingsFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
const auto pathToSettingsFile{ CascadiaSettings::GetSettingsPath() };
|
||||
wil::unique_hfile hFile{ CreateFileW(pathToSettingsFile.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
nullptr) };
|
||||
|
||||
if (!hFile)
|
||||
{
|
||||
// If the file doesn't exist, that's fine. Just log the error and return
|
||||
// nullopt - we'll create the defaults.
|
||||
LOG_LAST_ERROR();
|
||||
return std::nullopt;
|
||||
// GH#1770 - Now that we're _not_ roaming our settings, do a quick check
|
||||
// to see if there's a file in the Roaming App data folder. If there is
|
||||
// a file there, but not in the LocalAppData, it's likely the user is
|
||||
// upgrading from a version of the terminal from before this change.
|
||||
// We'll try moving the file from the Roaming app data folder to the
|
||||
// local appdata folder.
|
||||
|
||||
const auto pathToRoamingSettingsFile{ CascadiaSettings::GetSettingsPath(true) };
|
||||
wil::unique_hfile hRoamingFile{ CreateFileW(pathToRoamingSettingsFile.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
nullptr) };
|
||||
|
||||
if (hRoamingFile)
|
||||
{
|
||||
// Close the file handle, move it, and re-open the file in its new location.
|
||||
hRoamingFile.reset();
|
||||
|
||||
// Note: We're unsure if this is unsafe. Theoretically it's possible
|
||||
// that two instances of the app will try and move the settings file
|
||||
// simultaneously. We don't know what might happen in that scenario,
|
||||
// but we're also not sure how to safely lock the file to prevent
|
||||
// that from ocurring.
|
||||
THROW_LAST_ERROR_IF(!MoveFile(pathToRoamingSettingsFile.c_str(),
|
||||
pathToSettingsFile.c_str()));
|
||||
|
||||
hFile.reset(CreateFileW(pathToSettingsFile.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
nullptr));
|
||||
|
||||
// hFile shouldn't be INVALID. That's unexpected - We just moved the
|
||||
// file, we should be able to open it. Throw the error so we can get
|
||||
// some information here.
|
||||
THROW_LAST_ERROR_IF(!hFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the roaming file didn't exist, and the local file doesn't exist,
|
||||
// that's fine. Just log the error and return nullopt - we'll
|
||||
// create the defaults.
|
||||
LOG_LAST_ERROR();
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
// fileSize is in bytes
|
||||
const auto fileSize = GetFileSize(hFile, nullptr);
|
||||
const auto fileSize = GetFileSize(hFile.get(), nullptr);
|
||||
THROW_LAST_ERROR_IF(fileSize == INVALID_FILE_SIZE);
|
||||
|
||||
auto utf8buffer = std::make_unique<char[]>(fileSize);
|
||||
|
||||
DWORD bytesRead = 0;
|
||||
THROW_LAST_ERROR_IF(!ReadFile(hFile, utf8buffer.get(), fileSize, &bytesRead, nullptr));
|
||||
CloseHandle(hFile);
|
||||
THROW_LAST_ERROR_IF(!ReadFile(hFile.get(), utf8buffer.get(), fileSize, &bytesRead, nullptr));
|
||||
|
||||
// convert buffer to UTF-8 string
|
||||
std::string utf8string(utf8buffer.get(), fileSize);
|
||||
|
@ -289,25 +341,27 @@ std::optional<std::string> CascadiaSettings::_ReadSettings()
|
|||
|
||||
// function Description:
|
||||
// - Returns the full path to the settings file, either within the application
|
||||
// package, or in its unpackaged location.
|
||||
// package, or in its unpackaged location. This path is under the "Local
|
||||
// AppData" folder, so it _doesn't_ roam to other machines.
|
||||
// - If the application is unpackaged,
|
||||
// the file will end up under e.g. C:\Users\admin\AppData\Roaming\Microsoft\Windows Terminal\profiles.json
|
||||
// the file will end up under e.g. C:\Users\admin\AppData\Local\Microsoft\Windows Terminal\profiles.json
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the full path to the settings file
|
||||
std::wstring CascadiaSettings::GetSettingsPath()
|
||||
std::wstring CascadiaSettings::GetSettingsPath(const bool useRoamingPath)
|
||||
{
|
||||
wil::unique_cotaskmem_string roamingAppDataFolder;
|
||||
wil::unique_cotaskmem_string localAppDataFolder;
|
||||
// KF_FLAG_FORCE_APP_DATA_REDIRECTION, when engaged, causes SHGet... to return
|
||||
// the new AppModel paths (Packages/xxx/RoamingState, etc.) for standard path requests.
|
||||
// Using this flag allows us to avoid Windows.Storage.ApplicationData completely.
|
||||
if (FAILED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_FORCE_APP_DATA_REDIRECTION, 0, &roamingAppDataFolder)))
|
||||
const auto knowFolderId = useRoamingPath ? FOLDERID_RoamingAppData : FOLDERID_LocalAppData;
|
||||
if (FAILED(SHGetKnownFolderPath(knowFolderId, KF_FLAG_FORCE_APP_DATA_REDIRECTION, 0, &localAppDataFolder)))
|
||||
{
|
||||
THROW_LAST_ERROR();
|
||||
}
|
||||
|
||||
std::filesystem::path parentDirectoryForSettingsFile{ roamingAppDataFolder.get() };
|
||||
std::filesystem::path parentDirectoryForSettingsFile{ localAppDataFolder.get() };
|
||||
|
||||
if (!_IsPackaged())
|
||||
{
|
||||
|
|
|
@ -66,7 +66,8 @@ void ColorScheme::ApplyScheme(TerminalSettings terminalSettings) const
|
|||
terminalSettings.DefaultForeground(_defaultForeground);
|
||||
terminalSettings.DefaultBackground(_defaultBackground);
|
||||
|
||||
for (int i = 0; i < _table.size(); i++)
|
||||
auto const tableCount = gsl::narrow_cast<int>(_table.size());
|
||||
for (int i = 0; i < tableCount; i++)
|
||||
{
|
||||
terminalSettings.SetColorTableEntry(i, _table[i]);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus
|
|||
_lastFocused{ lastFocused },
|
||||
_profile{ profile }
|
||||
{
|
||||
_root.Children().Append(_control.GetControl());
|
||||
_root.Children().Append(_control);
|
||||
_connectionClosedToken = _control.ConnectionClosed({ this, &Pane::_ControlClosedHandler });
|
||||
|
||||
// Set the background of the pane to match that of the theme's default grid
|
||||
|
@ -426,7 +426,7 @@ bool Pane::_HasFocusedChild() const noexcept
|
|||
// We're intentionally making this one giant expression, so the compiler
|
||||
// will skip the following lookups if one of the lookups before it returns
|
||||
// true
|
||||
return (_control && _control.GetControl().FocusState() != FocusState::Unfocused) ||
|
||||
return (_control && _control.FocusState() != FocusState::Unfocused) ||
|
||||
(_firstChild && _firstChild->_HasFocusedChild()) ||
|
||||
(_secondChild && _secondChild->_HasFocusedChild());
|
||||
}
|
||||
|
@ -445,7 +445,7 @@ void Pane::UpdateFocus()
|
|||
if (_IsLeaf())
|
||||
{
|
||||
const auto controlFocused = _control &&
|
||||
_control.GetControl().FocusState() != FocusState::Unfocused;
|
||||
_control.FocusState() != FocusState::Unfocused;
|
||||
|
||||
_lastFocused = controlFocused;
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ void Pane::_FocusFirstChild()
|
|||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
_control.GetControl().Focus(FocusState::Programmatic);
|
||||
_control.Focus(FocusState::Programmatic);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -564,11 +564,11 @@ void Pane::_CloseChild(const bool closeFirst)
|
|||
_separatorRoot = { nullptr };
|
||||
|
||||
// Reattach the TermControl to our grid.
|
||||
_root.Children().Append(_control.GetControl());
|
||||
_root.Children().Append(_control);
|
||||
|
||||
if (_lastFocused)
|
||||
{
|
||||
_control.GetControl().Focus(FocusState::Programmatic);
|
||||
_control.Focus(FocusState::Programmatic);
|
||||
}
|
||||
|
||||
_splitState = SplitState::None;
|
||||
|
|
|
@ -150,7 +150,8 @@ TerminalSettings Profile::CreateTerminalSettings(const std::vector<ColorScheme>&
|
|||
TerminalSettings terminalSettings{};
|
||||
|
||||
// Fill in the Terminal Setting's CoreSettings from the profile
|
||||
for (int i = 0; i < _colorTable.size(); i++)
|
||||
auto const colorTableCount = gsl::narrow_cast<int>(_colorTable.size());
|
||||
for (int i = 0; i < colorTableCount; i++)
|
||||
{
|
||||
terminalSettings.SetColorTableEntry(i, _colorTable[i]);
|
||||
}
|
||||
|
@ -489,12 +490,12 @@ Profile Profile::FromJson(const Json::Value& json)
|
|||
|
||||
void Profile::SetFontFace(std::wstring fontFace) noexcept
|
||||
{
|
||||
_fontFace = fontFace;
|
||||
_fontFace = std::move(fontFace);
|
||||
}
|
||||
|
||||
void Profile::SetColorScheme(std::optional<std::wstring> schemeName) noexcept
|
||||
{
|
||||
_schemeName = schemeName;
|
||||
_schemeName = std::move(schemeName);
|
||||
}
|
||||
|
||||
void Profile::SetAcrylicOpacity(double opacity) noexcept
|
||||
|
@ -504,17 +505,17 @@ void Profile::SetAcrylicOpacity(double opacity) noexcept
|
|||
|
||||
void Profile::SetCommandline(std::wstring cmdline) noexcept
|
||||
{
|
||||
_commandline = cmdline;
|
||||
_commandline = std::move(cmdline);
|
||||
}
|
||||
|
||||
void Profile::SetStartingDirectory(std::wstring startingDirectory) noexcept
|
||||
{
|
||||
_startingDirectory = startingDirectory;
|
||||
_startingDirectory = std::move(startingDirectory);
|
||||
}
|
||||
|
||||
void Profile::SetName(std::wstring name) noexcept
|
||||
{
|
||||
_name = name;
|
||||
_name = std::move(name);
|
||||
}
|
||||
|
||||
void Profile::SetUseAcrylic(bool useAcrylic) noexcept
|
||||
|
@ -553,15 +554,16 @@ bool Profile::HasIcon() const noexcept
|
|||
// - tabTitle: the tab title
|
||||
void Profile::SetTabTitle(std::wstring tabTitle) noexcept
|
||||
{
|
||||
_tabTitle = tabTitle;
|
||||
_tabTitle = std::move(tabTitle);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets this profile's icon path.
|
||||
// Arguments:
|
||||
// - path: the path
|
||||
void Profile::SetIconPath(std::wstring_view path) noexcept
|
||||
void Profile::SetIconPath(std::wstring_view path)
|
||||
{
|
||||
static_assert(!noexcept(_icon.emplace(path)));
|
||||
_icon.emplace(path);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
bool HasIcon() const noexcept;
|
||||
std::wstring_view GetIconPath() const noexcept;
|
||||
void SetIconPath(std::wstring_view path) noexcept;
|
||||
void SetIconPath(std::wstring_view path);
|
||||
|
||||
bool GetCloseOnExit() const noexcept;
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ void Tab::_Focus()
|
|||
auto lastFocusedControl = _rootPane->GetFocusedTerminalControl();
|
||||
if (lastFocusedControl)
|
||||
{
|
||||
lastFocusedControl.GetControl().Focus(FocusState::Programmatic);
|
||||
lastFocusedControl.Focus(FocusState::Programmatic);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ void Tab::SetTabText(const winrt::hstring& text)
|
|||
void Tab::Scroll(const int delta)
|
||||
{
|
||||
auto control = GetFocusedTerminalControl();
|
||||
control.GetControl().Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [control, delta]() {
|
||||
control.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [control, delta]() {
|
||||
const auto currentOffset = control.GetScrollOffset();
|
||||
control.KeyboardScrollViewport(currentOffset + delta);
|
||||
});
|
||||
|
|
|
@ -279,7 +279,7 @@
|
|||
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
|
||||
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
|
||||
<_MUXRoot>$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\</_MUXRoot>
|
||||
<_MUXAppRoot>$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\</_MUXAppRoot>
|
||||
<_MUXAppRoot>$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\</_MUXAppRoot>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Microsoft.UI.XAML -->
|
||||
|
@ -309,7 +309,7 @@
|
|||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview7\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.2" targetFramework="native" />
|
||||
<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.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
50
src/cascadia/TerminalConnection/AzureConnection-ARM64.cpp
Normal file
50
src/cascadia/TerminalConnection/AzureConnection-ARM64.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AzureConnection-ARM64.h"
|
||||
#include "AzureConnection.g.cpp"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
bool AzureConnection::IsAzureConnectionAvailable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AzureConnection::AzureConnection(uint32_t rows, uint32_t columns)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
winrt::event_token AzureConnection::TerminalOutput(Microsoft::Terminal::TerminalConnection::TerminalOutputEventArgs const& handler)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
void AzureConnection::TerminalOutput(winrt::event_token const& token)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
winrt::event_token AzureConnection::TerminalDisconnected(Microsoft::Terminal::TerminalConnection::TerminalDisconnectedEventArgs const& handler)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
void AzureConnection::TerminalDisconnected(winrt::event_token const& token)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
void AzureConnection::Start()
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
void AzureConnection::WriteInput(hstring const& data)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
void AzureConnection::Resize(uint32_t rows, uint32_t columns)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
void AzureConnection::Close()
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
}
|
31
src/cascadia/TerminalConnection/AzureConnection-ARM64.h
Normal file
31
src/cascadia/TerminalConnection/AzureConnection-ARM64.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
#include "AzureConnection.g.h"
|
||||
#include "pch.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
struct AzureConnection : AzureConnectionT<AzureConnection>
|
||||
{
|
||||
AzureConnection() = default;
|
||||
|
||||
AzureConnection(uint32_t rows, uint32_t columns);
|
||||
static bool IsAzureConnectionAvailable();
|
||||
winrt::event_token TerminalOutput(Microsoft::Terminal::TerminalConnection::TerminalOutputEventArgs const& handler);
|
||||
void TerminalOutput(winrt::event_token const& token);
|
||||
winrt::event_token TerminalDisconnected(Microsoft::Terminal::TerminalConnection::TerminalDisconnectedEventArgs const& handler);
|
||||
void TerminalDisconnected(winrt::event_token const& token);
|
||||
void Start();
|
||||
void WriteInput(hstring const& data);
|
||||
void Resize(uint32_t rows, uint32_t columns);
|
||||
void Close();
|
||||
};
|
||||
}
|
||||
namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation
|
||||
{
|
||||
struct AzureConnection : AzureConnectionT<AzureConnection, implementation::AzureConnection>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -25,6 +25,15 @@ using namespace winrt::Windows::Security::Credentials;
|
|||
|
||||
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
// This file only builds for non-ARM64 so we don't need to check that here
|
||||
// This function exists because the clientID only gets added by the release pipelines
|
||||
// and is not available on local builds, so we want to be able to make sure we don't
|
||||
// try to make an Azure connection if its a local build
|
||||
bool AzureConnection::IsAzureConnectionAvailable()
|
||||
{
|
||||
return (AzureClientID != L"0");
|
||||
}
|
||||
|
||||
AzureConnection::AzureConnection(const uint32_t initialRows, const uint32_t initialCols) :
|
||||
_initialRows{ initialRows },
|
||||
_initialCols{ initialCols }
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||
{
|
||||
struct AzureConnection : AzureConnectionT<AzureConnection>
|
||||
{
|
||||
static bool IsAzureConnectionAvailable();
|
||||
AzureConnection(const uint32_t rows, const uint32_t cols);
|
||||
|
||||
winrt::event_token TerminalOutput(TerminalConnection::TerminalOutputEventArgs const& handler);
|
||||
|
|
|
@ -7,6 +7,8 @@ namespace Microsoft.Terminal.TerminalConnection
|
|||
{
|
||||
[default_interface] runtimeclass AzureConnection : ITerminalConnection
|
||||
{
|
||||
static Boolean IsAzureConnectionAvailable();
|
||||
|
||||
AzureConnection(UInt32 rows, UInt32 columns);
|
||||
};
|
||||
|
||||
|
|
|
@ -79,35 +79,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||
extraEnvVars.emplace(L"WT_SESSION", pwszGuid);
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(
|
||||
CreateConPty(cmdline,
|
||||
startingDirectory,
|
||||
static_cast<short>(_initialCols),
|
||||
static_cast<short>(_initialRows),
|
||||
&_inPipe,
|
||||
&_outPipe,
|
||||
&_signalPipe,
|
||||
&_piConhost,
|
||||
CREATE_SUSPENDED,
|
||||
extraEnvVars));
|
||||
|
||||
_hJob.reset(CreateJobObjectW(nullptr, nullptr));
|
||||
THROW_LAST_ERROR_IF_NULL(_hJob);
|
||||
|
||||
// We want the conhost and all associated descendant processes
|
||||
// to be terminated when the tab is closed. GUI applications
|
||||
// spawned from the shell tend to end up in their own jobs.
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobExtendedInformation{};
|
||||
jobExtendedInformation.BasicLimitInformation.LimitFlags =
|
||||
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
|
||||
THROW_IF_WIN32_BOOL_FALSE(SetInformationJobObject(_hJob.get(),
|
||||
JobObjectExtendedLimitInformation,
|
||||
&jobExtendedInformation,
|
||||
sizeof(jobExtendedInformation)));
|
||||
|
||||
THROW_IF_WIN32_BOOL_FALSE(AssignProcessToJobObject(_hJob.get(), _piConhost.hProcess));
|
||||
|
||||
// Create our own output handling thread
|
||||
// Each connection needs to make sure to drain the output from its backing host.
|
||||
_hOutputThread.reset(CreateThread(nullptr,
|
||||
|
@ -119,8 +90,17 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||
|
||||
THROW_LAST_ERROR_IF_NULL(_hOutputThread);
|
||||
|
||||
// Wind up the conhost! We only do this after we've got everything in place.
|
||||
THROW_LAST_ERROR_IF(-1 == ResumeThread(_piConhost.hThread));
|
||||
THROW_IF_FAILED(
|
||||
CreateConPty(cmdline,
|
||||
startingDirectory,
|
||||
static_cast<short>(_initialCols),
|
||||
static_cast<short>(_initialRows),
|
||||
&_inPipe,
|
||||
&_outPipe,
|
||||
&_signalPipe,
|
||||
&_piConhost,
|
||||
0,
|
||||
extraEnvVars));
|
||||
|
||||
_connected = true;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="AzureClientID.h" Condition="'$(Platform)'!='ARM64'" />
|
||||
<ClInclude Include="AzureConnection.h" Condition="'$(Platform)'!='ARM64'" />
|
||||
<ClInclude Include="AzureConnection-ARM64.h" Condition="'$(Platform)'=='ARM64'" />
|
||||
<ClInclude Include="AzureConnectionStrings.h" Condition="'$(Platform)'!='ARM64'" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="ConhostConnection.h">
|
||||
|
@ -35,6 +36,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AzureConnection.cpp" Condition="'$(Platform)'!='ARM64'" />
|
||||
<ClCompile Include="AzureConnection-ARM64.cpp" Condition="'$(Platform)'=='ARM64'" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -50,7 +52,7 @@
|
|||
<Midl Include="ITerminalConnection.idl" />
|
||||
<Midl Include="ConhostConnection.idl" />
|
||||
<Midl Include="EchoConnection.idl" />
|
||||
<Midl Include="AzureConnection.idl" Condition="'$(Platform)'!='ARM64'" />
|
||||
<Midl Include="AzureConnection.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
<package id="vcpkg-cpprestsdk" version="2.10.0" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "..\..\types\inc\GlyphWidth.hpp"
|
||||
|
||||
#include "TermControl.g.cpp"
|
||||
#include "TermControlAutomationPeer.h"
|
||||
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
using namespace ::Microsoft::Terminal::Core;
|
||||
|
@ -30,7 +31,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
_connection{ connection },
|
||||
_initializedTerminal{ false },
|
||||
_root{ nullptr },
|
||||
_controlRoot{ nullptr },
|
||||
_swapChainPanel{ nullptr },
|
||||
_settings{ settings },
|
||||
_closing{ false },
|
||||
|
@ -52,11 +52,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
|
||||
void TermControl::_Create()
|
||||
{
|
||||
// Create a dummy UserControl to use as the "root" of our control we'll
|
||||
// build manually.
|
||||
Controls::UserControl myControl;
|
||||
_controlRoot = myControl;
|
||||
|
||||
Controls::Grid container;
|
||||
|
||||
Controls::ColumnDefinition contentColumn{};
|
||||
|
@ -108,20 +103,20 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
_bgImageLayer = bgImageLayer;
|
||||
|
||||
_swapChainPanel = swapChainPanel;
|
||||
_controlRoot.Content(_root);
|
||||
this->Content(_root);
|
||||
|
||||
_ApplyUISettings();
|
||||
|
||||
// These are important:
|
||||
// 1. When we get tapped, focus us
|
||||
_controlRoot.Tapped([this](auto&, auto& e) {
|
||||
_controlRoot.Focus(FocusState::Pointer);
|
||||
this->Tapped([this](auto&, auto& e) {
|
||||
this->Focus(FocusState::Pointer);
|
||||
e.Handled(true);
|
||||
});
|
||||
// 2. Make sure we can be focused (why this isn't `Focusable` I'll never know)
|
||||
_controlRoot.IsTabStop(true);
|
||||
this->IsTabStop(true);
|
||||
// 3. Actually not sure about this one. Maybe it isn't necessary either.
|
||||
_controlRoot.AllowFocusOnInteraction(true);
|
||||
this->AllowFocusOnInteraction(true);
|
||||
|
||||
// DON'T CALL _InitializeTerminal here - wait until the swap chain is loaded to do that.
|
||||
|
||||
|
@ -345,14 +340,16 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
Close();
|
||||
}
|
||||
|
||||
UIElement TermControl::GetRoot()
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer TermControl::OnCreateAutomationPeer()
|
||||
{
|
||||
return _root;
|
||||
// create a custom automation peer with this code pattern:
|
||||
// (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers)
|
||||
return winrt::make<winrt::Microsoft::Terminal::TerminalControl::implementation::TermControlAutomationPeer>(*this);
|
||||
}
|
||||
|
||||
Controls::UserControl TermControl::GetControl()
|
||||
::Microsoft::Console::Render::IRenderData* TermControl::GetRenderData() const
|
||||
{
|
||||
return _controlRoot;
|
||||
return _terminal.get();
|
||||
}
|
||||
|
||||
void TermControl::SwapChainChanged()
|
||||
|
@ -506,9 +503,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// through CharacterRecieved.
|
||||
// I don't believe there's a difference between KeyDown and
|
||||
// PreviewKeyDown for our purposes
|
||||
// These two handlers _must_ be on _controlRoot, not _root.
|
||||
_controlRoot.PreviewKeyDown({ this, &TermControl::_KeyDownHandler });
|
||||
_controlRoot.CharacterReceived({ this, &TermControl::_CharacterHandler });
|
||||
// These two handlers _must_ be on this, not _root.
|
||||
this->PreviewKeyDown({ this, &TermControl::_KeyDownHandler });
|
||||
this->CharacterReceived({ this, &TermControl::_CharacterHandler });
|
||||
|
||||
auto pfnTitleChanged = std::bind(&TermControl::_TerminalTitleChanged, this, std::placeholders::_1);
|
||||
_terminal->SetTitleChangedCallback(pfnTitleChanged);
|
||||
|
@ -542,14 +539,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// import value from WinUser (convert from milli-seconds to micro-seconds)
|
||||
_multiClickTimer = GetDoubleClickTime() * 1000;
|
||||
|
||||
_gotFocusRevoker = _controlRoot.GotFocus(winrt::auto_revoke, { this, &TermControl::_GotFocusHandler });
|
||||
_lostFocusRevoker = _controlRoot.LostFocus(winrt::auto_revoke, { this, &TermControl::_LostFocusHandler });
|
||||
_gotFocusRevoker = this->GotFocus(winrt::auto_revoke, { this, &TermControl::_GotFocusHandler });
|
||||
_lostFocusRevoker = this->LostFocus(winrt::auto_revoke, { this, &TermControl::_LostFocusHandler });
|
||||
|
||||
// Focus the control here. If we do it up above (in _Create_), then the
|
||||
// focus won't actually get passed to us. I believe this is because
|
||||
// we're not technically a part of the UI tree yet, so focusing us
|
||||
// becomes a no-op.
|
||||
_controlRoot.Focus(FocusState::Programmatic);
|
||||
this->Focus(FocusState::Programmatic);
|
||||
|
||||
_connection.Start();
|
||||
_initializedTerminal = true;
|
||||
|
@ -622,35 +619,41 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
}
|
||||
|
||||
const auto modifiers = _GetPressedModifierKeys();
|
||||
const auto vkey = static_cast<WORD>(e.OriginalKey());
|
||||
|
||||
// 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());
|
||||
bool handled = false;
|
||||
|
||||
auto bindings = _settings.KeyBindings();
|
||||
if (bindings)
|
||||
{
|
||||
KeyChord chord(
|
||||
handled = bindings.TryKeyChord({
|
||||
modifiers.IsCtrlPressed(),
|
||||
modifiers.IsAltPressed(),
|
||||
modifiers.IsShiftPressed(),
|
||||
vkey);
|
||||
handled = bindings.TryKeyChord(chord);
|
||||
vkey,
|
||||
});
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
_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.
|
||||
handled = _terminal->SendKeyEvent(vkey, modifiers);
|
||||
|
||||
if (_cursorTimer.has_value())
|
||||
{
|
||||
// Manually show the cursor when a key is pressed. Restarting
|
||||
// the timer prevents flickering.
|
||||
_terminal->SetCursorVisible(true);
|
||||
_cursorTimer.value().Start();
|
||||
}
|
||||
handled = _TrySendKeyEvent(vkey, modifiers);
|
||||
}
|
||||
|
||||
// Manually prevent keyboard navigation with tab. We want to send tab to
|
||||
|
@ -664,6 +667,45 @@ 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.
|
||||
// - Clears the current selection.
|
||||
// - Makes the cursor briefly visible during typing.
|
||||
// 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)
|
||||
{
|
||||
_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;
|
||||
|
||||
if (_cursorTimer.has_value())
|
||||
{
|
||||
// Manually show the cursor when a key is pressed. Restarting
|
||||
// the timer prevents flickering.
|
||||
_terminal->SetCursorVisible(true);
|
||||
_cursorTimer.value().Start();
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - handle a mouse click event. Begin selection process.
|
||||
// Arguments:
|
||||
|
|
|
@ -35,8 +35,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
TermControl();
|
||||
TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection);
|
||||
|
||||
Windows::UI::Xaml::UIElement GetRoot();
|
||||
Windows::UI::Xaml::Controls::UserControl GetControl();
|
||||
void UpdateSettings(Settings::IControlSettings newSettings);
|
||||
|
||||
hstring Title();
|
||||
|
@ -55,6 +53,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
void SwapChainChanged();
|
||||
~TermControl();
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
::Microsoft::Console::Render::IRenderData* GetRenderData() const;
|
||||
|
||||
static Windows::Foundation::Point GetProposedDimensions(Microsoft::Terminal::Settings::IControlSettings const& settings, const uint32_t dpi);
|
||||
|
||||
// clang-format off
|
||||
|
@ -71,7 +72,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
TerminalConnection::ITerminalConnection _connection;
|
||||
bool _initializedTerminal;
|
||||
|
||||
Windows::UI::Xaml::Controls::UserControl _controlRoot;
|
||||
Windows::UI::Xaml::Controls::Grid _root;
|
||||
Windows::UI::Xaml::Controls::Image _bgImageLayer;
|
||||
Windows::UI::Xaml::Controls::SwapChainPanel _swapChainPanel;
|
||||
|
@ -164,6 +164,8 @@ 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);
|
||||
|
||||
const COORD _GetTerminalPosition(winrt::Windows::Foundation::Point cursorPosition);
|
||||
const unsigned int _NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime);
|
||||
|
|
|
@ -14,15 +14,13 @@ namespace Microsoft.Terminal.TerminalControl
|
|||
}
|
||||
|
||||
[default_interface]
|
||||
runtimeclass TermControl
|
||||
runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl
|
||||
{
|
||||
TermControl();
|
||||
TermControl(Microsoft.Terminal.Settings.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||
|
||||
static Windows.Foundation.Point GetProposedDimensions(Microsoft.Terminal.Settings.IControlSettings settings, UInt32 dpi);
|
||||
|
||||
Windows.UI.Xaml.UIElement GetRoot();
|
||||
Windows.UI.Xaml.Controls.UserControl GetControl();
|
||||
void UpdateSettings(Microsoft.Terminal.Settings.IControlSettings newSettings);
|
||||
|
||||
event TitleChangedEventArgs TitleChanged;
|
||||
|
|
154
src/cascadia/TerminalControl/TermControlAutomationPeer.cpp
Normal file
154
src/cascadia/TerminalControl/TermControlAutomationPeer.cpp
Normal file
|
@ -0,0 +1,154 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include <UIAutomationCore.h>
|
||||
#include "TermControlAutomationPeer.h"
|
||||
#include "TermControl.h"
|
||||
#include "TermControlAutomationPeer.g.cpp"
|
||||
|
||||
#include "XamlUiaTextRange.h"
|
||||
|
||||
using namespace Microsoft::Console::Types;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||
|
||||
namespace UIA
|
||||
{
|
||||
using ::ITextRangeProvider;
|
||||
using ::SupportedTextSelection;
|
||||
}
|
||||
|
||||
namespace XamlAutomation
|
||||
{
|
||||
using winrt::Windows::UI::Xaml::Automation::SupportedTextSelection;
|
||||
using winrt::Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple;
|
||||
using winrt::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider;
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
TermControlAutomationPeer::TermControlAutomationPeer(winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl const& owner) :
|
||||
TermControlAutomationPeerT<TermControlAutomationPeer>(owner), // pass owner to FrameworkElementAutomationPeer
|
||||
_uiaProvider{ owner.GetRenderData(), nullptr, std::bind(&TermControlAutomationPeer::GetBoundingRectWrapped, this) } {};
|
||||
|
||||
winrt::hstring TermControlAutomationPeer::GetClassNameCore() const
|
||||
{
|
||||
return L"TermControl";
|
||||
}
|
||||
|
||||
AutomationControlType TermControlAutomationPeer::GetAutomationControlTypeCore() const
|
||||
{
|
||||
return AutomationControlType::Text;
|
||||
}
|
||||
|
||||
winrt::hstring TermControlAutomationPeer::GetLocalizedControlTypeCore() const
|
||||
{
|
||||
// TODO GitHub #2142: Localize string
|
||||
return L"TerminalControl";
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable TermControlAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
|
||||
{
|
||||
switch (patternInterface)
|
||||
{
|
||||
case PatternInterface::Text:
|
||||
return *this;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region ITextProvider
|
||||
winrt::com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetSelection()
|
||||
{
|
||||
SAFEARRAY* pReturnVal;
|
||||
THROW_IF_FAILED(_uiaProvider.GetSelection(&pReturnVal));
|
||||
return WrapArrayOfTextRangeProviders(pReturnVal);
|
||||
}
|
||||
|
||||
winrt::com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetVisibleRanges()
|
||||
{
|
||||
SAFEARRAY* pReturnVal;
|
||||
THROW_IF_FAILED(_uiaProvider.GetVisibleRanges(&pReturnVal));
|
||||
return WrapArrayOfTextRangeProviders(pReturnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement)
|
||||
{
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
// ScreenInfoUiaProvider doesn't actually use parameter, so just pass in nullptr
|
||||
THROW_IF_FAILED(_uiaProvider.RangeFromChild(/* IRawElementProviderSimple */ nullptr,
|
||||
&returnVal));
|
||||
|
||||
auto parentProvider = this->ProviderFromPeer(*this);
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation)
|
||||
{
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider.RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal));
|
||||
|
||||
auto parentProvider = this->ProviderFromPeer(*this);
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::DocumentRange()
|
||||
{
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider.get_DocumentRange(&returnVal));
|
||||
|
||||
auto parentProvider = this->ProviderFromPeer(*this);
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::Automation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection()
|
||||
{
|
||||
UIA::SupportedTextSelection returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider.get_SupportedTextSelection(&returnVal));
|
||||
return static_cast<XamlAutomation::SupportedTextSelection>(returnVal);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
RECT TermControlAutomationPeer::GetBoundingRectWrapped()
|
||||
{
|
||||
auto rect = GetBoundingRectangle();
|
||||
return {
|
||||
gsl::narrow<LONG>(rect.X),
|
||||
gsl::narrow<LONG>(rect.Y),
|
||||
gsl::narrow<LONG>(rect.X + rect.Width),
|
||||
gsl::narrow<LONG>(rect.Y + rect.Height)
|
||||
};
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - extracts the UiaTextRanges from the SAFEARRAY and converts them to Xaml ITextRangeProviders
|
||||
// Arguments:
|
||||
// - SAFEARRAY of UIA::UiaTextRange (ITextRangeProviders)
|
||||
// Return Value:
|
||||
// - com_array of Xaml Wrapped UiaTextRange (ITextRangeProviders)
|
||||
winrt::com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
|
||||
{
|
||||
// transfer ownership of UiaTextRanges to this new vector
|
||||
auto providers = SafeArrayToOwningVector<::Microsoft::Console::Types::UiaTextRange>(textRanges);
|
||||
int count = providers.size();
|
||||
|
||||
std::vector<XamlAutomation::ITextRangeProvider> vec;
|
||||
vec.reserve(count);
|
||||
auto parentProvider = this->ProviderFromPeer(*this);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(providers[i].detach(), parentProvider);
|
||||
vec.emplace_back(xutr.as<XamlAutomation::ITextRangeProvider>());
|
||||
}
|
||||
|
||||
winrt::com_array<XamlAutomation::ITextRangeProvider> result{ vec };
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
63
src/cascadia/TerminalControl/TermControlAutomationPeer.h
Normal file
63
src/cascadia/TerminalControl/TermControlAutomationPeer.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- TermControlAutomationPeer.h
|
||||
|
||||
Abstract:
|
||||
- This module provides UI Automation access to the TermControl
|
||||
to support both automation tests and accessibility (screen
|
||||
reading) applications. This mainly interacts with ScreenInfoUiaProvider
|
||||
to allow for shared code between ConHost and Windows Terminal
|
||||
accessibility providers.
|
||||
- Based on the Custom Automation Peers guide on msdn
|
||||
(https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers)
|
||||
- Wraps the UIAutomationCore ITextProvider
|
||||
(https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-itextprovider)
|
||||
with a XAML ITextProvider
|
||||
(https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.provider.itextprovider)
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora (CaZamor) 2019
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "TermControl.h"
|
||||
#include "TermControlAutomationPeer.g.h"
|
||||
#include <winrt/Microsoft.Terminal.TerminalControl.h>
|
||||
#include "../../renderer/inc/IRenderData.hpp"
|
||||
#include "../types/ScreenInfoUiaProvider.h"
|
||||
#include "../types/WindowUiaProviderBase.hpp"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
struct TermControlAutomationPeer :
|
||||
public TermControlAutomationPeerT<TermControlAutomationPeer>
|
||||
{
|
||||
public:
|
||||
TermControlAutomationPeer(winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl const& owner);
|
||||
|
||||
winrt::hstring GetClassNameCore() const;
|
||||
winrt::Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const;
|
||||
winrt::hstring GetLocalizedControlTypeCore() const;
|
||||
winrt::Windows::Foundation::IInspectable GetPatternCore(winrt::Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) const;
|
||||
|
||||
#pragma region ITextProvider Pattern
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider RangeFromPoint(Windows::Foundation::Point screenLocation);
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider RangeFromChild(Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple childElement);
|
||||
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetVisibleRanges();
|
||||
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetSelection();
|
||||
Windows::UI::Xaml::Automation::SupportedTextSelection SupportedTextSelection();
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange();
|
||||
#pragma endregion
|
||||
|
||||
RECT GetBoundingRectWrapped();
|
||||
|
||||
private:
|
||||
::Microsoft::Console::Types::ScreenInfoUiaProvider _uiaProvider;
|
||||
|
||||
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges);
|
||||
};
|
||||
}
|
14
src/cascadia/TerminalControl/TermControlAutomationPeer.idl
Normal file
14
src/cascadia/TerminalControl/TermControlAutomationPeer.idl
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TermControl.idl";
|
||||
|
||||
namespace Microsoft.Terminal.TerminalControl
|
||||
{
|
||||
[default_interface]
|
||||
runtimeclass TermControlAutomationPeer :
|
||||
Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer,
|
||||
Windows.UI.Xaml.Automation.Provider.ITextProvider
|
||||
{
|
||||
}
|
||||
}
|
|
@ -20,6 +20,10 @@
|
|||
<ClInclude Include="TermControl.h">
|
||||
<DependentUpon>TermControl.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TermControlAutomationPeer.h">
|
||||
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="XamlUiaTextRange.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
|
@ -30,9 +34,14 @@
|
|||
<DependentUpon>TermControl.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="TermControlAutomationPeer.cpp">
|
||||
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XamlUiaTextRange.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="TermControl.idl" />
|
||||
<Midl Include="TermControlAutomationPeer.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
@ -50,7 +59,7 @@
|
|||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalCore\lib\TerminalCore-lib.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" >
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj">
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -11,20 +11,20 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="KeyChord.cpp" />
|
||||
<ClCompile Include="TermControl.cpp" />
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="TermControlAutomationPeer.cpp" />
|
||||
<ClCompile Include="XamlUiaTextRange.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="KeyChord.h" />
|
||||
<ClInclude Include="TermControl.h" />
|
||||
<ClInclude Include="TermControlAP.h" />
|
||||
<ClInclude Include="XamlUiaTextRange.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="TermControl.idl" />
|
||||
<Midl Include="KeyChord.idl" />
|
||||
<Midl Include="IKeyBindings.idl" />
|
||||
<Midl Include="IControlSettings.idl" />
|
||||
<Midl Include="TermControlAutomationPeer.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="TerminalControl.def" />
|
||||
|
@ -33,4 +33,4 @@
|
|||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
199
src/cascadia/TerminalControl/XamlUiaTextRange.cpp
Normal file
199
src/cascadia/TerminalControl/XamlUiaTextRange.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "XamlUiaTextRange.h"
|
||||
#include "../types/UiaTextRange.hpp"
|
||||
|
||||
namespace UIA
|
||||
{
|
||||
using ::ITextRangeProvider;
|
||||
using ::SupportedTextSelection;
|
||||
using ::TextPatternRangeEndpoint;
|
||||
using ::TextUnit;
|
||||
}
|
||||
|
||||
namespace XamlAutomation
|
||||
{
|
||||
using winrt::Windows::UI::Xaml::Automation::SupportedTextSelection;
|
||||
using winrt::Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple;
|
||||
using winrt::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider;
|
||||
using winrt::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint;
|
||||
using winrt::Windows::UI::Xaml::Automation::Text::TextUnit;
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
XamlAutomation::ITextRangeProvider XamlUiaTextRange::Clone() const
|
||||
{
|
||||
UIA::ITextRangeProvider* pReturn;
|
||||
THROW_IF_FAILED(_uiaProvider->Clone(&pReturn));
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(pReturn, _parentProvider);
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
}
|
||||
|
||||
bool XamlUiaTextRange::Compare(XamlAutomation::ITextRangeProvider pRange) const
|
||||
{
|
||||
auto self = winrt::get_self<XamlUiaTextRange>(pRange);
|
||||
|
||||
BOOL returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->Compare(self->_uiaProvider.get(), &returnVal));
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
int32_t XamlUiaTextRange::CompareEndpoints(XamlAutomation::TextPatternRangeEndpoint endpoint,
|
||||
XamlAutomation::ITextRangeProvider pTargetRange,
|
||||
XamlAutomation::TextPatternRangeEndpoint targetEndpoint)
|
||||
{
|
||||
auto self = winrt::get_self<XamlUiaTextRange>(pTargetRange);
|
||||
|
||||
int32_t returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->CompareEndpoints(static_cast<UIA::TextPatternRangeEndpoint>(endpoint),
|
||||
self->_uiaProvider.get(),
|
||||
static_cast<UIA::TextPatternRangeEndpoint>(targetEndpoint),
|
||||
&returnVal));
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::ExpandToEnclosingUnit(XamlAutomation::TextUnit unit) const
|
||||
{
|
||||
THROW_IF_FAILED(_uiaProvider->ExpandToEnclosingUnit(static_cast<UIA::TextUnit>(unit)));
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider XamlUiaTextRange::FindAttribute(int32_t textAttributeId,
|
||||
winrt::Windows::Foundation::IInspectable val,
|
||||
bool searchBackward)
|
||||
{
|
||||
// TODO GitHub #2161: potential accessibility improvement
|
||||
// we don't support this currently
|
||||
throw winrt::hresult_not_implemented();
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider XamlUiaTextRange::FindText(winrt::hstring text,
|
||||
bool searchBackward,
|
||||
bool ignoreCase)
|
||||
{
|
||||
// TODO GitHub #605: Search functionality
|
||||
// we need to wrap this around the UiaTextRange FindText() function
|
||||
// but right now it returns E_NOTIMPL, so let's just return nullptr for now.
|
||||
throw winrt::hresult_not_implemented();
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable XamlUiaTextRange::GetAttributeValue(int32_t textAttributeId) const
|
||||
{
|
||||
// Copied functionality from Types::UiaTextRange.cpp
|
||||
if (textAttributeId == UIA_IsReadOnlyAttributeId)
|
||||
{
|
||||
return winrt::box_value(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::GetBoundingRectangles(com_array<double>& returnValue) const
|
||||
{
|
||||
returnValue = {};
|
||||
try
|
||||
{
|
||||
SAFEARRAY* pReturnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->GetBoundingRectangles(&pReturnVal));
|
||||
|
||||
double* pVals;
|
||||
THROW_IF_FAILED(SafeArrayAccessData(pReturnVal, (void**)&pVals));
|
||||
|
||||
long lBound, uBound;
|
||||
THROW_IF_FAILED(SafeArrayGetLBound(pReturnVal, 1, &lBound));
|
||||
THROW_IF_FAILED(SafeArrayGetUBound(pReturnVal, 1, &uBound));
|
||||
|
||||
long count = uBound - lBound + 1;
|
||||
|
||||
std::vector<double> vec;
|
||||
vec.reserve(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
double element = pVals[i];
|
||||
vec.push_back(element);
|
||||
}
|
||||
|
||||
winrt::com_array<double> result{ vec };
|
||||
returnValue = std::move(result);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
XamlAutomation::IRawElementProviderSimple XamlUiaTextRange::GetEnclosingElement()
|
||||
{
|
||||
return _parentProvider;
|
||||
}
|
||||
|
||||
winrt::hstring XamlUiaTextRange::GetText(int32_t maxLength) const
|
||||
{
|
||||
BSTR returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->GetText(maxLength, &returnVal));
|
||||
return winrt::to_hstring(returnVal);
|
||||
}
|
||||
|
||||
int32_t XamlUiaTextRange::Move(XamlAutomation::TextUnit unit,
|
||||
int32_t count)
|
||||
{
|
||||
int returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->Move(static_cast<UIA::TextUnit>(unit),
|
||||
count,
|
||||
&returnVal));
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
int32_t XamlUiaTextRange::MoveEndpointByUnit(XamlAutomation::TextPatternRangeEndpoint endpoint,
|
||||
XamlAutomation::TextUnit unit,
|
||||
int32_t count) const
|
||||
{
|
||||
int returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->MoveEndpointByUnit(static_cast<UIA::TextPatternRangeEndpoint>(endpoint),
|
||||
static_cast<UIA::TextUnit>(unit),
|
||||
count,
|
||||
&returnVal));
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::MoveEndpointByRange(XamlAutomation::TextPatternRangeEndpoint endpoint,
|
||||
XamlAutomation::ITextRangeProvider pTargetRange,
|
||||
XamlAutomation::TextPatternRangeEndpoint targetEndpoint) const
|
||||
{
|
||||
auto self = winrt::get_self<XamlUiaTextRange>(pTargetRange);
|
||||
THROW_IF_FAILED(_uiaProvider->MoveEndpointByRange(static_cast<UIA::TextPatternRangeEndpoint>(endpoint),
|
||||
/*pTargetRange*/ self->_uiaProvider.get(),
|
||||
static_cast<UIA::TextPatternRangeEndpoint>(targetEndpoint)));
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::Select() const
|
||||
{
|
||||
THROW_IF_FAILED(_uiaProvider->Select());
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::AddToSelection() const
|
||||
{
|
||||
// we don't support this
|
||||
throw winrt::hresult_not_implemented();
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::RemoveFromSelection() const
|
||||
{
|
||||
// we don't support this
|
||||
throw winrt::hresult_not_implemented();
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::ScrollIntoView(bool alignToTop) const
|
||||
{
|
||||
THROW_IF_FAILED(_uiaProvider->ScrollIntoView(alignToTop));
|
||||
}
|
||||
|
||||
winrt::com_array<XamlAutomation::IRawElementProviderSimple> XamlUiaTextRange::GetChildren() const
|
||||
{
|
||||
// we don't have any children
|
||||
return {};
|
||||
}
|
||||
}
|
75
src/cascadia/TerminalControl/XamlUiaTextRange.h
Normal file
75
src/cascadia/TerminalControl/XamlUiaTextRange.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- XamlUiaTextRange.h
|
||||
|
||||
Abstract:
|
||||
- This module is a wrapper for the UiaTextRange
|
||||
(a text range accessibility provider). It allows
|
||||
for UiaTextRange to be used in Windows Terminal.
|
||||
- Wraps the UIAutomationCore ITextRangeProvider
|
||||
(https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-itextrangeprovider)
|
||||
with a XAML ITextRangeProvider
|
||||
(https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.provider.itextrangeprovider)
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora (CaZamor) 2019
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "TermControlAutomationPeer.h"
|
||||
#include <UIAutomationCore.h>
|
||||
#include "../types/UiaTextRange.hpp"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
class XamlUiaTextRange :
|
||||
public winrt::implements<XamlUiaTextRange, Windows::UI::Xaml::Automation::Provider::ITextRangeProvider>
|
||||
{
|
||||
public:
|
||||
XamlUiaTextRange(::ITextRangeProvider* uiaProvider, Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider) :
|
||||
_parentProvider{ parentProvider }
|
||||
{
|
||||
_uiaProvider.attach(uiaProvider);
|
||||
}
|
||||
|
||||
#pragma region ITextRangeProvider
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider Clone() const;
|
||||
bool Compare(Windows::UI::Xaml::Automation::Provider::ITextRangeProvider pRange) const;
|
||||
int32_t CompareEndpoints(Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint,
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider pTargetRange,
|
||||
Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint targetEndpoint);
|
||||
void ExpandToEnclosingUnit(Windows::UI::Xaml::Automation::Text::TextUnit unit) const;
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider FindAttribute(int32_t textAttributeId,
|
||||
winrt::Windows::Foundation::IInspectable val,
|
||||
bool searchBackward);
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider FindText(winrt::hstring text,
|
||||
bool searchBackward,
|
||||
bool ignoreCase);
|
||||
winrt::Windows::Foundation::IInspectable GetAttributeValue(int32_t textAttributeId) const;
|
||||
void GetBoundingRectangles(winrt::com_array<double>& returnValue) const;
|
||||
Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple GetEnclosingElement();
|
||||
winrt::hstring GetText(int32_t maxLength) const;
|
||||
int32_t Move(Windows::UI::Xaml::Automation::Text::TextUnit unit,
|
||||
int32_t count);
|
||||
int32_t MoveEndpointByUnit(Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint,
|
||||
Windows::UI::Xaml::Automation::Text::TextUnit unit,
|
||||
int32_t count) const;
|
||||
void MoveEndpointByRange(Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint,
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider pTargetRange,
|
||||
Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint targetEndpoint) const;
|
||||
void Select() const;
|
||||
void AddToSelection() const;
|
||||
void RemoveFromSelection() const;
|
||||
void ScrollIntoView(bool alignToTop) const;
|
||||
winrt::com_array<Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple> GetChildren() const;
|
||||
#pragma endregion ITextRangeProvider
|
||||
|
||||
private:
|
||||
wil::com_ptr<::ITextRangeProvider> _uiaProvider;
|
||||
Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple _parentProvider;
|
||||
};
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/windows.ui.core.h>
|
||||
#include <winrt/Windows.ui.input.h>
|
||||
#include <winrt/Windows.UI.Xaml.h>
|
||||
#include <winrt/Windows.UI.Xaml.Automation.Peers.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.ui.xaml.media.h>
|
||||
|
|
|
@ -24,7 +24,11 @@ namespace Microsoft::Terminal::Core
|
|||
virtual bool SetCursorPosition(short x, short y) = 0;
|
||||
virtual COORD GetCursorPosition() = 0;
|
||||
|
||||
virtual bool DeleteCharacter(const unsigned int uiCount) = 0;
|
||||
virtual bool InsertCharacter(const unsigned int uiCount) = 0;
|
||||
virtual bool EraseCharacters(const unsigned int numChars) = 0;
|
||||
virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0;
|
||||
virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0;
|
||||
|
||||
virtual bool SetWindowTitle(std::wstring_view title) = 0;
|
||||
|
||||
|
|
|
@ -210,18 +210,6 @@ bool Terminal::SendKeyEvent(const WORD vkey, const ControlKeyStates states)
|
|||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (states.IsAltGrPressed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Alt key sequences _require_ the char to be in the keyevent. If alt is
|
||||
// pressed, manually get the character that's being typed, and put it in the
|
||||
// KeyEvent.
|
||||
|
|
|
@ -66,7 +66,11 @@ public:
|
|||
bool ReverseText(bool reversed) override;
|
||||
bool SetCursorPosition(short x, short y) override;
|
||||
COORD GetCursorPosition() override;
|
||||
bool DeleteCharacter(const unsigned int uiCount) override;
|
||||
bool InsertCharacter(const unsigned int uiCount) override;
|
||||
bool EraseCharacters(const unsigned int numChars) override;
|
||||
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
|
||||
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
|
||||
bool SetWindowTitle(std::wstring_view title) override;
|
||||
bool SetColorTableEntry(const size_t tableIndex, const COLORREF dwColor) override;
|
||||
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "pch.h"
|
||||
#include "Terminal.hpp"
|
||||
#include "../src/inc/unicode.hpp"
|
||||
|
||||
using namespace Microsoft::Terminal::Core;
|
||||
using namespace Microsoft::Console::Types;
|
||||
|
@ -126,17 +127,240 @@ COORD Terminal::GetCursorPosition()
|
|||
return newPos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - deletes uiCount characters starting from the cursor's current position
|
||||
// - it moves over the remaining text to 'replace' the deleted text
|
||||
// - for example, if the buffer looks like this ('|' is the cursor): [abc|def]
|
||||
// - calling DeleteCharacter(1) will change it to: [abc|ef],
|
||||
// - i.e. the 'd' gets deleted and the 'ef' gets shifted over 1 space and **retain their previous text attributes**
|
||||
// Arguments:
|
||||
// - uiCount, the number of characters to delete
|
||||
// Return value:
|
||||
// - true if succeeded, false otherwise
|
||||
bool Terminal::DeleteCharacter(const unsigned int uiCount)
|
||||
{
|
||||
SHORT dist;
|
||||
if (!SUCCEEDED(UIntToShort(uiCount, &dist)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const auto cursorPos = _buffer->GetCursor().GetPosition();
|
||||
const auto copyToPos = cursorPos;
|
||||
const COORD copyFromPos{ cursorPos.X + dist, cursorPos.Y };
|
||||
auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
|
||||
SHORT width;
|
||||
if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a rectangle of the source
|
||||
auto source = Viewport::FromDimensions(copyFromPos, width, 1);
|
||||
|
||||
// Get a rectangle of the target
|
||||
const auto target = Viewport::FromDimensions(copyToPos, source.Dimensions());
|
||||
const auto walkDirection = Viewport::DetermineWalkDirection(source, target);
|
||||
|
||||
auto sourcePos = source.GetWalkOrigin(walkDirection);
|
||||
auto targetPos = target.GetWalkOrigin(walkDirection);
|
||||
|
||||
// Iterate over the source cell data and copy it over to the target
|
||||
do
|
||||
{
|
||||
const auto data = OutputCell(*(_buffer->GetCellDataAt(sourcePos)));
|
||||
_buffer->Write(OutputCellIterator({ &data, 1 }), targetPos);
|
||||
} while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Inserts uiCount spaces starting from the cursor's current position, moving over the existing text
|
||||
// - for example, if the buffer looks like this ('|' is the cursor): [abc|def]
|
||||
// - calling InsertCharacter(1) will change it to: [abc| def],
|
||||
// - i.e. the 'def' gets shifted over 1 space and **retain their previous text attributes**
|
||||
// Arguments:
|
||||
// - uiCount, the number of spaces to insert
|
||||
// Return value:
|
||||
// - true if succeeded, false otherwise
|
||||
bool Terminal::InsertCharacter(const unsigned int uiCount)
|
||||
{
|
||||
// NOTE: the code below is _extremely_ similar to DeleteCharacter
|
||||
// We will want to use this same logic and implement a helper function instead
|
||||
// that does the 'move a region from here to there' operation
|
||||
// TODO: Github issue #2163
|
||||
SHORT dist;
|
||||
if (!SUCCEEDED(UIntToShort(uiCount, &dist)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const auto cursorPos = _buffer->GetCursor().GetPosition();
|
||||
const auto copyFromPos = cursorPos;
|
||||
const COORD copyToPos{ cursorPos.X + dist, cursorPos.Y };
|
||||
auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
|
||||
SHORT width;
|
||||
if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a rectangle of the source
|
||||
auto source = Viewport::FromDimensions(copyFromPos, width, 1);
|
||||
const auto sourceOrigin = source.Origin();
|
||||
|
||||
// Get a rectangle of the target
|
||||
const auto target = Viewport::FromDimensions(copyToPos, source.Dimensions());
|
||||
const auto walkDirection = Viewport::DetermineWalkDirection(source, target);
|
||||
|
||||
auto sourcePos = source.GetWalkOrigin(walkDirection);
|
||||
auto targetPos = target.GetWalkOrigin(walkDirection);
|
||||
|
||||
// Iterate over the source cell data and copy it over to the target
|
||||
do
|
||||
{
|
||||
const auto data = OutputCell(*(_buffer->GetCellDataAt(sourcePos)));
|
||||
_buffer->Write(OutputCellIterator({ &data, 1 }), targetPos);
|
||||
} while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection));
|
||||
auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), dist);
|
||||
_buffer->Write(eraseIter, cursorPos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::EraseCharacters(const unsigned int numChars)
|
||||
{
|
||||
const auto absoluteCursorPos = _buffer->GetCursor().GetPosition();
|
||||
const auto viewport = _GetMutableViewport();
|
||||
const short distanceToRight = viewport.RightExclusive() - absoluteCursorPos.X;
|
||||
const short fillLimit = std::min(static_cast<short>(numChars), distanceToRight);
|
||||
auto eraseIter = OutputCellIterator(L' ', _buffer->GetCurrentAttributes(), fillLimit);
|
||||
auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), fillLimit);
|
||||
_buffer->Write(eraseIter, absoluteCursorPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method description:
|
||||
// - erases a line of text, either from
|
||||
// 1. beginning to the cursor's position
|
||||
// 2. cursor's position to end
|
||||
// 3. beginning to end
|
||||
// - depending on the erase type
|
||||
// Arguments:
|
||||
// - the erase type
|
||||
// Return value:
|
||||
// - true if succeeded, false otherwise
|
||||
bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType)
|
||||
{
|
||||
const auto cursorPos = _buffer->GetCursor().GetPosition();
|
||||
const auto viewport = _GetMutableViewport();
|
||||
COORD startPos = { 0 };
|
||||
startPos.Y = cursorPos.Y;
|
||||
// nlength determines the number of spaces we need to write
|
||||
DWORD nlength = 0;
|
||||
|
||||
// Determine startPos.X and nlength by the eraseType
|
||||
switch (eraseType)
|
||||
{
|
||||
case DispatchTypes::EraseType::FromBeginning:
|
||||
nlength = cursorPos.X - viewport.Left() + 1;
|
||||
break;
|
||||
case DispatchTypes::EraseType::ToEnd:
|
||||
startPos.X = cursorPos.X;
|
||||
nlength = viewport.RightInclusive() - startPos.X;
|
||||
break;
|
||||
case DispatchTypes::EraseType::All:
|
||||
startPos.X = viewport.Left();
|
||||
nlength = viewport.RightInclusive() - startPos.X;
|
||||
break;
|
||||
case DispatchTypes::EraseType::Scrollback:
|
||||
return false;
|
||||
}
|
||||
|
||||
auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), nlength);
|
||||
_buffer->Write(eraseIter, startPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method description:
|
||||
// - erases text in the buffer in two ways depending on erase type
|
||||
// 1. 'erases' all text visible to the user (i.e. the text in the viewport)
|
||||
// 2. erases all the text in the scrollback
|
||||
// Arguments:
|
||||
// - the erase type
|
||||
// Return Value:
|
||||
// - true if succeeded, false otherwise
|
||||
bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType)
|
||||
{
|
||||
// Store the relative cursor position so we can restore it later after we move the viewport
|
||||
const auto cursorPos = _buffer->GetCursor().GetPosition();
|
||||
auto relativeCursor = cursorPos;
|
||||
_mutableViewport.ConvertToOrigin(&relativeCursor);
|
||||
|
||||
// Initialize the new location of the viewport
|
||||
// the top and bottom parameters are determined by the eraseType
|
||||
SMALL_RECT newWin;
|
||||
newWin.Left = _mutableViewport.Left();
|
||||
newWin.Right = _mutableViewport.RightExclusive();
|
||||
|
||||
if (eraseType == DispatchTypes::EraseType::All)
|
||||
{
|
||||
// In this case, we simply move the viewport down, effectively pushing whatever text was on the screen into the scrollback
|
||||
// and thus 'erasing' the text visible to the user
|
||||
const auto coordLastChar = _buffer->GetLastNonSpaceCharacter(_mutableViewport);
|
||||
if (coordLastChar.X == 0 && coordLastChar.Y == 0)
|
||||
{
|
||||
// Nothing to clear, just return
|
||||
return true;
|
||||
}
|
||||
|
||||
short sNewTop = coordLastChar.Y + 1;
|
||||
|
||||
// Increment the circular buffer only if the new location of the viewport would be 'below' the buffer
|
||||
const short delta = (sNewTop + _mutableViewport.Height()) - (_buffer->GetSize().Height());
|
||||
for (auto i = 0; i < delta; i++)
|
||||
{
|
||||
_buffer->IncrementCircularBuffer();
|
||||
sNewTop--;
|
||||
}
|
||||
|
||||
newWin.Top = sNewTop;
|
||||
newWin.Bottom = sNewTop + _mutableViewport.Height();
|
||||
}
|
||||
else if (eraseType == DispatchTypes::EraseType::Scrollback)
|
||||
{
|
||||
// We only want to erase the scrollback, and leave everything else on the screen as it is
|
||||
// so we grab the text in the viewport and rotate it up to the top of the buffer
|
||||
COORD scrollFromPos{ 0, 0 };
|
||||
_mutableViewport.ConvertFromOrigin(&scrollFromPos);
|
||||
_buffer->ScrollRows(scrollFromPos.Y, _mutableViewport.Height(), -scrollFromPos.Y);
|
||||
|
||||
// Since we only did a rotation, the text that was in the scrollback is now _below_ where we are going to move the viewport
|
||||
// and we have to make sure we erase that text
|
||||
auto eraseStart = _mutableViewport.Height();
|
||||
auto eraseEnd = _buffer->GetLastNonSpaceCharacter(_mutableViewport).Y;
|
||||
for (SHORT i = eraseStart; i <= eraseEnd; i++)
|
||||
{
|
||||
_buffer->GetRowByOffset(i).Reset(_buffer->GetCurrentAttributes());
|
||||
}
|
||||
|
||||
// Reset the scroll offset now because there's nothing for the user to 'scroll' to
|
||||
_scrollOffset = 0;
|
||||
|
||||
newWin.Top = 0;
|
||||
newWin.Bottom = _mutableViewport.Height();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Move the viewport, adjust the scoll bar if needed, and restore the old cursor position
|
||||
_mutableViewport = Viewport::FromExclusive(newWin);
|
||||
Terminal::_NotifyScrollEvent();
|
||||
SetCursorPosition(relativeCursor.X, relativeCursor.Y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Terminal::SetWindowTitle(std::wstring_view title)
|
||||
{
|
||||
_title = title;
|
||||
|
|
|
@ -47,6 +47,20 @@ bool TerminalDispatch::CursorForward(const unsigned int uiDistance)
|
|||
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
|
||||
}
|
||||
|
||||
bool TerminalDispatch::CursorBackward(const unsigned int uiDistance)
|
||||
{
|
||||
const auto cursorPos = _terminalApi.GetCursorPosition();
|
||||
const COORD newCursorPos{ cursorPos.X - gsl::narrow<short>(uiDistance), cursorPos.Y };
|
||||
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
|
||||
}
|
||||
|
||||
bool TerminalDispatch::CursorUp(const unsigned int uiDistance)
|
||||
{
|
||||
const auto cursorPos = _terminalApi.GetCursorPosition();
|
||||
const COORD newCursorPos{ cursorPos.X, cursorPos.Y + gsl::narrow<short>(uiDistance) };
|
||||
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
|
||||
}
|
||||
|
||||
bool TerminalDispatch::EraseCharacters(const unsigned int uiNumChars)
|
||||
{
|
||||
return _terminalApi.EraseCharacters(uiNumChars);
|
||||
|
@ -98,9 +112,45 @@ bool TerminalDispatch::SetDefaultBackground(const DWORD dwColor)
|
|||
}
|
||||
|
||||
// Method Description:
|
||||
// - For now, this is a hacky backspace
|
||||
// - TODO: GitHub #1883
|
||||
bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType)
|
||||
// - Erases characters in the buffer depending on the erase type
|
||||
// Arguments:
|
||||
// - eraseType: the erase type (from beginning, to end, or all)
|
||||
// Return Value:
|
||||
// True if handled successfully. False otherwise.
|
||||
bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType)
|
||||
{
|
||||
return _terminalApi.EraseCharacters(1);
|
||||
return _terminalApi.EraseInLine(eraseType);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Deletes uiCount number of characters starting from where the cursor is currently
|
||||
// Arguments:
|
||||
// - uiCount, the number of characters to delete
|
||||
// Return Value:
|
||||
// True if handled successfully. False otherwise.
|
||||
bool TerminalDispatch::DeleteCharacter(const unsigned int uiCount)
|
||||
{
|
||||
return _terminalApi.DeleteCharacter(uiCount);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Adds uiCount number of spaces starting from where the cursor is currently
|
||||
// Arguments:
|
||||
// - uiCount, the number of spaces to add
|
||||
// Return Value:
|
||||
// True if handled successfully, false otherwise
|
||||
bool TerminalDispatch::InsertCharacter(const unsigned int uiCount)
|
||||
{
|
||||
return _terminalApi.InsertCharacter(uiCount);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the viewport and erases text from the buffer depending on the eraseType
|
||||
// Arguments:
|
||||
// - eraseType: the desired erase type
|
||||
// Return Value:
|
||||
// True if handled successfully. False otherwise
|
||||
bool TerminalDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType)
|
||||
{
|
||||
return _terminalApi.EraseInDisplay(eraseType);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ public:
|
|||
const unsigned int uiColumn) override; // CUP
|
||||
|
||||
bool CursorForward(const unsigned int uiDistance) override;
|
||||
bool CursorBackward(const unsigned int uiDistance) override;
|
||||
bool CursorUp(const unsigned int uiDistance) override;
|
||||
|
||||
bool EraseCharacters(const unsigned int uiNumChars) override;
|
||||
bool SetWindowTitle(std::wstring_view title) override;
|
||||
|
@ -29,7 +31,10 @@ public:
|
|||
|
||||
bool SetDefaultForeground(const DWORD dwColor) override;
|
||||
bool SetDefaultBackground(const DWORD dwColor) override;
|
||||
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType /* eraseType*/) override; // ED
|
||||
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; // ED
|
||||
bool DeleteCharacter(const unsigned int uiCount) override;
|
||||
bool InsertCharacter(const unsigned int uiCount) override;
|
||||
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
|
||||
|
||||
private:
|
||||
::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -64,7 +64,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
|||
|
||||
void TerminalSettings::SetColorTableEntry(int32_t index, uint32_t value)
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, index > _colorTable.size());
|
||||
auto const colorTableCount = gsl::narrow_cast<decltype(index)>(_colorTable.size());
|
||||
THROW_HR_IF(E_INVALIDARG, index >= colorTableCount);
|
||||
_colorTable[index] = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -181,6 +181,11 @@ namespace TerminalCoreUnitTests
|
|||
|
||||
TEST_METHOD(SelectWideGlyph_Trailing)
|
||||
{
|
||||
#ifdef _X86_
|
||||
Log::Comment(L"This test is unreliable on x86 but is fine elsewhere. Disabled on x86.");
|
||||
Log::Result(WEX::Logging::TestResults::Skipped);
|
||||
return;
|
||||
#else
|
||||
Terminal term;
|
||||
DummyRenderTarget emptyRT;
|
||||
term.Create({ 100, 100 }, 0, emptyRT);
|
||||
|
@ -206,10 +211,16 @@ namespace TerminalCoreUnitTests
|
|||
|
||||
auto selection = term.GetViewport().ConvertToOrigin(selectionRects.at(0)).ToInclusive();
|
||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 4, 10, 5, 10 }));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_METHOD(SelectWideGlyph_Leading)
|
||||
{
|
||||
#ifdef _X86_
|
||||
Log::Comment(L"This test is unreliable on x86 but is fine elsewhere. Disabled on x86.");
|
||||
Log::Result(WEX::Logging::TestResults::Skipped);
|
||||
return;
|
||||
#else
|
||||
Terminal term;
|
||||
DummyRenderTarget emptyRT;
|
||||
term.Create({ 100, 100 }, 0, emptyRT);
|
||||
|
@ -235,10 +246,16 @@ namespace TerminalCoreUnitTests
|
|||
|
||||
auto selection = term.GetViewport().ConvertToOrigin(selectionRects.at(0)).ToInclusive();
|
||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 4, 10, 5, 10 }));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_METHOD(SelectWideGlyphsInBoxSelection)
|
||||
{
|
||||
#ifdef _X86_
|
||||
Log::Comment(L"This test is unreliable on x86 but is fine elsewhere. Disabled on x86.");
|
||||
Log::Result(WEX::Logging::TestResults::Skipped);
|
||||
return;
|
||||
#else
|
||||
Terminal term;
|
||||
DummyRenderTarget emptyRT;
|
||||
term.Create({ 100, 100 }, 0, emptyRT);
|
||||
|
@ -290,6 +307,7 @@ namespace TerminalCoreUnitTests
|
|||
|
||||
rowValue++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -623,6 +623,12 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
|||
break;
|
||||
}
|
||||
}
|
||||
case WM_DPICHANGED:
|
||||
{
|
||||
auto lprcNewScale = reinterpret_cast<RECT*>(lParam);
|
||||
OnSize(RECT_WIDTH(lprcNewScale), RECT_HEIGHT(lprcNewScale));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return IslandWindow::MessageHandler(message, wParam, lParam);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<application>
|
||||
<!-- Windows 10 1903 -->
|
||||
<!-- See https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/xaml-islands -->
|
||||
<maxversiontested Id="10.0.18362.0"/>
|
||||
<maxVersionTested Id="10.0.18362.0"/>
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<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>
|
||||
|
@ -110,17 +110,17 @@
|
|||
</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-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.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'))" />
|
||||
</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-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.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
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.2" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
<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.0-rc" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190521.3" targetFramework="native" />
|
||||
<package id="Microsoft.VCRTForwarders.140" version="1.0.1-rc" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -80,3 +80,33 @@ public:
|
|||
\
|
||||
private: \
|
||||
type _##name;
|
||||
|
||||
// This is a helper method for deserializing a SAFEARRAY of
|
||||
// COM objects and converting it to a vector that
|
||||
// owns the extracted COM objects
|
||||
template<typename T>
|
||||
std::vector<wil::com_ptr<T>> SafeArrayToOwningVector(SAFEARRAY* safeArray)
|
||||
{
|
||||
T** pVals;
|
||||
THROW_IF_FAILED(SafeArrayAccessData(safeArray, (void**)&pVals));
|
||||
|
||||
THROW_HR_IF(E_UNEXPECTED, SafeArrayGetDim(safeArray) != 1);
|
||||
|
||||
long lBound, uBound;
|
||||
THROW_IF_FAILED(SafeArrayGetLBound(safeArray, 1, &lBound));
|
||||
THROW_IF_FAILED(SafeArrayGetUBound(safeArray, 1, &uBound));
|
||||
|
||||
long count = uBound - lBound + 1;
|
||||
|
||||
// If any of the above fail, we cannot destruct/release
|
||||
// any of the elements in the SAFEARRAY because we
|
||||
// cannot identify how many elements there are.
|
||||
|
||||
std::vector<wil::com_ptr<T>> result{ gsl::narrow<std::size_t>(count) };
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
result[i].attach(pVals[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -30,4 +30,12 @@
|
|||
<PropertyGroup>
|
||||
<CAExcludePath>$(SolutionDir)\dep\;$(CAExcludePath)</CAExcludePath>
|
||||
</PropertyGroup>
|
||||
<Target Name="CleanUpPrecompForSmallCIAgents" AfterTargets="AfterBuild" Condition="'$(AGENT_ID)' != ''">
|
||||
<ItemGroup>
|
||||
<FilesToClean Include="$(IntDir)\**\*.pch" />
|
||||
<FilesToClean Include="$(IntDir)\**\precomp.obj" />
|
||||
</ItemGroup>
|
||||
<Delete Files="@(FilesToClean)"/>
|
||||
<Message Text="PCH and Precomp objects have been deleted for $(ProjectName)." />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -64,13 +64,13 @@
|
|||
</ItemDefinitionGroup>
|
||||
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<Import Project="..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<!-- 17134 is RS4 -->
|
||||
|
|
|
@ -397,3 +397,37 @@ void VtIo::_ShutdownIfNeeded()
|
|||
ServiceLocator::RundownAndExit(ERROR_BROKEN_PIPE);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tell the vt renderer to begin a resize operation. During a resize
|
||||
// operation, the vt renderer should _not_ request to be repainted during a
|
||||
// text buffer circling event. Any callers of this method should make sure to
|
||||
// call EndResize to make sure the renderer returns to normal behavior.
|
||||
// See GH#1795 for context on this method.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void VtIo::BeginResize()
|
||||
{
|
||||
if (_pVtRenderEngine)
|
||||
{
|
||||
_pVtRenderEngine->BeginResizeRequest();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tell the vt renderer to end a resize operation.
|
||||
// See BeginResize for more details.
|
||||
// See GH#1795 for context on this method.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void VtIo::EndResize()
|
||||
{
|
||||
if (_pVtRenderEngine)
|
||||
{
|
||||
_pVtRenderEngine->EndResizeRequest();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ namespace Microsoft::Console::VirtualTerminal
|
|||
void CloseInput() override;
|
||||
void CloseOutput() override;
|
||||
|
||||
void BeginResize();
|
||||
void EndResize();
|
||||
|
||||
private:
|
||||
// After CreateIoHandlers is called, these will be invalid.
|
||||
wil::unique_hfile _hInput;
|
||||
|
|
|
@ -102,9 +102,9 @@ protected:
|
|||
CommandLine(CommandLine const&) = delete;
|
||||
CommandLine& operator=(CommandLine const&) = delete;
|
||||
|
||||
[[nodiscard]] NTSTATUS CommandLine::_startCommandListPopup(COOKED_READ_DATA& cookedReadData);
|
||||
[[nodiscard]] NTSTATUS CommandLine::_startCopyFromCharPopup(COOKED_READ_DATA& cookedReadData);
|
||||
[[nodiscard]] NTSTATUS CommandLine::_startCopyToCharPopup(COOKED_READ_DATA& cookedReadData);
|
||||
[[nodiscard]] NTSTATUS _startCommandListPopup(COOKED_READ_DATA& cookedReadData);
|
||||
[[nodiscard]] NTSTATUS _startCopyFromCharPopup(COOKED_READ_DATA& cookedReadData);
|
||||
[[nodiscard]] NTSTATUS _startCopyToCharPopup(COOKED_READ_DATA& cookedReadData);
|
||||
|
||||
void _processHistoryCycling(COOKED_READ_DATA& cookedReadData, const CommandHistory::SearchDirection searchDirection);
|
||||
void _setPromptToOldestCommand(COOKED_READ_DATA& cookedReadData);
|
||||
|
|
|
@ -273,13 +273,18 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||
{
|
||||
try
|
||||
{
|
||||
RETURN_NTSTATUS(_DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
false,
|
||||
true,
|
||||
waiter));
|
||||
NTSTATUS Status = _DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
false,
|
||||
true,
|
||||
waiter);
|
||||
if (CONSOLE_STATUS_WAIT == Status)
|
||||
{
|
||||
return HRESULT_FROM_NT(Status);
|
||||
}
|
||||
RETURN_NTSTATUS(Status);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
@ -308,13 +313,18 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||
{
|
||||
try
|
||||
{
|
||||
RETURN_NTSTATUS(_DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
true,
|
||||
true,
|
||||
waiter));
|
||||
NTSTATUS Status = _DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
true,
|
||||
true,
|
||||
waiter);
|
||||
if (CONSOLE_STATUS_WAIT == Status)
|
||||
{
|
||||
return HRESULT_FROM_NT(Status);
|
||||
}
|
||||
RETURN_NTSTATUS(Status);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
@ -343,13 +353,18 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||
{
|
||||
try
|
||||
{
|
||||
RETURN_NTSTATUS(_DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
false,
|
||||
false,
|
||||
waiter));
|
||||
NTSTATUS Status = _DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
false,
|
||||
false,
|
||||
waiter);
|
||||
if (CONSOLE_STATUS_WAIT == Status)
|
||||
{
|
||||
return HRESULT_FROM_NT(Status);
|
||||
}
|
||||
RETURN_NTSTATUS(Status);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
@ -378,13 +393,18 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||
{
|
||||
try
|
||||
{
|
||||
RETURN_NTSTATUS(_DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
true,
|
||||
false,
|
||||
waiter));
|
||||
NTSTATUS Status = _DoGetConsoleInput(context,
|
||||
outEvents,
|
||||
eventsToRead,
|
||||
readHandleState,
|
||||
true,
|
||||
false,
|
||||
waiter);
|
||||
if (CONSOLE_STATUS_WAIT == Status)
|
||||
{
|
||||
return HRESULT_FROM_NT(Status);
|
||||
}
|
||||
RETURN_NTSTATUS(Status);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
|
|
@ -1670,6 +1670,19 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
|
|||
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
// If we're in conpty mode, suppress any immediate painting we might do
|
||||
// during the resize.
|
||||
if (gci.IsInVtIoMode())
|
||||
{
|
||||
gci.GetVtIo()->BeginResize();
|
||||
}
|
||||
auto endResize = wil::scope_exit([&] {
|
||||
if (gci.IsInVtIoMode())
|
||||
{
|
||||
gci.GetVtIo()->EndResize();
|
||||
}
|
||||
});
|
||||
|
||||
// cancel any active selection before resizing or it will not necessarily line up with the new buffer positions
|
||||
Selection::Instance().ClearSelection();
|
||||
|
||||
|
|
|
@ -314,16 +314,16 @@ void Window::_UpdateSystemMetrics() const
|
|||
|
||||
if (useDx)
|
||||
{
|
||||
status = NTSTATUS_FROM_HRESULT(pDxEngine->SetHwnd(hWnd));
|
||||
status = NTSTATUS_FROM_WIN32(HRESULT_CODE((pDxEngine->SetHwnd(hWnd))));
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
status = NTSTATUS_FROM_HRESULT(pDxEngine->Enable());
|
||||
status = NTSTATUS_FROM_WIN32(HRESULT_CODE((pDxEngine->Enable())));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NTSTATUS_FROM_HRESULT(pGdiEngine->SetHwnd(hWnd));
|
||||
status = NTSTATUS_FROM_WIN32(HRESULT_CODE((pGdiEngine->SetHwnd(hWnd))));
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
|
|
|
@ -98,10 +98,10 @@ public:
|
|||
} RegPropertyMap;
|
||||
|
||||
static const RegPropertyMap s_PropertyMappings[];
|
||||
static const size_t RegistrySerialization::s_PropertyMappingsSize;
|
||||
static const size_t s_PropertyMappingsSize;
|
||||
|
||||
static const RegPropertyMap s_GlobalPropMappings[];
|
||||
static const size_t RegistrySerialization::s_GlobalPropMappingsSize;
|
||||
static const size_t s_GlobalPropMappingsSize;
|
||||
|
||||
[[nodiscard]] static NTSTATUS s_LoadRegDword(const HKEY hKey, const _RegPropertyMap* const pPropMap, _In_ Settings* const pSettings);
|
||||
[[nodiscard]] static NTSTATUS s_LoadRegString(const HKEY hKey, const _RegPropertyMap* const pPropMap, _In_ Settings* const pSettings);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#pragma hdrstop
|
||||
|
||||
static constexpr float POINTS_PER_INCH = 72.0f;
|
||||
static std::wstring FALLBACK_FONT_FACE = L"Consolas";
|
||||
static constexpr std::wstring_view FALLBACK_LOCALE = L"en-us";
|
||||
|
||||
using namespace Microsoft::Console::Render;
|
||||
using namespace Microsoft::Console::Types;
|
||||
|
@ -133,14 +135,14 @@ DxEngine::~DxEngine()
|
|||
|
||||
const DWORD DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
// clang-format off
|
||||
// This causes problems for folks who do not have the whole DirectX SDK installed
|
||||
// when they try to run the rest of the project in debug mode.
|
||||
// As such, I'm leaving this flag here for people doing DX-specific work to toggle it
|
||||
// only when they need it and shutting it off otherwise.
|
||||
// Find out more about the debug layer here:
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-devices-layers
|
||||
// You can find out how to install it here:
|
||||
// https://docs.microsoft.com/en-us/windows/uwp/gaming/use-the-directx-runtime-and-visual-studio-graphics-diagnostic-features
|
||||
// This causes problems for folks who do not have the whole DirectX SDK installed
|
||||
// when they try to run the rest of the project in debug mode.
|
||||
// As such, I'm leaving this flag here for people doing DX-specific work to toggle it
|
||||
// only when they need it and shutting it off otherwise.
|
||||
// Find out more about the debug layer here:
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-devices-layers
|
||||
// You can find out how to install it here:
|
||||
// https://docs.microsoft.com/en-us/windows/uwp/gaming/use-the-directx-runtime-and-visual-studio-graphics-diagnostic-features
|
||||
// clang-format on
|
||||
// D3D11_CREATE_DEVICE_DEBUG |
|
||||
D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||
|
@ -1354,6 +1356,46 @@ float DxEngine::GetScaling() const noexcept
|
|||
return PostMessageW(_hwndTarget, CM_UPDATE_TITLE, 0, (LPARAM) nullptr) ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Attempts to locate the font given, but then begins falling back if we cannot find it.
|
||||
// - We'll try to fall back to Consolas with the given weight/stretch/style first,
|
||||
// then try Consolas again with normal weight/stretch/style,
|
||||
// and if nothing works, then we'll throw an error.
|
||||
// Arguments:
|
||||
// - familyName - The font name we should be looking for
|
||||
// - weight - The weight (bold, light, etc.)
|
||||
// - stretch - The stretch of the font is the spacing between each letter
|
||||
// - style - Normal, italic, etc.
|
||||
// Return Value:
|
||||
// - Smart pointer holding interface reference for queryable font data.
|
||||
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFace1> DxEngine::_ResolveFontFaceWithFallback(std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT& weight,
|
||||
DWRITE_FONT_STRETCH& stretch,
|
||||
DWRITE_FONT_STYLE& style,
|
||||
std::wstring& localeName) const
|
||||
{
|
||||
auto face = _FindFontFace(familyName, weight, stretch, style, localeName);
|
||||
|
||||
if (!face)
|
||||
{
|
||||
familyName = FALLBACK_FONT_FACE;
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName);
|
||||
}
|
||||
|
||||
if (!face)
|
||||
{
|
||||
familyName = FALLBACK_FONT_FACE;
|
||||
weight = DWRITE_FONT_WEIGHT_NORMAL;
|
||||
stretch = DWRITE_FONT_STRETCH_NORMAL;
|
||||
style = DWRITE_FONT_STYLE_NORMAL;
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName);
|
||||
}
|
||||
|
||||
THROW_IF_NULL_ALLOC(face);
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Locates a suitable font face from the given information
|
||||
// Arguments:
|
||||
|
@ -1363,10 +1405,11 @@ float DxEngine::GetScaling() const noexcept
|
|||
// - style - Normal, italic, etc.
|
||||
// Return Value:
|
||||
// - Smart pointer holding interface reference for queryable font data.
|
||||
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFace1> DxEngine::_FindFontFace(const std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT weight,
|
||||
DWRITE_FONT_STRETCH stretch,
|
||||
DWRITE_FONT_STYLE style) const
|
||||
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFace1> DxEngine::_FindFontFace(std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT& weight,
|
||||
DWRITE_FONT_STRETCH& stretch,
|
||||
DWRITE_FONT_STYLE& style,
|
||||
std::wstring& localeName) const
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace1> fontFace;
|
||||
|
||||
|
@ -1375,7 +1418,7 @@ float DxEngine::GetScaling() const noexcept
|
|||
|
||||
UINT32 familyIndex;
|
||||
BOOL familyExists;
|
||||
THROW_IF_FAILED(fontCollection->FindFamilyName(familyName.c_str(), &familyIndex, &familyExists));
|
||||
THROW_IF_FAILED(fontCollection->FindFamilyName(familyName.data(), &familyIndex, &familyExists));
|
||||
|
||||
if (familyExists)
|
||||
{
|
||||
|
@ -1389,11 +1432,107 @@ float DxEngine::GetScaling() const noexcept
|
|||
THROW_IF_FAILED(font->CreateFontFace(&fontFace0));
|
||||
|
||||
THROW_IF_FAILED(fontFace0.As(&fontFace));
|
||||
|
||||
// Dig the family name out at the end to return it.
|
||||
familyName = _GetFontFamilyName(fontFamily.Get(), localeName);
|
||||
}
|
||||
|
||||
return fontFace;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Helper to retrieve the user's locale preference or fallback to the default.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - A locale that can be used on construction of assorted DX objects that want to know one.
|
||||
[[nodiscard]] std::wstring DxEngine::_GetLocaleName() const
|
||||
{
|
||||
std::array<wchar_t, LOCALE_NAME_MAX_LENGTH> localeName;
|
||||
|
||||
const auto returnCode = GetUserDefaultLocaleName(localeName.data(), gsl::narrow<int>(localeName.size()));
|
||||
if (returnCode)
|
||||
{
|
||||
return { localeName.data() };
|
||||
}
|
||||
else
|
||||
{
|
||||
return { FALLBACK_LOCALE.data(), FALLBACK_LOCALE.size() };
|
||||
}
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Retrieves the font family name out of the given object in the given locale.
|
||||
// - If we can't find a valid name for the given locale, we'll fallback and report it back.
|
||||
// Arguments:
|
||||
// - fontFamily - DirectWrite font family object
|
||||
// - localeName - The locale in which the name should be retrieved.
|
||||
// - If fallback occurred, this is updated to what we retrieved instead.
|
||||
// Return Value:
|
||||
// - Localized string name of the font family
|
||||
[[nodiscard]] std::wstring DxEngine::_GetFontFamilyName(IDWriteFontFamily* const fontFamily,
|
||||
std::wstring& localeName) const
|
||||
{
|
||||
// See: https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nn-dwrite-idwritefontcollection
|
||||
Microsoft::WRL::ComPtr<IDWriteLocalizedStrings> familyNames;
|
||||
THROW_IF_FAILED(fontFamily->GetFamilyNames(&familyNames));
|
||||
|
||||
// First we have to find the right family name for the locale. We're going to bias toward what the caller
|
||||
// requested, but fallback if we need to and reply with the locale we ended up choosing.
|
||||
UINT32 index = 0;
|
||||
BOOL exists = false;
|
||||
|
||||
// This returns S_OK whether or not it finds a locale name. Check exists field instead.
|
||||
// If it returns an error, it's a real problem, not an absence of this locale name.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritelocalizedstrings-findlocalename
|
||||
THROW_IF_FAILED(familyNames->FindLocaleName(localeName.data(), &index, &exists));
|
||||
|
||||
// If we tried and it still doesn't exist, try with the fallback locale.
|
||||
if (!exists)
|
||||
{
|
||||
localeName = FALLBACK_LOCALE;
|
||||
THROW_IF_FAILED(familyNames->FindLocaleName(localeName.data(), &index, &exists));
|
||||
}
|
||||
|
||||
// If it still doesn't exist, we're going to try index 0.
|
||||
if (!exists)
|
||||
{
|
||||
index = 0;
|
||||
|
||||
// Get the locale name out so at least the caller knows what locale this name goes with.
|
||||
UINT32 length = 0;
|
||||
THROW_IF_FAILED(familyNames->GetLocaleNameLength(index, &length));
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritelocalizedstrings-getlocalenamelength
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritelocalizedstrings-getlocalename
|
||||
// GetLocaleNameLength does not include space for null terminator, but GetLocaleName needs it so add one.
|
||||
length++;
|
||||
|
||||
localeName.resize(length);
|
||||
|
||||
THROW_IF_FAILED(familyNames->GetLocaleName(index, localeName.data(), length));
|
||||
}
|
||||
|
||||
// OK, now that we've decided which family name and the locale that it's in... let's go get it.
|
||||
UINT32 length = 0;
|
||||
THROW_IF_FAILED(familyNames->GetStringLength(index, &length));
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritelocalizedstrings-getstringlength
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritelocalizedstrings-getstring
|
||||
// Once again, GetStringLength is without the null, but GetString needs the null. So add one.
|
||||
length++;
|
||||
|
||||
// Make our output buffer and resize it so it is allocated.
|
||||
std::wstring retVal;
|
||||
retVal.resize(length);
|
||||
|
||||
// FINALLY, go fetch the string name.
|
||||
THROW_IF_FAILED(familyNames->GetString(index, retVal.data(), length));
|
||||
|
||||
// and return it.
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Updates the font used for drawing
|
||||
// Arguments:
|
||||
|
@ -1411,13 +1550,13 @@ float DxEngine::GetScaling() const noexcept
|
|||
{
|
||||
try
|
||||
{
|
||||
const std::wstring fontName(desired.GetFaceName());
|
||||
const DWRITE_FONT_WEIGHT weight = DWRITE_FONT_WEIGHT_NORMAL;
|
||||
const DWRITE_FONT_STYLE style = DWRITE_FONT_STYLE_NORMAL;
|
||||
const DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL;
|
||||
std::wstring fontName(desired.GetFaceName());
|
||||
DWRITE_FONT_WEIGHT weight = DWRITE_FONT_WEIGHT_NORMAL;
|
||||
DWRITE_FONT_STYLE style = DWRITE_FONT_STYLE_NORMAL;
|
||||
DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL;
|
||||
std::wstring localeName = _GetLocaleName();
|
||||
|
||||
const auto face = _FindFontFace(fontName, weight, stretch, style);
|
||||
THROW_IF_NULL_ALLOC_MSG(face, "Failed to find the requested font");
|
||||
const auto face = _ResolveFontFaceWithFallback(fontName, weight, stretch, style, localeName);
|
||||
|
||||
DWRITE_FONT_METRICS1 fontMetrics;
|
||||
face->GetMetrics(&fontMetrics);
|
||||
|
@ -1508,7 +1647,7 @@ float DxEngine::GetScaling() const noexcept
|
|||
style,
|
||||
stretch,
|
||||
fontSize,
|
||||
L"",
|
||||
localeName.data(),
|
||||
&format));
|
||||
|
||||
THROW_IF_FAILED(format.As(&textFormat));
|
||||
|
@ -1529,10 +1668,6 @@ float DxEngine::GetScaling() const noexcept
|
|||
coordSize.X = gsl::narrow<SHORT>(widthExact);
|
||||
coordSize.Y = gsl::narrow<SHORT>(lineSpacing.height);
|
||||
|
||||
const auto familyNameLength = textFormat->GetFontFamilyNameLength() + 1; // 1 for space for null
|
||||
const auto familyNameBuffer = std::make_unique<wchar_t[]>(familyNameLength);
|
||||
THROW_IF_FAILED(textFormat->GetFontFamilyName(familyNameBuffer.get(), familyNameLength));
|
||||
|
||||
const DWORD weightDword = static_cast<DWORD>(textFormat->GetFontWeight());
|
||||
|
||||
// Unscaled is for the purposes of re-communicating this font back to the renderer again later.
|
||||
|
@ -1542,7 +1677,7 @@ float DxEngine::GetScaling() const noexcept
|
|||
|
||||
COORD scaled = coordSize;
|
||||
|
||||
actual.SetFromEngine(familyNameBuffer.get(),
|
||||
actual.SetFromEngine(fontName.data(),
|
||||
desired.GetFamily(),
|
||||
weightDword,
|
||||
false,
|
||||
|
|
|
@ -178,10 +178,22 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT _EnableDisplayAccess(const bool outputEnabled) noexcept;
|
||||
|
||||
[[nodiscard]] ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _FindFontFace(const std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT weight,
|
||||
DWRITE_FONT_STRETCH stretch,
|
||||
DWRITE_FONT_STYLE style) const;
|
||||
[[nodiscard]] ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _ResolveFontFaceWithFallback(std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT& weight,
|
||||
DWRITE_FONT_STRETCH& stretch,
|
||||
DWRITE_FONT_STYLE& style,
|
||||
std::wstring& localeName) const;
|
||||
|
||||
[[nodiscard]] ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _FindFontFace(std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT& weight,
|
||||
DWRITE_FONT_STRETCH& stretch,
|
||||
DWRITE_FONT_STYLE& style,
|
||||
std::wstring& localeName) const;
|
||||
|
||||
[[nodiscard]] std::wstring _GetLocaleName() const;
|
||||
|
||||
[[nodiscard]] std::wstring _GetFontFamilyName(IDWriteFontFamily* const fontFamily,
|
||||
std::wstring& localeName) const;
|
||||
|
||||
[[nodiscard]] HRESULT _GetProposedFont(const FontInfoDesired& desired,
|
||||
FontInfo& actual,
|
||||
|
|
|
@ -102,11 +102,19 @@ using namespace Microsoft::Console::Render;
|
|||
// - S_OK
|
||||
[[nodiscard]] HRESULT VtEngine::InvalidateCircling(_Out_ bool* const pForcePaint) noexcept
|
||||
{
|
||||
*pForcePaint = true;
|
||||
// If we're in the middle of a resize request, don't try to immediately start a frame.
|
||||
if (_inResizeRequest)
|
||||
{
|
||||
*pForcePaint = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pForcePaint = true;
|
||||
|
||||
// Keep track of the fact that we circled, we'll need to do some work on
|
||||
// end paint to specifically handle this.
|
||||
_circled = true;
|
||||
// Keep track of the fact that we circled, we'll need to do some work on
|
||||
// end paint to specifically handle this.
|
||||
_circled = true;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe,
|
|||
_terminalOwner{ nullptr },
|
||||
_newBottomLine{ false },
|
||||
_deferredCursorPos{ INVALID_COORDS },
|
||||
_inResizeRequest{ false },
|
||||
_trace{}
|
||||
{
|
||||
#ifndef UNIT_TESTING
|
||||
|
@ -417,3 +418,31 @@ HRESULT VtEngine::RequestCursor() noexcept
|
|||
RETURN_IF_FAILED(_Flush());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tell the vt renderer to begin a resize operation. During a resize
|
||||
// operation, the vt renderer should _not_ request to be repainted during a
|
||||
// text buffer circling event. Any callers of this method should make sure to
|
||||
// call EndResize to make sure the renderer returns to normal behavior.
|
||||
// See GH#1795 for context on this method.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void VtEngine::BeginResizeRequest()
|
||||
{
|
||||
_inResizeRequest = true;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tell the vt renderer to end a resize operation.
|
||||
// See BeginResize for more details.
|
||||
// See GH#1795 for context on this method.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void VtEngine::EndResizeRequest()
|
||||
{
|
||||
_inResizeRequest = false;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,8 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] virtual HRESULT WriteTerminalW(const std::wstring& str) noexcept = 0;
|
||||
|
||||
void SetTerminalOwner(Microsoft::Console::ITerminalOwner* const terminalOwner);
|
||||
void BeginResizeRequest();
|
||||
void EndResizeRequest();
|
||||
|
||||
protected:
|
||||
wil::unique_hfile _hFile;
|
||||
|
@ -132,6 +134,7 @@ namespace Microsoft::Console::Render
|
|||
Microsoft::Console::ITerminalOwner* _terminalOwner;
|
||||
|
||||
Microsoft::Console::VirtualTerminal::RenderTracing _trace;
|
||||
bool _inResizeRequest{ false };
|
||||
|
||||
[[nodiscard]] HRESULT _Write(std::string_view const str) noexcept;
|
||||
[[nodiscard]] HRESULT _WriteFormattedString(const std::string* const pFormat, ...) noexcept;
|
||||
|
|
|
@ -114,6 +114,8 @@ bool InteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulatio
|
|||
}
|
||||
break;
|
||||
case DispatchTypes::WindowManipulationType::ResizeWindowInCharacters:
|
||||
// TODO:GH#1765 We should introduce a better `ResizeConpty` function to
|
||||
// the ConGetSet interface, that specifically handles a conpty resize.
|
||||
if (cParams == 2)
|
||||
{
|
||||
fSuccess = DispatchCommon::s_ResizeWindow(*_pConApi, rgusParams[1], rgusParams[0]);
|
||||
|
|
|
@ -898,7 +898,7 @@ namespace fuzz
|
|||
|
||||
_Type operator->() const throw()
|
||||
{
|
||||
return (m_fFuzzed) ? m_t : m_tInit;
|
||||
return (this->m_fFuzzed) ? this->m_t : m_tInit;
|
||||
}
|
||||
|
||||
// This operator makes it possible to invoke the fuzzing map
|
||||
|
@ -960,7 +960,7 @@ namespace fuzz
|
|||
__inline virtual _Type** operator&() throw()
|
||||
{
|
||||
m_ftEffectiveTraits |= TRAIT_TRANSFER_ALLOCATION;
|
||||
return (m_fFuzzed) ? &m_t : &m_tInit;
|
||||
return (this->m_fFuzzed) ? &(this->m_t) : &m_tInit;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -978,11 +978,11 @@ namespace fuzz
|
|||
void OnFuzzedValueFromMap()
|
||||
{
|
||||
m_pszFuzzed = nullptr;
|
||||
m_ftEffectiveTraits = m_traits;
|
||||
m_pfnOnFuzzedValueFromMap = [&](_Type* psz, std::function<void(_Type*)> dealloc) {
|
||||
m_ftEffectiveTraits = this->m_traits;
|
||||
this->m_pfnOnFuzzedValueFromMap = [&](_Type* psz, std::function<void(_Type*)> dealloc) {
|
||||
FreeFuzzedString();
|
||||
_Type* pszFuzzed = psz;
|
||||
if (psz && psz != m_tInit)
|
||||
if (psz && psz != this->m_tInit)
|
||||
{
|
||||
size_t cb = (sizeof(_Type) == sizeof(char)) ?
|
||||
(strlen(reinterpret_cast<LPSTR>(psz)) + 1) * sizeof(char) :
|
||||
|
@ -1014,8 +1014,8 @@ namespace fuzz
|
|||
// allocation and deallocation responsibilities.
|
||||
if (m_ftEffectiveTraits & TRAIT_TRANSFER_ALLOCATION)
|
||||
{
|
||||
_Alloc::Free(m_tInit);
|
||||
m_tInit = nullptr;
|
||||
_Alloc::Free(this->m_tInit);
|
||||
this->m_tInit = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1070,11 +1070,11 @@ namespace fuzz
|
|||
protected:
|
||||
__inline virtual _Type GetValueFromMap()
|
||||
{
|
||||
if (!m_fFuzzed)
|
||||
if (!this->m_fFuzzed)
|
||||
{
|
||||
m_t = 0;
|
||||
m_fFuzzed = TRUE;
|
||||
for (auto& r : m_map)
|
||||
this->m_t = 0;
|
||||
this->m_fFuzzed = TRUE;
|
||||
for (auto& r : this->m_map)
|
||||
{
|
||||
// Generate a new random value during each map entry
|
||||
// and use it to evaluate if each individual fuzz map
|
||||
|
@ -1087,12 +1087,12 @@ namespace fuzz
|
|||
int iLow = iHigh - (r.range.iHigh - r.range.iLow);
|
||||
if (iLow <= wRandom && wRandom < iHigh)
|
||||
{
|
||||
m_t |= CallFuzzMapFunction(r.fte.pfnFuzz, m_tInit, m_tArgs);
|
||||
this->m_t |= CallFuzzMapFunction(r.fte.pfnFuzz, this->m_tInit, m_tArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_t;
|
||||
return this->m_t;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -31,9 +31,22 @@ SAFEARRAY* BuildIntSafeArray(_In_reads_(length) const int* const data, const int
|
|||
return psa;
|
||||
}
|
||||
|
||||
ScreenInfoUiaProvider::ScreenInfoUiaProvider(_In_ Microsoft::Console::Render::IRenderData* pData,
|
||||
_In_ WindowUiaProviderBase* const pUiaParent,
|
||||
_In_ std::function<RECT(void)> GetBoundingRect) :
|
||||
_pUiaParent(pUiaParent),
|
||||
_signalFiringMapping{},
|
||||
_cRefs(1),
|
||||
_pData(THROW_HR_IF_NULL(E_INVALIDARG, pData)),
|
||||
_getBoundingRect(GetBoundingRect)
|
||||
{
|
||||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
//Tracing::s_TraceUia(nullptr, ApiCall::Constructor, nullptr);
|
||||
}
|
||||
|
||||
ScreenInfoUiaProvider::ScreenInfoUiaProvider(_In_ Microsoft::Console::Render::IRenderData* pData,
|
||||
_In_ WindowUiaProviderBase* const pUiaParent) :
|
||||
_pUiaParent(THROW_HR_IF_NULL(E_INVALIDARG, pUiaParent)),
|
||||
_pUiaParent(pUiaParent),
|
||||
_signalFiringMapping{},
|
||||
_cRefs(1),
|
||||
_pData(THROW_HR_IF_NULL(E_INVALIDARG, pData))
|
||||
|
@ -253,6 +266,9 @@ IFACEMETHODIMP ScreenInfoUiaProvider::get_HostRawElementProvider(_COM_Outptr_res
|
|||
IFACEMETHODIMP ScreenInfoUiaProvider::Navigate(_In_ NavigateDirection direction,
|
||||
_COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider)
|
||||
{
|
||||
// TODO GitHub 2120: _pUiaParent should not be allowed to be null
|
||||
RETURN_HR_IF(E_NOTIMPL, _pUiaParent == nullptr);
|
||||
|
||||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
/*ApiMsgNavigate apiMsg;
|
||||
apiMsg.Direction = direction;
|
||||
|
@ -299,7 +315,16 @@ IFACEMETHODIMP ScreenInfoUiaProvider::get_BoundingRectangle(_Out_ UiaRect* pRect
|
|||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
//Tracing::s_TraceUia(this, ApiCall::GetBoundingRectangle, nullptr);
|
||||
|
||||
RECT rc = _pUiaParent->GetWindowRect();
|
||||
RECT rc;
|
||||
// TODO GitHub 2120: _pUiaParent should not be allowed to be null
|
||||
if (_pUiaParent == nullptr)
|
||||
{
|
||||
rc = _getBoundingRect();
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = _pUiaParent->GetWindowRect();
|
||||
}
|
||||
|
||||
pRect->left = rc.left;
|
||||
pRect->top = rc.top;
|
||||
|
@ -328,6 +353,9 @@ IFACEMETHODIMP ScreenInfoUiaProvider::SetFocus()
|
|||
|
||||
IFACEMETHODIMP ScreenInfoUiaProvider::get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider)
|
||||
{
|
||||
// TODO GitHub 2120: _pUiaParent should not be allowed to be null
|
||||
RETURN_HR_IF(E_NOTIMPL, _pUiaParent == nullptr);
|
||||
|
||||
//Tracing::s_TraceUia(this, ApiCall::GetFragmentRoot, nullptr);
|
||||
try
|
||||
{
|
||||
|
@ -657,10 +685,20 @@ void ScreenInfoUiaProvider::_UnlockConsole() noexcept
|
|||
|
||||
HWND ScreenInfoUiaProvider::GetWindowHandle() const
|
||||
{
|
||||
// TODO GitHub 2120: _pUiaParent should not be allowed to be null
|
||||
if (_pUiaParent == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _pUiaParent->GetWindowHandle();
|
||||
}
|
||||
|
||||
void ScreenInfoUiaProvider::ChangeViewport(const SMALL_RECT NewWindow)
|
||||
{
|
||||
// TODO GitHub 2120: _pUiaParent should not be allowed to be null
|
||||
if (_pUiaParent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_pUiaParent->ChangeViewport(NewWindow);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,11 @@ namespace Microsoft::Console::Types
|
|||
public ITextProvider
|
||||
{
|
||||
public:
|
||||
ScreenInfoUiaProvider(_In_ Microsoft::Console::Render::IRenderData* pData,
|
||||
_In_ WindowUiaProviderBase* const pUiaParent,
|
||||
_In_ std::function<RECT()> GetBoundingRect);
|
||||
|
||||
// TODO GitHub 2120: pUiaParent should not be allowed to be null
|
||||
ScreenInfoUiaProvider(_In_ Microsoft::Console::Render::IRenderData* pData,
|
||||
_In_ WindowUiaProviderBase* const pUiaParent);
|
||||
virtual ~ScreenInfoUiaProvider();
|
||||
|
@ -108,6 +113,9 @@ namespace Microsoft::Console::Types
|
|||
const Viewport _getViewport() const;
|
||||
void _LockConsole() noexcept;
|
||||
void _UnlockConsole() noexcept;
|
||||
|
||||
// these functions are reserved for Windows Terminal
|
||||
std::function<RECT(void)> _getBoundingRect;
|
||||
};
|
||||
|
||||
namespace ScreenInfoUiaProviderTracing
|
||||
|
|
|
@ -307,7 +307,14 @@ UiaTextRange::UiaTextRange(_In_ Microsoft::Console::Render::IRenderData* pData,
|
|||
{
|
||||
// change point coords to pixels relative to window
|
||||
HWND hwnd = _getWindowHandle();
|
||||
ScreenToClient(hwnd, &clientPoint);
|
||||
if (hwnd == nullptr)
|
||||
{
|
||||
// TODO GitHub #2103: NON-HWND IMPLEMENTATION OF SCREENTOCLIENT()
|
||||
}
|
||||
else
|
||||
{
|
||||
ScreenToClient(hwnd, &clientPoint);
|
||||
}
|
||||
|
||||
const COORD currentFontSize = _getScreenFontSize();
|
||||
row = (clientPoint.y / currentFontSize.Y) + viewport.Top;
|
||||
|
@ -1495,8 +1502,16 @@ void UiaTextRange::_addScreenInfoRowBoundaries(Microsoft::Console::Render::IRend
|
|||
// convert the coords to be relative to the screen instead of
|
||||
// the client window
|
||||
HWND hwnd = _getWindowHandle();
|
||||
ClientToScreen(hwnd, &topLeft);
|
||||
ClientToScreen(hwnd, &bottomRight);
|
||||
|
||||
if (hwnd == nullptr)
|
||||
{
|
||||
// TODO GitHub #2103: NON-HWND IMPLEMENTATION OF CLIENTTOSCREEN()
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientToScreen(hwnd, &topLeft);
|
||||
ClientToScreen(hwnd, &bottomRight);
|
||||
}
|
||||
|
||||
const LONG width = bottomRight.x - topLeft.x;
|
||||
const LONG height = bottomRight.y - topLeft.y;
|
||||
|
|
|
@ -1,42 +1,165 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A3FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52ECFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{77DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\convert.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\MouseEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\FocusEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\IInputEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\KeyEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\MenuEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ModifierKeyState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Viewport.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\WindowBufferSizeEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\precomp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CodepointWidthDetector.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\GlyphWidth.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Utf16Parser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\UTF8OutPipeReader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\WindowUiaProvider.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ScreenInfoUiaProvider.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\UiaTextRange.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\WindowUiaProviderBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\inc\IInputEvent.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Viewport.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\convert.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\precomp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\CodepointWidthDetector.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Utf16Parser.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\GlyphWidth.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\utils.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\UTF8OutPipeReader.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\WindowUiaProvider.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\IConsoleWindow.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ScreenInfoUiaProvider.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\UiaTextRange.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\WindowUiaProviderBase.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\IConsoleWindow.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\CodepointWidthDetector.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\convert.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\GlyphWidth.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\IInputEvent.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\UTF8OutPipeReader.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Viewport.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Utf16Parser.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\precomp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ScreenInfoUiaProvider.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\UiaTextRange.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\utils.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\WindowUiaProviderBase.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\IUiaWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\CodepointWidthDetector.cpp" />
|
||||
<ClCompile Include="..\convert.cpp" />
|
||||
<ClCompile Include="..\GlyphWidth.cpp" />
|
||||
<ClCompile Include="..\MouseEvent.cpp" />
|
||||
<ClCompile Include="..\FocusEvent.cpp" />
|
||||
<ClCompile Include="..\IInputEvent.cpp" />
|
||||
<ClCompile Include="..\KeyEvent.cpp" />
|
||||
<ClCompile Include="..\MenuEvent.cpp" />
|
||||
<ClCompile Include="..\ModifierKeyState.cpp" />
|
||||
<ClCompile Include="..\ScreenInfoUiaProvider.cpp" />
|
||||
<ClCompile Include="..\UiaTextRange.cpp" />
|
||||
<ClCompile Include="..\Utf16Parser.cpp" />
|
||||
<ClCompile Include="..\UTF8OutPipeReader.cpp" />
|
||||
<ClCompile Include="..\Viewport.cpp" />
|
||||
<ClCompile Include="..\WindowBufferSizeEvent.cpp" />
|
||||
<ClCompile Include="..\precomp.cpp" />
|
||||
<ClCompile Include="..\utils.cpp" />
|
||||
<ClCompile Include="..\WindowUiaProviderBase.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\IConsoleWindow.hpp" />
|
||||
<ClInclude Include="..\inc\CodepointWidthDetector.hpp" />
|
||||
<ClInclude Include="..\inc\convert.hpp" />
|
||||
<ClInclude Include="..\inc\GlyphWidth.hpp" />
|
||||
<ClInclude Include="..\inc\IInputEvent.hpp" />
|
||||
<ClInclude Include="..\inc\UTF8OutPipeReader.hpp" />
|
||||
<ClInclude Include="..\inc\Viewport.hpp" />
|
||||
<ClInclude Include="..\inc\Utf16Parser.hpp" />
|
||||
<ClInclude Include="..\precomp.h" />
|
||||
<ClInclude Include="..\ScreenInfoUiaProvider.h" />
|
||||
<ClInclude Include="..\UiaTextRange.hpp" />
|
||||
<ClInclude Include="..\utils.hpp" />
|
||||
<ClInclude Include="..\WindowUiaProviderBase.hpp" />
|
||||
<ClInclude Include="..\IUiaWindow.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
7
tools/bcx.cmd
Normal file
7
tools/bcx.cmd
Normal file
|
@ -0,0 +1,7 @@
|
|||
@echo off
|
||||
|
||||
rem bcx - Build only the project in this directory, cleaning it first.
|
||||
rem This is another script to help Microsoft developers feel at home working on
|
||||
rem the terminal project.
|
||||
|
||||
call bcz exclusive %*
|
|
@ -1,13 +1,26 @@
|
|||
@echo off
|
||||
|
||||
rem bcz - Clean and build the project
|
||||
rem This is another script to help Microsoft developers feel at home working on the openconsole project.
|
||||
rem bcz - Clean and build the solution.
|
||||
rem This is another script to help Microsoft developers feel at home working on the Terminal project.
|
||||
|
||||
rem Args:
|
||||
rem dbg: manually build the solution in the Debug configuration. If omitted,
|
||||
rem we'll use whatever the last configuration build was.
|
||||
rem rel: manually build the solution in the Release configuration. If
|
||||
rem omitted, we'll use whatever the last configuration build was.
|
||||
rem no_clean: Don't clean before building. This is a much faster build
|
||||
rem typically, but leaves artifacts from previous builds around, which
|
||||
rem can lead to unexpected build failures.
|
||||
rem exclusive: Only build the project in the cwd. If omitted, we'll try
|
||||
rem building the entire solution instead.
|
||||
|
||||
if (%_LAST_BUILD_CONF%)==() (
|
||||
set _LAST_BUILD_CONF=%DEFAULT_CONFIGURATION%
|
||||
)
|
||||
|
||||
set _MSBUILD_TARGET=Clean,Build
|
||||
set _EXCLUSIVE=
|
||||
set _APPX_ARGS=
|
||||
|
||||
:ARGS_LOOP
|
||||
if (%1) == () goto :POST_ARGS_LOOP
|
||||
|
@ -22,30 +35,43 @@ if (%1) == (rel) (
|
|||
if (%1) == (no_clean) (
|
||||
set _MSBUILD_TARGET=Build
|
||||
)
|
||||
if (%1) == (exclusive) (
|
||||
set _EXCLUSIVE=1
|
||||
)
|
||||
shift
|
||||
goto :ARGS_LOOP
|
||||
|
||||
:POST_ARGS_LOOP
|
||||
echo Starting build...
|
||||
|
||||
nuget.exe restore %OPENCON%\OpenConsole.sln
|
||||
|
||||
rem /p:AppxBundle=Never prevents us from building the appxbundle from the commandline.
|
||||
rem We don't want to do this from a debug build, because it takes ages, so disable it.
|
||||
rem if you want the appx, build release
|
||||
if "%_EXCLUSIVE%" == "1" (
|
||||
set "PROJECT_NAME="
|
||||
call :get_project
|
||||
) else if (%_LAST_BUILD_CONF%) == (Debug) (
|
||||
|
||||
set _APPX_ARGS=
|
||||
rem /p:AppxBundle=Never prevents us from building the appxbundle from the
|
||||
rem commandline. We don't want to do this from a debug build, because it
|
||||
rem takes ages, so disable it. if you want the appx, build release
|
||||
|
||||
rem Only do this check if we're doing a full solution build. If we're only
|
||||
rem trying to build the appx, then we obviously want to build the appx.
|
||||
|
||||
if (%_LAST_BUILD_CONF%) == (Debug) (
|
||||
echo Skipping building appx...
|
||||
set _APPX_ARGS=/p:AppxBundle=false
|
||||
) else (
|
||||
echo Building Appx...
|
||||
)
|
||||
|
||||
if "%_EXCLUSIVE%" == "1" (
|
||||
if "%PROJECT_NAME%" == "" ( goto :eof ) else echo Building only %PROJECT_NAME%
|
||||
)
|
||||
|
||||
echo Performing nuget restore...
|
||||
nuget.exe restore %OPENCON%\OpenConsole.sln
|
||||
|
||||
set _BUILD_CMDLINE="%MSBUILD%" %OPENCON%\OpenConsole.sln /t:%_MSBUILD_TARGET% /m /p:Configuration=%_LAST_BUILD_CONF% /p:Platform=%ARCH% %_APPX_ARGS%
|
||||
|
||||
echo %_BUILD_CMDLINE%
|
||||
echo Starting build...
|
||||
%_BUILD_CMDLINE%
|
||||
|
||||
rem Cleanup unused variables here. Note we cannot use setlocal because we need to pass modified
|
||||
|
@ -53,3 +79,48 @@ rem _LAST_BUILD_CONF out to OpenCon.cmd later.
|
|||
rem
|
||||
set _MSBUILD_TARGET=
|
||||
set _BIN_=%~dp0\bin\%PLATFORM%\%_LAST_BUILD_CONF%
|
||||
goto :eof
|
||||
|
||||
rem ############################################################################
|
||||
rem The code to figure out what project we're building needs to be in its own
|
||||
rem function. Otherwise, when cmd evaluates the if statement above `if
|
||||
rem "%_EXCLUSIVE%" == "1"`, it'll evaluate the entire block with the value of
|
||||
rem the the variables at the time the if was executed. So instead, make a
|
||||
rem function here with `enabledelayedexpansion` set.
|
||||
:get_project
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
rem TODO:GH#2172 Find a way to only rebuild the metaproj if the sln changed
|
||||
rem First generate the metaproj file
|
||||
set MSBuildEmitSolution=1
|
||||
"%msbuild%" %OPENCON%\OpenConsole.sln /t:ValidateSolutionConfiguration /m > NUL
|
||||
set MSBuildEmitSolution=
|
||||
|
||||
rem Use bx.ps1 to figure out which target we're looking at
|
||||
set _BX_SCRIPT=powershell bx.ps1
|
||||
set _OUTPUT=
|
||||
FOR /F "tokens=* USEBACKQ" %%F IN (`powershell bx.ps1 2^> NUL`) DO (
|
||||
set _OUTPUT=%%F
|
||||
)
|
||||
if "!_OUTPUT!" == "" (
|
||||
echo Could not find a .vcxproj file in this directory.
|
||||
echo `bx.cmd` only works in directories with a vcxproj file.
|
||||
echo Please navigate to directory with a project file in it, or try `bz` to build the entire solution.
|
||||
goto :eof
|
||||
)
|
||||
set "__PROJECT_NAME=!_OUTPUT!"
|
||||
|
||||
rem If we're trying to clean build, make sure to update the target here.
|
||||
if "%_MSBUILD_TARGET%" == "Build" (
|
||||
set __MSBUILD_TARGET=%__PROJECT_NAME%
|
||||
) else if "%_MSBUILD_TARGET%" == "Clean,Build" (
|
||||
set __MSBUILD_TARGET=%__PROJECT_NAME%:Rebuild
|
||||
)
|
||||
rem This statement will propogate our internal variables up to the calling
|
||||
rem scope. Because they're all on one line, the value of our local variables
|
||||
rem will be evaluated before we endlocal
|
||||
endlocal & set "PROJECT_NAME=%__PROJECT_NAME%" & set "_MSBUILD_TARGET=%__MSBUILD_TARGET%"
|
||||
rem ############################################################################
|
||||
|
||||
|
||||
:eof
|
||||
|
|
7
tools/bx.cmd
Normal file
7
tools/bx.cmd
Normal file
|
@ -0,0 +1,7 @@
|
|||
@echo off
|
||||
|
||||
rem bx - Build only the project in this directory without cleaning it first.
|
||||
rem This is another script to help Microsoft developers feel at home working on
|
||||
rem the terminal project.
|
||||
|
||||
call bcz exclusive no_clean %*
|
28
tools/bx.ps1
Normal file
28
tools/bx.ps1
Normal file
|
@ -0,0 +1,28 @@
|
|||
# This is a helper script to figure out which target corresponds to the project
|
||||
# in this directory. Parses the solution's .metaproj file looking for the
|
||||
# project file in this directory, to be able to get the project's name.
|
||||
|
||||
$projects = Get-Childitem -Path .\ -Filter *.vcxproj -File
|
||||
if ($projects.length -eq 0)
|
||||
{
|
||||
exit -1
|
||||
}
|
||||
$projectPath = $projects.FullName
|
||||
|
||||
$msBuildCondition = "'%(ProjectReference.Identity)' == '$projectPath.metaproj'"
|
||||
|
||||
# Parse the solution's metaproj file.
|
||||
[xml]$Metaproj = Get-Content "$env:OPENCON\OpenConsole.sln.metaproj"
|
||||
|
||||
$targets = $Metaproj.Project.Target
|
||||
|
||||
# Filter to project targets that match out metaproj file.
|
||||
# For Conhost\Server, this will match:
|
||||
# [Conhost\Server, Conhost\Server:Clean, Conhost\Server:Rebuild, Conhost\Server:Publish]
|
||||
$matchingTargets = $targets | Where-Object { $_.MSBuild.Condition -eq $msBuildCondition }
|
||||
|
||||
# Further filter to the targets that dont have a suffix (like ":Clean")
|
||||
$matchingTargets = $matchingTargets | Where-Object { $hasProperty = $_.MsBuild.PSobject.Properties.name -match "Targets" ; return -Not $hasProperty }
|
||||
|
||||
Write-Host $matchingTargets.Name
|
||||
exit 0
|
|
@ -1,6 +1,7 @@
|
|||
@echo off
|
||||
|
||||
rem bcz - Build the project without clean it first
|
||||
rem This is another script to help Microsoft developers feel at home working on the openconsole project.
|
||||
rem bz - Build the entire solution without cleaning it first.
|
||||
rem This is another script to help Microsoft developers feel at home working on
|
||||
rem the terminal project.
|
||||
|
||||
call bcz no_clean %*
|
||||
|
|
Loading…
Reference in a new issue