Compare commits
790 Commits
dev/miniks
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
595721658a | ||
|
|
306ad30753 | ||
|
|
00c7647594 | ||
|
|
97b0f06504 | ||
|
|
c2fcdcbe10 | ||
|
|
3d7480e9b7 | ||
|
|
97722d3efe | ||
|
|
a900ababdc | ||
|
|
54ed295588 | ||
|
|
bee6fb4368 | ||
|
|
6140fd9ab8 | ||
|
|
13e9546bab | ||
|
|
0a48836e83 | ||
|
|
43c76ee240 | ||
|
|
424414ec97 | ||
|
|
4f6f3b98b8 | ||
|
|
6268a4779c | ||
|
|
13bc71de3c | ||
|
|
a0670cb6b3 | ||
|
|
7908164f9d | ||
|
|
8ffea2c177 | ||
|
|
e0853ae4cc | ||
|
|
c089ae0c57 | ||
|
|
8d81497eb7 | ||
|
|
717ea85c9f | ||
|
|
efea1e5bad | ||
|
|
871b8de74f | ||
|
|
e4c5e8bd2a | ||
|
|
1acfef60f6 | ||
|
|
de379cd043 | ||
|
|
7112f4e081 | ||
|
|
7423734a48 | ||
|
|
07dc0601f9 | ||
|
|
6f42367ab8 | ||
|
|
d2c72e5c25 | ||
|
|
92437d718f | ||
|
|
817f598e20 | ||
|
|
2c5a35f1be | ||
|
|
ea58e4036b | ||
|
|
ee8800c739 | ||
|
|
f7b0f7444a | ||
|
|
1b6e6bd6dd | ||
|
|
7b6df26411 | ||
|
|
f3cc4c0328 | ||
|
|
f3a49fafe3 | ||
|
|
15c02b77a0 | ||
|
|
2c3368f766 | ||
|
|
b1131263cf | ||
|
|
c53fe1c2bf | ||
|
|
f9a844dbda | ||
|
|
23a19c5818 | ||
|
|
7712104983 | ||
|
|
608a49e817 | ||
|
|
10992b77a0 | ||
|
|
f6f5598c9c | ||
|
|
f681d3a1c1 | ||
|
|
d07546a6fe | ||
|
|
ed7c716978 | ||
|
|
0c901edd81 | ||
|
|
acf1ddc9c4 | ||
|
|
cb2f347c2f | ||
|
|
49874d1b9e | ||
|
|
cfdf03c24b | ||
|
|
70d44c84c8 | ||
|
|
1678b58dde | ||
|
|
482dcec60a | ||
|
|
46fd7caf5a | ||
|
|
638c6d0291 | ||
|
|
68294f863d | ||
|
|
59f184aa2d | ||
|
|
a544f56e17 | ||
|
|
29be8564f6 | ||
|
|
5d36e5d2df | ||
|
|
0220f71883 | ||
|
|
70560a789c | ||
|
|
a0edb12cd6 | ||
|
|
d3f9859051 | ||
|
|
f1dc649135 | ||
|
|
9eb9bc9235 | ||
|
|
d465a47bc5 | ||
|
|
9c858cd5b8 | ||
|
|
42bf605e1c | ||
|
|
121fb739fd | ||
|
|
ebf41dd6b2 | ||
|
|
a14b6f89f6 | ||
|
|
c55888f88d | ||
|
|
7acec306a6 | ||
|
|
cd4aabda84 | ||
|
|
fdffa24a71 | ||
|
|
9f2d40614b | ||
|
|
90ff261c35 | ||
|
|
dcbf7c74f1 | ||
|
|
76793b1e3f | ||
|
|
0b4839d94d | ||
|
|
2bd4670100 | ||
|
|
2eb659717c | ||
|
|
aea725f885 | ||
|
|
8ab3422b57 | ||
|
|
cccaab8545 | ||
|
|
e7108332f7 | ||
|
|
9ba20805ec | ||
|
|
94166942cc | ||
|
|
a2a605050f | ||
|
|
6936ee15fe | ||
|
|
a151607c79 | ||
|
|
fc64ff3029 | ||
|
|
34a6b1913c | ||
|
|
4b45bb8df1 | ||
|
|
f058b08fde | ||
|
|
b1bcc59230 | ||
|
|
10222a2ba2 | ||
|
|
3f5f37d910 | ||
|
|
37e0614554 | ||
|
|
d43a14c63f | ||
|
|
862217b04b | ||
|
|
3a71ead757 | ||
|
|
20e88d3e3e | ||
|
|
3ffaa1714a | ||
|
|
4c16cb278e | ||
|
|
335f69e099 | ||
|
|
cf97a9f772 | ||
|
|
41ade2c57e | ||
|
|
d1f152adcf | ||
|
|
8779249b12 | ||
|
|
10b12ac90c | ||
|
|
6ce2543a94 | ||
|
|
5a5902d580 | ||
|
|
0fefdac414 | ||
|
|
79115e2058 | ||
|
|
9c1331ab2e | ||
|
|
5f2ac4e3e7 | ||
|
|
6e70c4ae07 | ||
|
|
b05a557f48 | ||
|
|
2e246123cf | ||
|
|
fb69aecb19 | ||
|
|
730d6960ab | ||
|
|
7f3bc3cb04 | ||
|
|
8947909121 | ||
|
|
293c36d42f | ||
|
|
cf8f411b8f | ||
|
|
ee6ca81d70 | ||
|
|
b609266d29 | ||
|
|
59e2835736 | ||
|
|
3bf5436122 | ||
|
|
5ea778b2b8 | ||
|
|
cabb83db61 | ||
|
|
769e910e35 | ||
|
|
1d02f82ab7 | ||
|
|
84e30bcd3a | ||
|
|
f68324cd09 | ||
|
|
fca87b2bb5 | ||
|
|
c12835783d | ||
|
|
56bbe86f96 | ||
|
|
d13c37cd60 | ||
|
|
32fbd4cbb6 | ||
|
|
6d7723e3be | ||
|
|
e37fd5e546 | ||
|
|
59166faa27 | ||
|
|
19f8b9c3ca | ||
|
|
17e68a09a8 | ||
|
|
0980a0d50f | ||
|
|
1d33429673 | ||
|
|
ef8ba20bee | ||
|
|
a0e5085b49 | ||
|
|
d57fb84557 | ||
|
|
be2b77653f | ||
|
|
c18e0f5008 | ||
|
|
a89746a869 | ||
|
|
f339705ce7 | ||
|
|
f152573058 | ||
|
|
91b454ac95 | ||
|
|
6409ab91fa | ||
|
|
a0527a1dbe | ||
|
|
f03cacfa5b | ||
|
|
cdecfcd67f | ||
|
|
d6da6ba353 | ||
|
|
96f4a9daef | ||
|
|
1374396f10 | ||
|
|
192d6debba | ||
|
|
a50731119a | ||
|
|
305e3df8fa | ||
|
|
83c6bce73d | ||
|
|
59239e3b07 | ||
|
|
79a18f0825 | ||
|
|
d3b9a780d3 | ||
|
|
9b9b0738c8 | ||
|
|
f3e30d07fa | ||
|
|
ee3259847a | ||
|
|
ab5a8d701d | ||
|
|
6a37818c07 | ||
|
|
4fc283f8b6 | ||
|
|
51e1ae3e8a | ||
|
|
8c057a04a8 | ||
|
|
8c00dd7d55 | ||
|
|
848e353b9c | ||
|
|
e3b7a44b13 | ||
|
|
0d9a357373 | ||
|
|
85c485e94f | ||
|
|
1b79cc87c3 | ||
|
|
b7fc0f2d44 | ||
|
|
2770228e09 | ||
|
|
4f0b57ec8e | ||
|
|
e2005ca5d7 | ||
|
|
c8f00df170 | ||
|
|
c90de69250 | ||
|
|
b6593216f2 | ||
|
|
b3b648496e | ||
|
|
1ae6e3b772 | ||
|
|
448684a5f4 | ||
|
|
0d3f85de85 | ||
|
|
2bd5791feb | ||
|
|
872309397a | ||
|
|
813f385c08 | ||
|
|
296037a0fa | ||
|
|
1cc383f865 | ||
|
|
52dd988b3d | ||
|
|
1fcfb618ad | ||
|
|
92f0700d5d | ||
|
|
b98d4e5493 | ||
|
|
8f2605df0d | ||
|
|
34e2ce1885 | ||
|
|
d75ff17cbb | ||
|
|
b034fc9ae5 | ||
|
|
5bb8148ef9 | ||
|
|
e34897cd1f | ||
|
|
31a39b3b12 | ||
|
|
9294ecc8e5 | ||
|
|
8157605058 | ||
|
|
0788042540 | ||
|
|
fe283fc28b | ||
|
|
0f42ee189d | ||
|
|
a42cef9208 | ||
|
|
efc9116830 | ||
|
|
d0d3cc6a75 | ||
|
|
3c81b51b78 | ||
|
|
66f0a9cd70 | ||
|
|
c801029e3e | ||
|
|
becc254f67 | ||
|
|
94d39b7580 | ||
|
|
76d2aaddcf | ||
|
|
235f011d6c | ||
|
|
d7f2a39aeb | ||
|
|
4eb2c30abd | ||
|
|
1011dcebf4 | ||
|
|
2879fcf65b | ||
|
|
c9dc4198ac | ||
|
|
2fed4c4255 | ||
|
|
147cde214f | ||
|
|
e3281ce354 | ||
|
|
f3ca1ed136 | ||
|
|
89ca2ae05f | ||
|
|
d8647e01c1 | ||
|
|
31d78dceb5 | ||
|
|
eee1623f33 | ||
|
|
b2c2a4c159 | ||
|
|
e694f36ad2 | ||
|
|
5d6eec6cde | ||
|
|
43d5713a02 | ||
|
|
7687dd7b90 | ||
|
|
227ec3777a | ||
|
|
27582a9186 | ||
|
|
31e58809cc | ||
|
|
52560ff818 | ||
|
|
0d61466afe | ||
|
|
dd348dccda | ||
|
|
0dedb93cde | ||
|
|
89af44488f | ||
|
|
3f82613a3d | ||
|
|
d6288fae99 | ||
|
|
ee86799f85 | ||
|
|
20a722ce50 | ||
|
|
84f6a29d89 | ||
|
|
504e610841 | ||
|
|
ff8fdbd243 | ||
|
|
13f0b8e007 | ||
|
|
a8e4bedae3 | ||
|
|
eaeab7a807 | ||
|
|
c3bf8a5d25 | ||
|
|
a4ebeb0a56 | ||
|
|
b5edb77058 | ||
|
|
3a27386e25 | ||
|
|
996a680ec3 | ||
|
|
c66910b685 | ||
|
|
24f80bd9ba | ||
|
|
e3d673ecd4 | ||
|
|
3866771b1b | ||
|
|
6e11780ca6 | ||
|
|
7a41be5cd4 | ||
|
|
f7458a31fd | ||
|
|
f3cf321e87 | ||
|
|
66fdc645f7 | ||
|
|
bbe8275f69 | ||
|
|
7dadde5dd6 | ||
|
|
a3a2a4102d | ||
|
|
bfc4838042 | ||
|
|
9f45963e73 | ||
|
|
e0bd76b30d | ||
|
|
8564b269c4 | ||
|
|
258a6ce8a1 | ||
|
|
43040ef9d0 | ||
|
|
440b626ee3 | ||
|
|
b132fbe4a6 | ||
|
|
c0ab9cb5b5 | ||
|
|
563e20b25e | ||
|
|
0e8d5f24c4 | ||
|
|
b3775bc2b0 | ||
|
|
f518235599 | ||
|
|
22fd06e19b | ||
|
|
5713cd2148 | ||
|
|
b53bd672d7 | ||
|
|
cb55cec275 | ||
|
|
c3ca94ceca | ||
|
|
2b4c20bd6e | ||
|
|
7d71b4b9ba | ||
|
|
31414aa364 | ||
|
|
ac265aab99 | ||
|
|
2559ed6efa | ||
|
|
1ecf20b00a | ||
|
|
30d2d2c76d | ||
|
|
65b22b9abb | ||
|
|
d08271e734 | ||
|
|
1c414a7723 | ||
|
|
8f93f76214 | ||
|
|
3809bb556b | ||
|
|
c5fcbede78 | ||
|
|
4457a6dedc | ||
|
|
b7fa32881d | ||
|
|
810ce6911b | ||
|
|
7c439bac2c | ||
|
|
c95ed72aab | ||
|
|
f72e39a0f6 | ||
|
|
c11cab71a4 | ||
|
|
66b9b9d6f1 | ||
|
|
8910a16fd0 | ||
|
|
8d50609ba1 | ||
|
|
dc6631355f | ||
|
|
3d09c7de1b | ||
|
|
51920d9b46 | ||
|
|
aa54de1d64 | ||
|
|
cf8ac0eb07 | ||
|
|
8c6e13d90e | ||
|
|
913cf4b1a8 | ||
|
|
546322b5c1 | ||
|
|
d7e176998c | ||
|
|
dfb48f45c2 | ||
|
|
6b4f70e985 | ||
|
|
ad625a041d | ||
|
|
ad34291632 | ||
|
|
2065fa7b76 | ||
|
|
21b2e01643 | ||
|
|
7e2a0e193a | ||
|
|
b68ee23bf8 | ||
|
|
05e7ea1423 | ||
|
|
8bcb47339d | ||
|
|
74909c0c65 | ||
|
|
d7f690d7fc | ||
|
|
c90215b4e1 | ||
|
|
dba66da18d | ||
|
|
eddb99e9b2 | ||
|
|
3113d2e535 | ||
|
|
cdbcc17458 | ||
|
|
3368e602fd | ||
|
|
3ae93ebfdd | ||
|
|
4941084c00 | ||
|
|
9a2d27e9f6 | ||
|
|
7478248564 | ||
|
|
dab52c46a2 | ||
|
|
806c4c5d5c | ||
|
|
ab6f41f4bd | ||
|
|
0f217c173d | ||
|
|
bc1ff0b71a | ||
|
|
2219014385 | ||
|
|
b8e36bae9f | ||
|
|
7df4b3c823 | ||
|
|
8f79f7c4c8 | ||
|
|
83bd241cd2 | ||
|
|
9a276c6371 | ||
|
|
ca9e5e0fb0 | ||
|
|
912bd4dadb | ||
|
|
a9a58f7156 | ||
|
|
d367c6b6b0 | ||
|
|
959c423e7a | ||
|
|
b310b1cffc | ||
|
|
9e83655b08 | ||
|
|
7f5a19b627 | ||
|
|
8e7a866b06 | ||
|
|
ed1cd32f1f | ||
|
|
361877cf1b | ||
|
|
cdf2630204 | ||
|
|
c3f968b6c6 | ||
|
|
e80e9b9e96 | ||
|
|
6ca35b4445 | ||
|
|
b0c07ef1eb | ||
|
|
faf372f165 | ||
|
|
ebd07d7125 | ||
|
|
24b9a7a247 | ||
|
|
6f754a61eb | ||
|
|
fb597ed304 | ||
|
|
4b7d955012 | ||
|
|
fd99b012f5 | ||
|
|
c09472347c | ||
|
|
07c5735471 | ||
|
|
940254dd57 | ||
|
|
9d729a50b0 | ||
|
|
8f16fdd817 | ||
|
|
5ab78fcafb | ||
|
|
69df0de6bf | ||
|
|
295fa38295 | ||
|
|
03ea0f49ad | ||
|
|
c585a93fc9 | ||
|
|
19fb9b21da | ||
|
|
c7d2a818b0 | ||
|
|
cf5dc285a9 | ||
|
|
3323dc5724 | ||
|
|
c19aa89123 | ||
|
|
d6954244ad | ||
|
|
477c4d9986 | ||
|
|
b67f40f4c4 | ||
|
|
25527789c0 | ||
|
|
eac3eea484 | ||
|
|
ba543c0696 | ||
|
|
8470857016 | ||
|
|
704836e45d | ||
|
|
5a78566628 | ||
|
|
806d992a06 | ||
|
|
12275c8599 | ||
|
|
ea3e56db81 | ||
|
|
906edf7002 | ||
|
|
690fbbbc27 | ||
|
|
005b8cc5e0 | ||
|
|
e02d9a48e3 | ||
|
|
da1e1a693e | ||
|
|
da24f7d939 | ||
|
|
da3f02a6e2 | ||
|
|
d972ea2c28 | ||
|
|
a5ff7459b7 | ||
|
|
544bd44851 | ||
|
|
9bd097f4ad | ||
|
|
9069fcab79 | ||
|
|
f4d487efef | ||
|
|
fb734d166c | ||
|
|
2ed367fb49 | ||
|
|
acdcdcaccb | ||
|
|
d749df70ed | ||
|
|
a979e52f7c | ||
|
|
1519236f2b | ||
|
|
43c469fc95 | ||
|
|
8346968881 | ||
|
|
c5124956a9 | ||
|
|
44f1ba6d4d | ||
|
|
99b09c08d5 | ||
|
|
fbdfc4d446 | ||
|
|
28da6c4ecb | ||
|
|
b76087f561 | ||
|
|
efc92de19f | ||
|
|
af896cd4bc | ||
|
|
1a1b4ff21e | ||
|
|
691e02ef1c | ||
|
|
3029bb8a68 | ||
|
|
1e4c6978b7 | ||
|
|
6cd4e03a58 | ||
|
|
a47ed99272 | ||
|
|
95b031e27c | ||
|
|
8f9ccc55d1 | ||
|
|
3909cc103a | ||
|
|
8358f8d93f | ||
|
|
48d59e8304 | ||
|
|
83f2a3bb3d | ||
|
|
87fa526fb7 | ||
|
|
c6a31710d9 | ||
|
|
19bd0c94e7 | ||
|
|
629c06d0ad | ||
|
|
1202f89399 | ||
|
|
4a95341caf | ||
|
|
3cf7677d17 | ||
|
|
ac3fecb134 | ||
|
|
5aaf5b4d59 | ||
|
|
2961a104af | ||
|
|
7b1a660e59 | ||
|
|
cb03b97e67 | ||
|
|
f26c246c7c | ||
|
|
649c546960 | ||
|
|
a930aa390e | ||
|
|
d1bf0fcd1e | ||
|
|
66033dcb01 | ||
|
|
95f63a9100 | ||
|
|
6654f0d155 | ||
|
|
35e1168bfa | ||
|
|
ef4f2ca03e | ||
|
|
f87596f8f7 | ||
|
|
17c6f8e9ff | ||
|
|
81d773d2bf | ||
|
|
8ad4d1f19a | ||
|
|
99ffaa8a1a | ||
|
|
c9dea60bbe | ||
|
|
a158cc81ae | ||
|
|
049e37e514 | ||
|
|
eb0fb3e822 | ||
|
|
dfeb855d18 | ||
|
|
ba8bd006f4 | ||
|
|
177430272c | ||
|
|
69318d3ba1 | ||
|
|
ce99c2a349 | ||
|
|
e6aa902224 | ||
|
|
d12a71cdf9 | ||
|
|
bb0e1d3979 | ||
|
|
2c22b68e15 | ||
|
|
654c0cc286 | ||
|
|
c07553cb57 | ||
|
|
491cb21722 | ||
|
|
90699da23b | ||
|
|
eb349935a0 | ||
|
|
4c53c595e7 | ||
|
|
72cbe59078 | ||
|
|
ce0505073c | ||
|
|
847749f19e | ||
|
|
52d1533c4f | ||
|
|
ac3e4bfe56 | ||
|
|
12eb69f665 | ||
|
|
00d1dc99e4 | ||
|
|
557edc629d | ||
|
|
7d37ba22e7 | ||
|
|
525be22bd8 | ||
|
|
ca226d62e2 | ||
|
|
c1f844307c | ||
|
|
5ffb945b66 | ||
|
|
604eaf9bdd | ||
|
|
13e058d9f1 | ||
|
|
2f28d24fe0 | ||
|
|
49667c263f | ||
|
|
3822d5b662 | ||
|
|
7fac0c3571 | ||
|
|
7e11aeca0a | ||
|
|
38da2ff185 | ||
|
|
c3e0a8dce5 | ||
|
|
16d00a68fe | ||
|
|
4440256eba | ||
|
|
8f73145d9d | ||
|
|
42511265e5 | ||
|
|
ed19301ad3 | ||
|
|
3b247812ce | ||
|
|
03ebe514e9 | ||
|
|
8b2cdfd1f8 | ||
|
|
47f4b4197d | ||
|
|
6af49a5246 | ||
|
|
5fdad873d3 | ||
|
|
cad795470f | ||
|
|
a90289548f | ||
|
|
9047bbbafb | ||
|
|
3b7b200b59 | ||
|
|
3230b18020 | ||
|
|
a3c8beaba0 | ||
|
|
b009d06bc3 | ||
|
|
2c603ef953 | ||
|
|
5f8e3d1676 | ||
|
|
1962767aec | ||
|
|
47881a802f | ||
|
|
207f15498f | ||
|
|
4cce933f89 | ||
|
|
9cb8db8e9a | ||
|
|
230fad533e | ||
|
|
40e328984d | ||
|
|
ed4e829adc | ||
|
|
7c42ed4cc3 | ||
|
|
0811c572ae | ||
|
|
619710852c | ||
|
|
779354d368 | ||
|
|
45bee078f0 | ||
|
|
42f7403bf5 | ||
|
|
a5931fbead | ||
|
|
6b7149d9e6 | ||
|
|
3b9e6124e0 | ||
|
|
92b23700d3 | ||
|
|
9fb4fb2741 | ||
|
|
9d71fa817d | ||
|
|
40ebe5ab54 | ||
|
|
20152d9756 | ||
|
|
e207236713 | ||
|
|
597a3325ea | ||
|
|
636f436465 | ||
|
|
e7d32625be | ||
|
|
37cbcc3e2b | ||
|
|
b502e0e530 | ||
|
|
d29d72e1e0 | ||
|
|
96e0232603 | ||
|
|
054d7dbb1c | ||
|
|
ae8347f336 | ||
|
|
3f1262e4c2 | ||
|
|
b50df20cfe | ||
|
|
7b6958405e | ||
|
|
65269c8311 | ||
|
|
3e5d6e71a2 | ||
|
|
dff8f15efa | ||
|
|
2b27d4ce91 | ||
|
|
172d9a7f64 | ||
|
|
02fd7a0c15 | ||
|
|
acf36d0e4f | ||
|
|
d45cc4c2e1 | ||
|
|
9700598ecb | ||
|
|
124cbd9e47 | ||
|
|
b208a83666 | ||
|
|
8b855ca88c | ||
|
|
b6f5f2a323 | ||
|
|
9c4950cb32 | ||
|
|
3b53c6956c | ||
|
|
98d0613124 | ||
|
|
e7592ec3d4 | ||
|
|
b7a7aa0bc3 | ||
|
|
0fa286c011 | ||
|
|
12b12d5b07 | ||
|
|
f196285824 | ||
|
|
9fed14a95e | ||
|
|
c33a97955f | ||
|
|
a7d7362b95 | ||
|
|
9293867a06 | ||
|
|
2919d96c21 | ||
|
|
6c4878c8d5 | ||
|
|
90e7c28069 | ||
|
|
de49cf1d0d | ||
|
|
2b4b8dd1bd | ||
|
|
fa0cd8c7ed | ||
|
|
3c044f20cf | ||
|
|
9aea904229 | ||
|
|
f7b5ff322a | ||
|
|
9905bd5f09 | ||
|
|
e0f585251a | ||
|
|
9b1bb134bf | ||
|
|
e851c61777 | ||
|
|
f8ccf64252 | ||
|
|
5f590a5efa | ||
|
|
bf783842f2 | ||
|
|
612e3a0a3e | ||
|
|
20bfccefb7 | ||
|
|
9b636edad2 | ||
|
|
cb2cd7e219 | ||
|
|
aaf2395266 | ||
|
|
20fc57ee0f | ||
|
|
058cbd11e7 | ||
|
|
7235996b4d | ||
|
|
bc70a97fd7 | ||
|
|
e557a867ee | ||
|
|
49d008537f | ||
|
|
8bef5eefd5 | ||
|
|
039c80d443 | ||
|
|
c4c3c3116b | ||
|
|
7d503a4352 | ||
|
|
cceb0eaa68 | ||
|
|
713027b5e3 | ||
|
|
fcca88ab25 | ||
|
|
6b2ae625a5 | ||
|
|
a8b4044630 | ||
|
|
f087d03eb2 | ||
|
|
990e06b445 | ||
|
|
08646e5ca3 | ||
|
|
68e0af41a8 | ||
|
|
9b07cb8c71 | ||
|
|
5220738d8e | ||
|
|
0b0161d537 | ||
|
|
683f4e28d3 | ||
|
|
fc7b052461 | ||
|
|
8276b549e8 | ||
|
|
01a04906f3 | ||
|
|
96b9ba99b2 | ||
|
|
d37df8ab05 | ||
|
|
4f46129cb4 | ||
|
|
2485a638cb | ||
|
|
33470ad08e | ||
|
|
c5366cea75 | ||
|
|
477c04ab94 | ||
|
|
b8e6b8e27c | ||
|
|
e798258ae0 | ||
|
|
539a5dc0af | ||
|
|
551cc9a98b | ||
|
|
22d43a431c | ||
|
|
857a893660 | ||
|
|
7241fa29c6 | ||
|
|
fb3d772615 | ||
|
|
b140299e50 | ||
|
|
e943785e1a | ||
|
|
da6705c086 | ||
|
|
a1f42e87a8 | ||
|
|
cae0f9a718 | ||
|
|
61ccf44f22 | ||
|
|
ff5b2b84d2 | ||
|
|
1965fb5e73 | ||
|
|
d02812d699 | ||
|
|
3e2b94334d | ||
|
|
b80a4e45cc | ||
|
|
1d10235c8e | ||
|
|
2f9f103282 | ||
|
|
219ee0c654 | ||
|
|
8f60cfae41 | ||
|
|
ba8f38507e | ||
|
|
04309a2a49 | ||
|
|
eb2be374fd | ||
|
|
4111be389d | ||
|
|
f751cad2cf | ||
|
|
540cc33d1f | ||
|
|
6952f1acda | ||
|
|
c2e84d1a90 | ||
|
|
89d82ff546 | ||
|
|
e1a8657370 | ||
|
|
0bf9dcb63e | ||
|
|
1d08288406 | ||
|
|
0b88694c07 | ||
|
|
ddfb6adb98 | ||
|
|
05c0d4c0e4 | ||
|
|
87492c4a26 | ||
|
|
d944d9f181 | ||
|
|
88039532cd | ||
|
|
956a045a85 | ||
|
|
3ccd831a3b | ||
|
|
2a2f6b32a2 | ||
|
|
104a4e48bd | ||
|
|
8d26f45278 | ||
|
|
3995196072 | ||
|
|
f072eaf9d8 | ||
|
|
3181b6a517 | ||
|
|
60f1b0b285 | ||
|
|
d3bcd85900 | ||
|
|
f8edcf57bd | ||
|
|
3a5042a774 | ||
|
|
1acc649510 | ||
|
|
62131720aa | ||
|
|
4060a18937 | ||
|
|
2a79ba2fd3 | ||
|
|
90316be322 | ||
|
|
91aafe8da5 | ||
|
|
ef98d300eb | ||
|
|
9cffe27731 | ||
|
|
b1e1c7cdf4 | ||
|
|
b7bebc765e | ||
|
|
f5a016c3d0 | ||
|
|
d09fdd61cb | ||
|
|
274f5a74f5 | ||
|
|
d497dfd113 | ||
|
|
67dfbd21a6 | ||
|
|
14fe993516 | ||
|
|
a77b49406c | ||
|
|
fd37e1dc9f | ||
|
|
a52a1d3b8d | ||
|
|
7db05b1383 | ||
|
|
f8ffc439e5 | ||
|
|
1e42bc8e4f | ||
|
|
1fbcf34ba8 | ||
|
|
16e8a84cfb | ||
|
|
c41e078e85 | ||
|
|
435e45726e | ||
|
|
2a340802dc | ||
|
|
9a070490d4 | ||
|
|
6b503ba887 | ||
|
|
77a204b765 | ||
|
|
a8f3f584a0 | ||
|
|
eb26d5e83a | ||
|
|
ee1c1011f7 | ||
|
|
6115f8db82 | ||
|
|
d28a4da596 | ||
|
|
d4b635589c | ||
|
|
e3fcfccc52 | ||
|
|
e80108118d | ||
|
|
0437fe9d8e | ||
|
|
1f54efff2f | ||
|
|
7dece459ac | ||
|
|
d5bfd237e5 | ||
|
|
c0b1fe0525 | ||
|
|
499877978e | ||
|
|
3a57378f15 | ||
|
|
5a942bcb6f | ||
|
|
64aa911aee | ||
|
|
048f8d505e | ||
|
|
3a5c33b005 | ||
|
|
0c0830b2f2 | ||
|
|
e9a7b24296 | ||
|
|
624d07f283 | ||
|
|
c90ecf7263 | ||
|
|
79855b452b | ||
|
|
3f75788d29 | ||
|
|
1aff3bc216 | ||
|
|
015675d87c | ||
|
|
bdbd1bd307 | ||
|
|
5de4f98d7e | ||
|
|
6639df9edc | ||
|
|
930e24c6b3 | ||
|
|
341bb4f91e | ||
|
|
c0c23291b8 | ||
|
|
d5d2b7727f | ||
|
|
c173f20244 | ||
|
|
4eeaddc583 | ||
|
|
d1b8d60e16 | ||
|
|
a13a7c3948 |
12
.config/dotnet-tools.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"XamlStyler.Console": {
|
||||
"version": "3.2008.4",
|
||||
"commands": [
|
||||
"xstyler"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
54
.github/ISSUE_TEMPLATE/Bug_Report.md
vendored
@@ -1,54 +0,0 @@
|
||||
---
|
||||
name: "Bug report 🐛"
|
||||
about: Report errors or unexpected behavior
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
||||
|
||||
I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING:
|
||||
1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement.
|
||||
2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement.
|
||||
3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number).
|
||||
4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement.
|
||||
5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement.
|
||||
|
||||
All good? Then proceed!
|
||||
-->
|
||||
|
||||
<!--
|
||||
This bug tracker is monitored by Windows Terminal development team and other technical folks.
|
||||
|
||||
**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.
|
||||
|
||||
-->
|
||||
|
||||
# Environment
|
||||
|
||||
```none
|
||||
Windows build number: [run `[Environment]::OSVersion` for powershell, or `ver` for cmd]
|
||||
Windows Terminal version (if applicable):
|
||||
|
||||
Any other software?
|
||||
```
|
||||
|
||||
# Steps to reproduce
|
||||
|
||||
<!-- A description of how to trigger this bug. -->
|
||||
|
||||
# Expected behavior
|
||||
|
||||
<!-- A description of what you're expecting, possibly containing screenshots or reference material. -->
|
||||
|
||||
# Actual behavior
|
||||
|
||||
<!-- What's actually happening? -->
|
||||
53
.github/ISSUE_TEMPLATE/Bug_Report.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: "Bug report 🐛"
|
||||
description: Report errors or unexpected behavior
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please make sure to [search for existing issues](https://github.com/microsoft/terminal/issues) and [check the FAQ](https://github.com/microsoft/terminal/wiki/Frequently-Asked-Questions-(FAQ)) before filing a new one!
|
||||
|
||||
If this is an application crash, please also provide a [Feedback Hub](https://aka.ms/terminal-feedback-hub) submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal" and choose "Share My Feedback" after submission to get the link.
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Windows Terminal version (or Windows build number)
|
||||
placeholder: "10.0.19042.0, 1.7.3651.0"
|
||||
description: |
|
||||
If you are reporting an issue in Windows Terminal, you can find the version in the about dialog.
|
||||
|
||||
If you are reporting an issue with the Windows Console, please run `ver` or `[Environment]::OSVersion`.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other Software
|
||||
description: If you're reporting a bug about our interaction with other software, what software? What versions?
|
||||
placeholder: |
|
||||
vim 8.2 (inside WSL)
|
||||
OpenSSH_for_Windows_8.1p1
|
||||
My Cool Application v0.3 (include a code snippet if it would help!)
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
placeholder: Tell us the steps required to trigger your bug.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: If you want to include screenshots, paste them into the markdown editor below.
|
||||
placeholder: What were you expecting?
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Actual Behavior
|
||||
placeholder: What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
12
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
blank_issues_enabled: true
|
||||
|
||||
contact_links:
|
||||
- name: Microsoft Security Response Center 🔐
|
||||
url: https://msrc.microsoft.com/create-report
|
||||
about: Please report security vulnerabilities here.
|
||||
- name: Windows Terminal Documentation issue 📄
|
||||
url: https://github.com/MicrosoftDocs/terminal/issues/new
|
||||
about: Report issues with the documentation for the Windows Terminal (in docs.microsoft.com/windows/terminal)
|
||||
- name: Console Documentation issue 📄
|
||||
url: https://github.com/MicrosoftDocs/console-docs/issues/new
|
||||
about: Report issues with the documentation for the Console (in docs.microsoft.com/windows/console)
|
||||
57
.github/workflows/linter.yml
vendored
@@ -1,57 +0,0 @@
|
||||
---
|
||||
###########################
|
||||
###########################
|
||||
## Linter GitHub Actions ##
|
||||
###########################
|
||||
###########################
|
||||
name: Lint Code Base
|
||||
|
||||
#
|
||||
# Documentation:
|
||||
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
|
||||
#
|
||||
|
||||
###################################################
|
||||
# The linter is noisy; we used to run it on push. #
|
||||
###################################################
|
||||
#
|
||||
#on:
|
||||
# pull_request:
|
||||
# branches: [main]
|
||||
|
||||
###############
|
||||
# Set the Job #
|
||||
###############
|
||||
jobs:
|
||||
build:
|
||||
# Name the Job
|
||||
name: Lint Code Base
|
||||
# Set the agent to run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
##################
|
||||
# Load all steps #
|
||||
##################
|
||||
steps:
|
||||
##########################
|
||||
# Checkout the code base #
|
||||
##########################
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# Full git history is needed to get a proper list of changed files within `super-linter`
|
||||
fetch-depth: 0
|
||||
|
||||
################################
|
||||
# Run Linter against code base #
|
||||
################################
|
||||
- name: Lint Code Base
|
||||
uses: github/super-linter@v3
|
||||
env:
|
||||
VALIDATE_ALL_CODEBASE: false
|
||||
DEFAULT_BRANCH: main
|
||||
MARKDOWN_CONFIG_FILE: .markdown-lint.yml
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VALIDATE_EDITORCONFIG: false
|
||||
# The json linter doesn't like JSONC, which we use all over. So just disable it.
|
||||
VALIDATE_JSON: false
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="vswhere" version="2.6.7" />
|
||||
</packages>
|
||||
</packages>
|
||||
|
||||
13
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
"ms-vscode.cpptools"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": [
|
||||
|
||||
]
|
||||
}
|
||||
24
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug OpenConsole by Launching (x64, debug)",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}\\bin\\x64\\debug\\openconsole.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
},
|
||||
{
|
||||
"name": "Debug Terminal by Attaching (You go build/register/launch it first.)",
|
||||
"type": "cppvsdbg",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
}
|
||||
]
|
||||
}
|
||||
105
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"C_Cpp.default.browse.databaseFilename": "${workspaceFolder}\\.vscode\\.BROWSE.VC.DB",
|
||||
"C_Cpp.default.browse.path": [
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"C_Cpp.loggingLevel": "None",
|
||||
"files.associations": {
|
||||
"xstring": "cpp",
|
||||
"*.idl": "cpp",
|
||||
"array": "cpp",
|
||||
"future": "cpp",
|
||||
"istream": "cpp",
|
||||
"memory": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"variant": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"multi_span": "cpp",
|
||||
"pointers": "cpp",
|
||||
"vector": "cpp",
|
||||
"bitset": "cpp",
|
||||
"deque": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"list": "cpp",
|
||||
"queue": "cpp",
|
||||
"random": "cpp",
|
||||
"regex": "cpp",
|
||||
"stack": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp",
|
||||
"span": "cpp",
|
||||
"string_span": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"complex": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"exception": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"fstream": "cpp",
|
||||
"functional": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"locale": "cpp",
|
||||
"map": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"ostream": "cpp",
|
||||
"ratio": "cpp",
|
||||
"set": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xtr1common": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"**/bin/**": true,
|
||||
"**/obj/**": true,
|
||||
"**/packages/**": true,
|
||||
"**/Generated Files/**": true
|
||||
}
|
||||
}
|
||||
121
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "process",
|
||||
"label": "Build Terminal/Console",
|
||||
"command": "powershell.exe",
|
||||
"args": [
|
||||
"-Command",
|
||||
"Import-Module ${workspaceFolder}\\tools\\OpenConsole.psm1;",
|
||||
"Set-MsBuildDevEnvironment;",
|
||||
"$project = switch(\"${input:buildProjectChoice}\"){OpenConsole{\"Conhost\\Host_EXE\"} Terminal{\"Terminal\\CascadiaPackage\"} TermControl{\"Terminal\\TerminalControl\"}};",
|
||||
"$target = switch(\"${input:buildModeChoice}\"){Build{\"\"} Rebuild{\":Rebuild\"} Clean{\":Clean\"}};",
|
||||
"$target = $project + $target;",
|
||||
"msbuild",
|
||||
"${workspaceFolder}\\OpenConsole.sln",
|
||||
"/p:Configuration=${input:configChoice}",
|
||||
"/p:Platform=${input:platformChoice}",
|
||||
"/p:AppxSymbolPackageEnabled=false", // This takes a long time, so false if we don't really need it.
|
||||
"/t:$target",
|
||||
"/m", // Parallel builds
|
||||
"/verbosity:minimal"
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"runOptions": {
|
||||
"reevaluateOnRerun": false,
|
||||
"instanceLimit": 1,
|
||||
"runOn": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "process",
|
||||
"label": "Register Windows Terminal x64 Debug",
|
||||
"command": "powershell.exe",
|
||||
"args": [
|
||||
"-Command",
|
||||
"Import-Module ${workspaceFolder}\\tools\\OpenConsole.psm1;",
|
||||
"Set-MsBuildDevEnvironment;",
|
||||
"Set-Location -Path ${workspaceFolder}\\src\\cascadia\\CascadiaPackage\\AppPackages\\CascadiaPackage_0.0.1.0_x64_Debug_Test;",
|
||||
"if ((Get-AppxPackage -Name 'WindowsTerminalDev*') -ne $null) { Remove-AppxPackage 'WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe'};",
|
||||
"New-Item ..\\loose -Type Directory -Force;",
|
||||
"makeappx unpack /v /o /p .\\CascadiaPackage_0.0.1.0_x64_Debug.msix /d ..\\Loose\\;",
|
||||
"Add-AppxPackage -Path ..\\loose\\AppxManifest.xml -Register -ForceUpdateFromAnyVersion -ForceApplicationShutdown"
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "process",
|
||||
"label": "Run Windows Terminal Dev",
|
||||
"command": "wtd.exe",
|
||||
"args": [
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
},
|
||||
{
|
||||
"type": "process",
|
||||
"label": "Run Code Format",
|
||||
"command": "powershell.exe",
|
||||
"args": [
|
||||
"-Command",
|
||||
"Import-Module ${workspaceFolder}\\tools\\OpenConsole.psm1;",
|
||||
"Set-MsBuildDevEnvironment;",
|
||||
"Invoke-CodeFormat",
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
}
|
||||
],
|
||||
"inputs":[
|
||||
{
|
||||
"id": "platformChoice",
|
||||
"type": "pickString",
|
||||
"description": "Processor architecture choice",
|
||||
"options":[
|
||||
"x64",
|
||||
"x86",
|
||||
"arm64"
|
||||
],
|
||||
"default": "x64"
|
||||
},
|
||||
{
|
||||
"id": "configChoice",
|
||||
"type": "pickString",
|
||||
"description": "Debug or release?",
|
||||
"options":[
|
||||
"Debug",
|
||||
"Release"
|
||||
],
|
||||
"default": "Debug"
|
||||
},
|
||||
{
|
||||
"id": "buildModeChoice",
|
||||
"type": "pickString",
|
||||
"description": "Build, rebuild, or clean?",
|
||||
"options":[
|
||||
"Build",
|
||||
"Rebuild",
|
||||
"Clean"
|
||||
],
|
||||
"default": "Build"
|
||||
},
|
||||
{
|
||||
"id": "buildProjectChoice",
|
||||
"type": "pickString",
|
||||
"description": "OpenConsole or Terminal?",
|
||||
"options":[
|
||||
"OpenConsole",
|
||||
"Terminal",
|
||||
"TermControl"
|
||||
],
|
||||
"default": "Terminal"
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"Microsoft.Net.Component.4.5.TargetingPack",
|
||||
"Microsoft.VisualStudio.Component.DiagnosticTools",
|
||||
"Microsoft.VisualStudio.Component.Debugger.JustInTime",
|
||||
"Microsoft.VisualStudio.Component.Windows10SDK.18362",
|
||||
"Microsoft.VisualStudio.Component.Windows10SDK.19041",
|
||||
"Microsoft.VisualStudio.ComponentGroup.UWP.Support",
|
||||
"Microsoft.VisualStudio.Component.VC.CoreIde",
|
||||
"Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core",
|
||||
|
||||
@@ -43,7 +43,7 @@ If no existing item describes your issue/feature, great - please file a new issu
|
||||
* Have a question that you don't see answered in docs, videos, etc.? File an issue
|
||||
* Want to know if we're planning on building a particular feature? File an issue
|
||||
* Got a great idea for a new feature? File an issue/request/idea
|
||||
* Don't understand how to do something? File an issue/Community Guidance Request
|
||||
* Don't understand how to do something? File an issue
|
||||
* Found an existing issue that describes yours? Great - upvote and add additional commentary / info / repro-steps / etc.
|
||||
|
||||
When you hit "New Issue", select the type of issue closest to what you want to report/ask/request:
|
||||
@@ -111,13 +111,13 @@ However, some issues/features will require careful thought & formal design befor
|
||||
|
||||
Specs help collaborators discuss different approaches to solve a problem, describe how the feature will behave, how the feature will impact the user, what happens if something goes wrong, etc. Driving towards agreement in a spec, before any code is written, often results in simpler code, and less wasted effort in the long run.
|
||||
|
||||
Specs will be managed in a very similar manner as code contributions so please follow the "Fork, Branch and Create your PR" below.
|
||||
Specs will be managed in a very similar manner as code contributions so please follow the "[Fork, Branch and Create your PR](CONTRIBUTING.md#fork-clone-branch-and-create-your-pr)" section below.
|
||||
|
||||
### Writing / Contributing-to a Spec
|
||||
|
||||
To write/contribute to a spec: fork, branch and commit via PRs, as you would with any code changes.
|
||||
|
||||
Specs are written in markdown, stored under the `\doc\spec` folder and named `[issue id] - [spec description].md`.
|
||||
Specs are written in markdown, stored under the [`\doc\specs`](./doc/specs) folder and named `[issue id] - [spec description].md`.
|
||||
|
||||
👉 **It is important to follow the spec templates and complete the requested information**. The available spec templates will help ensure that specs contain the minimum information & decisions necessary to permit development to begin. In particular, specs require you to confirm that you've already discussed the issue/idea with the team in an issue and that you provide the issue ID for reference.
|
||||
|
||||
|
||||
80
NOTICE.md
@@ -217,3 +217,83 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
```
|
||||
|
||||
|
||||
## boost
|
||||
|
||||
**Source**: [https://github.com/boostorg/boost](https://github.com/boostorg/boost)
|
||||
|
||||
### License
|
||||
|
||||
```
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
```
|
||||
|
||||
# Microsoft Open Source
|
||||
|
||||
This product also incorporates source code from other Microsoft open source projects, all licensed under the MIT license.
|
||||
|
||||
## `GSL`
|
||||
|
||||
**Source**: [https://github.com/microsoft/GSL](https://github.com/microsoft/GSL)
|
||||
|
||||
## `Microsoft-UI-XAML`
|
||||
|
||||
**Source**: [https://github.com/microsoft/Microsoft-UI-XAML](https://github.com/microsoft/Microsoft-UI-XAML)
|
||||
|
||||
## `VirtualDesktopUtils`
|
||||
|
||||
**Source**: [https://github.com/microsoft/PowerToys](https://github.com/microsoft/PowerToys)
|
||||
|
||||
## `wil`
|
||||
|
||||
**Source**: [https://github.com/microsoft/wil](https://github.com/microsoft/wil)
|
||||
|
||||
### License
|
||||
|
||||
```
|
||||
The MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
```
|
||||
|
||||
20
NuGet.Config
@@ -1,24 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<!-- Add repositories here to the list of available repositories -->
|
||||
|
||||
<!-- Dependencies that we must carry because they're not on public nuget feeds right now. -->
|
||||
<clear />
|
||||
<!-- Dependencies that we can turn on to force override for testing purposes before uploading. -->
|
||||
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
|
||||
|
||||
<!-- Use our own NuGet Feed -->
|
||||
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/ms/terminal/_packaging/TerminalDependencies/nuget/v3/index.json" />
|
||||
|
||||
<!-- Temporarily? use the feeds from our friends in MUX for Helix test stuff -->
|
||||
<add key="dotnetfeed" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
|
||||
<add key="dnceng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
|
||||
<add key="MUX-Dependencies" value="https://pkgs.dev.azure.com/ms/microsoft-ui-xaml/_packaging/MUX-Dependencies/nuget/v3/index.json" />
|
||||
|
||||
<!-- Internal NuGet feeds that may not be accessible outside Microsoft corporate network -->
|
||||
<!--<add key="TAEF - internal" value="https://microsoft.pkgs.visualstudio.com/DefaultCollection/_packaging/Taef/nuget/v3/index.json" />
|
||||
<add key="OpenConsole - Internal" value="https://microsoft.pkgs.visualstudio.com/_packaging/OpenConsole/nuget/v3/index.json" />-->
|
||||
</packageSources>
|
||||
<disabledPackageSources>
|
||||
<clear />
|
||||
</disabledPackageSources>
|
||||
<config>
|
||||
<add key="repositorypath" value=".\packages" />
|
||||
</config>
|
||||
|
||||
1297
OpenConsole.sln
22
README.md
@@ -1,3 +1,5 @@
|
||||

|
||||
|
||||
# Welcome to the Windows Terminal, Console and Command-Line repo
|
||||
|
||||
This repository contains the source code for:
|
||||
@@ -33,10 +35,23 @@ This is our preferred method.
|
||||
|
||||
#### Via GitHub
|
||||
|
||||
For users who are unable to install Terminal from the Microsoft Store, Terminal
|
||||
builds can be manually downloaded from this repository's [Releases
|
||||
For users who are unable to install Windows Terminal from the Microsoft Store,
|
||||
released builds can be manually downloaded from this repository's [Releases
|
||||
page](https://github.com/microsoft/terminal/releases).
|
||||
|
||||
Download the `Microsoft.WindowsTerminal_<versionNumber>.msixbundle` file from
|
||||
the **Assets** section. To install the app, you can simply double-click on the
|
||||
`.msixbundle` file, and the app installer should automatically run. If that
|
||||
fails for any reason, you can try the following command at a PowerShell prompt:
|
||||
|
||||
```powershell
|
||||
# NOTE: If you are using PowerShell 7+, please run
|
||||
# Import-Module Appx -UseWindowsPowerShell
|
||||
# before using Add-AppxPackage.
|
||||
|
||||
Add-AppxPackage Microsoft.WindowsTerminal_<versionNumber>.msixbundle
|
||||
```
|
||||
|
||||
> 🔴 Note: If you install Terminal manually:
|
||||
>
|
||||
> * Terminal will not auto-update when new builds are released so you will need
|
||||
@@ -228,7 +243,7 @@ Visual Studio.
|
||||
|
||||
## Documentation
|
||||
|
||||
All project documentation is located at aka.ms/terminal-docs. If you would like
|
||||
All project documentation is located at [aka.ms/terminal-docs](https://aka.ms/terminal-docs). If you would like
|
||||
to contribute to the documentation, please submit a pull request on the [Windows
|
||||
Terminal Documentation repo](https://github.com/MicrosoftDocs/terminal).
|
||||
|
||||
@@ -263,6 +278,7 @@ If you would like to ask a question that you feel doesn't warrant an issue
|
||||
* Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft)
|
||||
* Leon Liang, Developer: [@leonmsft](https://twitter.com/leonmsft)
|
||||
* Pankaj Bhojwani, Developer
|
||||
* Leonard Hecker, Developer: [@LeonardHecker](https://twitter.com/LeonardHecker)
|
||||
|
||||
## Developer Guidance
|
||||
|
||||
|
||||
221
Scratch.sln
Normal file
@@ -0,0 +1,221 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31205.134
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Package", "scratch\ScratchIslandApp\Package\Package.wapproj", "{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleAppLib", "scratch\ScratchIslandApp\SampleApp\SampleAppLib.vcxproj", "{A4394404-37F7-41C1-802B-49788D3720E3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleApp", "scratch\ScratchIslandApp\SampleApp\dll\SampleApp.vcxproj", "{26C51792-41A3-4FE0-AB5E-8B69D557BF91}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3} = {A4394404-37F7-41C1-802B-49788D3720E3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowExe", "scratch\ScratchIslandApp\WindowExe\WindowExe.vcxproj", "{B4427499-9FDE-4208-B456-5BC580637633}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91} = {26C51792-41A3-4FE0-AB5E-8B69D557BF91}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common Props", "Common Props", "{53DD5520-E64C-4C06-B472-7CE62CA539C9}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\common.build.post.props = src\common.build.post.props
|
||||
src\common.build.pre.props = src\common.build.pre.props
|
||||
src\common.build.tests.props = src\common.build.tests.props
|
||||
common.openconsole.props = common.openconsole.props
|
||||
src\cppwinrt.build.post.props = src\cppwinrt.build.post.props
|
||||
src\cppwinrt.build.pre.props = src\cppwinrt.build.pre.props
|
||||
src\wap-common.build.post.props = src\wap-common.build.post.props
|
||||
src\wap-common.build.pre.props = src\wap-common.build.pre.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "src\dep\fmt\fmt.vcxproj", "{6BAE5851-50D5-4934-8D5E-30361A8A40F3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Types", "src\types\lib\types.vcxproj", "{18D09A24-8240-42D6-8CB6-236EEE820263}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
AuditMode|ARM64 = AuditMode|ARM64
|
||||
AuditMode|x64 = AuditMode|x64
|
||||
AuditMode|x86 = AuditMode|x86
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Fuzzing|ARM64 = Fuzzing|ARM64
|
||||
Fuzzing|x64 = Fuzzing|x64
|
||||
Fuzzing|x86 = Fuzzing|x86
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Build.0 = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Deploy.0 = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.ActiveCfg = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Build.0 = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Deploy.0 = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.ActiveCfg = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Build.0 = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Deploy.0 = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Build.0 = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Build.0 = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Build.0 = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.ActiveCfg = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Build.0 = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Deploy.0 = Debug|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.ActiveCfg = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Build.0 = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Deploy.0 = Debug|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.ActiveCfg = Release|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Build.0 = Release|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Deploy.0 = Release|x64
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.ActiveCfg = Release|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Build.0 = Release|x86
|
||||
{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Deploy.0 = Release|x86
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.Build.0 = Debug|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.ActiveCfg = Release|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.Build.0 = Release|x64
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.Build.0 = Release|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.Build.0 = Debug|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.Build.0 = Debug|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.ActiveCfg = Release|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.Build.0 = Release|x64
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.ActiveCfg = Release|Win32
|
||||
{26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.Build.0 = Release|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.Build.0 = Debug|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.ActiveCfg = Release|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.Build.0 = Release|x64
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.Build.0 = Release|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.Build.0 = Debug|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.ActiveCfg = Release|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.Build.0 = Release|x64
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.Build.0 = Release|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.Build.0 = Debug|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.Build.0 = Debug|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.ActiveCfg = Release|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.Build.0 = Release|x64
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.ActiveCfg = Release|Win32
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9}
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {05EAE315-9188-4D7B-B889-7D5F480A8915}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
41
XamlStyler.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"AttributesTolerance": 1,
|
||||
"KeepFirstAttributeOnSameLine": true,
|
||||
"MaxAttributeCharactersPerLine": 0,
|
||||
"MaxAttributesPerLine": 1,
|
||||
"NewlineExemptionElements": "RadialGradientBrush, GradientStop, LinearGradientBrush, ScaleTransform, SkewTransform, RotateTransform, TranslateTransform, Trigger, Condition, Setter",
|
||||
"SeparateByGroups": false,
|
||||
"AttributeIndentation": 0,
|
||||
"AttributeIndentationStyle": 1,
|
||||
"RemoveDesignTimeReferences": false,
|
||||
"EnableAttributeReordering": true,
|
||||
"AttributeOrderingRuleGroups": [
|
||||
"x:Class",
|
||||
"xmlns, xmlns:x",
|
||||
"xmlns:*",
|
||||
"x:Key, Key, x:Name, Name, x:Uid, Uid, Title",
|
||||
"Grid.Row, Grid.RowSpan, Grid.Column, Grid.ColumnSpan, Canvas.Left, Canvas.Top, Canvas.Right, Canvas.Bottom",
|
||||
"Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight",
|
||||
"Margin, Padding, HorizontalAlignment, VerticalAlignment, HorizontalContentAlignment, VerticalContentAlignment, Panel.ZIndex",
|
||||
"*:*, *",
|
||||
"PageSource, PageIndex, Offset, Color, TargetName, Property, Value, StartPoint, EndPoint",
|
||||
"mc:Ignorable, d:IsDataSource, d:LayoutOverrides, d:IsStaticText",
|
||||
"Storyboard.*, From, To, Duration"
|
||||
],
|
||||
"FirstLineAttributes": "",
|
||||
"OrderAttributesByName": true,
|
||||
"PutEndingBracketOnNewLine": false,
|
||||
"RemoveEndingTagOfEmptyElement": true,
|
||||
"SpaceBeforeClosingSlash": true,
|
||||
"RootElementLineBreakRule": 0,
|
||||
"ReorderVSM": 2,
|
||||
"ReorderGridChildren": false,
|
||||
"ReorderCanvasChildren": false,
|
||||
"ReorderSetters": 0,
|
||||
"FormatMarkupExtension": true,
|
||||
"NoNewLineMarkupExtensions": "x:Bind, Binding",
|
||||
"ThicknessSeparator": 2,
|
||||
"ThicknessAttributes": "Margin, Padding, BorderThickness, ThumbnailClipMargin",
|
||||
"FormatOnSave": true,
|
||||
"CommentPadding": 2,
|
||||
}
|
||||
@@ -29,4 +29,147 @@ function GetQueryTestRunsUri
|
||||
$baseUri = GetAzureDevOpsBaseUri -CollectionUri $CollectionUri -TeamProject $TeamProject
|
||||
$queryUri = "$baseUri/_apis/test/runs?buildUri=$BuildUri$includeRunDetailsParameter&api-version=5.0"
|
||||
return $queryUri
|
||||
}
|
||||
|
||||
function Get-HelixJobTypeFromTestRun
|
||||
{
|
||||
Param ($testRun)
|
||||
|
||||
$testRunSingleResultUri = "$($testRun.url)/results?`$top=1&`$skip=0&api-version=5.1"
|
||||
$singleTestResult = Invoke-RestMethod -Uri $testRunSingleResultUri -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$count = $singleTestResult.value.Length
|
||||
if($count -eq 0)
|
||||
{
|
||||
# If the count is 0, then results have not yet been reported for this run.
|
||||
# We only care about completed runs with results, so it is ok to just return 'UNKNOWN' for this run.
|
||||
return "UNKNOWN"
|
||||
}
|
||||
else
|
||||
{
|
||||
$info = ConvertFrom-Json $singleTestResult.value.comment
|
||||
$helixJobId = $info.HelixJobId
|
||||
$job = Invoke-RestMethodWithRetries "https://helix.dot.net/api/2019-06-17/jobs/${helixJobId}?access_token=${HelixAccessToken}"
|
||||
return $job.Type
|
||||
}
|
||||
}
|
||||
|
||||
function Append-HelixAccessTokenToUrl
|
||||
{
|
||||
Param ([string]$url, [string]$token)
|
||||
if($url.Contains("?"))
|
||||
{
|
||||
$url = "$($url)&access_token=$($token)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = "$($url)?access_token=$($token)"
|
||||
}
|
||||
return $url
|
||||
}
|
||||
|
||||
|
||||
# The Helix Rest api is sometimes unreliable. So we call these apis with retry logic.
|
||||
# Note: The Azure DevOps apis are stable and do not need to be called with this retry logic.
|
||||
$helixApiRetries = 0
|
||||
$helixApiRetriesMax = 10
|
||||
|
||||
function Download-StringWithRetries
|
||||
{
|
||||
Param ([string]$fileName, [string]$url)
|
||||
|
||||
$result = ""
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Host "Downloading $fileName"
|
||||
$result = (New-Object System.Net.WebClient).DownloadString($url)
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to download $fileName $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry download of $fileName"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to download $fileName"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Invoke-RestMethodWithRetries
|
||||
{
|
||||
Param ([string]$url,$Headers)
|
||||
|
||||
$result = @()
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = Invoke-RestMethod -Uri $url -Method Get -Headers $Headers
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to invoke Rest method $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry invoke"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to invoke Rest method"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Download-FileWithRetries
|
||||
{
|
||||
Param ([string]$fileurl, [string]$destination)
|
||||
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Host "Downloading $destination"
|
||||
$webClient.DownloadFile($fileurl, $destination)
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to download $destination $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry download of $destination"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to download $destination"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ Write-Host "Checking test results..."
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
$testRuns = Invoke-RestMethod -Uri $queryUri -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
[System.Collections.Generic.List[string]]$failingTests = @()
|
||||
[System.Collections.Generic.List[string]]$unreliableTests = @()
|
||||
[System.Collections.Generic.List[string]]$unexpectedResultTest = @()
|
||||
@@ -50,7 +50,7 @@ foreach ($testRun in ($testRuns.value | Sort-Object -Property "completedDate" -D
|
||||
$totalTestsExecutedCount += $testRun.totalTests
|
||||
|
||||
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
|
||||
$testResults = Invoke-RestMethod -Uri "$($testRun.url)/results?api-version=5.0" -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ $payloadDir = "HelixPayload\$Configuration\$Platform"
|
||||
|
||||
$repoDirectory = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "..\..\"
|
||||
$nugetPackagesDir = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "packages"
|
||||
|
||||
|
||||
# Create the payload directory. Remove it if it already exists.
|
||||
If(test-path $payloadDir)
|
||||
{
|
||||
@@ -19,11 +19,13 @@ New-Item -ItemType Directory -Force -Path $payloadDir
|
||||
|
||||
# Copy files from nuget packages
|
||||
Copy-Item "$nugetPackagesDir\microsoft.windows.apps.test.1.0.181203002\lib\netcoreapp2.1\*.dll" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\taef.redist.wlk.10.57.200731005-develop\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\taef.redist.wlk.10.57.200731005-develop\build\Binaries\$Platform\CoreClr\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\NetFx4.5\*" $payloadDir
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\lib\netcoreapp2.1\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\native\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir\content\"
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Internal.Windows.Terminal.TestContent.1.0.1\content\*" "$payloadDir\content\"
|
||||
|
||||
function Copy-If-Exists
|
||||
{
|
||||
@@ -52,3 +54,13 @@ Copy-Item "build\helix\HelixTestHelpers.cs" "$payloadDir"
|
||||
Copy-Item "build\helix\runtests.cmd" $payloadDir
|
||||
Copy-Item "build\helix\InstallTestAppDependencies.ps1" "$payloadDir"
|
||||
Copy-Item "build\Helix\EnsureMachineState.ps1" "$payloadDir"
|
||||
|
||||
# Copy the APPX package from the 'drop' artifact dir
|
||||
Copy-Item "$repoDirectory\Artifacts\$ArtifactName\appx\CascadiaPackage_0.0.1.0_$Platform.msix" $payloadDir\CascadiaPackage.zip
|
||||
|
||||
# Rename it to extension of ZIP because Expand-Archive is real sassy on the build machines
|
||||
# and refuses to unzip it because of its file extension while on a desktop, it just
|
||||
# does the job without complaining.
|
||||
|
||||
# Extract the APPX package
|
||||
Expand-Archive -LiteralPath $payloadDir\CascadiaPackage.zip -DestinationPath $payloadDir\appx
|
||||
|
||||
@@ -9,11 +9,6 @@ Param(
|
||||
|
||||
$helixLinkFile = "$OutputFolder\LinksToHelixTestFiles.html"
|
||||
|
||||
$accessTokenParam = ""
|
||||
if($HelixAccessToken)
|
||||
{
|
||||
$accessTokenParam = "?access_token=$HelixAccessToken"
|
||||
}
|
||||
|
||||
function Generate-File-Links
|
||||
{
|
||||
@@ -25,13 +20,31 @@ function Generate-File-Links
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<ul>"
|
||||
foreach($file in $files)
|
||||
{
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<li><a href=$($file.Link)>$($file.Name)</a></li>"
|
||||
$url = Append-HelixAccessTokenToUrl $file.Link "{Your-Helix-Access-Token-Here}"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<li>$($url)</li>"
|
||||
}
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "</ul>"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "</div>"
|
||||
}
|
||||
}
|
||||
|
||||
function Append-HelixAccessTokenToUrl
|
||||
{
|
||||
Param ([string]$url, [string]$token)
|
||||
if($token)
|
||||
{
|
||||
if($url.Contains("?"))
|
||||
{
|
||||
$url = "$($url)&access_token=$($token)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = "$($url)?access_token=$($token)"
|
||||
}
|
||||
}
|
||||
return $url
|
||||
}
|
||||
|
||||
#Create output directory
|
||||
New-Item $OutputFolder -ItemType Directory
|
||||
|
||||
@@ -45,66 +58,71 @@ $azureDevOpsRestApiHeaders = @{
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
$testRuns = Invoke-RestMethod -Uri $queryUri -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
$webClient = New-Object System.Net.WebClient
|
||||
[System.Collections.Generic.List[string]]$workItems = @()
|
||||
|
||||
foreach ($testRun in $testRuns.value)
|
||||
{
|
||||
$testResults = Invoke-RestMethod -Uri "$($testRun.url)/results?api-version=5.0" -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
Write-Host "testRunUri = $testRun.url"
|
||||
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
|
||||
$isTestRunNameShown = $false
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
if ("comment" -in $testResult)
|
||||
$info = ConvertFrom-Json $testResult.comment
|
||||
$helixJobId = $info.HelixJobId
|
||||
$helixWorkItemName = $info.HelixWorkItemName
|
||||
|
||||
$workItem = "$helixJobId-$helixWorkItemName"
|
||||
|
||||
Write-Host "Helix Work Item = $workItem"
|
||||
|
||||
if (-not $workItems.Contains($workItem))
|
||||
{
|
||||
$info = ConvertFrom-Json $testResult.comment
|
||||
$helixJobId = $info.HelixJobId
|
||||
$helixWorkItemName = $info.HelixWorkItemName
|
||||
$workItems.Add($workItem)
|
||||
$filesQueryUri = "https://helix.dot.net/api/2019-06-17/jobs/$helixJobId/workitems/$helixWorkItemName/files"
|
||||
$filesQueryUri = Append-HelixAccessTokenToUrl $filesQueryUri $helixAccessToken
|
||||
$files = Invoke-RestMethodWithRetries $filesQueryUri
|
||||
|
||||
$workItem = "$helixJobId-$helixWorkItemName"
|
||||
|
||||
if (-not $workItems.Contains($workItem))
|
||||
$screenShots = $files | where { $_.Name.EndsWith(".jpg") }
|
||||
$dumps = $files | where { $_.Name.EndsWith(".dmp") }
|
||||
$pgcFiles = $files | where { $_.Name.EndsWith(".pgc") }
|
||||
if ($screenShots.Count + $dumps.Count + $pgcFiles.Count -gt 0)
|
||||
{
|
||||
$workItems.Add($workItem)
|
||||
$filesQueryUri = "https://helix.dot.net/api/2019-06-17/jobs/$helixJobId/workitems/$helixWorkItemName/files$accessTokenParam"
|
||||
$files = Invoke-RestMethod -Uri $filesQueryUri -Method Get
|
||||
|
||||
$screenShots = $files | where { $_.Name.EndsWith(".jpg") }
|
||||
$dumps = $files | where { $_.Name.EndsWith(".dmp") }
|
||||
$pgcFiles = $files | where { $_.Name.EndsWith(".pgc") }
|
||||
if ($screenShots.Count + $dumps.Count + $pgcFiles.Count -gt 0)
|
||||
if(-Not $isTestRunNameShown)
|
||||
{
|
||||
if(-Not $isTestRunNameShown)
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h2>$($testRun.name)</h2>"
|
||||
$isTestRunNameShown = $true
|
||||
}
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h3>$helixWorkItemName</h3>"
|
||||
Generate-File-Links $screenShots "Screenshots"
|
||||
Generate-File-Links $dumps "CrashDumps"
|
||||
Generate-File-Links $pgcFiles "PGC files"
|
||||
$misc = $files | where { ($screenShots -NotContains $_) -And ($dumps -NotContains $_) -And ($visualTreeVerificationFiles -NotContains $_) -And ($pgcFiles -NotContains $_) }
|
||||
Generate-File-Links $misc "Misc"
|
||||
|
||||
foreach($pgcFile in $pgcFiles)
|
||||
{
|
||||
$flavorPath = $testResult.automatedTestName.Split('.')[0]
|
||||
$archPath = $testResult.automatedTestName.Split('.')[1]
|
||||
$fileName = $pgcFile.Name
|
||||
$fullPath = "$OutputFolder\PGO\$flavorPath\$archPath"
|
||||
$destination = "$fullPath\$fileName"
|
||||
|
||||
Write-Host "Copying $($pgcFile.Name) to $destination"
|
||||
|
||||
if (-Not (Test-Path $fullPath))
|
||||
{
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h2>$($testRun.name)</h2>"
|
||||
$isTestRunNameShown = $true
|
||||
New-Item $fullPath -ItemType Directory
|
||||
}
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h3>$helixWorkItemName</h3>"
|
||||
Generate-File-Links $screenShots "Screenshots"
|
||||
Generate-File-Links $dumps "CrashDumps"
|
||||
Generate-File-Links $pgcFiles "PGC files"
|
||||
$misc = $files | where { ($screenShots -NotContains $_) -And ($dumps -NotContains $_) -And ($visualTreeVerificationFiles -NotContains $_) -And ($pgcFiles -NotContains $_) }
|
||||
Generate-File-Links $misc "Misc"
|
||||
|
||||
foreach($pgcFile in $pgcFiles)
|
||||
{
|
||||
$flavorPath = $pgcFile.Name.Split('.')[0]
|
||||
$archPath = $pgcFile.Name.Split('.')[1]
|
||||
$fileName = $pgcFile.Name.Remove(0, $flavorPath.length + $archPath.length + 2)
|
||||
$fullPath = "$OutputFolder\PGO\$flavorPath\$archPath"
|
||||
$destination = "$fullPath\$fileName"
|
||||
$link = $pgcFile.Link
|
||||
|
||||
Write-Host "Copying $($pgcFile.Name) to $destination"
|
||||
Write-Host "Downloading $link to $destination"
|
||||
|
||||
if (-Not (Test-Path $fullPath))
|
||||
{
|
||||
New-Item $fullPath -ItemType Directory
|
||||
}
|
||||
|
||||
$link = "$($pgcFile.Link)$accessTokenParam"
|
||||
$webClient.DownloadFile($link, $destination)
|
||||
}
|
||||
$link = Append-HelixAccessTokenToUrl $link $HelixAccessToken
|
||||
Download-FileWithRetries $link $destination
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<!-- These .proj files are generated by the build machine prior to running tests via GenerateTestProjFile.ps1. -->
|
||||
<Import Project="$(ProjFilesPath)\RunTestsInHelix-TerminalAppLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\RunTestsInHelix-HostTestsUIA.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-TerminalAppLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-SettingsModelLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-HostTestsUIA.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-WindowsTerminalUIATests.proj" Condition=" '$(TestSuite)'=='PgoInstrumentationSuite' " />
|
||||
</Project>
|
||||
@@ -23,7 +23,7 @@ Write-Host "queryUri = $queryUri"
|
||||
# To account for unreliable tests, we'll iterate through all of the tests associated with this build, check to see any tests that were unreliable
|
||||
# (denoted by being marked as "skipped"), and if so, we'll instead mark those tests with a warning and enumerate all of the attempted runs
|
||||
# with their pass/fail states as well as any relevant error messages for failed attempts.
|
||||
$testRuns = Invoke-RestMethod -Uri $queryUri -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
$timesSeenByRunName = @{}
|
||||
|
||||
@@ -32,10 +32,10 @@ foreach ($testRun in $testRuns.value)
|
||||
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
|
||||
|
||||
Write-Host "Marking test run `"$($testRun.name)`" as in progress so we can change its results to account for unreliable tests."
|
||||
Invoke-RestMethod -Uri "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "InProgress" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
|
||||
Invoke-RestMethod "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "InProgress" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
|
||||
|
||||
Write-Host "Retrieving test results..."
|
||||
$testResults = Invoke-RestMethod -Uri $testRunResultsUri -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$testResults = Invoke-RestMethodWithRetries $testRunResultsUri -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
@@ -54,7 +54,8 @@ foreach ($testRun in $testRuns.value)
|
||||
Write-Host " Test $($testResult.testCaseTitle) was detected as unreliable. Updating..."
|
||||
|
||||
# The errorMessage field contains a link to the JSON-encoded rerun result data.
|
||||
$rerunResults = ConvertFrom-Json (New-Object System.Net.WebClient).DownloadString($testResult.errorMessage)
|
||||
$resultsJson = Download-StringWithRetries "Error results" $testResult.errorMessage
|
||||
$rerunResults = ConvertFrom-Json $resultsJson
|
||||
[System.Collections.Generic.List[System.Collections.Hashtable]]$rerunDataList = @()
|
||||
$attemptCount = 0
|
||||
$passCount = 0
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
|
||||
<package id="TAEF.Redist.Wlk" version="10.57.200731005-develop" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.TestContent" version="1.0.1" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
|
||||
<package id="microsoft.windows.apps.test" version="1.0.181203002" targetFramework="native" />
|
||||
<package id="runtime.win-x86.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
<package id="runtime.win-x64.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
|
||||
@@ -18,7 +18,7 @@ FOR %%A IN (TestHostApp.exe,te.exe,te.processhost.exe,conhost.exe,OpenConsole.ex
|
||||
|
||||
echo %TIME%
|
||||
|
||||
:: kill dhandler, which is a tool designed to handle unexpected windows appearing. But since our tests are
|
||||
:: kill dhandler, which is a tool designed to handle unexpected windows appearing. But since our tests are
|
||||
:: expected to show UI we don't want it running.
|
||||
taskkill -f -im dhandler.exe
|
||||
|
||||
@@ -28,7 +28,7 @@ echo %TIME%
|
||||
powershell -ExecutionPolicy Bypass .\InstallTestAppDependencies.ps1
|
||||
echo %TIME%
|
||||
|
||||
set testBinaryCandidates=TerminalApp.LocalTests.dll Conhost.UIA.Tests.dll
|
||||
set testBinaryCandidates=TerminalApp.LocalTests.dll SettingsModel.LocalTests.dll Conhost.UIA.Tests.dll WindowsTerminal.UIA.Tests.dll
|
||||
set testBinaries=
|
||||
for %%B in (%testBinaryCandidates%) do (
|
||||
if exist %%B (
|
||||
@@ -46,7 +46,6 @@ move te.wtl te_original.wtl
|
||||
|
||||
copy /y te_original.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
for /f "tokens=* delims=" %%a in ('dir /b *.pgc') do ren "%%a" "%testnameprefix%.%%~na.pgc"
|
||||
copy /y *.pgc %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
set FailedTestQuery=
|
||||
@@ -103,4 +102,4 @@ copy /y *_subresults.json %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
type testResults.xml
|
||||
|
||||
echo %TIME%
|
||||
echo %TIME%
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<SignConfigXML>
|
||||
<job platform="" configuration="" dest="__INPATHROOT__" jobname="EngFunSimpleSign" approvers="">
|
||||
<file src="__INPATHROOT__\Microsoft.Terminal*.nupkg" signType="NuGet" />
|
||||
</job>
|
||||
</SignConfigXML>
|
||||
@@ -1,5 +0,0 @@
|
||||
<SignConfigXML>
|
||||
<job platform="" configuration="" certSubject="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" jobname="EngFunSimpleSign" approvers="">
|
||||
<file src="__INPATHROOT__\Microsoft.WindowsTerminal*.msixbundle" signType="136020001" />
|
||||
</job>
|
||||
</SignConfigXML>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
|
||||
<package id="TAEF.Redist.Wlk" version="10.57.200731005-develop" targetFramework="native" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
27
build/pipelines/pgo.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
variables:
|
||||
- name: runCodesignValidationInjectionBG
|
||||
value: false
|
||||
|
||||
# 0.0.yyMM.dd##
|
||||
# 0.0.1904.0900
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
stages:
|
||||
- stage: Build_x64
|
||||
displayName: Build x64
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/build-console-pgo.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: Publish_PGO_Databases
|
||||
displayName: Publish PGO databases
|
||||
dependsOn: ['Build_x64']
|
||||
jobs:
|
||||
- template: ./templates/pgo-build-and-publish-nuget-job.yml
|
||||
parameters:
|
||||
pgoArtifact: 'PGO'
|
||||
@@ -1,48 +1,487 @@
|
||||
# This build should never run as CI or against a pull request.
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
pool:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS16-latest
|
||||
|
||||
parameters:
|
||||
- name: branding
|
||||
displayName: "Branding (Build Type)"
|
||||
type: string
|
||||
default: Release
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- name: buildTerminal
|
||||
displayName: "Build Windows Terminal MSIX"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildTerminalVPack
|
||||
displayName: "Build Windows Terminal VPack"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
displayName: "Build Terminal WPF Control"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
displayName: "PGO Build Mode"
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
|
||||
variables:
|
||||
baseYearForVersioning: 2019 # Used by build-console-int
|
||||
versionMajor: 0
|
||||
versionMinor: 1
|
||||
TerminalInternalPackageVersion: "0.0.7"
|
||||
|
||||
# When we move off PackageES for Versioning, we'll need to switch
|
||||
# name to this format. For now, though, we need to use DayOfYear.Rev
|
||||
# to unique our builds, as mandated by PackageES's Setup task.
|
||||
# name: '$(versionMajor).$(versionMinor).$(DayOfYear)$(Rev:r).0'
|
||||
#
|
||||
# Build name/version number above must end with .0 to make the
|
||||
# store publication machinery happy.
|
||||
name: 'Terminal_$(date:yyMM).$(date:dd)$(rev:rrr)'
|
||||
|
||||
# Build Arguments:
|
||||
# WindowsTerminalOfficialBuild=[true,false]
|
||||
# true - this is running on our build agent
|
||||
# false - running locally
|
||||
# WindowsTerminalBranding=[Dev,Preview,Release]
|
||||
# <none> - Development build resources (default)
|
||||
# Preview - Preview build resources
|
||||
# Release - regular build resources
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
resources:
|
||||
repositories:
|
||||
- repository: self
|
||||
type: git
|
||||
ref: main
|
||||
jobs:
|
||||
- template: ./templates/build-console-audit-job.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- job: Build
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ each platform in parameters.buildPlatforms }}:
|
||||
${{ config }}_${{ platform }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
BuildPlatform: ${{ platform }}
|
||||
displayName: Build
|
||||
cancelTimeoutInMinutes: 1
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- task: PowerShell@2
|
||||
displayName: Rationalize Build Platform
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Arch = "$(BuildPlatform)"
|
||||
|
||||
- template: ./templates/build-console-int.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
additionalBuildArguments: /p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=Preview
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
|
||||
- template: ./templates/build-console-int.yml
|
||||
parameters:
|
||||
platform: x86
|
||||
additionalBuildArguments: /p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=Preview
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.10
|
||||
inputs:
|
||||
versionSpec: 5.10
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet custom
|
||||
inputs:
|
||||
command: custom
|
||||
selectOrConfig: config
|
||||
nugetConfigPath: NuGet.Config
|
||||
arguments: restore OpenConsole.sln -SolutionDirectory $(Build.SourcesDirectory)
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: $(TerminalInternalPackageVersion)
|
||||
- task: TouchdownBuildTask@1
|
||||
displayName: Download Localization Files
|
||||
inputs:
|
||||
teamId: 7105
|
||||
authId: $(TouchdownAppId)
|
||||
authKey: $(TouchdownAppKey)
|
||||
resourceFilePath: >-
|
||||
src\cascadia\TerminalApp\Resources\en-US\Resources.resw
|
||||
|
||||
- template: ./templates/build-console-int.yml
|
||||
parameters:
|
||||
platform: arm64
|
||||
additionalBuildArguments: /p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=Preview
|
||||
src\cascadia\TerminalControl\Resources\en-US\Resources.resw
|
||||
|
||||
- template: ./templates/check-formatting.yml
|
||||
src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
|
||||
|
||||
- template: ./templates/release-sign-and-bundle.yml
|
||||
src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\WindowsTerminalUniversal\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
|
||||
appendRelativeDir: true
|
||||
localizationTarget: false
|
||||
pseudoSetting: Included
|
||||
- task: PowerShell@2
|
||||
displayName: Move Loc files one level up
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
|
||||
|
||||
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
|
||||
pwsh: true
|
||||
- task: PowerShell@2
|
||||
displayName: Generate NOTICE.html from NOTICE.md
|
||||
inputs:
|
||||
filePath: .\build\scripts\Generate-ThirdPartyNotices.ps1
|
||||
arguments: -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
|
||||
pwsh: true
|
||||
- ${{ if eq(parameters.pgoBuildMode, 'Optimize') }}:
|
||||
- task: PowerShell@2
|
||||
displayName: Restore PGO Database
|
||||
inputs:
|
||||
filePath: tools/PGODatabase/restore-pgodb.ps1
|
||||
workingDirectory: $(Build.SourcesDirectory)\tools\PGODatabase
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
vsVersion: 16.0
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /t:Terminal\CascadiaPackage;Terminal\WindowsTerminalUniversal /p:WindowsTerminalReleaseBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: binlog'
|
||||
condition: failed()
|
||||
continueOnError: True
|
||||
inputs:
|
||||
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
|
||||
ArtifactName: binlog-$(BuildPlatform)
|
||||
- ${{ if eq(parameters.pgoBuildMode, 'Optimize') }}:
|
||||
- task: PowerShell@2
|
||||
displayName: Validate binaries are optimized
|
||||
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Binaries = 'OpenConsole.exe', 'WindowsTerminal.exe', 'TerminalApp.dll', 'TerminalConnection.dll', 'Microsoft.Terminal.Control.dll', 'Microsoft.Terminal.Remoting.dll', 'Microsoft.Terminal.Settings.Editor.dll', 'Microsoft.Terminal.Settings.Model.dll'
|
||||
|
||||
foreach ($BinFile in $Binaries) {
|
||||
|
||||
& "$(Build.SourcesDirectory)\tools\PGODatabase\verify-pgo.ps1" "$(Build.SourcesDirectory)/src/cascadia/CascadiaPackage/bin/$(BuildPlatform)/$(BuildConfiguration)/$BinFile"
|
||||
|
||||
}
|
||||
- task: PowerShell@2
|
||||
displayName: Check MSIX for common regressions
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
|
||||
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
|
||||
pwsh: true
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for PublicTerminalCore
|
||||
condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64'))
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
vsVersion: 16.0
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Terminal\wpf\PublicTerminalCore
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
- task: PowerShell@2
|
||||
displayName: Source Index PDBs
|
||||
inputs:
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
errorActionPreference: silentlyContinue
|
||||
- task: ComponentGovernanceComponentDetection@0
|
||||
displayName: Component Detection
|
||||
- task: PowerShell@2
|
||||
displayName: Run Unit Tests
|
||||
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
enabled: False
|
||||
inputs:
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
|
||||
- task: PowerShell@2
|
||||
displayName: Run Feature Tests
|
||||
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
|
||||
enabled: False
|
||||
inputs:
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.appx/*.msix to Artifacts
|
||||
inputs:
|
||||
Contents: >-
|
||||
**/*.appx
|
||||
|
||||
**/*.msix
|
||||
|
||||
**/*.appxsym
|
||||
|
||||
!**/Microsoft.VCLibs*.appx
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/appx
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (appx)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/appx
|
||||
ArtifactName: appx-$(BuildPlatform)-$(BuildConfiguration)
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy PublicTerminalCore.dll to Artifacts
|
||||
condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64'))
|
||||
inputs:
|
||||
Contents: >-
|
||||
**/PublicTerminalCore.dll
|
||||
|
||||
**/api-ms-win-core-synch-l1-2-0.dll
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/wpf
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (PublicTerminalCore)
|
||||
condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64'))
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/wpf
|
||||
ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols path
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SearchPattern: '**/*.pdb'
|
||||
IndexSources: false
|
||||
SymbolServerType: TeamServices
|
||||
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- job: BundleAndSign
|
||||
displayName: Create and sign AppX/MSIX bundles
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download Artifacts (*.appx, *.msix)
|
||||
inputs:
|
||||
downloadType: specific
|
||||
itemPattern: >-
|
||||
**/*.msix
|
||||
|
||||
**/*.appx
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Create WindowsTerminal*.msixbundle
|
||||
inputs:
|
||||
filePath: build\scripts\Create-AppxBundle.ps1
|
||||
arguments: -InputPath "$(System.ArtifactsDirectory)" -ProjectName CascadiaPackage -BundleVersion 0.0.0.0 -OutputPath "$(System.ArtifactsDirectory)\Microsoft.WindowsTerminal_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
|
||||
- task: PowerShell@2
|
||||
displayName: Create WindowsTerminalUniversal*.msixbundle
|
||||
inputs:
|
||||
filePath: build\scripts\Create-AppxBundle.ps1
|
||||
arguments: -InputPath "$(System.ArtifactsDirectory)" -ProjectName WindowsTerminalUniversal -BundleVersion $(XES_APPXMANIFESTVERSION) -OutputPath "$(System.ArtifactsDirectory)\Microsoft.WindowsTerminalUniversal_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.msixbundle to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(System.ArtifactsDirectory)
|
||||
Pattern: Microsoft.WindowsTerminal*.msixbundle
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: appxbundle-signed'
|
||||
inputs:
|
||||
PathtoPublish: $(System.ArtifactsDirectory)
|
||||
ArtifactName: appxbundle-signed
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- job: PackageAndSignWPF
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
displayName: Create NuGet Package (WPF Terminal Control)
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download x86 PublicTerminalCore
|
||||
inputs:
|
||||
artifactName: wpf-dll-x86-$(BuildConfiguration)
|
||||
itemPattern: '**/*.dll'
|
||||
downloadPath: bin\Win32\$(BuildConfiguration)\
|
||||
extractTars: false
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download x64 PublicTerminalCore
|
||||
inputs:
|
||||
artifactName: wpf-dll-x64-$(BuildConfiguration)
|
||||
itemPattern: '**/*.dll'
|
||||
downloadPath: bin\x64\$(BuildConfiguration)\
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Move downloaded artifacts up a level
|
||||
inputs:
|
||||
targetType: inline
|
||||
# Find all artifact files and move them up a directory. Ugh.
|
||||
script: >-
|
||||
Get-ChildItem bin -Recurse -Directory -Filter wpf-dll-* | % {
|
||||
$_ | Get-ChildItem -Recurse -File | % {
|
||||
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
|
||||
}
|
||||
}
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.10.0
|
||||
inputs:
|
||||
versionSpec: 5.10.0
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet restore copy
|
||||
inputs:
|
||||
selectOrConfig: config
|
||||
nugetConfigPath: NuGet.Config
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for WPF Control
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
vsVersion: 16.0
|
||||
msbuildArgs: /p:WindowsTerminalReleaseBuild=$(UseReleaseBranding);Version=$(XES_PACKAGEVERSIONNUMBER) /t:Pack
|
||||
platform: Any CPU
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols path
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SearchPattern: '**/*.pdb'
|
||||
IndexSources: false
|
||||
SymbolServerType: TeamServices
|
||||
SymbolsArtifactName: Symbols_WPF_$(BuildConfiguration)
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.nupkg to Artifacts
|
||||
inputs:
|
||||
Contents: '**/*Wpf*.nupkg'
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (nupkg)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
ArtifactName: wpf-nupkg-$(BuildConfiguration)
|
||||
|
||||
- ${{ if eq(parameters.buildTerminalVPack, true) }}:
|
||||
- job: VPack
|
||||
displayName: Create Windows vPack
|
||||
dependsOn: BundleAndSign
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download Build Artifacts
|
||||
inputs:
|
||||
artifactName: appxbundle-signed
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Rename and stage packages for vpack
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
# Rename to known/fixed name for Windows build system
|
||||
|
||||
Get-ChildItem Microsoft.WindowsTerminal_*.msixbundle | Rename-Item -NewName { 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle' }
|
||||
|
||||
|
||||
# Create vpack directory and place item inside
|
||||
|
||||
mkdir WindowsTerminal.app
|
||||
|
||||
mv Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle .\WindowsTerminal.app\
|
||||
workingDirectory: $(System.ArtifactsDirectory)\appxbundle-signed
|
||||
- task: PkgESVPack@12
|
||||
displayName: 'Package ES - VPack'
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
sourceDirectory: $(System.ArtifactsDirectory)\appxbundle-signed\WindowsTerminal.app
|
||||
description: Windows Terminal pre-install application
|
||||
pushPkgName: WindowsTerminal.app
|
||||
owner: condev
|
||||
...
|
||||
|
||||
@@ -8,9 +8,12 @@ jobs:
|
||||
variables:
|
||||
BuildConfiguration: AuditMode
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool: "windevbuildagents"
|
||||
# The public pool is also an option!
|
||||
# pool: { vmImage: windows-2019 }
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS16-latest
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
|
||||
@@ -11,21 +11,32 @@ jobs:
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool: "windevbuildagents"
|
||||
# The public pool is also an option!
|
||||
# pool: { vmImage: windows-2019 }
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS16-latest
|
||||
|
||||
steps:
|
||||
- template: build-console-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}
|
||||
|
||||
# It appears that the Component Governance build task that gets automatically injected stopped working
|
||||
# when we renamed our main branch.
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: 'Component Detection'
|
||||
condition: and(succeededOrFailed(), not(eq(variables['Build.Reason'], 'PullRequest')))
|
||||
|
||||
- template: helix-runtests-job.yml
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
dependsOn: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
condition: and(succeeded(), and(eq('${{ parameters.platform }}', 'x64'), not(eq(variables['Build.Reason'], 'PullRequest'))))
|
||||
testSuite: 'DevTestSuite'
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: ${{ parameters.configuration }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
|
||||
- template: helix-processtestresults-job.yml
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
|
||||
pool:
|
||||
name: Package ES Lab E
|
||||
demands:
|
||||
- msbuild
|
||||
- visualstudio
|
||||
- vstest
|
||||
|
||||
steps:
|
||||
- task: PkgESSetupBuild@10
|
||||
displayName: 'Package ES - Setup Build'
|
||||
inputs:
|
||||
useDfs: false
|
||||
productName: WindowsTerminal
|
||||
disableOutputRedirect: true
|
||||
|
||||
- template: build-console-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: "/p:XesUseOneStoreVersioning=true;XesBaseYearForStoreVersion=$(baseYearForVersioning) ${{ parameters.additionalBuildArguments }}"
|
||||
54
build/pipelines/templates/build-console-pgo.yml
Normal file
@@ -0,0 +1,54 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
minimumExpectedTestsExecutedCount: 1 # Sanity check for minimum expected tests to be reported
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
PGOBuildMode: 'Instrument'
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS16-latest
|
||||
|
||||
steps:
|
||||
- template: build-console-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}
|
||||
|
||||
- template: helix-runtests-job.yml
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
dependsOn: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
condition: succeeded()
|
||||
testSuite: 'PgoInstrumentationSuite'
|
||||
taefQuery: '@IsPgo=true'
|
||||
configuration: ${{ parameters.configuration }}
|
||||
platform: ${{ parameters.platform }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
|
||||
- template: helix-processtestresults-job.yml
|
||||
parameters:
|
||||
name: 'ProcessTestResults'
|
||||
pgoArtifact: 'PGO'
|
||||
dependsOn:
|
||||
- RunTestsInHelix
|
||||
condition: succeededOrFailed()
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }}
|
||||
|
||||
- template: pgo-merge-pgd-job.yml
|
||||
parameters:
|
||||
name: 'MergePGD'
|
||||
dependsOn:
|
||||
- ProcessTestResults
|
||||
pgoArtifact: 'PGO'
|
||||
platform: ${{ parameters.platform }}
|
||||
@@ -22,7 +22,7 @@ steps:
|
||||
configPath: NuGet.config
|
||||
restoreSolution: OpenConsole.sln
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\packages'
|
||||
|
||||
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: Restore NuGet packages for extraneous build actions
|
||||
inputs:
|
||||
@@ -32,6 +32,29 @@ steps:
|
||||
restoreSolution: build/packages.config
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\packages'
|
||||
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display build machine environment variables'
|
||||
inputs:
|
||||
filename: 'set'
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'Restore PGO database'
|
||||
condition: eq(variables['PGOBuildMode'], 'Optimize')
|
||||
inputs:
|
||||
targetType: filePath
|
||||
workingDirectory: $(Build.SourcesDirectory)\tools\PGODatabase
|
||||
filePath: $(Build.SourcesDirectory)\tools\PGODatabase\restore-pgodb.ps1
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
@@ -45,6 +68,9 @@ steps:
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Check MSIX for common regressions'
|
||||
# PGO runtime needs its own CRT and it's in the package for convenience.
|
||||
# That will make this script mad so skip since we're not shipping the PGO Instrumentation one anyway.
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
@@ -53,6 +79,7 @@ steps:
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'Source Index PDBs'
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
@@ -68,13 +95,25 @@ steps:
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Validate binaries are optimized'
|
||||
condition: eq(variables['pgoBuildMode'], 'Optimize')
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Binaries = 'OpenConsole.exe', 'WindowsTerminal.exe', 'TerminalApp.dll', 'TerminalConnection.dll', 'Microsoft.Terminal.Control.dll', 'Microsoft.Terminal.Remoting.dll', 'Microsoft.Terminal.Settings.Editor.dll', 'Microsoft.Terminal.Settings.Model.dll'
|
||||
foreach ($BinFile in $Binaries)
|
||||
{
|
||||
& "$(Build.SourcesDirectory)\tools\PGODatabase\verify-pgo.ps1" "$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/$BinFile"
|
||||
}
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Unit Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}'
|
||||
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Feature Tests (x64 only)'
|
||||
@@ -82,7 +121,7 @@ steps:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}'
|
||||
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
|
||||
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), eq(variables['BuildPlatform'], 'x64'))
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Convert Test Logs from WTL to xUnit format'
|
||||
@@ -90,13 +129,14 @@ steps:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\ConvertWttLogToXUnit.ps1
|
||||
arguments: -WttInputPath '${{ parameters.testLogPath }}' -WttSingleRerunInputPath 'unused.wtl' -WttMultipleRerunInputPath 'unused2.wtl' -XUnitOutputPath 'onBuildMachineResults.xml' -TestNamePrefix '$(BuildConfiguration).$(BuildPlatform)'
|
||||
condition: or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86'))
|
||||
condition: and(ne(variables['PGOBuildMode'], 'Instrument'),or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Upload converted test logs'
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
|
||||
testResultsFiles: '**/onBuildMachineResults.xml'
|
||||
testResultsFiles: '**/onBuildMachineResults.xml'
|
||||
#searchFolder: '$(System.DefaultWorkingDirectory)' # Optional
|
||||
#mergeTestResults: false # Optional
|
||||
#failTaskOnFailedTests: false # Optional
|
||||
@@ -127,24 +167,47 @@ steps:
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/appx'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
|
||||
condition: succeeded()
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy outputs needed for test runs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
$(Build.SourcesDirectory)/bin/$(BuildPlatform)/$(BuildConfiguration)/*.exe
|
||||
$(Build.SourcesDirectory)/bin/$(BuildPlatform)/$(BuildConfiguration)/*.dll
|
||||
$(Build.SourcesDirectory)/bin/$(BuildPlatform)/$(BuildConfiguration)/*.xml
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.exe
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.dll
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.xml
|
||||
**/Microsoft.VCLibs.*.appx
|
||||
**/TestHostApp/*
|
||||
**/TestHostApp/*.exe
|
||||
**/TestHostApp/*.dll
|
||||
**/TestHostApp/*.xml
|
||||
!**/*.pdb
|
||||
!**/*.ipdb
|
||||
!**/*.obj
|
||||
!**/*.pch
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: and(and(succeeded(), eq(variables['BuildPlatform'], 'x64')), ne(variables['Build.Reason'], 'PullRequest'))
|
||||
condition: succeeded()
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All Build Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
ArtifactName: 'drop'
|
||||
ArtifactName: 'drop'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy PGO databases needed for PGO instrumentation run'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.pgd
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO/$(BuildPlatform)'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All PGO Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO'
|
||||
ArtifactName: 'PGO'
|
||||
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
clean: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Code Formattting Check'
|
||||
displayName: 'Code Formatting Check'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '.\build\scripts\Invoke-FormattingCheck.ps1'
|
||||
|
||||
@@ -12,4 +12,4 @@ steps:
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\GenerateTestProjFile.ps1
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\taef.redist.wlk.10.57.200731005-develop\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
||||
@@ -22,6 +22,7 @@ jobs:
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\UpdateUnreliableTests.ps1
|
||||
@@ -32,6 +33,7 @@ jobs:
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\OutputTestResults.ps1
|
||||
|
||||
@@ -5,24 +5,17 @@ parameters:
|
||||
testSuite: ''
|
||||
# If a Pipeline runs this template more than once, this parameter should be unique per build flavor to differentiate the
|
||||
# the different test runs:
|
||||
helixType: 'test/devtest'
|
||||
helixType: 'test/devtest'
|
||||
artifactName: 'drop'
|
||||
maxParallel: 4
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
taefQuery: ''
|
||||
configuration: ''
|
||||
platform: ''
|
||||
# if 'useBuildOutputFromBuildId' is set, we will default to using a build from this pipeline:
|
||||
useBuildOutputFromPipeline: $(System.DefinitionId)
|
||||
matrix:
|
||||
# Release_x86:
|
||||
# buildPlatform: 'x86'
|
||||
# buildConfiguration: 'release'
|
||||
# openHelixTargetQueues: 'windows.10.amd64.client19h1.open.xaml'
|
||||
# closedHelixTargetQueues: 'windows.10.amd64.client19h1.xaml'
|
||||
Release_x64:
|
||||
buildPlatform: 'x64'
|
||||
buildConfiguration: 'release'
|
||||
openHelixTargetQueues: 'windows.10.amd64.client19h1.open.xaml'
|
||||
closedHelixTargetQueues: 'windows.10.amd64.client19h1.xaml'
|
||||
openHelixTargetQueues: 'windows.10.amd64.client19h1.open.xaml'
|
||||
closedHelixTargetQueues: 'windows.10.amd64.client19h1.xaml'
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.name }}
|
||||
@@ -33,19 +26,21 @@ jobs:
|
||||
timeoutInMinutes: 120
|
||||
strategy:
|
||||
maxParallel: ${{ parameters.maxParallel }}
|
||||
matrix: ${{ parameters.matrix }}
|
||||
variables:
|
||||
buildConfiguration: ${{ parameters.configuration }}
|
||||
buildPlatform: ${{ parameters.platform }}
|
||||
openHelixTargetQueues: ${{ parameters.openHelixTargetQueues }}
|
||||
closedHelixTargetQueues: ${{ parameters.closedHelixTargetQueues }}
|
||||
artifactsDir: $(Build.SourcesDirectory)\Artifacts
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\taef.redist.wlk.10.57.200731005-develop\build\Binaries\$(buildPlatform)
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\$(buildPlatform)
|
||||
helixCommonArgs: '/binaryLogger:$(Build.SourcesDirectory)/${{parameters.name}}.$(buildPlatform).$(buildConfiguration).binlog /p:HelixBuild=$(Build.BuildId).$(buildPlatform).$(buildConfiguration) /p:Platform=$(buildPlatform) /p:Configuration=$(buildConfiguration) /p:HelixType=${{parameters.helixType}} /p:TestSuite=${{parameters.testSuite}} /p:ProjFilesPath=$(Build.ArtifactStagingDirectory) /p:rerunPassesRequiredToAvoidFailure=${{parameters.rerunPassesRequiredToAvoidFailure}}'
|
||||
|
||||
|
||||
steps:
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display build machine environment variables'
|
||||
inputs:
|
||||
filename: 'set'
|
||||
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 5.2.0'
|
||||
inputs:
|
||||
@@ -59,23 +54,23 @@ jobs:
|
||||
nugetConfigPath: nuget.config
|
||||
restoreDirectory: packages
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
- task: DownloadBuildArtifacts@0
|
||||
condition:
|
||||
and(succeeded(),eq(variables['useBuildOutputFromBuildId'],''))
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
downloadPath: '$(artifactsDir)'
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
- task: DownloadBuildArtifacts@0
|
||||
condition:
|
||||
and(succeeded(),ne(variables['useBuildOutputFromBuildId'],''))
|
||||
inputs:
|
||||
inputs:
|
||||
buildType: specific
|
||||
buildVersionToDownload: specific
|
||||
project: $(System.TeamProjectId)
|
||||
pipeline: ${{ parameters.useBuildOutputFromPipeline }}
|
||||
buildId: $(useBuildOutputFromBuildId)
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
downloadPath: '$(artifactsDir)'
|
||||
|
||||
- task: CmdLine@1
|
||||
@@ -90,37 +85,63 @@ jobs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\PrepareHelixPayload.ps1
|
||||
arguments: -Platform '$(buildPlatform)' -Configuration '$(buildConfiguration)' -ArtifactName '${{ parameters.artifactName }}'
|
||||
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display Helix payload contents'
|
||||
inputs:
|
||||
filename: 'dir'
|
||||
arguments: '/s $(Build.SourcesDirectory)\HelixPayload'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Make artifact directories'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\"
|
||||
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\"
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),ne('${{ parameters.testSuite }}','NugetTestSuite'))
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\TerminalApp.LocalTests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-TerminalAppLocalTests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),ne('${{ parameters.testSuite }}','NugetTestSuite'))
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\SettingsModel.LocalTests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-SettingsModelLocalTests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\Conhost.UIA.Tests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-HostTestsUIA.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),or(eq('${{ parameters.testSuite }}','PgoInstrumentationSuite'),eq('${{ parameters.testSuite }}','DevTestSuite')))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\WindowsTerminal.UIA.Tests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-WindowsTerminalUIATests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish generated .proj files'
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Run tests in Helix (open queues)'
|
||||
condition: and(succeeded(),eq(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
@@ -129,3 +150,14 @@ jobs:
|
||||
custom: msbuild
|
||||
arguments: '$(helixCommonArgs) /p:IsExternal=true /p:Creator=Terminal /p:HelixTargetQueues=$(openHelixTargetQueues)'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Run tests in Helix (closed queues)'
|
||||
condition: and(succeeded(),ne(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
command: custom
|
||||
projects: build\Helix\RunTestsInHelix.proj
|
||||
custom: msbuild
|
||||
arguments: '$(helixCommonArgs) /p:HelixTargetQueues=$(closedHelixTargetQueues)'
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# From our friends at MUX: https://github.com/microsoft/microsoft-ui-xaml/blob/main/build/AzurePipelinesTemplates/MUX-BuildAndPublishPGONuGet-Job.yml
|
||||
|
||||
parameters:
|
||||
dependsOn: ''
|
||||
pgoArtifact: PGO
|
||||
|
||||
jobs:
|
||||
- job: BuildAndPublishPGONuGet
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
variables:
|
||||
artifactsPath: $(Build.SourcesDirectory)\Artifacts
|
||||
pgoToolsPath: $(Build.SourcesDirectory)\tools\PGODatabase
|
||||
nuspecPath: $(pgoToolsPath)\NuSpecs
|
||||
nuspecFilename: PGO.nuspec
|
||||
|
||||
steps:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
downloadPath: $(artifactsPath)
|
||||
|
||||
- task: NuGetAuthenticate@0
|
||||
inputs:
|
||||
nuGetServiceConnections: 'Terminal Public Artifact Feed'
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 5.8.0'
|
||||
inputs:
|
||||
versionSpec: 5.8.0
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy pgd files to NuGet build directory'
|
||||
inputs:
|
||||
sourceFolder: $(artifactsPath)\${{ parameters.pgoArtifact }}
|
||||
contents: '**\*.pgd'
|
||||
targetFolder: $(nuspecPath)\tools
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'Generate NuSpec file'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: $(pgoToolsPath)\generate-nuspec.ps1
|
||||
workingDirectory: $(pgoToolsPath)
|
||||
arguments: $(nuspecPath)\$(nuspecFilename).template $(nuspecPath)\$(nuspecFilename)
|
||||
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet pack'
|
||||
inputs:
|
||||
command: pack
|
||||
packagesToPack: '$(nuspecPath)\$(nuspecFilename)'
|
||||
basePath: '$(nuspecPath)'
|
||||
packDestination: '$(Build.ArtifactStagingDirectory)'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet push'
|
||||
inputs:
|
||||
command: push
|
||||
nuGetFeedType: external
|
||||
packagesToPush: $(Build.ArtifactStagingDirectory)/*.nupkg
|
||||
# The actual URL and PAT for this feed is configured at
|
||||
# https://microsoft.visualstudio.com/Dart/_settings/adminservices
|
||||
# This is the name of that connection
|
||||
publishFeedCredentials: 'Terminal Public Artifact Feed'
|
||||
feedsToUse: config
|
||||
nugetConfigPath: '$(Build.SourcesDirectory)/NuGet.config'
|
||||
90
build/pipelines/templates/pgo-merge-pgd-job.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
parameters:
|
||||
dependsOn: ''
|
||||
pgoArtifact: PGO
|
||||
platform: ''
|
||||
|
||||
jobs:
|
||||
- job: MergePGD
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
variables:
|
||||
artifactsPath: $(Build.SourcesDirectory)\Artifacts
|
||||
pgoArtifactsPath: $(artifactsPath)\${{ parameters.pgoArtifact }}
|
||||
buildPlatform: ${{ parameters.platform }}
|
||||
|
||||
steps:
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
downloadPath: $(artifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge WindowsTerminal*.pgc WindowsTerminal.pgd
|
||||
displayName: 'Merge Terminal pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge OpenConsole*.pgc OpenConsole.pgd
|
||||
displayName: 'Merge OpenConsole pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge Microsoft.Terminal.Control*.pgc Microsoft.Terminal.Control.pgd
|
||||
displayName: 'Merge Microsoft.Terminal.Control pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge Microsoft.Terminal.Remoting*.pgc Microsoft.Terminal.Remoting.pgd
|
||||
displayName: 'Merge Microsoft.Terminal.Remoting pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge Microsoft.Terminal.Settings.Editor*.pgc Microsoft.Terminal.Settings.Editor.pgd
|
||||
displayName: 'Merge Microsoft.Terminal.Settings.Editor pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge Microsoft.Terminal.Settings.Model*.pgc Microsoft.Terminal.Settings.Model.pgd
|
||||
displayName: 'Merge Microsoft.Terminal.Settings.Model pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge TerminalApp*.pgc TerminalApp.pgd
|
||||
displayName: 'Merge TerminalApp pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- script: |
|
||||
cd $(buildPlatform)
|
||||
"%VCToolsInstallDir%\bin\hostx64\x64\pgomgr.exe" /merge TerminalConnection*.pgc TerminalConnection.pgd
|
||||
displayName: 'Merge TerminalConnection pgc files into pgd'
|
||||
workingDirectory: $(pgoArtifactsPath)
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy merged pgd to artifact staging'
|
||||
inputs:
|
||||
sourceFolder: $(pgoArtifactsPath)
|
||||
contents: '**\$(buildPlatform)\*.pgd'
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
@@ -1,74 +0,0 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
|
||||
jobs:
|
||||
- job: SignDeploy${{ parameters.configuration }}
|
||||
displayName: Sign and Deploy for ${{ parameters.configuration }}
|
||||
|
||||
dependsOn:
|
||||
- Buildx64AuditMode
|
||||
- Buildx64Release
|
||||
- Buildx86Release
|
||||
- Buildarm64Release
|
||||
- CodeFormatCheck
|
||||
condition: |
|
||||
and
|
||||
(
|
||||
in(dependencies.Buildx64AuditMode.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.Buildx64Release.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.Buildx86Release.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.Buildarm64Release.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.CodeFormatCheck.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
|
||||
)
|
||||
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
AppxProjectName: CascadiaPackage
|
||||
AppxBundleName: Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle
|
||||
|
||||
pool:
|
||||
name: Package ES Lab E
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
|
||||
- task: PkgESSetupBuild@10
|
||||
displayName: 'Package ES - Setup Build'
|
||||
inputs:
|
||||
useDfs: false
|
||||
productName: WindowsTerminal
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: 'Component Detection'
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download AppX artifacts
|
||||
inputs:
|
||||
artifactName: 'appx-$(BuildConfiguration)'
|
||||
itemPattern: |
|
||||
**/*.appx
|
||||
**/*.msix
|
||||
downloadPath: '$(Build.ArtifactStagingDirectory)\appx'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Create $(AppxBundleName)'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '.\build\scripts\Create-AppxBundle.ps1'
|
||||
arguments: |
|
||||
-InputPath "$(Build.ArtifactStagingDirectory)\appx" -ProjectName $(AppxProjectName) -BundleVersion 0.0.0.0 -OutputPath "$(Build.ArtifactStagingDirectory)\$(AppxBundleName)"
|
||||
|
||||
- task: PkgESCodeSign@10
|
||||
displayName: 'Package ES - SignConfig.WindowsTerminal.xml'
|
||||
inputs:
|
||||
signConfigXml: 'build\config\SignConfig.WindowsTerminal.xml'
|
||||
inPathRoot: '$(Build.ArtifactStagingDirectory)'
|
||||
outPathRoot: '$(Build.ArtifactStagingDirectory)\signed'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Signed AppX'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)\signed'
|
||||
ArtifactName: 'appxbundle-signed-$(BuildConfiguration)'
|
||||
97
build/rules/GenerateFeatureFlags.proj
Normal file
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- THIS PROJECT CANNOT BE LOADED INTO THE SOLUTION. -->
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Any CPU">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Fuzzing|Any CPU">
|
||||
<Configuration>Fuzzing</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="AuditMode|Any CPU">
|
||||
<Configuration>AuditMode</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Any CPU">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>d97c3c61-53cd-4e72-919b-9a0940e038f9</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<IntermediateOutputPath>$(SolutionDir)obj\$(Configuration)\GenerateFeatureFlags\</IntermediateOutputPath>
|
||||
<OpenConsoleCommonOutDir>$(SolutionDir)bin\$(Configuration)\</OpenConsoleCommonOutDir>
|
||||
|
||||
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Preview'">Preview</_WTBrandingName>
|
||||
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Release'">Release</_WTBrandingName>
|
||||
<_WTBrandingName Condition="'$(_WTBrandingName)'==''">Dev</_WTBrandingName>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="_GenerateBranchAndBrandingCache">
|
||||
<Exec Command="git.exe rev-parse --abbrev-ref HEAD"
|
||||
CustomWarningRegularExpression="^fatal:.*"
|
||||
ConsoleToMsBuild="true"
|
||||
IgnoreExitCode="true">
|
||||
<Output TaskParameter="ConsoleOutput" ItemName="_GitBranchLines" />
|
||||
</Exec>
|
||||
|
||||
<ItemGroup>
|
||||
<_BrandingLines Include="$(_WTBrandingName)" />
|
||||
</ItemGroup>
|
||||
|
||||
<WriteLinesToFile File="$(IntermediateOutputPath)branch_branding_cache.txt"
|
||||
Lines="@(_GitBranchLines);@(_BrandingLines)"
|
||||
Overwrite="true"
|
||||
WriteOnlyWhenDifferent="true" />
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="$(IntermediateOutputPath)branch_branding_cache.txt" />
|
||||
<_BranchBrandingCacheFiles Include="$(IntermediateOutputPath)branch_branding_cache.txt" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_RunFeatureFlagScript"
|
||||
Inputs="@(FeatureFlagFile);@(_BranchBrandingCacheFiles)"
|
||||
Outputs="$(OpenConsoleCommonOutDir)\inc\TilFeatureStaging.h"
|
||||
DependsOnTargets="_GenerateBranchAndBrandingCache">
|
||||
<MakeDir Directories="$(OpenConsoleCommonOutDir)\inc" />
|
||||
<Exec
|
||||
Command="powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy ByPass -Command "$(SolutionDir)\tools\Generate-FeatureStagingHeader.ps1" -Path "%(FeatureFlagFile.FullPath)" -Branding $(_WTBrandingName)"
|
||||
ConsoleToMsBuild="true"
|
||||
StandardOutputImportance="low">
|
||||
<Output TaskParameter="ConsoleOutput" ItemName="_FeatureFlagFileLines" />
|
||||
</Exec>
|
||||
|
||||
<!--
|
||||
We gather the feature flag output in MSBuild and emit the file so that we can take advantage of
|
||||
WriteOnlyWhenDifferent. Doing this ensures that we don't rebuild the world when the branch changes
|
||||
(if it results in a new TilFeatureStaging.h that would have had the same content/features as the previous one)
|
||||
-->
|
||||
|
||||
<WriteLinesToFile File="$(OpenConsoleCommonOutDir)\inc\TilFeatureStaging.h"
|
||||
Lines="@(_FeatureFlagFileLines)"
|
||||
Overwrite="true"
|
||||
WriteOnlyWhenDifferent="true" />
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="$(OpenConsoleCommonOutDir)\inc\TilFeatureStaging.h" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="Build" DependsOnTargets="_RunFeatureFlagScript" />
|
||||
<Target Name="Clean">
|
||||
<Delete Files="$(OpenConsoleCommonOutDir)\inc\TilFeatureStaging.h" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<FeatureFlagFile Include="$(SolutionDir)\src\features.xml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -22,7 +22,7 @@ Param(
|
||||
[Parameter(HelpMessage="Path to makeappx.exe")]
|
||||
[ValidateScript({Test-Path $_ -Type Leaf})]
|
||||
[string]
|
||||
$MakeAppxPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\MakeAppx.exe"
|
||||
$MakeAppxPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86\MakeAppx.exe"
|
||||
)
|
||||
|
||||
If ($null -Eq (Get-Item $MakeAppxPath -EA:SilentlyContinue)) {
|
||||
|
||||
@@ -3,12 +3,24 @@
|
||||
# Checks for code formatting errors. Will throw exception if any are found.
|
||||
function Invoke-CheckBadCodeFormatting() {
|
||||
Import-Module ./tools/OpenConsole.psm1
|
||||
Invoke-CodeFormat
|
||||
|
||||
# Don't run the XAML formatter in this step - even if it changes nothing,
|
||||
# it'll still touch all the .xaml files.
|
||||
Invoke-CodeFormat -IgnoreXaml
|
||||
|
||||
# returns a non-zero exit code if there are any diffs in the tracked files in the repo
|
||||
git diff-index --quiet HEAD --
|
||||
if ($lastExitCode -eq 1) {
|
||||
|
||||
# Write the list of files that need updating to the log
|
||||
git diff-index --name-only HEAD
|
||||
|
||||
throw "code formatting bad, run Invoke-CodeFormat on branch"
|
||||
}
|
||||
|
||||
# Manually check the formatting of our .xaml files, without touching them.
|
||||
Test-XamlFormat
|
||||
|
||||
}
|
||||
|
||||
Invoke-CheckBadCodeFormatting
|
||||
|
||||
@@ -8,7 +8,7 @@ Param(
|
||||
[Parameter(HelpMessage="Path to Windows Kit")]
|
||||
[ValidateScript({Test-Path $_ -Type Leaf})]
|
||||
[string]
|
||||
$WindowsKitPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0"
|
||||
$WindowsKitPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
@@ -58,7 +58,7 @@ Try {
|
||||
|
||||
### Check the activatable class entries for a few DLLs we need.
|
||||
$inProcServers = $Manifest.Package.Extensions.Extension.InProcessServer.Path
|
||||
$RequiredInProcServers = ("TerminalApp.dll", "TerminalControl.dll", "TerminalConnection.dll")
|
||||
$RequiredInProcServers = ("TerminalApp.dll", "Microsoft.Terminal.Control.dll", "Microsoft.Terminal.Remoting.dll", "Microsoft.Terminal.Settings.Editor.dll", "Microsoft.Terminal.Settings.Model.dll", "TerminalConnection.dll")
|
||||
|
||||
Write-Verbose "InProc Servers: $inProcServers"
|
||||
|
||||
|
||||
@@ -19,9 +19,13 @@
|
||||
"/.github/",
|
||||
"/samples/",
|
||||
"/res/terminal/",
|
||||
"/res/fonts/",
|
||||
"/doc/specs/",
|
||||
"/doc/cascadia/",
|
||||
"/doc/user-docs/"
|
||||
"/doc/user-docs/",
|
||||
"/src/tools/MonarchPeasantSample/",
|
||||
"/scratch/",
|
||||
"Scratch.sln",
|
||||
],
|
||||
"SuffixFilters": [
|
||||
".dbb",
|
||||
@@ -37,6 +41,7 @@
|
||||
".wrn",
|
||||
".rec",
|
||||
".err",
|
||||
"XamlStyler.json",
|
||||
".xlsx"
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<!-- This file is read by XES, which we use in our Release builds. -->
|
||||
<PropertyGroup Label="Version">
|
||||
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
|
||||
<XesBaseYearForStoreVersion>2020</XesBaseYearForStoreVersion>
|
||||
<XesBaseYearForStoreVersion>2021</XesBaseYearForStoreVersion>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>5</VersionMinor>
|
||||
<VersionMinor>12</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
2
dep/wil
@@ -5,13 +5,13 @@
|
||||
`.../console/published/wincon.w` in the OS repo when you submit the PR.
|
||||
The branch won't build without it.
|
||||
* For now, you can update winconp.h with your consumable changes.
|
||||
* define registry name (ex `CONSOLE_REGISTRY_CURSORCOLOR`)
|
||||
* add the setting to `CONSOLE_STATE_INFO`
|
||||
* define the property key ID and the property key itself
|
||||
* Define registry name (ex `CONSOLE_REGISTRY_CURSORCOLOR`)
|
||||
* Add the setting to `CONSOLE_STATE_INFO`
|
||||
* Define the property key ID and the property key itself.
|
||||
- Yes, the large majority of the `DEFINE_PROPERTYKEY` defs are the same, it's only the last byte of the guid that changes
|
||||
|
||||
2. Add matching fields to Settings.hpp
|
||||
- add getters, setters, the whole drill.
|
||||
- Add getters, setters, the whole drill.
|
||||
|
||||
3. Add to the propsheet
|
||||
- We need to add it to *reading and writing* the registry from the propsheet, and *reading* the link from the propsheet. Yes, that's weird, but the propsheet is smart enough to re-use ShortcutSerialization::s_SetLinkValues, but not smart enough to do the same with RegistrySerialization.
|
||||
|
||||
20
doc/TAEF.md
@@ -12,11 +12,11 @@ Use the [TAEF Verify Macros for C++](https://docs.microsoft.com/en-us/windows-ha
|
||||
|
||||
### Running Tests
|
||||
|
||||
If you have Visual Studio and related C++ components installed, and you have successfully restored NuGets, you should have the TAEF test runner `te.exe` available locally as part of the `Taef.Redist.Wlk` package.
|
||||
If you have Visual Studio and related C++ components installed, and you have successfully restored NuGets, you should have the TAEF test runner `te.exe` available locally as part of the `Microsoft.Taef` package.
|
||||
|
||||
> Note that you cannot easily run TAEF tests directly through Visual Studio. The `Taef.Redist.Wlk` NuGet package comes with an adapter that will let you browse and execute TAEF tests inside of Visual Studio, but its performance and reliability prevent us from recommending it here.
|
||||
> Note that you cannot easily run TAEF tests directly through Visual Studio. The `Microsoft.Taef` NuGet package comes with an adapter that will let you browse and execute TAEF tests inside of Visual Studio, but its performance and reliability prevent us from recommending it here.
|
||||
|
||||
In a "normal" CMD environment, `te.exe` may not be directly available. Try the following command to set up the development enviroment first:
|
||||
In a "normal" CMD environment, `te.exe` may not be directly available. Try the following command to set up the development environment first:
|
||||
|
||||
```shell
|
||||
.\tools\razzle.cmd
|
||||
@@ -48,3 +48,17 @@ Invoke-OpenConsoleTests
|
||||
```
|
||||
|
||||
`Invoke-OpenConsoleTests` supports a number of options, which you can enumerate by running `Invoke-OpenConsoleTests -?`.
|
||||
|
||||
|
||||
### Debugging Tests
|
||||
|
||||
If you want to debug a test, you can do so by using the TAEF /waitForDebugger flag, such as:
|
||||
|
||||
runut *Tests.dll /name:TextBufferTests::TestInsertCharacter /waitForDebugger
|
||||
|
||||
Replace the test name with the one you want to debug. Then, TAEF will begin executing the test and output something like this:
|
||||
|
||||
TAEF: Waiting for debugger - PID <some PID> @ IP <some IP address>
|
||||
|
||||
You can then attach to that PID in your debugger of choice. In Visual Studio, you can use Debug -> Attach To Process, or you could use WinDbg or whatever you want.
|
||||
Once the debugger attaches, the test will execute and your breakpoints will be hit.
|
||||
|
||||
@@ -9,13 +9,13 @@ The primary usages of WIL in our code so far are...
|
||||
|
||||
### Smart Pointers ###
|
||||
|
||||
Inside [wil\resource.h](https://github.com/microsoft/wil/blob/master/include/wil/resource.h) are smart pointer like classes for many Windows OS resources like file handles, socket handles, process handles, and so on. They're of the form `wil::unique_handle` and call the appropriate/matching OS function (like `CloseHandle()` in this case) when they go out of scope.
|
||||
Inside [wil/resource.h](https://github.com/microsoft/wil/blob/master/include/wil/resource.h) are smart pointer like classes for many Windows OS resources like file handles, socket handles, process handles, and so on. They're of the form `wil::unique_handle` and call the appropriate/matching OS function (like `CloseHandle()` in this case) when they go out of scope.
|
||||
|
||||
Another useful item is `wil::make_unique_nothrow()` which is analogous to `std::make_unique` (except without the exception which might help you integrate with existing exception-free code in the console.) This will return a `wistd::unique_ptr` (vs. a `std::unique_ptr`) which can be used in a similar manner.
|
||||
|
||||
### Result Handling ###
|
||||
|
||||
To manage the various types of result codes that come back from Windows APIs, the file [wil\result.h](https://github.com/microsoft/wil/blob/master/include/wil/result.h) provides a wealth of macros that can help.
|
||||
To manage the various types of result codes that come back from Windows APIs, the file [wil/result.h](https://github.com/microsoft/wil/blob/master/include/wil/result.h) provides a wealth of macros that can help.
|
||||
|
||||
As an example, the method `DuplicateHandle()` returns a `BOOL` value that is `FALSE` under failure and would like you to `GetLastError()` from the operating system to find out what the actual result code is. In this circumstance, you could use the macro `RETURN_IF_WIN32_BOOL_FALSE` to wrap the call to `DuplicateHandle()` which would automatically handle this pattern for you and return the `HRESULT` equivalent on failure.
|
||||
|
||||
|
||||
@@ -127,4 +127,4 @@ When a release is created, if the PR ID number is linked inside the release desc
|
||||
- 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/)
|
||||
[Here](https://portal.fabricbot.ms/bot/?repo=microsoft/terminal)
|
||||
|
||||
@@ -9,7 +9,13 @@ git submodule update --init --recursive
|
||||
|
||||
OpenConsole.sln may be built from within Visual Studio or from the command-line using a set of convenience scripts & tools in the **/tools** directory:
|
||||
|
||||
When using Visual Studio, be sure to set up the path for code formatting. This can be done in Visual Studio by going to Tools > Options > Text Editor > C++ > Formatting and checking "Use custom clang-format.exe file" and choosing the clang-format.exe in the repository at /dep/llvm/clang-format.exe by clicking "browse" right under the check box.
|
||||
When using Visual Studio, be sure to set up the path for code formatting. To download the required clang-format.exe file, follow one of the building instructions below and run:
|
||||
```powershell
|
||||
Import-Module .\tools\OpenConsole.psm1
|
||||
Set-MsBuildDevEnvironment
|
||||
Get-Format
|
||||
```
|
||||
After, go to Tools > Options > Text Editor > C++ > Formatting and checking "Use custom clang-format.exe file" in Visual Studio and choose the clang-format.exe in the repository at /packages/clang-format.win-x86.10.0.0/tools/clang-format.exe by clicking "browse" right under the check box.
|
||||
|
||||
### Building in PowerShell
|
||||
|
||||
|
||||
397
doc/cascadia/AddASetting.md
Normal file
@@ -0,0 +1,397 @@
|
||||
# Adding Settings to Windows Terminal
|
||||
|
||||
Adding a setting to Windows Terminal is fairly straightforward. This guide serves as a reference on how to add a setting.
|
||||
|
||||
## 1. Terminal Settings Model
|
||||
|
||||
The Terminal Settings Model (`Microsoft.Terminal.Settings.Model`) is responsible for (de)serializing and exposing settings.
|
||||
|
||||
### `INHERITABLE_SETTING` macro
|
||||
|
||||
The `INHERITABLE_SETTING` macro can be used to implement inheritance for your new setting and store the setting in the settings model. It takes three parameters:
|
||||
- `type`: the type that the setting will be stored as
|
||||
- `name`: the name of the variable for storage
|
||||
- `defaultValue`: the value to use if the user does not define the setting anywhere
|
||||
|
||||
### Adding a Profile setting
|
||||
|
||||
This tutorial will add `CloseOnExitMode CloseOnExit` as a profile setting.
|
||||
|
||||
1. In `Profile.h`, declare/define the setting:
|
||||
|
||||
```c++
|
||||
INHERITABLE_SETTING(CloseOnExitMode, CloseOnExit, CloseOnExitMode::Graceful)
|
||||
```
|
||||
|
||||
2. In `Profile.idl`, expose the setting via WinRT:
|
||||
|
||||
```c++
|
||||
Boolean HasCloseOnExit();
|
||||
void ClearCloseOnExit();
|
||||
CloseOnExitMode CloseOnExit;
|
||||
```
|
||||
|
||||
3. In `Profile.cpp`, add (de)serialization and copy logic:
|
||||
|
||||
```c++
|
||||
// Top of file:
|
||||
// - Add the serialization key
|
||||
static constexpr std::string_view CloseOnExitKey{ "closeOnExit" };
|
||||
|
||||
// CopySettings() or Copy():
|
||||
// - The setting is exposed in the Settings UI
|
||||
profile->_CloseOnExit = source->_CloseOnExit;
|
||||
|
||||
// LayerJson():
|
||||
// - get the value from the JSON
|
||||
JsonUtils::GetValueForKey(json, CloseOnExitKey, _CloseOnExit);
|
||||
|
||||
// ToJson():
|
||||
// - write the value to the JSON
|
||||
JsonUtils::SetValueForKey(json, CloseOnExitKey, _CloseOnExit);
|
||||
```
|
||||
|
||||
- If the setting is not a primitive type, in `TerminalSettingsSerializationHelpers.h` add (de)serialization logic for the accepted values:
|
||||
|
||||
```c++
|
||||
// For enum values...
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::CloseOnExitMode)
|
||||
{
|
||||
JSON_MAPPINGS(3) = {
|
||||
pair_type{ "always", ValueType::Always },
|
||||
pair_type{ "graceful", ValueType::Graceful },
|
||||
pair_type{ "never", ValueType::Never },
|
||||
};
|
||||
};
|
||||
|
||||
// For enum flag values...
|
||||
JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::TerminalControl::CopyFormat)
|
||||
{
|
||||
JSON_MAPPINGS(5) = {
|
||||
pair_type{ "none", AllClear },
|
||||
pair_type{ "html", ValueType::HTML },
|
||||
pair_type{ "rtf", ValueType::RTF },
|
||||
pair_type{ "all", AllSet },
|
||||
};
|
||||
};
|
||||
|
||||
// NOTE: This is also where you can add functionality for...
|
||||
// - overloaded type support (i.e. accept a bool and an enum)
|
||||
// - custom (de)serialization logic (i.e. coordinates)
|
||||
```
|
||||
|
||||
### Adding a Global setting
|
||||
|
||||
Follow the "adding a Profile setting" instructions above, but do it on the `GlobalAppSettings` files.
|
||||
|
||||
### Adding an Action
|
||||
|
||||
This tutorial will add the `openSettings` action.
|
||||
|
||||
1. In `KeyMapping.idl`, declare the action:
|
||||
|
||||
```c++
|
||||
// Add the action to ShortcutAction
|
||||
enum ShortcutAction
|
||||
{
|
||||
OpenSettings
|
||||
}
|
||||
```
|
||||
|
||||
2. In `ActionAndArgs.cpp`, add serialization logic:
|
||||
|
||||
```c++
|
||||
// Top of file:
|
||||
// - Add the serialization key
|
||||
static constexpr std::string_view OpenSettingsKey{ "openSettings" };
|
||||
|
||||
// ActionKeyNamesMap:
|
||||
// - map the new enum to the json key
|
||||
{ OpenSettingsKey, ShortcutAction::OpenSettings },
|
||||
```
|
||||
|
||||
3. If the action should automatically generate a name when it appears in the Command Palette...
|
||||
```c++
|
||||
// In ActionAndArgs.cpp GenerateName() --> GeneratedActionNames
|
||||
{ ShortcutAction::OpenSettings, RS_(L"OpenSettingsCommandKey") },
|
||||
|
||||
// In Resources.resw for Microsoft.Terminal.Settings.Model.Lib,
|
||||
// add the generated name
|
||||
// NOTE: Visual Studio presents the resw file as a table.
|
||||
// If you choose to edit the file with a text editor,
|
||||
// the code should look something like this...
|
||||
<data name="OpenSettingsCommandKey" xml:space="preserve">
|
||||
<value>Open settings file</value>
|
||||
</data>
|
||||
```
|
||||
|
||||
4. If the action supports arguments...
|
||||
- In `ActionArgs.idl`, declare the arguments
|
||||
```c++
|
||||
[default_interface] runtimeclass OpenSettingsArgs : IActionArgs
|
||||
{
|
||||
// this declares the "target" arg
|
||||
SettingsTarget Target { get; };
|
||||
};
|
||||
```
|
||||
- In `ActionArgs.h`, define the new runtime class
|
||||
```c++
|
||||
struct OpenSettingsArgs : public OpenSettingsArgsT<OpenSettingsArgs>
|
||||
{
|
||||
OpenSettingsArgs() = default;
|
||||
|
||||
// adds a getter/setter for your argument, and defines the json key
|
||||
WINRT_PROPERTY(SettingsTarget, Target, SettingsTarget::SettingsFile);
|
||||
static constexpr std::string_view TargetKey{ "target" };
|
||||
|
||||
public:
|
||||
hstring GenerateName() const;
|
||||
|
||||
bool Equals(const IActionArgs& other)
|
||||
{
|
||||
auto otherAsUs = other.try_as<OpenSettingsArgs>();
|
||||
if (otherAsUs)
|
||||
{
|
||||
return otherAsUs->_Target == _Target;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
static FromJsonResult FromJson(const Json::Value& json)
|
||||
{
|
||||
// LOAD BEARING: Not using make_self here _will_ break you in the future!
|
||||
auto args = winrt::make_self<OpenSettingsArgs>();
|
||||
JsonUtils::GetValueForKey(json, TargetKey, args->_Target);
|
||||
return { *args, {} };
|
||||
}
|
||||
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<OpenSettingsArgs>() };
|
||||
copy->_Target = _Target;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
```
|
||||
- In `ActionArgs.cpp`, define `GenerateName()`. This is used to automatically generate a name when it appears in the Command Palette.
|
||||
- In `ActionAndArgs.cpp`, add serialization logic:
|
||||
|
||||
```c++
|
||||
// ActionKeyNamesMap --> argParsers
|
||||
{ ShortcutAction::OpenSettings, OpenSettingsArgs::FromJson },
|
||||
```
|
||||
|
||||
### Adding an Action Argument
|
||||
|
||||
Follow step 3 from the "adding an Action" instructions above, but modify the relevant `ActionArgs` files.
|
||||
|
||||
## 2. Setting Functionality
|
||||
|
||||
Now that the Terminal Settings Model is updated, Windows Terminal can read and write to the settings file. This section covers how to add functionality to your newly created setting.
|
||||
|
||||
### App-level settings
|
||||
|
||||
App-level settings are settings that affect the frame of Windows Terminal. Generally, these tend to be global settings. The `TerminalApp` project is responsible for presenting the frame of Windows Terminal. A few files of interest include:
|
||||
- `TerminalPage`: XAML control responsible for the look and feel of Windows Terminal
|
||||
- `AppLogic`: WinRT class responsible for window-related issues (i.e. the titlebar, focus mode, etc...)
|
||||
|
||||
Both have access to a `CascadiaSettings` object, for you to read the loaded setting and update Windows Terminal appropriately.
|
||||
|
||||
### Terminal-level settings
|
||||
|
||||
Terminal-level settings are settings that affect a shell session. Generally, these tend to be profile settings. The `TerminalApp` project is responsible for packaging this settings from the Terminal Settings Model to the terminal instance. There are two kinds of settings here:
|
||||
- `IControlSettings`:
|
||||
- These are settings that affect the `TerminalControl` (a XAML control that hosts a shell session).
|
||||
- Examples include background image customization, interactivity behavior (i.e. selection), acrylic and font customization.
|
||||
- The `TerminalControl` project has access to these settings via a saved `IControlSettings` member.
|
||||
- `ICoreSettings`:
|
||||
- These are settings that affect the `TerminalCore` (a lower level object that interacts with the text buffer).
|
||||
- Examples include initial size, history size, and cursor customization.
|
||||
- The `TerminalCore` project has access to these settings via a saved `ICoreSettings` member.
|
||||
|
||||
`TerminalApp` packages these settings into a `TerminalSettings : IControlSettings, ICoreSettings` object upon creating a new terminal instance. To do so, you must submit the following changes:
|
||||
- Declare the setting in `IControlSettings.idl` or `ICoreSettings.idl` (whichever is relevant to your setting). If your setting is an enum setting, declare the enum here instead of in the `TerminalSettingsModel` project.
|
||||
- In `TerminalSettings.h`, declare/define the setting...
|
||||
```c++
|
||||
// The WINRT_PROPERTY macro declares/defines a getter setter for the setting.
|
||||
// Like INHERITABLE_SETTING, it takes in a type, name, and defaultValue.
|
||||
WINRT_PROPERTY(bool, UseAcrylic, false);
|
||||
```
|
||||
- In `TerminalSettings.cpp`...
|
||||
- update `_ApplyProfileSettings` for profile settings
|
||||
- update `_ApplyGlobalSettings` for global settings
|
||||
- If additional processing is necessary, that would happen here. For example, `backgroundImageAlignment` is stored as a `ConvergedAlignment` in the Terminal Settings Model, but converted into XAML's separate horizontal and vertical alignment enums for packaging.
|
||||
|
||||
### Actions
|
||||
|
||||
Actions are packaged as an `ActionAndArgs` object, then handled in `TerminalApp`. To add functionality for actions...
|
||||
- In the `ShortcutActionDispatch` files, dispatch an event when the action occurs...
|
||||
```c++
|
||||
// ShortcutActionDispatch.idl
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> OpenSettings;
|
||||
|
||||
// ShortcutActionDispatch.h
|
||||
TYPED_EVENT(OpenSettings, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
|
||||
// ShortcutActionDispatch.cpp --> DoAction()
|
||||
// - dispatch the appropriate event
|
||||
case ShortcutAction::OpenSettings:
|
||||
{
|
||||
_OpenSettingsHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
```
|
||||
- In `TerminalPage` files, handle the event...
|
||||
```c++
|
||||
// TerminalPage.h
|
||||
// - declare the handler
|
||||
void _HandleOpenSettings(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
|
||||
// TerminalPage.cpp --> _RegisterActionCallbacks()
|
||||
// - register the handler
|
||||
_actionDispatch->OpenSettings({ this, &TerminalPage::_HandleOpenSettings });
|
||||
|
||||
// AppActionHandlers.cpp
|
||||
// - direct the function to the right place and call a helper function
|
||||
void TerminalPage::_HandleOpenSettings(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
// NOTE: this if-statement can be omitted if the action does not support arguments
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<OpenSettingsArgs>())
|
||||
{
|
||||
_LaunchSettings(realArgs.Target());
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`AppActionHandlers` vary based on the action you want to perform. A few useful helper functions include:
|
||||
- `_GetFocusedTab()`: retrieves the focused tab
|
||||
- `_GetActiveControl()`: retrieves the active terminal control
|
||||
- `_GetTerminalTabImpl()`: tries to cast the given tab as a `TerminalTab` (a tab that hosts a terminal instance)
|
||||
|
||||
|
||||
## 3. Settings UI
|
||||
|
||||
### Exposing Enum Settings
|
||||
If the new setting supports enums, you need to expose a map of the enum and the respective value in the Terminal Settings Model's `EnumMappings`:
|
||||
|
||||
```c++
|
||||
// EnumMappings.idl
|
||||
static Windows.Foundation.Collections.IMap<String, Microsoft.Terminal.Settings.Model.CloseOnExitMode> CloseOnExitMode { get; };
|
||||
|
||||
// EnumMappings.h
|
||||
static winrt::Windows::Foundation::Collections::IMap<winrt::hstring, CloseOnExitMode> CloseOnExitMode();
|
||||
|
||||
// EnumMappings.cpp
|
||||
// - this macro leverages the json enum mapper in TerminalSettingsSerializationHelper to expose
|
||||
// the mapped values across project boundaries
|
||||
DEFINE_ENUM_MAP(Model::CloseOnExitMode, CloseOnExitMode);
|
||||
```
|
||||
|
||||
### Binding and Localizing the Enum Setting
|
||||
|
||||
Find the page in the Settings UI that the new setting fits best in. In this example, we are adding `LaunchMode`.
|
||||
1. In `Launch.idl`, expose the bindable setting...
|
||||
```c++
|
||||
// Expose the current value for the setting
|
||||
IInspectable CurrentLaunchMode;
|
||||
|
||||
// Expose the list of possible values
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> LaunchModeList { get; };
|
||||
```
|
||||
|
||||
2. In `Launch.h`, declare the bindable enum setting...
|
||||
```c++
|
||||
// the GETSET_BINDABLE_ENUM_SETTING macro accepts...
|
||||
// - name: the name of the setting
|
||||
// - enumType: the type of the setting
|
||||
// - settingsModelName: how to retrieve the setting (use State() to get access to the settings model)
|
||||
// - settingNameInModel: the name of the setting in the terminal settings model
|
||||
GETSET_BINDABLE_ENUM_SETTING(LaunchMode, Model::LaunchMode, State().Settings().GlobalSettings, LaunchMode);
|
||||
```
|
||||
|
||||
3. In `Launch.cpp`, populate these functions...
|
||||
```c++
|
||||
// Constructor (after InitializeComponent())
|
||||
// the INITIALIZE_BINDABLE_ENUM_SETTING macro accepts...
|
||||
// - name: the name of the setting
|
||||
// - enumMappingsName: the name from the TerminalSettingsModel's EnumMappings
|
||||
// - enumType: the type for the enum
|
||||
// - resourceSectionAndType: prefix for the localization
|
||||
// - resourceProperty: postfix for the localization
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(LaunchMode, LaunchMode, LaunchMode, L"Globals_LaunchMode", L"Content");
|
||||
```
|
||||
|
||||
4. In `Resources.resw` for Microsoft.Terminal.Settings.Editor, add the localized text to expose each enum value. Use the following format: `<SettingGroup>_<SettingName><EnumValue>.Content`
|
||||
- `SettingGroup`:
|
||||
- `Globals` for global settings
|
||||
- `Profile` for profile settings
|
||||
- `SettingName`:
|
||||
- the Pascal-case format for the setting type (i.e. `LaunchMode` for `"launchMode"`)
|
||||
- `EnumValue`:
|
||||
- the json key for the setting value, but with the first letter capitalized (i.e. `Focus` for `"focus"`)
|
||||
- The resulting resw key should look something like this `Globals_LaunchModeFocus.Content`
|
||||
- This is the text that will be used in your control
|
||||
|
||||
### Updating the UI
|
||||
|
||||
When adding a setting to the UI, make sure you follow the [UWP design guidance](https://docs.microsoft.com/windows/uwp/design/).
|
||||
|
||||
#### Enum Settings
|
||||
|
||||
Now, create a XAML control in the relevant XAML file. Use the following tips and tricks to style everything appropriately:
|
||||
- Wrap the control in a `ContentPresenter` adhering to the `SettingContainerStyle` style
|
||||
- Bind `SelectedItem` to the relevant `Current<Setting>` (i.e. `CurrentLaunchMode`). Ensure it's a TwoWay binding
|
||||
- Bind `ItemsSource` to `<Setting>List` (i.e. `LaunchModeList`)
|
||||
- Set the ItemTemplate to the `Enum<ControlType>Template` (i.e. `EnumRadioButtonTemplate` for radio buttons)
|
||||
- Set the style to the appropriate one in `CommonResources.xaml`
|
||||
|
||||
```xml
|
||||
<!--Launch Mode-->
|
||||
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
|
||||
<muxc:RadioButtons x:Uid="Globals_LaunchMode"
|
||||
SelectedItem="{x:Bind CurrentLaunchMode, Mode="TwoWay"}"
|
||||
ItemsSource="{x:Bind LaunchModeList}"
|
||||
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
|
||||
Style="{StaticResource RadioButtonsSettingStyle}"/>
|
||||
</ContentPresenter>
|
||||
```
|
||||
|
||||
To add any localized text, add a `x:Uid`, and access the relevant property via the Resources.resw file. For example, `Globals_LaunchMode.Header` sets the header for this control. You can also set the tooltip text like this:
|
||||
`Globals_DefaultProfile.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip`.
|
||||
|
||||
#### Non-Enum Settings
|
||||
|
||||
Continue to reference `CommonResources.xaml` for appropriate styling and wrap the control with a similar `ContentPresenter`. However, instead of binding to the `Current<Setting>` and `<Setting>List`, bind directly to the setting via the state. Binding a setting like `altGrAliasing` should look something like this:
|
||||
```xml
|
||||
<!--AltGr Aliasing-->
|
||||
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
|
||||
<CheckBox x:Uid="Profile_AltGrAliasing"
|
||||
IsChecked="{x:Bind State.Profile.AltGrAliasing, Mode=TwoWay}"
|
||||
Style="{StaticResource CheckBoxSettingStyle}"/>
|
||||
</ContentPresenter>
|
||||
```
|
||||
|
||||
#### Profile Settings
|
||||
|
||||
If you are specifically adding a Profile setting, in addition to the steps above, you need to make the setting observable by modifying the `Profiles` files...
|
||||
```c++
|
||||
// Profiles.idl --> ProfileViewModel
|
||||
// - this declares the setting as observable using the type and the name of the setting
|
||||
OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.Settings.Model.CloseOnExitMode, CloseOnExit);
|
||||
|
||||
// Profiles.h --> ProfileViewModel
|
||||
// - this defines the setting as observable off of the _profile object
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, CloseOnExit);
|
||||
|
||||
// Profiles.h --> ProfileViewModel
|
||||
// - if the setting cannot be inherited by another profile (aka missing the Clear() function), use the following macro instead:
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, Guid);
|
||||
```
|
||||
|
||||
The `ProfilePageNavigationState` holds a `ProfileViewModel`, which wraps the `Profile` object from the Terminal Settings Model. The `ProfileViewModel` makes all of the profile settings observable.
|
||||
|
||||
### Actions
|
||||
|
||||
Actions are not yet supported in the Settings UI.
|
||||
@@ -8,19 +8,20 @@ return a JSON value coerced into the specified type.
|
||||
When reading into existing storage, it returns a boolean indicating whether that storage was modified.
|
||||
|
||||
If the JSON value cannot be converted to the specified type, an exception will be generated.
|
||||
For non-nullable type conversions (most POD types), `null` is considered to be an invalid type.
|
||||
|
||||
```c++
|
||||
std::string one;
|
||||
std::optional<std::string> two;
|
||||
|
||||
JsonUtils::GetValue(json, one);
|
||||
// one is populated or unchanged.
|
||||
// one is populated or an exception is thrown.
|
||||
|
||||
JsonUtils::GetValue(json, two);
|
||||
// two is populated, nullopt or unchanged
|
||||
// two is populated, nullopt or an exception is thrown
|
||||
|
||||
auto three = JsonUtils::GetValue<std::string>(json);
|
||||
// three is populated or zero-initialized
|
||||
// three is populated or an exception is thrown
|
||||
|
||||
auto four = JsonUtils::GetValue<std::optional<std::string>>(json);
|
||||
// four is populated or nullopt
|
||||
@@ -225,14 +226,14 @@ auto v = JsonUtils::GetValue<int>(json, conv);
|
||||
|
||||
-|json type invalid|json null|valid
|
||||
-|-|-|-
|
||||
`T`|❌ exception|🔵 unchanged|✔ converted
|
||||
`T`|❌ exception|❌ exception|✔ converted
|
||||
`std::optional<T>`|❌ exception|🟨 `nullopt`|✔ converted
|
||||
|
||||
### GetValue<T>() (returning)
|
||||
|
||||
-|json type invalid|json null|valid
|
||||
-|-|-|-
|
||||
`T`|❌ exception|🟨 `T{}` (zero value)|✔ converted
|
||||
`T`|❌ exception|❌ exception|✔ converted
|
||||
`std::optional<T>`|❌ exception|🟨 `nullopt`|✔ converted
|
||||
|
||||
### GetValueForKey(T&) (type-deducing)
|
||||
@@ -242,14 +243,14 @@ a "key not found" state. The remaining three cases are the same.
|
||||
|
||||
val type|key not found|_json type invalid_|_json null_|_valid_
|
||||
-|-|-|-|-
|
||||
`T`|🔵 unchanged|_❌ exception_|_🔵 unchanged_|_✔ converted_
|
||||
`std::optional<T>`|_🔵 unchanged_|_❌ exception_|_🟨 `nullopt`_|_✔ converted_
|
||||
`T`|🔵 unchanged|_❌ exception_|_❌ exception_|_✔ converted_
|
||||
`std::optional<T>`|🔵 unchanged|_❌ exception_|_🟨 `nullopt`_|_✔ converted_
|
||||
|
||||
### GetValueForKey<T>() (return value)
|
||||
|
||||
val type|key not found|_json type invalid_|_json null_|_valid_
|
||||
-|-|-|-|-
|
||||
`T`|🟨 `T{}` (zero value)|_❌ exception_|_🟨 `T{}` (zero value)_|_✔ converted_
|
||||
`T`|🟨 `T{}` (zero value)|_❌ exception_|_❌ exception_|_✔ converted_
|
||||
`std::optional<T>`|🟨 `nullopt`|_❌ exception_|_🟨 `nullopt`_|_✔ converted_
|
||||
|
||||
### Future Direction
|
||||
|
||||
@@ -166,7 +166,7 @@ should be working just the same as before.
|
||||
Now that you have a static library project, you can start building your unittest
|
||||
dll. Start by creating a new directory for your unittest code, and creating a
|
||||
`.vcxproj` for a TAEF unittest dll. For the Terminal solution, we use the TAEF
|
||||
nuget package `Taef.Redist.Wlk`.
|
||||
nuget package `Microsoft.Taef`.
|
||||
|
||||
### Referencing your C++/WinRT static lib
|
||||
|
||||
@@ -380,7 +380,7 @@ Here's the AppxManifest we're using:
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.19041.0" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
</Dependencies>
|
||||
@@ -517,7 +517,7 @@ This is because of a few key lines we already put in the appxmanifest:
|
||||
|
||||
```xml
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.19041.0" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
</Dependencies>
|
||||
|
||||
65
doc/feature_flags.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# til::feature
|
||||
|
||||
Feature flags are controlled by an XML document stored at `src/features.xml`.
|
||||
|
||||
## Example Document
|
||||
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<featureStaging xmlns="http://microsoft.com/TilFeatureStaging-Schema.xsd">
|
||||
<feature>
|
||||
<!-- This will produce Feature_XYZ::IsEnabled() and TIL_FEATURE_XYZ_ENABLED (preprocessor) -->
|
||||
<name>Feature_XYZ</name>
|
||||
|
||||
<description>Does a cool thing</description>
|
||||
|
||||
<!-- GitHub deliverable number; optional -->
|
||||
<id>1234</id>
|
||||
|
||||
<!-- Whether the feature defaults to enabled or disabled -->
|
||||
<stage>AlwaysEnabled|AlwaysDisabled</stage>
|
||||
|
||||
<!-- Branch wildcards where the feature should be *DISABLED* -->
|
||||
<alwaysDisabledBranchTokens>
|
||||
<branchToken>branch/with/wildcard/*</branchToken>
|
||||
<!-- ... more branchTokens ... -->
|
||||
</alwaysDisabledBranchTokens>
|
||||
|
||||
<!-- Just like alwaysDisabledBranchTokens, but for *ENABLING* the feature. -->
|
||||
<alwaysEnabledBranchTokens>
|
||||
<branchToken>...</branchToken>
|
||||
</alwaysEnabledBranchTokens>
|
||||
|
||||
<!-- Brandings where the feature should be *DISABLED* -->
|
||||
<alwaysDisabledBrandingTokens>
|
||||
<!-- Valid brandings include Dev, Preview, Release, WindowsInbox -->
|
||||
<brandingToken>Release</brandingToken>
|
||||
<!-- ... more brandingTokens ... -->
|
||||
</alwaysDisabledBrandingTokens>
|
||||
|
||||
<!-- Just like alwaysDisabledBrandingTokens, but for *ENABLING* the feature -->
|
||||
<alwaysEnabledBrandingTokens>
|
||||
<branchToken>...</branchToken>
|
||||
</alwaysEnabledBrandingTokens>
|
||||
|
||||
<!-- Unequivocally disable this feature in Release -->
|
||||
<alwaysDisabledReleaseTokens />
|
||||
</feature>
|
||||
</featureStaging>
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
Features that are disabled for Release using `alwaysDisabledReleaseTokens` are
|
||||
*always* disabled in Release, even if they come from a branch that would have
|
||||
been enabled by the wildcard.
|
||||
|
||||
### Precedence
|
||||
|
||||
1. `alwaysDisabledReleaseTokens`
|
||||
2. Enabled branches
|
||||
3. Disabled branches
|
||||
* The longest branch token that matches your branch will win.
|
||||
3. Enabled brandings
|
||||
4. Disabled brandings
|
||||
5. The feature's default state
|
||||
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 300 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 98 KiB |
239
doc/reference/Build-SupportedSequenceIndex.ps1
Normal file
@@ -0,0 +1,239 @@
|
||||
#requires -version 6.1
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Scan source code and build a list of supported VT sequences.
|
||||
.DESCRIPTION
|
||||
Scan source code and build a list of supported VT sequences.
|
||||
TODO: add more details
|
||||
#>
|
||||
[cmdletbinding(DefaultParameterSetName="stdout")]
|
||||
param(
|
||||
[parameter(ParameterSetName="file", mandatory)]
|
||||
[string]$OutFile,
|
||||
[parameter(ParameterSetName="file")]
|
||||
[switch]$Force, # for overwriting $OutFile if it exists
|
||||
|
||||
[parameter(ParameterSetName="stdout")]
|
||||
[parameter(ParameterSetName="file")]
|
||||
[switch]$NoLogo, # no logo in summary
|
||||
[parameter(ParameterSetName="stdout")]
|
||||
[switch]$SummaryOnly, # no markdown generated
|
||||
[parameter(ParameterSetName="stdout")]
|
||||
[parameter(ParameterSetName="file")]
|
||||
[switch]$Quiet, # no summary or logo
|
||||
|
||||
[parameter(ParameterSetName="file")]
|
||||
[parameter(ParameterSetName="stdout")]
|
||||
[string]$SolutionRoot = "..\..",
|
||||
[parameter(ParameterSetName="file")]
|
||||
[parameter(ParameterSetName="stdout")]
|
||||
[string]$InterfacePath = $(join-path $solutionRoot "src\terminal\adapter\ITermDispatch.hpp"),
|
||||
[parameter(ParameterSetName="file")]
|
||||
[parameter(ParameterSetName="stdout")]
|
||||
[string]$ConsoleAdapterPath = $(join-path $solutionRoot "src\terminal\adapter\adaptDispatch.hpp"),
|
||||
[parameter(ParameterSetName="file")]
|
||||
[parameter(ParameterSetName="stdout")]
|
||||
[string]$TerminalAdapterPath = $(join-path $solutionRoot "src\cascadia\terminalcore\terminalDispatch.hpp")
|
||||
)
|
||||
|
||||
if ($PSCmdlet.ParameterSetName -eq "stdout") {
|
||||
Write-Verbose "Emitting markdown to STDOUT"
|
||||
}
|
||||
|
||||
<#
|
||||
GLOBALS
|
||||
#>
|
||||
|
||||
[semver]$myVer = "0.6-beta"
|
||||
$sequences = import-csv ".\master-sequence-list.csv"
|
||||
$base = @{}
|
||||
$conhost = @{}
|
||||
$terminal = @{}
|
||||
$prefix = "https://vt100.net/docs/vt510-rm/"
|
||||
$repo = "https://github.com/oising/terminal/tree/master"
|
||||
$conhostUrl = $ConsoleAdapterPath.TrimStart($SolutionRoot).replace("\", "/")
|
||||
$terminalUrl = $TerminalAdapterPath.TrimStart($SolutionRoot).replace("\", "/")
|
||||
|
||||
function Read-SourceFiles {
|
||||
# extract base interface
|
||||
$baseScanner = [regex]'(?x)virtual\s\w+\s(?<method>\w+)(?s)[^;]+;(?-s).*?(?<seq>(?<=\/\/\s).+)'
|
||||
|
||||
$baseScanner.Matches(($src = get-content -raw $interfacePath)) | foreach-object {
|
||||
$match = $_
|
||||
#$line = (($src[0..$_.Index] -join "") -split "`n").Length
|
||||
#$decl = $_.groups[0].value
|
||||
$_.groups["seq"].value.split(",") | ForEach-Object {
|
||||
$SCRIPT:base[$_.trim()] = $match.groups["method"].value
|
||||
}
|
||||
}
|
||||
|
||||
# match overrides of ITermDispatch
|
||||
$scanner = [regex]'(?x)\s+\w+\s(?<method>\w+)(?s)[^;]+override;'
|
||||
|
||||
$scanner.Matches(($src = Get-Content -raw $consoleAdapterPath)) | ForEach-Object {
|
||||
$line = (($src[0..$_.Index] -join "") -split "`n").Length
|
||||
$SCRIPT:conhost[$_.groups["method"].value] = $line
|
||||
}
|
||||
|
||||
$scanner.Matches(($src = Get-Content -raw $terminalAdapterPath)) | ForEach-Object {
|
||||
$line = (($src[0..$_.Index] -join "") -split "`n").Length
|
||||
#write-verbose $_.groups[0].value
|
||||
$SCRIPT:terminal[$_.groups["method"].value] = $line
|
||||
}
|
||||
}
|
||||
|
||||
function Get-SequenceIndexMarkdown {
|
||||
# "Sequence","Parent","Description","Origin","Heading","Subheading", "ImplementedBy", "ConsoleHost","Terminal"
|
||||
|
||||
$heading = $null
|
||||
$subheading = $null
|
||||
<#
|
||||
Emit markdown
|
||||
|
||||
TODO:
|
||||
- auto-generate TOC
|
||||
#>
|
||||
@"
|
||||
# VT Function Support
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Code Extension Functions](#code-extension-functions)
|
||||
* [Control Coding](#control-coding)
|
||||
* [Character Coding](#character-coding)
|
||||
* [Graphic Character Sets](#graphic-character-sets)
|
||||
* [Terminal Management Functions](#terminal-management-functions)
|
||||
* [Identification, status, and Initialization](#identification-status-and-initialization)
|
||||
* [Emulations](#emulations)
|
||||
* [Set-Up](#set-up)
|
||||
* [Display Coordinate System and Addressing](#display-coordinate-system-and-addressing)
|
||||
* [Active Position and Cursor](#active-position-and-cursor)
|
||||
* [Margins and Scrolling](#margins-and-scrolling)
|
||||
* [Cursor Movement](#cursor-movement)
|
||||
* [Horizontal Tabulation](#horizontal-tabulation)
|
||||
* [Page Size and Arrangement](#page-size-and-arrangement)
|
||||
* [Page Movement](#page-movement)
|
||||
* [Status Display](#status-display)
|
||||
* [Right to Left](#right-to-left)
|
||||
* [Window Management](#window-management)
|
||||
* [Visual Attributes and Renditions](#visual-attributes-and-renditions)
|
||||
* [Line Renditions](#line-renditions)
|
||||
* [Character Renditions](#character-renditions)
|
||||
* [Audible Indicators](#audible-indicators)
|
||||
* [Mode States](#mode-states)
|
||||
* [ANSI](#ansi)
|
||||
* [DEC Private](#dec-private)
|
||||
* [Editing Functions](#editing-functions)
|
||||
* [OLTP Features](#OLTP-features)
|
||||
* [Rectangular Area Operations](#rectangular-area-operations)
|
||||
* [Data Integrity](#data-integrity)
|
||||
* [Macros](#macros)
|
||||
* [Saving and Restoring Terminal State](#saving-and-restoring-terminal-state)
|
||||
* [Cursor Save Buffer](#cursor-save-buffer)
|
||||
* [Terminal State Interrogation](#terminal-state-interrogation)
|
||||
* [Keyboard Processing Functions](#keyboard-processing-functions)
|
||||
* [Soft Key Mapping (UDK)](#soft-key-mapping-UDK)
|
||||
* [Soft Fonts (DRCS)](#soft-fonts-drcs)
|
||||
* [Printing](#printing)
|
||||
* [Terminal Communication and Synchronization](#terminal-communication-and-synchronization)
|
||||
* [Text Locator Extension](#text-locator-extension)
|
||||
* [Session Management Extension](#session-management-extension)
|
||||
* [Documented Exceptions](#documented-exceptions)
|
||||
|
||||
$($sequences | ForEach-Object {
|
||||
if ($method = $base[$_.sequence]) {
|
||||
$_.ImplementedBy = $method
|
||||
$_.ConsoleHost = $conhost[$method]
|
||||
$_.Terminal = $terminal[$method]
|
||||
}
|
||||
# "Sequence","Associated","Description","Origin","Heading","Subheading", "ImplementedBy", "ConsoleHost","Terminal"
|
||||
$c0 = "[$($_.Sequence)]($prefix$($_.sequence).html ""View page on vt100.net"")"
|
||||
$c1 = "$($_.description)"
|
||||
$c2 = "$($_.origin)"
|
||||
$c3 = $(if ($_.consolehost) {"[✓](${repo}/${conhostUrl}#L$($_.consolehost) ""View console host implementation"")"})
|
||||
$c4 = $(if ($_.terminal) {"[✓](${repo}/${terminalUrl}#L$($_.terminal)} ""View windows terminal implementation"")"})
|
||||
|
||||
$shouldRenderHeader = $false
|
||||
|
||||
if ($heading -ne $_.heading) {
|
||||
$heading = $_.heading
|
||||
@"
|
||||
|
||||
## $heading
|
||||
|
||||
"@
|
||||
$shouldRenderHeader = $true
|
||||
}
|
||||
|
||||
if ($subheading -ne $_.subheading) {
|
||||
$subheading = $_.subheading
|
||||
@"
|
||||
|
||||
### $subheading
|
||||
|
||||
"@
|
||||
$shouldRenderHeader = $true
|
||||
}
|
||||
|
||||
if ($shouldRenderHeader) {
|
||||
@"
|
||||
|
||||
|Symbol|Function|Origin 🖳|Console Host|Terminal|
|
||||
|:-|:--|:--:|:--:|:--:|
|
||||
"@
|
||||
}
|
||||
@"
|
||||
|
||||
|$c0|$c1|$c2|$c3|$c4|
|
||||
"@
|
||||
})
|
||||
|
||||
---
|
||||
Generated on $(get-date -DisplayHint DateTime)
|
||||
"@
|
||||
}
|
||||
|
||||
function Show-Summary {
|
||||
write-host "`n$(' '*7)Windows Terminal Sequencer v${myVer}"
|
||||
if (-not $NoLogo.IsPresent) {
|
||||
Get-Content .\windows-terminal-logo.ans | ForEach-Object { Write-Host $_ }
|
||||
}
|
||||
$summary = @"
|
||||
`e[1mSequence Support:`e[0m
|
||||
|
||||
`e[7m {0:000} `e[0m known in master-sequence-list.csv.
|
||||
`e[7m {1:000} `e[0m common members in ITermDispatch base, of which:
|
||||
`e[7m {2:000} `e[0m are implemented by ConsoleHost.
|
||||
`e[7m {3:000} `e[0m are implemented by Windows Terminal.
|
||||
|
||||
"@ -f $sequences.Count, $base.count, $conhost.count, $terminal.Count
|
||||
|
||||
write-host $summary
|
||||
}
|
||||
|
||||
<#
|
||||
Entry Point
|
||||
#>
|
||||
|
||||
Read-SourceFiles
|
||||
|
||||
if (-not $SummaryOnly.IsPresent) {
|
||||
|
||||
$markdown = Get-SequenceIndexMarkdown
|
||||
|
||||
if ($PSCmdlet.ParameterSetName -eq "file") {
|
||||
# send to file and overwrite
|
||||
$markdown | Out-File -FilePath $OutFile -Force:$Force.IsPresent -Encoding utf8NoBOM
|
||||
} else {
|
||||
# send to STDOUT
|
||||
$markdown
|
||||
}
|
||||
|
||||
if (-not $Quiet.IsPresent) {
|
||||
Show-Summary
|
||||
}
|
||||
} else {
|
||||
# summary only
|
||||
Show-Summary
|
||||
}
|
||||
224
doc/reference/master-sequence-list.csv
Normal file
@@ -0,0 +1,224 @@
|
||||
"Sequence","Parent","Description","Origin","Heading","Subheading","ImplementedBy","ConsoleHost","Terminal"
|
||||
"CAN","","Cancel","`VT100`","Code Extension Functions","Control Coding","","",""
|
||||
"SUB","","Substitute","`VT100`","Code Extension Functions","Control Coding","","",""
|
||||
"ESC","","Escape","`VT100`","Code Extension Functions","Control Coding","","",""
|
||||
"DCS","","Device Control String","`VT220`","Code Extension Functions","Control Coding","","",""
|
||||
"CSI","","Control Sequence Introducer","`VT100`","Code Extension Functions","Control Coding","","",""
|
||||
"ST","","String Terminator","`VT220`","Code Extension Functions","Control Coding","","",""
|
||||
"OSC","","Operating System Command","`DECterm`","Code Extension Functions","Control Coding","","",""
|
||||
"PM","","Privacy Message","``","Code Extension Functions","Control Coding","","",""
|
||||
"APC","","Application Program Command","`VT420`","Code Extension Functions","Control Coding","","",""
|
||||
"S7C1T","","Select 7-bit C1 Transmission","`VT220`","Code Extension Functions","Control Coding","","",""
|
||||
"S8C1T","","Select 8-bit C1 Transmission","`VT220`","Code Extension Functions","Control Coding","","",""
|
||||
"LS0","","Locking Shift Zero (SI)","`VT100`","Code Extension Functions","Character Coding","","",""
|
||||
"LS1","","Locking Shift One (SO)","`VT100`","Code Extension Functions","Character Coding","","",""
|
||||
"LS2","","Locking Shift Two","`VT220`","Code Extension Functions","Character Coding","","",""
|
||||
"LS3","","Locking Shift Three","`VT220`","Code Extension Functions","Character Coding","","",""
|
||||
"LS1R","","Locking Shift One Right","`VT220`","Code Extension Functions","Character Coding","","",""
|
||||
"LS2R","","Locking Shift Two Right","`VT220`","Code Extension Functions","Character Coding","","",""
|
||||
"LS3R","","Locking Shift Three Right","`VT220`","Code Extension Functions","Character Coding","","",""
|
||||
"SS2","","Single Shift Two","`VT220`","Code Extension Functions","Character Coding","","",""
|
||||
"SS3","","Single Shift Three","`VT220`","Code Extension Functions","Character Coding","","",""
|
||||
"SCS","","Select Character Set","`VT100`","Code Extension Functions","Graphic Character Sets","","",""
|
||||
"DECNRCM","","(National Replacement) Character Set Mode","`VT220`","Code Extension Functions","Graphic Character Sets","","",""
|
||||
"DECAUPSS","","Assign User-Preference Supplemental Set","`VT320`","Code Extension Functions","Graphic Character Sets","","",""
|
||||
"DECRQUPSS","","Request User-Preference Supplemental Set","`VT320`","Code Extension Functions","Graphic Character Sets","","",""
|
||||
"DA1","","Primary Device Attributes","`VT100`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DA2","","Secondary Device Attributes","`VT220`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DA3","","Tertiary Device Attributes","`VT420`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DSR","","Device Status Report","`VT100`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECID","","Identify Device","`VT100`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECTID","","Select Terminal ID","`VT510`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECSCL","","Select Conformance Level","`VT220`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECSR","","Secure Reset","`VT420`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECSRC","","Secure Reset Confirmation","`VT420`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECSTR","","Soft Terminal Reset","`VT220`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECSTUI","","Set Terminal Unit ID (Restricted)","`VT420`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"RIS","","Reset to Initial state","`VT100`","Terminal Management Functions","Identification, status, and Initialization","","",""
|
||||
"DECPCTERM","","Enter/Exit PC Term Mode from DEC VT mode","`VT420PC`","Terminal Management Functions","Emulations","","",""
|
||||
"DECTME","","Terminal Mode Emulation","`VT510`","Terminal Management Functions","Emulations","","",""
|
||||
"DECSSL","","Select Set-Up Language","`VT510`","Terminal Management Functions","Set-Up","","",""
|
||||
"DECCRTSM","","CRT Save Mode (not required)","`VT510`","Terminal Management Functions","Set-Up","","",""
|
||||
"DECOSCNM","","Overscan Mode","`VT510`","Terminal Management Functions","Set-Up","","",""
|
||||
"DECSRFR","","Select Refresh Rate","`VT510`","Terminal Management Functions","Set-Up","","",""
|
||||
"DECLTOD","","Load Time of Day","`VT510`","Terminal Management Functions","Set-Up","","",""
|
||||
"DECLBAN","","Load Banner Message","`VT510`","Terminal Management Functions","Set-Up","","",""
|
||||
"DECTCEM","","Text Cursor Enable Mode","`VT220`","Display Coordinate System and Addressing","Active Position and Cursor","","",""
|
||||
"DECSCUSR","","Set Cursor Style","`VT510`","Display Coordinate System and Addressing","Active Position and Cursor","","",""
|
||||
"DECSTBM","","Set Top and Bottom Margin","`VT100`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"DECSLRM","","Set Left and Right Margin","`VT420`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"DECLRMM","","Left Right Margin Mode","`VT420`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"DECOM","","Origin Mode","`VT100`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"DECSCLM","","Scrolling Mode","`VT100`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"IND","","Index","`VT100`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"RI","","Reverse Index","`VT100`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"DECFI","","Forward Index","`VT420`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"DECBI","","Back Index","`VT420`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"DECSSCLS","","Set Scroll Speed","`VT510`","Display Coordinate System and Addressing","Margins and Scrolling","","",""
|
||||
"BS","","Backspace","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"LF","","Line Feed","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"VT","","Vertical Tab","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"FF","","Form Feed","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CR","","Carriage Return","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"NEL","","Next Line","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"LNM","","Line Feed/New Line Mode","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CUU","","Cursor Up","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CUD","","Cursor Down","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CUF","","Cursor Forward","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CUB","","Cursor Backward","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CUP","","Cursor Position","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"HVP","","Horizontal/Vertical Position","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"DSR-CPR","","Device Status Report (Cursor Position Report)","`VT100`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"DSR-XCPR","","Device Status Report (Extended Cursor Position Report)","`VT340` `VT420`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CHA","","Cursor Horizontal Absolute","`VT510`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CNL","","Cursor Next Line","`VT510`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"CPL","","Cursor Previous Line","`VT510`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"HPA","","Horizontal Position Absolute","`VT510`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"HPR","","Horizontal Position Relative","`VT510`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"VPA","","Vertical Line Position Absolute","`VT510`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"VPR","","Vertical Position Relative","`VT510`","Display Coordinate System and Addressing","Cursor Movement","","",""
|
||||
"HT","","Horizontal Tab","`VT100`","Display Coordinate System and Addressing","Horizontal Tabulation","","",""
|
||||
"HTS","","Horizontal Tabulation Set","`VT100`","Display Coordinate System and Addressing","Horizontal Tabulation","","",""
|
||||
"TBC","","Tabulation Clear","`VT100`","Display Coordinate System and Addressing","Horizontal Tabulation","","",""
|
||||
"CBT","","Cursor Backward Tabulation","`VT510`","Display Coordinate System and Addressing","Horizontal Tabulation","","",""
|
||||
"CHT","","Cursor Horizontal Forward Tabulation","`VT510`","Display Coordinate System and Addressing","Horizontal Tabulation","","",""
|
||||
"DECST8C","","Set Tab at every 8 columns","`VT420PC`","Display Coordinate System and Addressing","Horizontal Tabulation","","",""
|
||||
"DECCOLM","","Column Mode","`VT100`","Display Coordinate System and Addressing","Page Size and Arrangement","","",""
|
||||
"DECNCSM","","No Clear Screen on column Mode","`VT510`","Display Coordinate System and Addressing","Page Size and Arrangement","","",""
|
||||
"DECSCPP","","Set Columns Per Page","`VT340` `VT420`","Display Coordinate System and Addressing","Page Size and Arrangement","","",""
|
||||
"DECSLPP","","Set Lines Per Page","`VT340` `VT420`","Display Coordinate System and Addressing","Page Size and Arrangement","","",""
|
||||
"NP","","Next Page","`VT340` `VT420`","Display Coordinate System and Addressing","Page Movement","","",""
|
||||
"PP","","Preceding Page","`VT340` `VT420`","Display Coordinate System and Addressing","Page Movement","","",""
|
||||
"PPA","","Page Position Absolute","`VT340` `VT420`","Display Coordinate System and Addressing","Page Movement","","",""
|
||||
"PPR","","Page Position Relative","`VT340` `VT420`","Display Coordinate System and Addressing","Page Movement","","",""
|
||||
"PPB","","Page Position Backward","`VT340` `VT420`","Display Coordinate System and Addressing","Page Movement","","",""
|
||||
"DECSASD","","Select Active Status Display","`VT340` `VT320`","Display Coordinate System and Addressing","Status Display","","",""
|
||||
"DECSSDT","","Select Status Display Type","`VT340` `VT320`","Display Coordinate System and Addressing","Status Display","","",""
|
||||
"DECRLM","","Right to Left Mode","`VT510`","Display Coordinate System and Addressing","Right to Left","","",""
|
||||
"DECRLCM","","Right to Left Copy Mode","`VT510`","Display Coordinate System and Addressing","Right to Left","","",""
|
||||
"DDD1","","`VT100` mode Hebrew","`VT510`","Display Coordinate System and Addressing","Right to Left","","",""
|
||||
"DDD2","","`VT100` mode Hebrew","`VT510`","Display Coordinate System and Addressing","Right to Left","","",""
|
||||
"DDD3","","`VT100` mode Hebrew","`VT510`","Display Coordinate System and Addressing","Right to Left","","",""
|
||||
"DECHCCM","","Horizontal Cursor Coupling Mode","`VT340` `VT420`","Window Management","Right to Left","","",""
|
||||
"DECVCCM","","Vertical Cursor Coupling Mode","`VT340` `VT420`","Window Management","Right to Left","","",""
|
||||
"DECPCCM","","Page Cursor Coupling Mode","`VT340` `VT420`","Window Management","Right to Left","","",""
|
||||
"DECRQDE","","Request Displayed Extent","`VT340` `VT420`","Window Management","Right to Left","","",""
|
||||
"DECSNLS","","Select Number of Lines per Screen (exception)","`VT420`","Window Management","Right to Left","","",""
|
||||
"DECARSM","","Auto Resize Mode","`DECterm` `VT420`","Window Management","Right to Left","","",""
|
||||
"SU","","Pan Down","`VT340` `VT420`","Window Management","Right to Left","","",""
|
||||
"SD","","Pan Up","`VT340` `VT420`","Window Management","Right to Left","","",""
|
||||
"DECSCNM","","Screen Mode","`VT100`","Visual Attributes and Renditions","Right to Left","","",""
|
||||
"DECSWL","","Single Width Line","`VT100`","Visual Attributes and Renditions","Line Renditions","","",""
|
||||
"DECDWL","","Double Width Line","`VT100`","Visual Attributes and Renditions","Line Renditions","","",""
|
||||
"DECDHLT","","Double Height Line Top","`VT100`","Visual Attributes and Renditions","Line Renditions","","",""
|
||||
"DECDHLB","","Double Height Line Bottom","`VT100`","Visual Attributes and Renditions","Line Renditions","","",""
|
||||
"SGR","","Select Graphic Rendition","`VT100`","Visual Attributes and Renditions","Character Renditions","","",""
|
||||
"BEL","","Warning Bell","`VT100`","Audible Indicators","Character Renditions","","",""
|
||||
"DECSKCV","","Set Keyclick Volume","`VT510`","Audible Indicators","Character Renditions","","",""
|
||||
"DECSWBV","","Set Warning Bell Volume","`VT510`","Audible Indicators","Character Renditions","","",""
|
||||
"DECSMBV","","Set Margin Bell Volume","`VT510`","Audible Indicators","Character Renditions","","",""
|
||||
"IRM","","Insert/Replacement Mode","`VT102`","Editing Functions","DEC Private","","",""
|
||||
"ICH","","Insert Character","`VT102`","Editing Functions","DEC Private","","",""
|
||||
"DCH","","Delete Character","`VT102`","Editing Functions","DEC Private","","",""
|
||||
"IL","","Insert Line","`VT100`","Editing Functions","DEC Private","","",""
|
||||
"DL","","Delete Line","`VT100`","Editing Functions","DEC Private","","",""
|
||||
"DECIC","","Insert Column","`VT420`","Editing Functions","DEC Private","","",""
|
||||
"DECDC","","Delete Column","`VT420`","Editing Functions","DEC Private","","",""
|
||||
"ECH","","Erase Character","`VT100`","Editing Functions","DEC Private","","",""
|
||||
"EL","","Erase in Line","`VT100`","Editing Functions","DEC Private","","",""
|
||||
"DECSEL","","Selective Erase in Line","`VT220`","Editing Functions","DEC Private","","",""
|
||||
"ED","","Erase in Display","`VT100`","Editing Functions","DEC Private","","",""
|
||||
"DECSED","","Selective Erase in Display","`VT220`","Editing Functions","DEC Private","","",""
|
||||
"DECSCA","","Select Character Attribute (selective erase)","`VT220`","Editing Functions","DEC Private","","",""
|
||||
"DECCRA","","Copy Rectangular Area","`VT420`","OLTP Features","Rectangular Area Operations","","",""
|
||||
"DECFRA","","Fill Rectangular Area","`VT420`","OLTP Features","Rectangular Area Operations","","",""
|
||||
"DECERA","","Erase Rectangular Area","`VT420`","OLTP Features","Rectangular Area Operations","","",""
|
||||
"DECSERA","","Selective Erase Rectangular Area","`VT420`","OLTP Features","Rectangular Area Operations","","",""
|
||||
"DECCARA","","Change Attribute in Rectangular Area","`VT420`","OLTP Features","Rectangular Area Operations","","",""
|
||||
"DECRARA","","Reverse Attribute in Rectangular Area","`VT420`","OLTP Features","Rectangular Area Operations","","",""
|
||||
"DECSACE","","Select Attribute Change Extent Mode","`VT420`","OLTP Features","Rectangular Area Operations","","",""
|
||||
"DECRQCRA","","Request Checksum of Rectangular Area","`VT420`","OLTP Features","Data Integrity","","",""
|
||||
"DSR-DECCKSR","","Device Status Report (Memory Checksum)","`VT420`","OLTP Features","Data Integrity","","",""
|
||||
"DECDMAC","","Define Macro","`VT420`","OLTP Features","Macros","","",""
|
||||
"DECINVM","","Invoke Macro","`VT420`","OLTP Features","Macros","","",""
|
||||
"DSR-MSR","","Device Status Report (Macro Space Report)","`VT420`","OLTP Features","Macros","","",""
|
||||
"DECSC","","Save Cursor","`VT100`","Saving and Restoring Terminal State","Cursor Save Buffer","","",""
|
||||
"DECRC","","Restore Cursor","`VT100`","Saving and Restoring Terminal State","Cursor Save Buffer","","",""
|
||||
"DECRQM","","Request Mode","`VT320`","Saving and Restoring Terminal State","Terminal State Interrogation","","",""
|
||||
"DECNKM","","Numeric Keypad Mode","`VT320`","Saving and Restoring Terminal State","Terminal State Interrogation","","",""
|
||||
"DECRQSS","","Request Selection or Setting","`VT320`","Saving and Restoring Terminal State","Terminal State Interrogation","","",""
|
||||
"DECRQPSR","","Request Presentation State Report","`VT320`","Saving and Restoring Terminal State","Terminal State Interrogation","","",""
|
||||
"DECRSPS","","Restore Presentation State","`VT320`","Saving and Restoring Terminal State","Terminal State Interrogation","","",""
|
||||
"DECRQTSR","","Request Terminal State Report","`VT320`","Saving and Restoring Terminal State","Terminal State Interrogation","","",""
|
||||
"DECRSTS","","Restore Terminal State","`VT320`","Saving and Restoring Terminal State","Terminal State Interrogation","","",""
|
||||
"DECARM","","Autorepeat Mode","`VT100`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECBKM","","Backarrow Key Mode","`VT420`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECCKM","","Cursor Keys Mode","`VT100`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECKBUM","","Keyboard Usage Mode","`VT320`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECKPAM","","Keypad Application Mode","`VT100`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECKPM","","Key Position Mode","`VT420`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECKPNM","","Keypad Numeric Mode","`VT100`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECNKM","","Numeric Keypad Mode","`VT320`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DSR-KBD","","Device Status Report (keyboard status)","`VT220`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"KAM","","Keyboard Action Mode","`VT220`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECLFC","","Local Functions Control","`VT420`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECLFKC","","Local Function Key Control","`VT420`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECSMKR","","Select Modifier Key Reporting","`VT420`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECHEBM","","Hebrew Keyboard Map mode","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECHCEM","","Hebrew Encoding Mode","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECNAKB","","NA/Greek Selection","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECESKM","","Secondary Keyboard Language Mode","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECSLCK","","Set Lock Key Style","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECKBD","","Keyboard Dialect Selection","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECNUMLK","","NumLock Mode","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECCAPSLK","","CapsLock Mode","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECKLHIM","","Keyboard LEDs Host Indicator Mode","`VT510`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECLL","","Load LEDs","`VT100`","Keyboard Processing Functions","Terminal State Interrogation","","",""
|
||||
"DECUDK","","User Defined Keys","`VT220`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DSR-UDK","","Device Status Report (UDK lock)","`VT220`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECPKA","","Program Key Action","`VT510`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECPFK","","Program Function Key","`VT510`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECPAK","","Program Alphanumeric Key","`VT510`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECCKD","","Copy Key Default","`VT510`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECRQPKFM","","Program Key Free Memory Inquiry","`VT510`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECRQKT","","Inquire a Key Type","`VT510`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECRQKD","","Inquire a Key Definition","`VT510`","Soft Key Mapping (UDK)","Terminal State Interrogation","","",""
|
||||
"DECDLD","","Downline Load","`VT220`","Soft Fonts (DRCS)","Terminal State Interrogation","","",""
|
||||
"DECPEX","","Print Extent Mode","`VT220`","Printing","Terminal State Interrogation","","",""
|
||||
"DECPFF","","Print Form Feed Mode","`VT220`","Printing","Terminal State Interrogation","","",""
|
||||
"DSR-PP","","Device Status Report (printer port)","`VT220`","Printing","Terminal State Interrogation","","",""
|
||||
"MC","","Media Copy","`VT220`","Printing","Terminal State Interrogation","","",""
|
||||
"DECSPRTT","","Select Printer Type","`VT510`","Printing","Terminal State Interrogation","","",""
|
||||
"DECSDPT","","Select Digital Printed Data Type","`VT510`","Printing","Terminal State Interrogation","","",""
|
||||
"DECSPPCS","","Select Proprinter Character Set","`VT510`","Printing","Terminal State Interrogation","","",""
|
||||
"BREAK","","BREAK","`VT100`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"XON","","XON","`VT100`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"XOFF","","XOFF","`VT100`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"ENQ","","Enquiry","`VT100`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"SRM","","Send Receive Mode","`VT220`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECXRLM","","Transmit Rate Limiting Mode","`VT420`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECMCM","","Modem Control Mode","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECAAM","","Auto Answerback Mode","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECLANS","","Load Answerback Message","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECCANSM","","Conceal Answerback Message Mode","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECNULM","","Ignore Null Mode","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECHPDXM","","Half Duplex Mode","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECSFC","","Select Flow Control","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECSDDT","","Select Disconnect Delay Time","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECSTRL","","Set Transmit Rate Limit","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECSCS","","Select Communication Speed","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECSCP","","Select Communication Port","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECSPP","","Set Port Parameter","`VT510`","Terminal Communication and Synchronization","Terminal State Interrogation","","",""
|
||||
"DECEFR","","Enable Filter Rectangle","`UWS`","Text Locator Extension","Terminal State Interrogation","","",""
|
||||
"DECELR","","Enable Locator Reports","`UWS`","Text Locator Extension","Terminal State Interrogation","","",""
|
||||
"DECLKD","","Locator Key Definition","`UWS`","Text Locator Extension","Terminal State Interrogation","","",""
|
||||
"DECLRP","","Locator Report","`UWS`","Text Locator Extension","Terminal State Interrogation","","",""
|
||||
"DECRQLP","","Request Locator Position","`UWS`","Text Locator Extension","Terminal State Interrogation","","",""
|
||||
"DECSLE","","Select Locator Events","`UWS`","Text Locator Extension","Terminal State Interrogation","","",""
|
||||
"DSR-LS","","Device Status Report (Locator Status)","`UWS`","Text Locator Extension","Terminal State Interrogation","","",""
|
||||
"DECES","","Enable Sessions","`VT340` `VT420`","Session Management Extension","Terminal State Interrogation","","",""
|
||||
"DECANM","","`ANSI`/`VT52` Mode","`VT100`","Documented Exceptions","Terminal State Interrogation","","",""
|
||||
"DECALN","","Screen Alignment","`VT100`","Documented Exceptions","Terminal State Interrogation","","",""
|
||||
"DECAWM","","Autowrap Mode","`VT100`","Documented Exceptions","Terminal State Interrogation","","",""
|
||||
"DECTST","","Invoke Confidence Test","`VT100`","Documented Exceptions","Terminal State Interrogation","","",""
|
||||
"CRM","","Control Representation Mode","`VT100`","Documented Exceptions","Terminal State Interrogation","","",""
|
||||
|
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 117 KiB |
15
doc/reference/windows-terminal-logo.ans
Normal file
@@ -0,0 +1,15 @@
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;191;191;191m[48;2;204;204;204m▀[0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[38;2;95;95;95m[48;2;102;102;102m▀[0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;204;204;204m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;153;153;153m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m[7m[38;2;102;102;102m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;77;77;77m[48;2;76;76;76m▀[0m[7m[38;2;76;76;76m [0m[38;2;76;76;76m[48;2;75;75;75m▀[0m[38;2;76;76;76m[48;2;75;75;75m▀[0m[7m[38;2;75;75;75m [0m[38;2;75;75;75m[48;2;74;74;74m▀[0m[38;2;75;75;75m[48;2;74;74;74m▀[0m[7m[38;2;74;74;74m [0m[38;2;74;74;74m[48;2;73;73;73m▀[0m[38;2;74;74;74m[48;2;73;73;73m▀[0m[7m[38;2;73;73;73m [0m[38;2;73;73;73m[48;2;72;72;72m▀[0m[38;2;73;73;73m[48;2;72;72;72m▀[0m[7m[38;2;72;72;72m [0m[38;2;72;72;72m[48;2;71;71;71m▀[0m[7m[38;2;71;71;71m [0m[7m[38;2;71;71;71m [0m[38;2;71;71;71m[48;2;70;70;70m▀[0m[7m[38;2;70;70;70m [0m[7m[38;2;70;70;70m [0m[38;2;70;70;70m[48;2;69;69;69m▀[0m[7m[38;2;69;69;69m [0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[7m[38;2;68;68;68m [0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[7m[38;2;67;67;67m [0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[7m[38;2;66;66;66m [0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[7m[38;2;65;65;65m [0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[7m[38;2;64;64;64m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;76;76;76m[48;2;75;75;75m▀[0m[7m[38;2;75;75;75m [0m[38;2;75;75;75m[48;2;74;74;74m▀[0m[38;2;75;75;75m[48;2;74;74;74m▀[0m[38;2;74;74;74m[48;2;73;73;73m▀[0m[38;2;74;74;74m[48;2;71;71;71m▀[0m[38;2;73;73;73m[48;2;67;67;67m▀[0m[38;2;73;73;73m[48;2;70;70;70m▀[0m[38;2;73;73;73m[48;2;71;71;71m▀[0m[7m[38;2;72;72;72m [0m[38;2;72;72;72m[48;2;71;71;71m▀[0m[38;2;72;72;72m[48;2;71;71;71m▀[0m[7m[38;2;71;71;71m [0m[38;2;71;71;71m[48;2;70;70;70m▀[0m[38;2;71;71;71m[48;2;70;70;70m▀[0m[7m[38;2;70;70;70m [0m[38;2;70;70;70m[48;2;69;69;69m▀[0m[38;2;70;70;70m[48;2;69;69;69m▀[0m[7m[38;2;69;69;69m [0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[7m[38;2;68;68;68m [0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[7m[38;2;66;66;66m [0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[7m[38;2;65;65;65m [0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[7m[38;2;64;64;64m [0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[7m[38;2;63;63;63m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[7m[38;2;74;74;74m [0m[38;2;74;74;74m[48;2;73;73;73m▀[0m[38;2;74;74;74m[48;2;73;73;73m▀[0m[38;2;72;72;72m[48;2;71;71;71m▀[0m[38;2;70;70;70m[48;2;97;97;97m▀[0m[38;2;138;138;138m[48;2;229;229;229m▀[0m[38;2;229;229;229m[48;2;228;228;228m▀[0m[38;2;203;203;203m[48;2;226;226;226m▀[0m[38;2;84;84;84m[48;2;200;200;200m▀[0m[38;2;70;70;70m[48;2;82;82;82m▀[0m[38;2;71;71;71m[48;2;69;69;69m▀[0m[7m[38;2;70;70;70m [0m[7m[38;2;70;70;70m [0m[38;2;70;70;70m[48;2;69;69;69m▀[0m[7m[38;2;69;69;69m [0m[7m[38;2;69;69;69m [0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[7m[38;2;68;68;68m [0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[7m[38;2;67;67;67m [0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[7m[38;2;66;66;66m [0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[7m[38;2;65;65;65m [0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[7m[38;2;64;64;64m [0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[7m[38;2;63;63;63m [0m[7m[38;2;63;63;63m [0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[7m[38;2;62;62;62m [0m[7m[38;2;62;62;62m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[7m[38;2;73;73;73m [0m[38;2;73;73;73m[48;2;72;72;72m▀[0m[7m[38;2;71;71;71m [0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[38;2;94;94;94m[48;2;62;62;62m▀[0m[38;2;227;227;227m[48;2;130;130;130m▀[0m[38;2;226;226;226m[48;2;224;224;224m▀[0m[38;2;224;224;224m[48;2;222;222;222m▀[0m[38;2;223;223;223m[48;2;221;221;221m▀[0m[38;2;197;197;197m[48;2;220;220;220m▀[0m[38;2;81;81;81m[48;2;195;195;195m▀[0m[38;2;68;68;68m[48;2;80;80;80m▀[0m[38;2;69;69;69m[48;2;67;67;67m▀[0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[7m[38;2;68;68;68m [0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[7m[38;2;67;67;67m [0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[7m[38;2;66;66;66m [0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[7m[38;2;65;65;65m [0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[7m[38;2;64;64;64m [0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[7m[38;2;63;63;63m [0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[7m[38;2;62;62;62m [0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[7m[38;2;61;61;61m [0m[38;2;61;61;61m[48;2;60;60;60m▀[0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;72;72;72m[48;2;71;71;71m▀[0m[38;2;72;72;72m[48;2;71;71;71m▀[0m[7m[38;2;70;70;70m [0m[7m[38;2;69;69;69m [0m[38;2;64;64;64m[48;2;66;66;66m▀[0m[38;2;58;58;58m[48;2;62;62;62m▀[0m[38;2;127;127;127m[48;2;57;57;57m▀[0m[38;2;220;220;220m[48;2;125;125;125m▀[0m[38;2;219;219;219m[48;2;217;217;217m▀[0m[38;2;218;218;218m[48;2;216;216;216m▀[0m[38;2;217;217;217m[48;2;215;215;215m▀[0m[38;2;192;192;192m[48;2;214;214;214m▀[0m[38;2;79;79;79m[48;2;195;195;195m▀[0m[38;2;66;66;66m[48;2;83;83;83m▀[0m[38;2;67;67;67m[48;2;65;65;65m▀[0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[7m[38;2;66;66;66m [0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[7m[38;2;65;65;65m [0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[7m[38;2;64;64;64m [0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[7m[38;2;63;63;63m [0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[7m[38;2;62;62;62m [0m[7m[38;2;62;62;62m [0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[7m[38;2;61;61;61m [0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[7m[38;2;60;60;60m [0m[38;2;60;60;60m[48;2;59;59;59m▀[0m[38;2;60;60;60m[48;2;59;59;59m▀[0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;71;71;71m[48;2;70;70;70m▀[0m[7m[38;2;70;70;70m [0m[38;2;70;70;70m[48;2;69;69;69m▀[0m[38;2;70;70;70m[48;2;69;69;69m▀[0m[38;2;68;68;68m[48;2;69;69;69m▀[0m[38;2;66;66;66m[48;2;67;67;67m▀[0m[38;2;62;62;62m[48;2;64;64;64m▀[0m[38;2;56;56;56m[48;2;60;60;60m▀[0m[38;2;123;123;123m[48;2;62;62;62m▀[0m[38;2;214;214;214m[48;2;161;161;161m▀[0m[38;2;213;213;213m[48;2;211;211;211m▀[0m[38;2;212;212;212m[48;2;210;210;210m▀[0m[38;2;211;211;211m[48;2;209;209;209m▀[0m[38;2;192;192;192m[48;2;208;208;208m▀[0m[38;2;74;74;74m[48;2;84;84;84m▀[0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[38;2;65;65;65m[48;2;64;64;64m▀[0m[7m[38;2;64;64;64m [0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[7m[38;2;63;63;63m [0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[7m[38;2;62;62;62m [0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[7m[38;2;61;61;61m [0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[7m[38;2;60;60;60m [0m[7m[38;2;60;60;60m [0m[38;2;60;60;60m[48;2;59;59;59m▀[0m[7m[38;2;59;59;59m [0m[7m[38;2;59;59;59m [0m[38;2;59;59;59m[48;2;58;58;58m▀[0m[7m[38;2;58;58;58m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;70;70;70m[48;2;69;69;69m▀[0m[7m[38;2;69;69;69m [0m[38;2;69;69;69m[48;2;68;68;68m▀[0m[7m[38;2;68;68;68m [0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;67;67;67m[48;2;65;65;65m▀[0m[38;2;64;64;64m[48;2;72;72;72m▀[0m[38;2;69;69;69m[48;2;151;151;151m▀[0m[38;2;140;140;140m[48;2;160;160;160m▀[0m[38;2;139;139;139m[48;2;150;150;150m▀[0m[38;2;165;165;165m[48;2;137;137;137m▀[0m[38;2;208;208;208m[48;2;154;154;154m▀[0m[38;2;207;207;207m[48;2;116;116;116m▀[0m[38;2;132;132;132m[48;2;55;55;55m▀[0m[38;2;59;59;59m[48;2;60;60;60m▀[0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[7m[38;2;63;63;63m [0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[7m[38;2;62;62;62m [0m[7m[38;2;62;62;62m [0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[7m[38;2;61;61;61m [0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[7m[38;2;60;60;60m [0m[38;2;60;60;60m[48;2;59;59;59m▀[0m[38;2;60;60;60m[48;2;59;59;59m▀[0m[7m[38;2;59;59;59m [0m[38;2;59;59;59m[48;2;58;58;58m▀[0m[38;2;59;59;59m[48;2;58;58;58m▀[0m[7m[38;2;58;58;58m [0m[38;2;58;58;58m[48;2;57;57;57m▀[0m[38;2;58;58;58m[48;2;57;57;57m▀[0m[7m[38;2;57;57;57m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[7m[38;2;68;68;68m [0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;68;68;68m[48;2;67;67;67m▀[0m[38;2;67;67;67m[48;2;65;65;65m▀[0m[38;2;65;65;65m[48;2;69;69;69m▀[0m[38;2;72;72;72m[48;2;152;152;152m▀[0m[38;2;154;154;154m[48;2;168;168;168m▀[0m[38;2;168;168;168m[48;2;165;165;165m▀[0m[38;2;163;163;163m[48;2;162;162;162m▀[0m[38;2;156;156;156m[48;2;159;159;159m▀[0m[38;2;148;148;148m[48;2;97;97;97m▀[0m[38;2;93;93;93m[48;2;55;55;55m▀[0m[38;2;54;54;54m[48;2;58;58;58m▀[0m[38;2;58;58;58m[48;2;61;61;61m▀[0m[38;2;61;61;61m[48;2;62;62;62m▀[0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[38;2;63;63;63m[48;2;61;61;61m▀[0m[38;2;62;62;62m[48;2;108;108;108m▀[0m[38;2;62;62;62m[48;2;144;144;144m▀[0m[38;2;61;61;61m[48;2;143;143;143m▀[0m[38;2;61;61;61m[48;2;143;143;143m▀[0m[38;2;61;61;61m[48;2;141;141;141m▀[0m[38;2;60;60;60m[48;2;140;140;140m▀[0m[38;2;60;60;60m[48;2;140;140;140m▀[0m[38;2;60;60;60m[48;2;138;138;138m▀[0m[38;2;59;59;59m[48;2;138;138;138m▀[0m[38;2;59;59;59m[48;2;137;137;137m▀[0m[38;2;58;58;58m[48;2;136;136;136m▀[0m[38;2;58;58;58m[48;2;100;100;100m▀[0m[38;2;58;58;58m[48;2;56;56;56m▀[0m[38;2;58;58;58m[48;2;57;57;57m▀[0m[7m[38;2;57;57;57m [0m[38;2;57;57;57m[48;2;56;56;56m▀[0m[38;2;57;57;57m[48;2;56;56;56m▀[0m[7m[38;2;56;56;56m [0m[38;2;56;56;56m[48;2;55;55;55m▀[0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[38;2;67;67;67m[48;2;66;66;66m▀[0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[38;2;63;63;63m[48;2;62;62;62m▀[0m[38;2;83;83;83m[48;2;62;62;62m▀[0m[38;2;166;166;166m[48;2;145;145;145m▀[0m[38;2;164;164;164m[48;2;161;161;161m▀[0m[38;2;162;162;162m[48;2;158;158;158m▀[0m[38;2;160;160;160m[48;2;97;97;97m▀[0m[38;2;98;98;98m[48;2;53;53;53m▀[0m[38;2;54;54;54m[48;2;57;57;57m▀[0m[38;2;58;58;58m[48;2;60;60;60m▀[0m[7m[38;2;61;61;61m [0m[7m[38;2;62;62;62m [0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[38;2;61;61;61m[48;2;59;59;59m▀[0m[38;2;56;56;56m[48;2;53;53;53m▀[0m[7m[38;2;226;226;226m [0m[38;2;227;227;227m[48;2;224;224;224m▀[0m[38;2;225;225;225m[48;2;223;223;223m▀[0m[38;2;224;224;224m[48;2;221;221;221m▀[0m[38;2;222;222;222m[48;2;220;220;220m▀[0m[38;2;221;221;221m[48;2;218;218;218m▀[0m[38;2;219;219;219m[48;2;217;217;217m▀[0m[38;2;218;218;218m[48;2;215;215;215m▀[0m[38;2;216;216;216m[48;2;214;214;214m▀[0m[38;2;215;215;215m[48;2;212;212;212m▀[0m[38;2;213;213;213m[48;2;211;211;211m▀[0m[38;2;210;210;210m[48;2;209;209;209m▀[0m[38;2;53;53;53m[48;2;50;50;50m▀[0m[38;2;56;56;56m[48;2;55;55;55m▀[0m[7m[38;2;56;56;56m [0m[38;2;56;56;56m[48;2;55;55;55m▀[0m[7m[38;2;55;55;55m [0m[38;2;55;55;55m[48;2;54;54;54m▀[0m[38;2;55;55;55m[48;2;54;54;54m▀[0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;66;66;66m[48;2;65;65;65m▀[0m[7m[38;2;65;65;65m [0m[7m[38;2;64;64;64m [0m[7m[38;2;62;62;62m [0m[38;2;57;57;57m[48;2;59;59;59m▀[0m[38;2;60;60;60m[48;2;56;56;56m▀[0m[38;2;100;100;100m[48;2;53;53;53m▀[0m[38;2;85;85;85m[48;2;55;55;55m▀[0m[38;2;53;53;53m[48;2;57;57;57m▀[0m[38;2;57;57;57m[48;2;60;60;60m▀[0m[38;2;59;59;59m[48;2;61;61;61m▀[0m[7m[38;2;61;61;61m [0m[38;2;62;62;62m[48;2;61;61;61m▀[0m[7m[38;2;61;61;61m [0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[7m[38;2;58;58;58m [0m[38;2;52;52;52m[48;2;54;54;54m▀[0m[38;2;182;182;182m[48;2;46;46;46m▀[0m[38;2;222;222;222m[48;2;43;43;43m▀[0m[38;2;220;220;220m[48;2;41;41;41m▀[0m[38;2;219;219;219m[48;2;41;41;41m▀[0m[38;2;217;217;217m[48;2;41;41;41m▀[0m[38;2;216;216;216m[48;2;40;40;40m▀[0m[38;2;214;214;214m[48;2;40;40;40m▀[0m[38;2;212;212;212m[48;2;40;40;40m▀[0m[38;2;211;211;211m[48;2;40;40;40m▀[0m[38;2;209;209;209m[48;2;40;40;40m▀[0m[38;2;208;208;208m[48;2;40;40;40m▀[0m[38;2;169;169;169m[48;2;43;43;43m▀[0m[38;2;48;48;48m[48;2;50;50;50m▀[0m[7m[38;2;53;53;53m [0m[38;2;55;55;55m[48;2;54;54;54m▀[0m[38;2;55;55;55m[48;2;54;54;54m▀[0m[7m[38;2;54;54;54m [0m[38;2;54;54;54m[48;2;53;53;53m▀[0m[38;2;54;54;54m[48;2;53;53;53m▀[0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m[38;2;65;65;65m[48;2;59;59;59m▀[0m[7m[38;2;64;64;64m [0m[38;2;64;64;64m[48;2;63;63;63m▀[0m[7m[38;2;63;63;63m [0m[38;2;61;61;61m[48;2;63;63;63m▀[0m[38;2;60;60;60m[48;2;61;61;61m▀[0m[38;2;59;59;59m[48;2;61;61;61m▀[0m[38;2;59;59;59m[48;2;61;61;61m▀[0m[38;2;60;60;60m[48;2;61;61;61m▀[0m[7m[38;2;61;61;61m [0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[38;2;61;61;61m[48;2;60;60;60m▀[0m[7m[38;2;60;60;60m [0m[38;2;60;60;60m[48;2;59;59;59m▀[0m[38;2;60;60;60m[48;2;59;59;59m▀[0m[38;2;58;58;58m[48;2;59;59;59m▀[0m[38;2;56;56;56m[48;2;57;57;57m▀[0m[38;2;53;53;53m[48;2;55;55;55m▀[0m[38;2;50;50;50m[48;2;54;54;54m▀[0m[38;2;50;50;50m[48;2;53;53;53m▀[0m[38;2;49;49;49m[48;2;53;53;53m▀[0m[38;2;49;49;49m[48;2;53;53;53m▀[0m[38;2;49;49;49m[48;2;52;52;52m▀[0m[38;2;48;48;48m[48;2;52;52;52m▀[0m[38;2;48;48;48m[48;2;52;52;52m▀[0m[38;2;47;47;47m[48;2;51;51;51m▀[0m[38;2;47;47;47m[48;2;51;51;51m▀[0m[38;2;48;48;48m[48;2;52;52;52m▀[0m[38;2;49;49;49m[48;2;52;52;52m▀[0m[38;2;51;51;51m[48;2;53;53;53m▀[0m[7m[38;2;53;53;53m [0m[38;2;54;54;54m[48;2;53;53;53m▀[0m[7m[38;2;53;53;53m [0m[38;2;53;53;53m[48;2;52;52;52m▀[0m[38;2;53;53;53m[48;2;52;52;52m▀[0m[38;2;52;52;52m[48;2;48;48;48m▀[0m [0m [0m [0m [0m [0m [0m [0m
|
||||
[0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m [0m
|
||||
@@ -9,7 +9,7 @@ issue id: #1043
|
||||
|
||||
## Abstract
|
||||
|
||||
This spec is for task #1043 “Be able to set an initial position for the terminal”. It goes over the details of a new feature that allows users to set the initial position and size of the terminal. Expected behavior and design of this feature is included. Besides, future possible follow-up works are also addressed.
|
||||
This spec is for task #1043 “Be able to set an initial position for the terminal”. It goes over the details of a new feature that allows users to set the initial position and size of the terminal. Expected behavior and design of this feature is included. Besides, future possible follow-up works are also addressed.
|
||||
|
||||
## Inspiration
|
||||
|
||||
@@ -17,7 +17,7 @@ The idea is to allow users to set the initial position of the Terminal when they
|
||||
|
||||
## Solution Design
|
||||
|
||||
For now, the Terminal window is put on a default initial position. The program uses CW_USEDEFAULT in the screen coordinates for top-left corner. We have two different types of window – client window and non-client window. However, code path for window creation (WM_CREATE message is shared by the two types of windows) are almost the same for the two types of windows, except that there are some differences in calculation of the width and height of the window.
|
||||
For now, the Terminal window is put on a default initial position. The program uses CW_USEDEFAULT in the screen coordinates for top-left corner. We have two different types of window – client window and non-client window. However, code path for window creation (WM_CREATE message is shared by the two types of windows) are almost the same for the two types of windows, except that there are some differences in calculation of the width and height of the window.
|
||||
|
||||
Two new properties should be added in the json settings file:
|
||||
|
||||
@@ -92,9 +92,9 @@ For now, this feature only allows the user to set initial position and choose wh
|
||||
|
||||
3. We may also consider more launch modes. Like full screen mode and minimized mode.
|
||||
|
||||
Github issue for future follow-ups: https://github.com/microsoft/terminal/issues/766
|
||||
GitHub issue for future follow-ups: https://github.com/microsoft/terminal/issues/766
|
||||
|
||||
## Resources
|
||||
|
||||
Github issue:
|
||||
GitHub issue:
|
||||
https://github.com/microsoft/terminal/issues/1043
|
||||
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 345 KiB After Width: | Height: | Size: 253 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 29 KiB |
BIN
doc/specs/#1564 - Settings UI/add-new-profile.png
Normal file
|
After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 233 KiB |
146
doc/specs/#1564 - Settings UI/cascading-settings.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
authors: Carlos Zamora (@carlos-zamora) and Kayla Cinnamon (@cinnamon-msft)
|
||||
created on: 2020-11-10
|
||||
last updated: 2020-11-19
|
||||
issue id: 1564
|
||||
---
|
||||
|
||||
# Cascading Settings
|
||||
|
||||
## Abstract
|
||||
|
||||
Windows Terminal's settings model adheres to a cascading settings architecture. This allows a settings object to be defined incrementally across multiple layers of declarations. The value for any global setting like `copyOnSelect`, for example, is set to your settings.json value if one is defined, otherwise defaults.json, and otherwise a system set value. Profiles in particular are more complicated in that they must also take into account the values in `profiles.defaults` and dynamic profile generators.
|
||||
|
||||
This spec explores how to represent this feature in the Settings UI.
|
||||
|
||||
## Inspiration
|
||||
|
||||
Cascading settings (and `profiles.defaults` by extension) provide some major benefits:
|
||||
1. opt-in behavior for settings values provided in-box (i.e. reset to default)
|
||||
2. easy way to apply a setting to all your profiles
|
||||
3. (possible future feature) simple way to base a profile off of another profile
|
||||
|
||||
The following terminal emulators approach this issue as follows.
|
||||
| Terminal Emulator(s) | Relevant Features/Approach |
|
||||
|--|--|
|
||||
| ConEmu, Cmder | "Clone" a separate profile |
|
||||
| Fluent Terminal | "Restore Defaults" button on each page |
|
||||
| iTerm2 | "Bulk Copy from Selected Profile..." and "Duplicate Profile" |
|
||||
|
||||
Other Settings UIs have approached this issue as follows:
|
||||
| Project | Relevant Approach |
|
||||
|--|--|
|
||||
| Visual Studio | Present a dropdown with your options. An extra "\<inherit\>" option is shown to inherit a value from another place. |
|
||||
|
||||
## Solution Design
|
||||
|
||||
The XAML implementation will consist of introducing a `ContentControl` for each setting. The `ContentControl` simply wraps the XAML control used for a setting, then adds the chosen UI approach below.
|
||||
|
||||
The `ContentControl` will take advantage of the following TerminalSettingsModel APIs for each setting:
|
||||
```c++
|
||||
// Note: String and "Name" are replaced for each setting
|
||||
bool HasName();
|
||||
void ClearName();
|
||||
String Name();
|
||||
void Name(String val);
|
||||
```
|
||||
|
||||
## UI/UX Design Proposals
|
||||
|
||||
The proposals below will be used in combination with each other.
|
||||
|
||||
### 1: Text under a setting control
|
||||
|
||||
This design renames the "Global" page under Profiles to "Base layer". Settings that override those in profile.defaults will get text under the control saying "Overrides Base layer.". Next to the titles of controls that override the base layer is a reset button with a tooltip that says "Reset".
|
||||
|
||||

|
||||
|
||||
### Add New --> Duplicate Profile
|
||||
|
||||
The Add new profile button in the navigation menu would take you to a new page. This page will have radio buttons listing your profiles along with a default settings option. The user can choose to either duplicate a profile or create a new one from the default settings. Once the user makes a selection, the settings UI will take them to their new profile page. The fields on that profile page will be filled according to which profile selection the user made.
|
||||
|
||||

|
||||
|
||||
### Reset Profile button
|
||||
|
||||
On the Advanced pivot of a profile's page, there will be a button at the bottom for resetting a profile called "Reset to default settings". This button will remove the user's custom settings inside this profile's object and reset it to defaults, prioritizing profile.defaults then defaults.json.
|
||||
|
||||
### "Apply to all profiles" button
|
||||
|
||||
A way we could apply settings to all profiles is by adding a "Copy settings to..." button to the Advanced page of each profile. This button will open a content dialog with a tree view listing every profile setting. The user can select which settings they would like to copy over to another profile. At the bottom of the content dialog will list the user's profiles with checkboxes, allowing them to pick which profiles they'd like to copy settings to.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Previously considered ideas
|
||||
|
||||
These ideas were considered however we will not be moving forward with them.
|
||||
|
||||
### 1: \<inherit\> option
|
||||
|
||||
Each setting is an Editable ComboBox (except for boolean and enumerable settings). For booleans, the items will be Enabled and Disabled in a regular ComboBox. Enumerable settings will have their options listed in a regular ComboBox. For integers, most commonly used numbers will be listed.
|
||||
|
||||

|
||||
|
||||
**Pros**
|
||||
|
||||
- Doesn't clutter the screen.
|
||||
|
||||
**Cons**
|
||||
|
||||
- Every setting is a dropdown.
|
||||
|
||||
**Pitfalls**
|
||||
|
||||
- How will color pickers work with this scenario?
|
||||
|
||||
**Other considerations**
|
||||
|
||||
Each dropdown has either "inherit" or "custom". If the user selects "custom", the original control will appear (i.e. a color picker for colors or a number picker for integers).
|
||||
|
||||
This option was not chosen because it added too much overhead for changing a setting. For example, if you wanted to enable acrylic, you'd have to click the dropdown, select custom, watch the checkbox appear, and then select the checkbox.
|
||||
|
||||
### 2: Lock Button
|
||||
|
||||
Every setting will have a lock button next to it. If the lock is locked, that means the setting is being inherited from Global, and the control is disabled. If the user wants to edit the setting, they can click the lock, which will changed it to the unlocked lock icon, and the control will become enabled.
|
||||
|
||||

|
||||
|
||||
**Pros**
|
||||
|
||||
- Least amount of clutter on the screen while still keeping the original controls
|
||||
|
||||
**Cons**
|
||||
|
||||
- The lock concept is slightly confusing. Some may assume locking the setting means that it *won't* be inherited from Global and that it's "locked" to the profile. This is the opposite case for its current design. However, flipping the logic of the locks wouldn't make sense with an unlocked lock and a disabled control.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
All of these additions to the settings UI will have to be accessibility tested.
|
||||
|
||||
### Security
|
||||
|
||||
These changes will not impact security.
|
||||
|
||||
### Reliability
|
||||
|
||||
These changes will not impact reliability.
|
||||
|
||||
### Compatibility
|
||||
|
||||
The partial parity with JSON route will give the settings UI a different compatibility from the JSON file itself. This is not necessarily a bad thing. The settings UI is intended to be a simplistic way for people to successfully edit their settings. If too many options are added to give it fully parity with JSON, it could compromise the simplistic benefit the settings UI provides.
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
These changes will not impact performance, power, nor efficiency.
|
||||
|
||||
## Potential Issues
|
||||
|
||||
## Future considerations
|
||||
|
||||
When we add profile inheritance later, we can implement a layering page using a rearrangeable TreeView.
|
||||
|
||||
## Resources
|
||||
BIN
doc/specs/#1564 - Settings UI/copy-settings-1.png
Normal file
|
After Width: | Height: | Size: 364 KiB |
BIN
doc/specs/#1564 - Settings UI/copy-settings-2.png
Normal file
|
After Width: | Height: | Size: 362 KiB |
BIN
doc/specs/#1564 - Settings UI/inheritance-dropdown.png
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
doc/specs/#1564 - Settings UI/inheritance-locks.png
Normal file
|
After Width: | Height: | Size: 267 KiB |
BIN
doc/specs/#1564 - Settings UI/inheritance-text.png
Normal file
|
After Width: | Height: | Size: 268 KiB |
|
Before Width: | Height: | Size: 215 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 211 KiB After Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 26 KiB |
105
doc/specs/#1790 - Font features and axes-spec.md
Normal file
@@ -0,0 +1,105 @@
|
||||
---
|
||||
author: Pankaj Bhojwani, pabhojwa@microsoft.com
|
||||
created on: 2021-6-17
|
||||
last updated: 2021-6-23
|
||||
issue id: #1790
|
||||
---
|
||||
|
||||
# Font features and axes of variation
|
||||
|
||||
## Abstract
|
||||
|
||||
This spec outlines how we can allow users to specify font features and axes of variation for fonts in Windows Terminal. Font features include things like being able to specify whether ligatures should be used as well as the specific stylistic set used for a font. Axes of variation commonly include things like weight and slant but can also include fancier things like shadow distance, depending on the font.
|
||||
|
||||
## Inspiration
|
||||
|
||||
Reference: [#1790](https://github.com/microsoft/terminal/issues/1790)
|
||||
|
||||
Currently, if a font has ligatures, we offer no way for a user to disable them. Many users would like the option to do so, and would also like the ability to choose stylistic sets for fonts - for example, at the time of this writing, Cascadia Code offers 4 stylistic sets but we offer no way for users to specify any of them.
|
||||
|
||||
In a similar vein, many fonts allow for setting variations on the font along certain attributes, commonly referred to as 'axes of variation'. We can offer users more font customization options by allowing them to configure these font variations.
|
||||
|
||||
## Solution Design
|
||||
|
||||
### Font features
|
||||
|
||||
It is already possible to pass in a list of [font feature structs](https://docs.microsoft.com/en-us/windows/win32/api/dwrite/ns-dwrite-dwrite_font_feature) to DWrite for it to handle. A font feature struct contains only 2 things:
|
||||
|
||||
1. A font feature tag
|
||||
2. A parameter value
|
||||
|
||||
A font feature tag is constructed using a 4-character feature tag and the parameter value defines how the feature is applied. For most features, the parameter value is simply treated as a binary value - a value of 0 means the feature is not applied and a non-zero value means the feature is applied. For example, a font feature struct like {'ss03', 1} enables stylistic set 3 for the font and a font feature struct like {'liga', 0} disables ligatures. (Technically, the feature tag is _constructed_ with the 4-character tag and is not the 4-character tag itself, but they are treated the same in the example here for brevity's sake).
|
||||
|
||||
Currently, we pass in to DWrite a null value for the list of features to apply to the font. This causes DWrite to automatically apply a ['standard' list](https://github.com/fdwr/TextLayoutSampler/blob/master/DrawableObject.ixx#L802) of font features to the font. Naturally, passing in our own list of font features to DWrite means DWrite will _only_ apply the features we defined, and no longer apply the standard list. Since the standard list contains 11 features, we need to consider how we can allow users to specify 1 additional feature or delete 1 of the standard features without needing to redefine all the others.
|
||||
|
||||
We will do this by allowing users to define a dictionary in their settings.json file, where the keys are the 4-character feature tags and the values are the parameter values. This dictionary will then get applied to our internal dictionary (which will contain the standard list of 11 features with their parameter values), meaning that any new key-value pairs will get added to our dictionary and any existing key-value pairs will get updated. Finally, this 'merged' dictionary will be what we use to construct the list of features to pass into DWrite.
|
||||
|
||||
### Axes of variation
|
||||
|
||||
Specifying axes of variation is done in an extremely similar manner to the way font features are specified - a 4-character tag is used to specify which font axis is being modified and a numerical value is provided to specify the value the axis should be set to. For example, {'slnt', 20} specifies that the 'slant' axis should be set to 20.
|
||||
|
||||
There is also a standard list of axes of variation, and each axis has its own default. We will approach this the same way we approached font features, by allowing users to specify additional features or omit features without needing to redefine the defaults.
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
Users will be able to add a new setting to their font objects (added in [#10433](https://github.com/microsoft/terminal/pull/10433)). The resultant font object may look something like this
|
||||
|
||||
```json
|
||||
"font": {
|
||||
"face": "Cascadia Code",
|
||||
"size": 12,
|
||||
"features": {
|
||||
"ss03": 1,
|
||||
"liga": 0
|
||||
},
|
||||
"axes": {
|
||||
"slnt": 20.5
|
||||
}
|
||||
}
|
||||
```
|
||||
There is one point to note here about clashing. For example, if a user has the old "weight" setting defined _as well as_ a "wght" axis defined, we will only use the "wght" axis value. We prioritize that value for a few reasons:
|
||||
|
||||
1. It is the more recent addition to our settings model. Thus, it is likely that a user that has defined both values probably just forgot to remove the old value.
|
||||
2. It is the more precise value, it is a specific float value whereas the the old "weight" setting is an enum (that eventually gets mapped to a float value).
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
Should not affect accessibility.
|
||||
|
||||
### Security
|
||||
|
||||
Should not affect security.
|
||||
|
||||
### Reliability
|
||||
|
||||
Aside from additional parsing required for the settings file (which inherently offers more locations for parsing to fail), we need to be careful about badly formed/non-existant feature tags or axes specified in the user-defined dictionaries. We must make sure to ignore such declarations (perhaps alongside emitting a warning to the user) and only apply those that are correctly formed and exist.
|
||||
|
||||
### Compatibility
|
||||
|
||||
Older versions of Windows may not have the DWrite updates that allow for defining font features and axes of variation. We must make sure to fallback to the current implementation in these cases.
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
Currently when rendering a run of text, if we detect that the given run is simple we will use a shortcut to obtain the glyphs needed, skipping over an expensive `GetGlyphs` call to DWrite. However, when the default feature list is changed in any way (either by adding a new feature or removing one of the defaults), there is no way for us to detect beforehand how the font glyphs would change.
|
||||
|
||||
This means that as long as the user requests a change to the default font feature list, we will _always_ skip the shortcut and call the expensive `GetGlyphs` function for every run of text.
|
||||
|
||||
This will naturally cause a performance cost that we will have to bear for this feature. However, it is worth noting that there are a fair number of glyphs that will cause a run of text to be deemed "not simple" (and thus cause us to call `GetGlyphs` anyway), for example when using Cascadia Code, any run of text that has the letters 'i', 'j', 'l', 'n', 'w' or 'x' is not considered simple (because those glyphs have localized variants).
|
||||
|
||||
## Potential Issues
|
||||
|
||||
See performance issues above.
|
||||
|
||||
## Future considerations
|
||||
|
||||
DWrite additionally offers the ability to vary the font features across runs of text. However, for our initial implementation of this feature, we will only apply font features to the entire buffer. If/when we decide to allow specifying font features for particular runs of text, we can lean into our existing mechanisms of splitting up runs of text to implement that.
|
||||
|
||||
We will also need to consider how we want to represent this in the settings UI. This is slightly more complex than other settings since users should be allowed to manually input 4-character tags.
|
||||
|
||||
## Resources
|
||||
|
||||
[DWRITE_FONT_FEATURE structure](https://docs.microsoft.com/en-us/windows/win32/api/dwrite/ns-dwrite-dwrite_font_feature)
|
||||
|
||||
[DWRITE_FONT_AXIS_VALUE structure](https://docs.microsoft.com/en-us/windows/win32/api/dwrite_3/ns-dwrite_3-dwrite_font_axis_value)
|
||||
302
doc/specs/#2871 - Pane Navigation/#2871 - Pane Navigation.md
Normal file
@@ -0,0 +1,302 @@
|
||||
---
|
||||
author: Mike Griese @zadjii-msft
|
||||
created on: 2020-11-23
|
||||
last updated: 2020-12-15
|
||||
issue id: #2871
|
||||
---
|
||||
|
||||
# Focus Pane Actions
|
||||
|
||||
## Abstract
|
||||
|
||||
Currently, the Terminal only allows users to navigate through panes
|
||||
_directionally_. However, we might also want to allow a user to navigate through
|
||||
panes in most recently used order ("MRU" order), or to navigate directly to a
|
||||
specific pane. This spec proposes some additional actions in order to enable
|
||||
these sorts of scenarios.
|
||||
|
||||
## Background
|
||||
|
||||
### Inspiration
|
||||
|
||||
`tmux` allows the user to navigate through panes using its `select-pane`
|
||||
command. The `select-pane` command works in the following way:
|
||||
|
||||
```
|
||||
select-pane [-DLlMmRU] [-T title] [-t target-pane]
|
||||
|
||||
Make pane target-pane the active pane in window target-window, or set its
|
||||
style (with -P). If one of -D, -L, -R, or -U is used, respectively the
|
||||
pane below, to the left, to the right, or above the target pane is used.
|
||||
-l is the same as using the last-pane command.
|
||||
|
||||
-m and -M are used to set and clear the marked pane. There is one marked
|
||||
pane at a time, setting a new marked pane clears the last. The marked pane
|
||||
is the default target for -s to join-pane, swap-pane and swap-window.
|
||||
```
|
||||
_from `man tmux`_.
|
||||
|
||||
The Terminal currently allows the user to navigate through panes with the
|
||||
`moveFocus` action, which only accepts a `direction` to move in.
|
||||
|
||||
Additionally, the Terminal allows movement between tabs with the `nextTab` and
|
||||
`prevTab` actions, who move between tabs either in-order or in MRU order.
|
||||
Furthermore, these actions may or may not display the "tab switcher" user
|
||||
interface, based on the value of `tabSwitcherMode`.
|
||||
|
||||
### User Stories
|
||||
|
||||
* **Scenario 1**: A user who wants to be able to split the window into 4 equal
|
||||
corners from the commandline. Currently this isn't possible, because the user
|
||||
cannot move focus during the startup actions - `split-pane` actions always end
|
||||
up splitting the current leaf in the tree of panes. (see [#5464])
|
||||
* **Scenario 2**: A user who wants to quickly navigate to the previous pane they
|
||||
had opened. (see [#2871])
|
||||
* **Scenario 3**: A user who wants to bind a keybinding like <kbd>alt+1</kbd>,
|
||||
<kbd>alt+2</kbd>, etc to immediately focus the first, second, etc. pane in a
|
||||
tab. (see [#5803])
|
||||
|
||||
### Future Considerations
|
||||
|
||||
There's been talk of updating the advanced tab switcher to also display panes,
|
||||
in addition to just tabs. This would allow users to navigate through the ATS
|
||||
directly to a pane, and see all the panes in a tab. Currently, `tabSwitcherMode`
|
||||
changes the behavior of `nextTab`, `prevTab` - should we just build the
|
||||
`paneSwitcherMode` directly into the action we end up designing?
|
||||
|
||||
## Solution Design
|
||||
|
||||
Does using the pane switcher with a theoretical `focusPane(target=id)` action
|
||||
even make sense? Certainly not! That's like `switchToTab(index=id)`, the user
|
||||
already knows which tab they want to go to, there's no reason to pop an
|
||||
ephemeral UI in front of them.
|
||||
|
||||
Similarly, it almost certainly doesn't make sense to display the pane switcher
|
||||
while moving focus directionally. Consider moving focus with a key bound to the
|
||||
arrow keys. Displaying another UI in front of them while moving focus with the
|
||||
arrow keys would be confusing.
|
||||
|
||||
Addressing Scenario 1 is relatively easy. So long as we add any of the proposed
|
||||
actions, including the existing `moveFocus` action as a subcommand that can be
|
||||
passed to `wt.exe`, then the user should be able to navigate through the panes
|
||||
they've created with the startup commandline, and build the tree of panes
|
||||
however they see fit.
|
||||
|
||||
Scenario 2 is more complicated, because MRU switching is always more
|
||||
complicated. Without a UI of some sort, there's no way to switch to another pane
|
||||
in the MRU order without also updating the MRU order as you go. So this would
|
||||
almost certainly necessitate a "pane switcher", like the tab switcher.
|
||||
|
||||
|
||||
### Proposal A: Add next, prev to moveFocus
|
||||
|
||||
* `moveFocus(direction="up|down|left|right|next|prev")`
|
||||
|
||||
* **Pros**:
|
||||
- Definitely gets the "MRU Pane Switching" scenario working
|
||||
* **Cons**:
|
||||
- Doesn't really address any of the other scenarios
|
||||
- How will it play with pane switching in the UI?
|
||||
- MRU switching without a dialog to track & display the MRU stack doesn't
|
||||
really work - this only allows to the user to navigate to the most recently
|
||||
used pane, or through all the panes in least-recently-used order. This is
|
||||
because switching to the MRU pane _will update the MRU pane_.
|
||||
|
||||
❌ This proposal is no longer being considered.
|
||||
|
||||
### Proposal B: focusNextPane, focusPrevPane with order, useSwitcher args
|
||||
|
||||
```json
|
||||
// Focus pane 1
|
||||
// - This is sensible, no arguments here
|
||||
{ "command": { "action": "focusPane", "id": 1 } },
|
||||
|
||||
// Focus the next MRU pane
|
||||
// - Without the switcher, this can only go one pane deep in the MRU stack
|
||||
// - presumably once there's a pane switcher, it would default to enabled?
|
||||
{ "command": { "action": "focusNextPane", "order": "mru" } },
|
||||
|
||||
// Focus the prev inOrder pane
|
||||
// - this seems straightforward
|
||||
{ "command": { "action": "focusPrevPane", "order": "inOrder" } },
|
||||
|
||||
// Focus the next pane, in mru order, explicitly disable the switcher
|
||||
// - The user opted in to only being able to MRU switch one deep. That's fine, that's what they want.
|
||||
{ "command": { "action": "focusNextPane", "order": "mru", "useSwitcher": false} },
|
||||
|
||||
// Focus the prev inOrder pane, explicitly with the switcher
|
||||
// - Maybe they disabled the switcher globally, but what it on for this action?
|
||||
{ "command": { "action": "focusPrevPane", "order": "inOrder", "useSwitcher": true } },
|
||||
```
|
||||
_From [discussion in the implementation
|
||||
PR](https://github.com/microsoft/terminal/pull/8183#issuecomment-729672645)_
|
||||
|
||||
Boiled down, that's three actions:
|
||||
* `focusPane(target=id)`
|
||||
* `focusNextPane(order="inOrder|mru", useSwitcher=true|false)`
|
||||
* `focusPrevPane(order="inOrder|mru", useSwitcher=true|false)`
|
||||
|
||||
* **Pros**:
|
||||
- Everything is explicit, including the option to use the pane switcher (when
|
||||
available)
|
||||
- Adds support for in-order pane switching
|
||||
- No "conditional parameters" - where providing one argument makes other
|
||||
arguments invalid or ambiguous.
|
||||
* **Cons**:
|
||||
- Doesn't really address any of the other scenarios
|
||||
- What does the "next most-recently-used tab" even mean? How is it different
|
||||
than "previous most-recently-used tab"? Semantically, these are the same
|
||||
thing!
|
||||
- No one's even asked for in-order pane switching. Is that a UX that even
|
||||
really makes sense?
|
||||
|
||||
❌ This proposal is no longer being considered.
|
||||
|
||||
> 👉 **NOTE**: At this point, we stopped considering navigating in both MRU
|
||||
> "directions", since both the next and prev MRU pane are the same thing. We're
|
||||
> now using "last" to mean "the previous MRU pane".
|
||||
|
||||
### Proposal C: One actions, combine the args
|
||||
|
||||
* `moveFocus(target=id|"up|down|left|right|last")`
|
||||
|
||||
* **Pros**:
|
||||
- Absolutely the least complicated action to author. There's only one
|
||||
parameter, `target`.
|
||||
- No "conditional parameters".
|
||||
* **Cons**:
|
||||
- How do we express this in the Settings UI? Mixed-type enums work fine for
|
||||
the font weight, where each enum value has a distinct integer value it maps
|
||||
to, but in this case, using `id` is entirely different from the other
|
||||
directional values
|
||||
|
||||
❌ This proposal is no longer being considered.
|
||||
|
||||
### Proposal D: Two actions
|
||||
|
||||
* `focusPane(target=id)`
|
||||
* `moveFocus(direction="up|down|left|right|last")`
|
||||
|
||||
* **Pros**:
|
||||
- Each action does explicitly one thing.
|
||||
* **Cons**:
|
||||
- two actions for _similar_ behavior
|
||||
- This now forks the "Direction" enum into "MoveFocusDirection" and
|
||||
"ResizeDirection" (because `resizePane(last)` doesn't make any sense).
|
||||
|
||||
This proposal doesn't really have any special consideration for the pane
|
||||
switcher UX. Neither of these actions would summon the pane switcher UX.
|
||||
|
||||
### Proposal E: Three actions
|
||||
|
||||
* `focusPane(target=id)`
|
||||
* `moveFocus(direction="up|down|left|right")`
|
||||
* `focusLastPane(usePaneSwitcher=false|true)`
|
||||
|
||||
In this design, neither `focusPane` nor `moveFocus` will summon the pane
|
||||
switcher UI (even once it's added). However, the `focusLastPane` one _could_,
|
||||
and subsequent keypresses could pop you through the MRU stack, while it's
|
||||
visible? The pane switcher could then display the panes for the tab in MRU
|
||||
order, and the user could just use the arrow keys to navigate the list if they
|
||||
so choose.
|
||||
|
||||
* **Pros**:
|
||||
- Each action does explicitly one thing.
|
||||
- Design accounts for future pane switcher UX
|
||||
* **Cons**:
|
||||
- Three separate actions for similar behavior
|
||||
|
||||
❌ This proposal is no longer being considered.
|
||||
|
||||
### Proposal F: It's literally just tmux
|
||||
|
||||
_Also known as the "one action to rule them all" proposal_
|
||||
|
||||
`focusPane(target=id, direction="up|down|left|right|last")`
|
||||
|
||||
Previously, this design was avoided, because what does `focusPane(target=4,
|
||||
direction=down)` do? Does it focus pane 4, or does it move focus down?
|
||||
|
||||
`tmux` solves this in one action by just doing both!
|
||||
|
||||
```
|
||||
Make pane target-pane the active pane ... If one of -D, -L, -R, or -U is used,
|
||||
respectively the pane below, to the left, to the right, or above the target pane
|
||||
is used.
|
||||
```
|
||||
_from `man tmux`_.
|
||||
|
||||
So `focusPane(target=1, direction=up)` will attempt to focus the pane above pane
|
||||
1. This action would not summon the pane switcher UX, even for
|
||||
`focusPane(direction=last)`
|
||||
|
||||
* **Pros**:
|
||||
- Fewest redundant actions
|
||||
* **Cons**:
|
||||
- Is this intuitive? That combining the params would do both, with `target`
|
||||
happening "first"?
|
||||
- Assumes that there will be a separate action added in the future for "Open
|
||||
the pane switcher (with some given ordering)"
|
||||
|
||||
|
||||
> 👉 **NOTE**: At this point, the author considered "Do we even want a separate
|
||||
> action to engage the tab switcher with panes expanded?" Perhaps panes being
|
||||
> visible in the tab switcher is just part fo the tab switcher's behavior. Maybe
|
||||
> there shouldn't be a separate "open the tab switcher with the panes expanded
|
||||
> to the pane I'm currently on, and the panes listed in MRU order" action.
|
||||
|
||||
❌ This proposal is no longer being considered.
|
||||
|
||||
## Conclusion
|
||||
|
||||
After much discussion as a team, we decided that **Proposal D** would be the
|
||||
best option. We felt that there wasn't a need to add any extra configuration to
|
||||
invoke the "pane switcher" as anything different than the "tab switcher". The
|
||||
"pane switcher" should really just exist as a part of the functionality of the
|
||||
advanced tab switcher, not as it's own thing.
|
||||
|
||||
Additionally, we concurred that the new "direction" value should be `prev`, not
|
||||
`last`, for consistency's sake.
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
The only real UX being added with the agreed upon design is allowing the user to
|
||||
execute an action to move to the previously active pane within a single tab. No
|
||||
additional UX (including the pane switcher) is being prescribed in this spec at
|
||||
this time.
|
||||
|
||||
## Potential Issues
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><strong>Compatibility</strong></td>
|
||||
<td>
|
||||
|
||||
We've only adding a single enum value to an existing enum. Since we're not
|
||||
changing the meaning of any of the existing values, we do not expect any
|
||||
compatibility issues there. Additionally, we're not changing the default value
|
||||
of the `direction` param of the `moveFocus` action, so there are no further
|
||||
compatibility concerns there. Furthermore, no additional parameters are being
|
||||
added to the `moveFocus` action that would potentially give it a different
|
||||
meaning.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
In the current design, there's no way to move through all the panes with a
|
||||
single keybinding. For example, if a user wanted to bind <kbd>Alt+]</kbd> to
|
||||
move to the "next" pane, and <kbd>Alt+[</kbd> to move to the "previous" one.
|
||||
These movements would necessarily need to be in-order traversals, since there's
|
||||
no way of doing multiple MRU steps.
|
||||
|
||||
Fortunately, no one's really asked for traversing the panes in-order, so we're
|
||||
not really worried about this. Otherwise, it would maybe make sense for `last`
|
||||
to be the "previous MRU pane", and reserve `next`/`prev` for in-order traversal.
|
||||
|
||||
|
||||
[#2871]: https://github.com/microsoft/terminal/issues/2871
|
||||
[#5464]: https://github.com/microsoft/terminal/issues/5464
|
||||
[#5803]: https://github.com/microsoft/terminal/issues/5803
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
author: Pankaj Bhojwani, pabhojwa@microsoft.com
|
||||
created on: 2020-11-20
|
||||
last updated: 2021-2-5
|
||||
issue id: #8345
|
||||
---
|
||||
|
||||
# Appearance configuration objects for profiles
|
||||
|
||||
## Abstract
|
||||
|
||||
This spec outlines how we can support 'configuration objects' in our profiles, which
|
||||
will allow us to render differently depending on the state of the control. For example, a
|
||||
control can be rendered differently if it's focused as compared to when it's unfocused.
|
||||
|
||||
## Inspiration
|
||||
|
||||
Reference: [#3062](https://github.com/microsoft/terminal/issues/3062)
|
||||
|
||||
Users want there to be a more visible indicator than the one we have currently for which
|
||||
pane is focused and which panes are unfocused. This change would grant us that feature.
|
||||
|
||||
## Solution Design
|
||||
|
||||
The implementation design for appearance config objects centers around the recent change where inheritance was added to the
|
||||
`TerminalSettings` class in the Terminal Settings Model - i.e. different `TerminalSettings` objects can inherit from each other.
|
||||
The reason for this change was that we did not want a settings reload to erase any overrides `TermControl` may have made
|
||||
to the settings during runtime. By instead passing a child of the `TerminalSettings` object to the control, we can change
|
||||
the parent of the child during a settings reload without the overrides being erased (since those overrides live in the child).
|
||||
|
||||
The idea behind unfocused appearance configurations is similar. We will pass in another `TerminalSettings` object to the control,
|
||||
which is simply a child that already has some overrides in it. When the control gains or loses focus, it simply switches between
|
||||
the two settings objects appropriately.
|
||||
|
||||
### Allowed parameters
|
||||
|
||||
For now, these states are meant to be entirely appearance-based. So, not all parameters which can be
|
||||
defined in a `Profile` can be defined in this new object (for example, we do not want parameters which
|
||||
would cause a resize in this object.) Here is the list of parameters we will allow:
|
||||
|
||||
- Anything regarding colors: `colorScheme`, `foreground`, `background`, `cursorColor` etc
|
||||
- Anything regarding background image: `path`, `opacity`, `alignment`, `stretchMode`
|
||||
- `cursorShape`
|
||||
|
||||
We may wish to allow further parameters in these objects in the future (like `bellStyle`?). The addition
|
||||
of further parameters can be discussed in the future and is out of scope for this spec.
|
||||
|
||||
### Inheritance
|
||||
|
||||
The inheritance model can be thought of as an 'all-or-nothing' approach in the sense that the `unfocusedAppearance` object
|
||||
is considered as a *single* setting instead of an object with many settings. We have chosen this model because it is cleaner
|
||||
and easier to understand than the alternative, where each setting within an `unfocusedAppearance` object has a parent from which
|
||||
it obtains its value.
|
||||
|
||||
Note that when `TerminalApp` initializes a control, it creates a `TerminalSettings` object for that profile and passes the
|
||||
control a child of that object (so that the control can store overrides in the child, as described earlier). If an unfocused
|
||||
config is defined in the profile (or in globals/profile defaults), then `TerminalApp` will create a *child of that child*,
|
||||
put the relevant overrides in it, and pass that into the control as well. Thus, the inheritance of any undefined parameters
|
||||
in the unfocused config will be as follows:
|
||||
|
||||
1. The unfocused config specified in the profile (or in globals/profile defaults)
|
||||
2. Overrides made by the terminal control
|
||||
3. The parent profile
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
Users will be able to add a new setting to their profiles that will look like this:
|
||||
|
||||
```
|
||||
"unfocusedAppearance":
|
||||
{
|
||||
"colorScheme": "Campbell",
|
||||
"cursorColor": "#888",
|
||||
"cursorShape": "emptyBox",
|
||||
"foreground": "#C0C0C0",
|
||||
"background": "#000000"
|
||||
}
|
||||
```
|
||||
|
||||
When certain appearance settings are changed via OSC sequences (such as the background color), only the focused/regular
|
||||
appearance will change and the unfocused one will remain unchanged. However, since the unfocused settings object inherits
|
||||
from the regular one, it will still apply the change (provided it does not define its own value for that setting).
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
Does not affect accessibility.
|
||||
|
||||
### Security
|
||||
|
||||
Does not affect security.
|
||||
|
||||
### Reliability
|
||||
|
||||
This is another location in the settings where parsing/loading the settings may fail. However, this is the case
|
||||
for any new setting we add so I would say that this is a reasonable cost for this feature.
|
||||
|
||||
### Compatibility
|
||||
|
||||
Should not affect compatibility.
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
Rapidly switching between many panes, causing several successive appearance changes in a short period of time, could
|
||||
potentially impact performance. However, regular/reasonable pane switching should not have a noticeable effect.
|
||||
|
||||
## Potential Issues
|
||||
|
||||
Inactive tabs will be 'rendered' in the background with the `UnfocusedRenderingParams` object, we need to make
|
||||
sure that switching to an inactive tab (and so causing the renderer to update with the 'normal' parameters)
|
||||
does not cause the window to flash/show a jarring indicator that the rendering values changed.
|
||||
|
||||
## Future considerations
|
||||
|
||||
We will need to decide how this will look in the settings UI.
|
||||
|
||||
We may wish to add more states in the future (like 'elevated'). When that happens, we will need to deal with how
|
||||
these appearance objects can scale/layer over each other. We had a lot of discussion about this and could not find
|
||||
a suitable solution to the problem of multiple states being valid at the same time (like unfocused and elevated).
|
||||
This, along with the fact that it is uncertain if there even will be more states we would want to add led us to
|
||||
the conclusion that we should only support the unfocused state for now, and come back to this issue later. If there
|
||||
are no more states other than unfocused and elevated, we could allow combining them (like having an 'unfocused elevated' state).
|
||||
If there are more states, we could do the implementation as an extension rather than inherently supporting it.
|
||||
|
||||
## Resources
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 46 KiB |
@@ -0,0 +1,619 @@
|
||||
---
|
||||
author: Mike Griese @zadjii-msft
|
||||
created on: 2020-11-20
|
||||
last updated: 2021-08-17
|
||||
issue id: #1032
|
||||
---
|
||||
|
||||
# Elevation Quality of Life Improvements
|
||||
|
||||
## Abstract
|
||||
|
||||
For a long time, we've been researching adding support to the Windows Terminal
|
||||
for running both unelevated and elevated (admin) tabs side-by-side, in the same
|
||||
window. However, after much research, we've determined that there isn't a safe
|
||||
way to do this without opening the Terminal up as a potential
|
||||
escalation-of-privilege vector.
|
||||
|
||||
Instead, we'll be adding a number of features to the Terminal to improve the
|
||||
user experience of working in elevated scenarios. These improvements include:
|
||||
|
||||
* A visible indicator that the Terminal window is elevated ([#1939])
|
||||
* Configuring the Terminal to always run elevated ([#632])
|
||||
* Configuring a specific profile to always open elevated ([#632])
|
||||
* Allowing new tabs, panes to be opened elevated directly from an unelevated
|
||||
window
|
||||
* Dynamic profile appearance that changes depending on if the Terminal is
|
||||
elevated or not. ([#1939], [#8311])
|
||||
|
||||
## Background
|
||||
|
||||
_This section was originally authored in the [Process Model 2.0 Spec]. Please
|
||||
refer to it there for its original context._
|
||||
|
||||
Let's presume that you're a user who wants to be able to open an elevated tab
|
||||
within an otherwise unelevated Terminal window. We call this scenario "mixed
|
||||
elevation" - the tabs within the Terminal can be running either unelevated _or_
|
||||
elevated client applications.
|
||||
|
||||
It wouldn't be terribly difficult for the unelevated Terminal to request the
|
||||
permission of the user to spawn an elevated client application. The user would
|
||||
see a UAC prompt, they'd accept, and then they'd be able to have an elevated
|
||||
shell alongside their unelevated tabs.
|
||||
|
||||
However, this creates an escalation of privilege vector. Now, there's an
|
||||
unelevated window which is connected directly to an elevated process. At this
|
||||
point, **any other unelevated application could send input to the Terminal's
|
||||
`HWND`**. This would make it possible for another unelevated process to "drive"
|
||||
the Terminal window, and send commands to the elevated client application.
|
||||
|
||||
It was initially theorized that the window/content model architecture would also
|
||||
help enable "mixed elevation". With mixed elevation, tabs could run at different
|
||||
integrity levels within the same terminal window. However, after investigation
|
||||
and research, it has become apparent that this scenario is not possible to do
|
||||
safely after all. There are numerous technical difficulties involved, and each
|
||||
with their own security risks. At the end of the day, the team wouldn't be
|
||||
comfortable shipping a mixed-elevation solution, because there's simply no way
|
||||
for us to be confident that we haven't introduced an escalation-of-privilege
|
||||
vector utilizing the Terminal. No matter how small the attack surface might be,
|
||||
we wouldn't be confident that there are _no_ vectors for an attack.
|
||||
|
||||
Some things we considered during this investigation:
|
||||
|
||||
* If a user requests a new elevated tab from an otherwise unelevated window, we
|
||||
could use UAC to create a new, elevated window process, and "move" all the
|
||||
current tabs to that window process, as well as the new elevated client. Now,
|
||||
the window process would be elevated, preventing it from input injection, and
|
||||
it would still contains all the previously existing tabs. The original window
|
||||
process could now be discarded, as the new elevated window process will
|
||||
pretend to be the original window.
|
||||
- However, it is unfortunately not possible with COM to have an elevated
|
||||
client attach to an unelevated server that's registered at runtime. Even in
|
||||
a packaged environment, the OS will reject the attempt to `CoCreateInstance`
|
||||
the content process object. this will prevent elevated windows from
|
||||
re-connecting to unelevated client processes.
|
||||
- We could theoretically build an RPC tunnel between content and window
|
||||
processes, and use the RPC connection to marshal the content process to the
|
||||
elevated window. However, then _we_ would need to be responsible for
|
||||
securing access the the RPC endpoint, and we feel even less confident doing
|
||||
that.
|
||||
- Attempts were also made to use a window-broker-content architecture, with
|
||||
the broker process having a static CLSID in the registry, and having the
|
||||
window and content processes at mixed elevation levels `CoCreateInstance`
|
||||
that broker. This however _also_ did not work across elevation levels. This
|
||||
may be due to a lack of Packaged COM support for mixed elevation levels.
|
||||
|
||||
It's also possible that the author forgot that packaged WinRT doesn't play
|
||||
nicely with creating objects in an elevated context. The Terminal has
|
||||
previously needed to manually manifest all its classes in a SxS manifest for
|
||||
Unpackaged WinRT to allow the classes to be activated, rather than relying
|
||||
on the packaged catalog. It's theoretically possible that doing that would
|
||||
have allowed the broker to be activated across integrity levels.
|
||||
|
||||
Even if this approach did end up working, we would still need to be
|
||||
responsible for securing the elevated windows so that an unelevated attacker
|
||||
couldn't hijack a content process and trigger unexpected code in the window
|
||||
process. We didn't feel confident that we could properly secure this channel
|
||||
either.
|
||||
|
||||
We also considered allowing mixed content in windows that were _originally_
|
||||
elevated. If the window is already elevated, then it can launch new unelevated
|
||||
processes. We could allow elevated windows to still create unelevated
|
||||
connections. However, we'd want to indicate per-pane what the elevation state
|
||||
of each connection is. The user would then need to keep track themselves of
|
||||
which terminal instances are elevated, and which are not.
|
||||
|
||||
This also marks a departure from the current behavior, where everything in an
|
||||
elevated window would be elevated by default. The user would need to specify for
|
||||
each thing in the elevated window that they'd want to create it elevated. Or the
|
||||
Terminal would need to provide some setting like
|
||||
`"autoElevateEverythingInAnElevatedWindow"`.
|
||||
|
||||
We cannot support mixed elevation when starting in a unelevated window.
|
||||
Therefore, it doesn't make a lot of UX sense to support it in the other
|
||||
direction. It's a cleaner UX story to just have everything in a single window at
|
||||
the same elevation level.
|
||||
|
||||
## Solution Design
|
||||
|
||||
Instead of supporting mixed elevation in the same window, we'll introduce the
|
||||
following features to the Terminal. These are meant as a way of improving the
|
||||
quality of life for users who work in mixed-elevation (or even just elevated)
|
||||
environments.
|
||||
|
||||
### Visible indicator for elevated windows
|
||||
|
||||
As requested in [#1939], it would be nice if it was easy to visibly identify if
|
||||
a Terminal window was elevated or not.
|
||||
|
||||
One easy way of doing this is by adding a simple UAC shield to the left of the
|
||||
tabs for elevated windows. This shield could be configured by the theme (see
|
||||
[#3327]). We could provide the following states:
|
||||
* Colored (the default)
|
||||
* Monochrome
|
||||
* Hidden, to hide the shield even on elevated windows. This is the current
|
||||
behavior.
|
||||
|
||||

|
||||
_figure 1: a monochrome UAC shield in the titlebar of the window, courtesy of @mdtauk_
|
||||
|
||||
We could also simplify this to only allow a boolean true/false for displaying
|
||||
the shield. As we do often with other enums, we could define `true` to be the
|
||||
same as the default appearance, and `false` to be the hidden option. As always,
|
||||
the development of the Terminal is an iterative process, where we can
|
||||
incrementally improve from no setting, to a boolean setting, to a enum-backed
|
||||
one.
|
||||
|
||||
### Configuring a profile to always run elevated
|
||||
|
||||
Oftentimes, users might have a particular tool chain that only works when
|
||||
running elevated. In these scenarios, it would be convenient for the user to be
|
||||
able to identify that the profile should _always_ run elevated. That way, they
|
||||
could open the profile from the dropdown menu of an otherwise unelevated window
|
||||
and have the elevated window open with the profile automatically.
|
||||
|
||||
We'll be adding the `"elevate": true|false` setting as a per-profile setting,
|
||||
with a default value of `false`. When set to `true`, we'll try to auto-elevate
|
||||
the profile whenever it's launched. We'll check to see if this window is
|
||||
elevated before creating the connection for this profile. If the window is not
|
||||
elevated, then we'll create a new window with the requested elevation level to
|
||||
handle the new connection.
|
||||
|
||||
`"elevate": false` will do nothing. If the window is already elevated, then the
|
||||
profile won't open an un-elevated window.
|
||||
|
||||
If the user tries to open an `"elevate": true` profile in a window that's
|
||||
already elevated, then a new tab/split will open in the existing window, rather
|
||||
than spawning an additional elevated window.
|
||||
|
||||
There are three situations where we're creating new terminal instances: new
|
||||
tabs, new splits, and new windows. Currently, these are all actions that are
|
||||
also exposed in the `wt` commandline as subcommands. We can convert from the
|
||||
commandline arguments into these actions already. Therefore, it shouldn't be too
|
||||
challenging to convert these actions back into the equal commandline arguments.
|
||||
|
||||
For the following examples, let's assume the user is currently in an unelevated
|
||||
Terminal window.
|
||||
|
||||
When the user tries to create a new elevated **tab**, we'll need to create a new
|
||||
process, elevated, with the following commandline:
|
||||
|
||||
```
|
||||
wt new-tab [args...]
|
||||
```
|
||||
|
||||
When we create this new `wt` instance, it will obey the glomming rules as
|
||||
specified in [Session Management Spec]. It might end up glomming to another
|
||||
existing window at that elevation level, or possibly create its own window.
|
||||
|
||||
Similarly, for a new elevated **window**, we can make sure to pass the `-w new`
|
||||
arguments to `wt`. These parameters indicate that we definitely want this
|
||||
command to run in a new window, regardless of the current glomming settings.
|
||||
|
||||
```
|
||||
wt -w new new-tab [args...]
|
||||
```
|
||||
|
||||
However, creating a new **pane** is a little trickier. Invoking the `wt
|
||||
split-pane [args...]` is straightforward enough.
|
||||
|
||||
<!-- Discussion notes follow:
|
||||
If the current window doesn't have the same elevation level as the
|
||||
requested profile, do we always want to just create a new split? If the command
|
||||
ends up glomming to an existing window, does that even make sense? That invoking
|
||||
an elevated split in an unelevated window would end up splitting the elevated
|
||||
window? It's very possible that the user wanted a split in the tab they're
|
||||
currently in, in the unelevated window, but they don't want a split in the
|
||||
elevated window.
|
||||
|
||||
What if there's not space in the elevated window to create the split (but there
|
||||
would be in the current window)? That would sure make it seem like nothing
|
||||
happened, silently.
|
||||
|
||||
We could alternatively have cross-elevation splits default to always opening a
|
||||
new tab. That might mitigate some of the odd behaviors. Until we actually have
|
||||
support for running commands in existing windows, we'll always need to make a
|
||||
new window when running elevated. We'll need to make the new window for new tabs
|
||||
and splits, because there's no way to invoke another existing window.
|
||||
|
||||
A third proposal is to pop a warning dialog at the user when they try to open an
|
||||
elevated split from and unelevated window. This dialog could be something like
|
||||
|
||||
> What you requested couldn't be completed. Do you want to:
|
||||
> A. Make me a new tab instead.
|
||||
> B. Forget it and cancel. I'll go fix my config.
|
||||
|
||||
I'm certainly leaning towards proposal 2 - always create a new tab. This is how
|
||||
it's implemented in [#8514]. In that PR, this seems to work sensibly.
|
||||
-->
|
||||
|
||||
After discussing with the team, we have decided that the most sensible approach
|
||||
for handling a cross-elevation `split-pane` is to just create a new tab in the
|
||||
elevated window. The user can always re-attach the pane as a split with the
|
||||
`move-pane` command once the new pane in the elevated window.
|
||||
|
||||
#### Configure the Terminal to _always_ run elevated
|
||||
|
||||
`elevate` is a per-profile property, not a global property. If a user
|
||||
wants to always have all instances of the Terminal run elevated, they
|
||||
could set `"elevate": true` in their profile defaults. That would cause _all_
|
||||
profiles they launch to always spawn as elevated windows.
|
||||
|
||||
#### `elevate` in Actions
|
||||
|
||||
Additionally, we'll add the `elevate` property to the `NewTerminalArgs` used in
|
||||
the `newTab`, `splitPane`, and `newWindow` actions. This is similar to how other
|
||||
properties of profiles can be overridden at launch time. This will allow
|
||||
windows, tabs and panes to all be created specifically as elevated windows.
|
||||
|
||||
In the `NewTerminalArgs`, `elevate` will be an optional boolean, with the
|
||||
following behavior:
|
||||
* `null` (_default_): Don't modify the `elevate` property for this profile
|
||||
* `true`: This launch should act like the profile had `"elevate": true` in its
|
||||
properties.
|
||||
* `false`: This launch should act like the profile had `"elevate": false` in its
|
||||
properties.
|
||||
|
||||
We'll also add an iterable command for opening a profile in an
|
||||
elevated tab, with the following json:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// New elevated tab...
|
||||
"name": { "key": "NewElevatedTabParentCommandName", "icon": "UAC-Shield.png" },
|
||||
"commands": [
|
||||
{
|
||||
"iterateOn": "profiles",
|
||||
"icon": "${profile.icon}",
|
||||
"name": "${profile.name}",
|
||||
"command": { "action": "newTab", "profile": "${profile.name}", "elevated": true }
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
#### Elevation from the dropdown
|
||||
|
||||
Currently, the new tab dropdown supports opening a new pane by
|
||||
<kbd>Alt+click</kbd>ing on a profile. We could similarly add support to open a
|
||||
tab elevated with <kbd>Ctrl+click</kbd>. This is similar to the behavior of the
|
||||
Windows taskbar. It supports creating an elevated instance of a program by
|
||||
<kbd>Ctrl+click</kbd>ing on entries as well.
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Starting an elevated process from an unelevated process
|
||||
|
||||
It seems that we're able to create an elevated process by passing the `"runas"`
|
||||
verb to
|
||||
[`ShellExecute`](https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutea).
|
||||
So we could use something like
|
||||
|
||||
```c++
|
||||
ShellExecute(nullptr,
|
||||
L"runas",
|
||||
L"wt.exe",
|
||||
L"-w new new-tab [args...]",
|
||||
nullptr,
|
||||
SW_SHOWNORMAL);
|
||||
```
|
||||
|
||||
This will ask the shell to perform a UAC prompt before spawning `wt.exe` as an
|
||||
elevated process.
|
||||
|
||||
> 👉 NOTE: This mechanism won't always work on non-Desktop SKUs of Windows. For
|
||||
> more discussion, see [Elevation on OneCore SKUs](#Elevation-on-OneCore-SKUs).
|
||||
|
||||
## Potential Issues
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><strong>Accessibility</strong></td>
|
||||
<td>
|
||||
|
||||
The set of changes proposed here are not expected to introduce any new
|
||||
accessibility issues. Users can already create elevated Terminal windows. Making
|
||||
it easier to create these windows doesn't really change our accessibility story.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Security</strong></td>
|
||||
<td>
|
||||
|
||||
We won't be doing anything especially unique, so there aren't expected to be any
|
||||
substantial security risks associated with these changes. Users can already
|
||||
create elevated Terminal windows, so we're not really introducing any new
|
||||
functionality, from a security perspective.
|
||||
|
||||
We're relying on the inherent security of the `runas` verb of `ShellExecute` to
|
||||
prevent any sort of unexpected escalation-of-privilege.
|
||||
|
||||
<hr>
|
||||
|
||||
One security concern is the fact that the `settings.json` file is currently a
|
||||
totally unsecured file. It's completely writable by any medium-IL process. That
|
||||
means it's totally possible for a malicious program to change the file. The
|
||||
malicious program could find a user's "Elevated PowerShell" profile, and change
|
||||
the commandline to `malicious.exe`. The user might then think that their
|
||||
"Elevated PowerShell" will run `powershell.exe` elevated, but will actually
|
||||
auto-elevate this attacker.
|
||||
|
||||
If all we expose to the user is the name of the profile in the UAC dialog, then
|
||||
there's no way for the user to be sure that the program that's about to be
|
||||
launched is actually what they expect.
|
||||
|
||||
To help mitigate this, we should _always_ pass the evaluated `commandline` as a
|
||||
part of the call to `ShellExecute`. the arguments that are passed to
|
||||
`ShellExecute` are visible to the user, though they need to click the "More
|
||||
Details" dropdown to reveal them.
|
||||
|
||||
We will need to mitigate this vulnerability regardless of adding support for the
|
||||
auto-elevation of individual terminal tabs/panes. If a user is launching the
|
||||
Terminal elevated (i.e. from the Win+X menu in Windows 11), then it's possible
|
||||
for a malicious program to overwrite the `commandline` of their default profile.
|
||||
The user may now unknowingly invoke this malicious program while thinking they
|
||||
are simply launching the Terminal.
|
||||
|
||||
To deal with this more broadly, we will display a dialog within the Terminal
|
||||
window before creating **any** elevated terminal instance. In that dialog, we'll
|
||||
display the commandline that will be executed, so the user can very easily
|
||||
confirm the commandline.
|
||||
|
||||
This will need to happen for all elevated terminal instances. For an elevated
|
||||
Windows Terminal window, this means _all_ connections made by the Terminal.
|
||||
Every time the user opens a new profile or a new commandline in a pane, we'll
|
||||
need to prompt them first to confirm the commandline. This dialog within the
|
||||
elevated window will also prevent an attacker from editing the `settings.json`
|
||||
file while the user already has an elevated Terminal window open and hijacking a
|
||||
profile.
|
||||
|
||||
The dialog options will certainly be annoying to users who don't want to be
|
||||
taken out of their flow to confirm the commandline that they wish to launch.
|
||||
There's precedent for a similar warning being implemented by VSCode, with their
|
||||
[Workspace Trust] feature. They too faced a similar backlash when the feature
|
||||
first shipped. However, in light of recent global cybersecurity attacks, this is
|
||||
seen as an acceptable UX degradation in the name of application trust. We don't
|
||||
want to provide an avenue that's too easy to abuse.
|
||||
|
||||
When the user confirms the commandline of this profile as something safe to run,
|
||||
we'll add it to an elevated-only version of `state.json`. (see [#7972] for more
|
||||
details). This elevated version of the file will only be accessible by the
|
||||
elevated Terminal, so an attacker cannot hijack the contents of the file. This
|
||||
will help mitigate the UX discomfort caused by prompting on every commandline
|
||||
launched. This should mean that the discomfort is only limited to the first
|
||||
elevated launch of a particular profile. Subsequent launches (without modifying
|
||||
the `commandline`) will work as they always have.
|
||||
|
||||
The dialog for confirming these commandlines should have a link to the docs for
|
||||
"Learn more...". Transparency in the face of this dialog should
|
||||
mitigate some dissatisfaction.
|
||||
|
||||
The dialog will _not_ appear if the user does not have a split token - if the
|
||||
user's PC does not have UAC enabled, then they're _already_ running as an
|
||||
Administrator. Everything they do is elevated, so they shouldn't be prompted in
|
||||
this way.
|
||||
|
||||
The Settings UI should also expose a way of viewing and removing these cached
|
||||
entries. This page should only be populated in the elevated version of the
|
||||
Terminal.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Reliability</strong></td>
|
||||
<td>
|
||||
|
||||
No changes to our reliability are expected as a part of this change.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Compatibility</strong></td>
|
||||
<td>
|
||||
|
||||
There are no serious compatibility concerns expected with this changelist. The
|
||||
new `elevate` property will be unset by default, so users will heed to opt-in
|
||||
to the new auto-elevating behavior.
|
||||
|
||||
There is one minor concern regarding introducing the UAC shield on the window.
|
||||
We're planning on using themes to configure the appearance of the shield. That
|
||||
means we'll need to ship themes before the user will be able to hide the shield
|
||||
again.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Performance, Power, and Efficiency</strong></td>
|
||||
<td>
|
||||
|
||||
No changes to our performance are expected as a part of this change.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Centennial Applications
|
||||
|
||||
In the past, we've had a notoriously rough time with the Centennial app
|
||||
infrastructure and running the Terminal elevated. Notably, we've had to list all
|
||||
our WinRT classes in our SxS manifest so they could be activated using
|
||||
unpackaged WinRT while running elevated. Additionally, there are plenty of
|
||||
issues running the Terminal in an "over the shoulder" elevation (OTS) scenario.
|
||||
|
||||
Specifically, we're concerned with the following scenario:
|
||||
* the current user account has the Terminal installed,
|
||||
* but they aren't an Administrator,
|
||||
* the Administrator account doesn't have the Terminal installed.
|
||||
|
||||
In that scenario, the user can run into issues launching the Terminal in an
|
||||
elevated context (even after entering the Admin's credentials in the UAC
|
||||
prompt).
|
||||
|
||||
This spec proposes no new mitigations for dealing with these issues. It may in
|
||||
fact make them more prevalent, by making elevated contexts more easily
|
||||
accessible.
|
||||
|
||||
Unfortunately, these issues are OS bugs that are largely out of our own control.
|
||||
We will continue to apply pressure to the centennial app team internally as we
|
||||
encounter these issues. They are are team best equipped to resolve these issues.
|
||||
|
||||
### Default Terminal & auto-elevation
|
||||
|
||||
In the future, when we support setting the Terminal as the "default terminal
|
||||
emulator" on Windows. When that lands, we will use the `profiles.defaults`
|
||||
settings to create the tab where we'll be hosting the commandline client. If the user has
|
||||
`"elevate": true` in their `profiles.defaults`, we'd usually try to
|
||||
auto-elevate the profile. In this scenario, however, we can't do that. The
|
||||
Terminal is being invoked on behalf of the client app launching, instead of the
|
||||
Terminal invoking the client application.
|
||||
|
||||
**2021-08-17 edit**: Now that "defterm" has shipped, we're a little more aware
|
||||
of some of the limitations with packaged COM and elevation boundaries. Defterm
|
||||
cannot be used with elevated processes _at all_ currently (see [#10276]). When
|
||||
an elevated commandline application is launched, it will always just appear in
|
||||
`conhost.exe`. Furthermore, An unelevated peasant can't communicate with an
|
||||
elevated monarch so we can't toss the connection to the elevated monarch and
|
||||
have them handle it.
|
||||
|
||||
The simplest solution here is to just _always_ ignore the `elevate` property for
|
||||
incoming defterm connections. This is not an ideal solution, and one that we're
|
||||
willing to revisit if/when [#10276] is ever fixed.
|
||||
|
||||
### Elevation on OneCore SKUs
|
||||
|
||||
This spec proposes using `ShellExecute` to elevate the Terminal window. However,
|
||||
not all Windows SKUs have support for `ShellExecute`. Notably, the non-Desktop
|
||||
SKUs, which are often referred to as "OneCore" SKUs. On these platforms, we
|
||||
won't be able to use `ShellExecute` to elevate the Terminal. There might not
|
||||
even be the concept of multiple elevation levels, or different users, depending
|
||||
on the SKU.
|
||||
|
||||
Fortunately, this is a mostly hypothetical concern for the moment. Desktop is
|
||||
the only publicly supported SKU for the Terminal currently. If the Terminal ever
|
||||
does become available on those SKUs, we can use these proposals as mitigations.
|
||||
|
||||
* If elevation is supported, there must be some other way of elevating a
|
||||
process. We could always use that mechanism instead.
|
||||
* If elevation isn't supported (I'm thinking 10X is one of these), then we could
|
||||
instead display a warning dialog whenever a user tries to open an elevated
|
||||
profile.
|
||||
- We could take the warning a step further. We could add another settings
|
||||
validation step. This would warn the user if they try to mark any profiles
|
||||
or actions as `"elevate":true`
|
||||
|
||||
## Future considerations
|
||||
|
||||
* If we wanted to go even further down the visual differentiation route, we
|
||||
could consider allowing the user to set an entirely different theme ([#3327])
|
||||
based on the elevation state. Something like `elevatedTheme`, to pick another
|
||||
theme from the set of themes. This would allow them to force elevated windows
|
||||
to have a red titlebar, for example.
|
||||
* Over the course of discussion concerning appearance objects ([#8345]), it
|
||||
became clear that having separate "elevated" appearances defined for
|
||||
`profile`s was overly complicated. This is left as a consideration for a
|
||||
possible future extension that could handle this scenario in a cleaner way.
|
||||
* Similarly, we're going to leave [#3637] "different profiles when elevated vs
|
||||
unelevated" for the future. This also plays into the design of "configure the
|
||||
new tab dropdown" ([#1571]), and reconciling those two designs is out-of-scope
|
||||
for this particular release.
|
||||
* Tangentially, we may want to have a separate Terminal icon we ship with the
|
||||
UAC shield present on it. This would be especially useful for the tray icon.
|
||||
Since there will be different tray icon instances for elevated and unelevated
|
||||
windows, having unique icons may help users identify which is which.
|
||||
|
||||
### De-elevating a Terminal
|
||||
|
||||
the original version of this spec proposed that `"elevated":false` from an
|
||||
elevated Terminal window should create a new unelevated Terminal instance. The
|
||||
mechanism for doing this is described in [The Old New Thing: How can I launch an
|
||||
unelevated process from my elevated process, redux].
|
||||
|
||||
This works well when the Terminal is running unpackaged. However, de-elevating a
|
||||
process does not play well with packaged centennial applications. When asking
|
||||
the OS to run the packaged application from an elevated context, the system will
|
||||
still create the child process _elevated_. This means the packaged version of
|
||||
the Terminal won't be able to create a new unelevated Terminal instance.
|
||||
|
||||
From an internal mail thread:
|
||||
|
||||
> App model intercepts the `CreateProcess` call and redirects it to a COM
|
||||
> service. The parent of a packaged app is not the launching app, it’s some COM
|
||||
> service. So none of the parent process nonsense will work because the
|
||||
> parameters you passed to `CreateProcess` aren’t being used to create the
|
||||
> process.
|
||||
|
||||
If this is fixed in the future, we could theoretically re-introduce de-elevating
|
||||
a profile. The original spec proposed a `"elevated": bool?` setting, with the
|
||||
following behaviors:
|
||||
* `null` (_default_): Don't modify the elevation level when running this profile
|
||||
* `true`: If the current window is unelevated, try to create a new elevated
|
||||
window to host this connection.
|
||||
* `false`: If the current window is elevated, try to create a new unelevated
|
||||
window to host this connection.
|
||||
|
||||
We could always re-introduce this setting, to supercede `elevate`.
|
||||
|
||||
### Change profile appearance for elevated windows
|
||||
|
||||
In [#3062] and [#8345], we're planning on allowing users to set different
|
||||
appearances for a profile whether it's focused or not. We could do similar thing
|
||||
to enable a profile to have a different appearance when elevated. In the
|
||||
simplest case, this could allow the user to set `"background": "#ff0000"`. This
|
||||
would make a profile always appear to have a red background when in an elevated
|
||||
window.
|
||||
|
||||
The more specific details of this implementation are left to the spec
|
||||
[Configuration object for profiles].
|
||||
|
||||
In discussion of that spec, we decided that it would be far too complicated to
|
||||
try and overload the `unfocusedAppearance` machinery for differentiating between
|
||||
elevated and unelevated versions of the same profile. Already, that would lead
|
||||
to 4 states: [`appearance`, `unfocusedAppearance`, `elevatedAppearance`,
|
||||
`elevatedUnfocusedAppearance`]. This would lead to a combinatorial explosion if
|
||||
we decided in the future that there should also be other states for a profile.
|
||||
|
||||
This particular QoL improvement is currently being left as a future
|
||||
consideration, should someone come up with a clever way of defining
|
||||
elevated-specific settings.
|
||||
|
||||
<!--
|
||||
Brainstorming notes for future readers:
|
||||
|
||||
You could have a profile that layers on an existing profile, with elevated-specific settings:
|
||||
|
||||
{
|
||||
"name": "foo",
|
||||
"background": "#0000ff",
|
||||
"commandline": "cmd.exe /k echo I am unelevated"
|
||||
},
|
||||
{
|
||||
"inheritsFrom": "foo",
|
||||
"background": "#ff0000",
|
||||
"elevate": true,
|
||||
"commandline": "cmd.exe /k echo I am ELEVATED"
|
||||
}
|
||||
-->
|
||||
|
||||
<!-- Footnotes -->
|
||||
|
||||
[#632]: https://github.com/microsoft/terminal/issues/632
|
||||
[#1032]: https://github.com/microsoft/terminal/issues/1032
|
||||
[#1571]: https://github.com/microsoft/terminal/issues/1571
|
||||
[#1939]: https://github.com/microsoft/terminal/issues/1939
|
||||
[#3062]: https://github.com/microsoft/terminal/issues/3062
|
||||
[#3327]: https://github.com/microsoft/terminal/issues/3327
|
||||
[#3637]: https://github.com/microsoft/terminal/issues/3637
|
||||
[#4472]: https://github.com/microsoft/terminal/issues/4472
|
||||
[#5000]: https://github.com/microsoft/terminal/issues/5000
|
||||
[#7972]: https://github.com/microsoft/terminal/pull/7972
|
||||
[#8311]: https://github.com/microsoft/terminal/issues/8311
|
||||
[#8345]: https://github.com/microsoft/terminal/issues/8345
|
||||
[#8514]: https://github.com/microsoft/terminal/issues/8514
|
||||
[#10276]: https://github.com/microsoft/terminal/issues/10276
|
||||
|
||||
[Process Model 2.0 Spec]: https://github.com/microsoft/terminal/blob/main/doc/specs/%235000%20-%20Process%20Model%202.0.md
|
||||
[Configuration object for profiles]: https://github.com/microsoft/terminal/blob/main/doc/specs/Configuration%20object%20for%20profiles.md
|
||||
[Session Management Spec]: https://github.com/microsoft/terminal/blob/main/doc/specs/%234472%20-%20Windows%20Terminal%20Session%20Management.md
|
||||
[The Old New Thing: How can I launch an unelevated process from my elevated process, redux]: https://devblogs.microsoft.com/oldnewthing/20190425-00/?p=102443
|
||||
[Workspace Trust]: https://code.visualstudio.com/docs/editor/workspace-trust
|
||||
@@ -0,0 +1,562 @@
|
||||
---
|
||||
author: Mike Griese @zadjii-msft
|
||||
created on: 2020-10-30
|
||||
last updated: 2020-02-05
|
||||
issue id: #4472
|
||||
---
|
||||
|
||||
# Windows Terminal Session Management
|
||||
|
||||
## Abstract
|
||||
This document is intended to serve as an addition to the [Process Model 2.0
|
||||
Spec]. That document provides a big-picture overview of changes to the entirety
|
||||
of the Windows Terminal process architecture, including both the split of
|
||||
window/content processes, as well as the introduction of monarch/peasant
|
||||
processes. The focus of that document was to identify solutions to a set of
|
||||
scenarios that were closely intertwined, and establish these solutions would
|
||||
work together, without preventing any one scenario from working. What that
|
||||
document did not do was prescribe specific solutions to the given scenarios.
|
||||
|
||||
This document offers a deeper dive on a subset of the issues in [#5000], to
|
||||
describe specifics for managing multiple windows with the Windows Terminal. This
|
||||
includes features such as:
|
||||
|
||||
* Run `wt` in the current window ([#4472])
|
||||
* Single Instance Mode ([#2227])
|
||||
|
||||
## Solution Design
|
||||
|
||||
### Monarch and Peasant Processes
|
||||
|
||||
This document assumes the reader is already familiar with the "Monarch and
|
||||
Peasant" architecture as detailed in the [Windows Terminal Process Model 2.0
|
||||
Spec]. As a quick summary:
|
||||
|
||||
* Every Windows Terminal window is a "Peasant" process.
|
||||
* One of the Windows Terminal window processes is also the "Monarch" process.
|
||||
The Monarch is picked randomly from the Terminal windows, and there is only
|
||||
ever one Monarch process at a time.
|
||||
* Peasants can communicate with the monarch when certain state changes (such as
|
||||
their window being activated), and the monarch can send commands to any of the
|
||||
peasants.
|
||||
|
||||
This architecture will be used to enable each of the following scenarios.
|
||||
|
||||
### Scenario: Open new tabs in most recently used window
|
||||
|
||||
A common feature of many browsers is that when a web URL is clicked somewhere,
|
||||
the web page is opened as a new tab in the most recently used window of the
|
||||
browser. This functionality is often referred to as "glomming", as the new tab
|
||||
"gloms" onto the existing window.
|
||||
|
||||
Currently, the terminal does not support such a feature - every `wt` invocation
|
||||
creates a new window. With the monarch/peasant architecture, it'll now be
|
||||
possible to enable such a scenario.
|
||||
|
||||
As each window is activated, it will call a method on the `Monarch` object
|
||||
(hosted by the monarch process) which will indicate that "I am peasant N, and
|
||||
I've been focused". The monarch will use those method calls to update its own
|
||||
internal stack of the most recently used windows.
|
||||
|
||||
Whenever a new `wt.exe` process is launched, that process will _first_ ask the
|
||||
monarch if it should run the commandline in an existing window, or create its
|
||||
own window.
|
||||
|
||||

|
||||
|
||||
If glomming is enabled, the monarch will dispatch the commandline to the
|
||||
appropriate window for them to handle instead. To the user, it'll seem as if the
|
||||
tab just opened in the most recent window.
|
||||
|
||||
Users should certainly be able to specify if they want new instances to glom
|
||||
onto the MRU window or not. You could imagine that currently, we default to the
|
||||
hypothetical value `"windowingBehavior": "useNew"`, meaning that each new wt gets
|
||||
its own new window.
|
||||
|
||||
If glomming is disabled, then the Monarch will call back to the peasant and tell
|
||||
it to run the provided commandline. The monarch will use the return value of
|
||||
`ExecuteCommandline` to indicate that the calling process should create a window
|
||||
and become a peasant process, and run the commandline itself.
|
||||
|
||||
#### Glomming within the same virtual desktop
|
||||
|
||||
When links are opened in the new Edge browser, they will only glom onto an
|
||||
existing window if that window is open in the current virtual desktop. This
|
||||
seems like a good idea of a feature for the Terminal to follow as well.
|
||||
|
||||
There must be some way for an application to determine which virtual desktop it
|
||||
is open on. We could use that information to have the monarch track the last
|
||||
active window _per-desktop_, and only glom when there's one on the current
|
||||
desktop.
|
||||
|
||||
We could make the `windowingBehavior` property accept a variety of
|
||||
configurations:
|
||||
|
||||
- `"useExisting"`: always glom to the most recent window, regardless of desktop.
|
||||
- `"useExistingOnSameDesktop"`: Only glom if there's an existing window on this
|
||||
virtual desktop, otherwise create a new window. This will be the new default
|
||||
value.
|
||||
- `"useNew"`: Never glom, always create a new window. This is technically the
|
||||
current behavior of the Terminal.
|
||||
|
||||
### Handling the current working directory
|
||||
|
||||
Consider the following scenario: the user runs `wt -d .` in the address bar of
|
||||
explorer, and the monarch determines that this new tab should be created in an
|
||||
existing window. For clarity during this example, we will label the existing
|
||||
window WT[1], and the second `wt.exe` process WT[2].
|
||||
|
||||
An example of this scenario is given in the following diagram:
|
||||
|
||||

|
||||
|
||||
In this scenario, we want the new tab to be spawned in the current working
|
||||
directory of WT[2], not WT[1]. So when WT[1] is about to run the commands that
|
||||
were passed to WT[2], WT[1] will need to:
|
||||
|
||||
* First, stash its own CWD
|
||||
* Change to the CWD of WT[2]
|
||||
* Run the commands from WT[2]
|
||||
* Then return to its original CWD.
|
||||
|
||||
So, as a part of the interface that a peasant uses to communicate the startup
|
||||
commandline to the monarch, we should also include the current working
|
||||
directory.
|
||||
|
||||
### Scenario: Run `wt` in the current window
|
||||
|
||||
One often requested scenario is the ability to run a `wt.exe` commandline in the
|
||||
current window, as opposed to always creating a new window. Presume we have the
|
||||
ability to communicate between different window processes. The logical extension
|
||||
of this scenario would be "run a `wt` commandline in _any_ given WT window".
|
||||
|
||||
Each window process will have its own unique ID assigned to it by the monarch.
|
||||
This ID will be a positive number. Windows can also have names assigned to them.
|
||||
These names are strings that the user specifies. A window will always have an
|
||||
ID, but not necessarily a name. Running a command in a given window with ID N
|
||||
should be as easy as something like:
|
||||
|
||||
```sh
|
||||
wt.exe --window N new-tab ; split-pane
|
||||
```
|
||||
|
||||
(or for shorthand, `wt -w N new-tab ; split-pane`).
|
||||
|
||||
More formally, we will add the following parameter to the top-level `wt`
|
||||
command:
|
||||
|
||||
#### `--window,-w <window-id>`
|
||||
Run these commands in the given Windows Terminal session. This enables opening
|
||||
new tabs, splits, etc. in already running Windows Terminal windows.
|
||||
* If `window-id` is `0`, run the given commands in _the current window_.
|
||||
* If `window-id` is a negative number, or the reserved name `new`, run the
|
||||
commands in a _new_ Terminal window.
|
||||
* If `window-id` is the ID or name of an existing window, then run the
|
||||
commandline in that window.
|
||||
* If `window-id` is _not_ the ID or name of an existing window, create a new
|
||||
window. That window will be assigned the ID or name provided in the
|
||||
commandline. The provided subcommands will be run in that new window.
|
||||
* If `window-id` is omitted, then obey the value of `windowingBehavior` when
|
||||
determining which window to run the command in.
|
||||
|
||||
_Whenever_ `wt.exe` is started, it must _always_ pass the provided commandline
|
||||
first to the monarch process for handling. This is important for glomming
|
||||
scenarios (as noted above). The monarch will parse the commandline, determine
|
||||
which window the commandline is destined for, then call `ExecuteCommandline` on
|
||||
that peasant, who will then run the command.
|
||||
|
||||
#### Running commands in the current window:`wt --window 0`
|
||||
|
||||
If `wt -w 0 <commands>` is run _outside_ a WT instance, it could attempt to glom
|
||||
onto _the most recent WT window_ instead. This seems more logical than something
|
||||
like `wt --window last` or some other special value indicating "run this in the
|
||||
MRU window".<sup>[[2]](#footnote-2)</sup>
|
||||
|
||||
That might be a simple, but **wrong**, implementation for "the current window".
|
||||
If the peasants always raise an event when their window is focused, and the
|
||||
monarch keeps track of the MRU order for peasants, then one could naively assume
|
||||
that the execution of `wt -w 0 <commands>` would always return the window the
|
||||
user was typing in, the current one. However, if someone were to do something
|
||||
like `sleep 10 ; wt -w 0 <commands>`, then the user could easily focus another
|
||||
WT window during the sleep, which would cause the MRU window to not be the same
|
||||
as the window executing the command.
|
||||
|
||||
To solve this issue, we'll other than
|
||||
attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process
|
||||
is spawned and that's in its environment variables, it could try and ask the
|
||||
monarch for the peasant who's hosting the session corresponding to that GUID.
|
||||
This is more of a theoretical solution than anything else.
|
||||
|
||||
In the past we've been reluctant to rely too heavily on `WT_SESSION`. However,
|
||||
an environment variable does seem to be the only reliable way to be confident
|
||||
where the window was created from. We could introduce another environment
|
||||
variable instead - `WT_WINDOW_ID`. That would allow us to shortcut the session
|
||||
ID lookup. However, I worry about exposing the window ID as an environment
|
||||
variable. If we do that, users will inevitably use that instead of the `wt -0`
|
||||
alias, which should take care of the work for them. Additionally, `WT_WINDOW_ID`
|
||||
wouldn't update in the child processes as tabs are torn out of windows to create
|
||||
new windows.
|
||||
|
||||
Both solutions are prone to the user changing the value of the variable to some
|
||||
garbage value. If they do that, this lookup will most certainly not work as
|
||||
expected. Using the session ID (a GUID) instead of the window ID (an int) makes
|
||||
it less likely that they guess the ID of an existing instance.
|
||||
|
||||
#### Running commands in a new window:`wt --window -1` / `wt --window new`
|
||||
|
||||
If the user passes a negative number, or the reserved name `new` to the
|
||||
`--window` parameter, then we will always create a new window for that
|
||||
commandline, regardless of the value of `windowingBehavior`. This will allow
|
||||
users to do something like `wt -w -1 new-tab` to _always_ create a new window.
|
||||
|
||||
#### `--window` in subcommands
|
||||
|
||||
The `--window` parameter is a setting to `wt.exe` itself, not to one of its
|
||||
subcommands (like `new-tab` or `split-pane`). This means that all of the
|
||||
subcommands in a particular `wt` commandline will all be handled by the same
|
||||
session. For example, let us consider a user who wants to open a new tab in
|
||||
window 2, and split a new pane in window 3, all at once. The user _cannot_ do
|
||||
something like:
|
||||
|
||||
```cmd
|
||||
wt -w 2 new-tab ; -w 3 split-pane
|
||||
```
|
||||
|
||||
Instead, the user will need to separate the commands (by whatever their shell's
|
||||
own command delimiter is) and run two different `wt.exe` instances:
|
||||
|
||||
```cmd
|
||||
wt -w 2 new-tab & wt -w 3 split-pane
|
||||
```
|
||||
|
||||
This is done to make the parsing of the subcommands easier, and for the internal
|
||||
passing of arguments simpler. If the `--window` parameter were a part of each
|
||||
subcommand, then each individual subcommand's parser would need to be
|
||||
enlightened about that parameter, and then it would need to be possible for any
|
||||
single part of the commandline to call out to another process. It would be
|
||||
especially tricky then to coordinate the work being done across process here.
|
||||
The source process would need some sort of way to wait for the other process to
|
||||
notify the source that a particular subcommand completed, before allowing the
|
||||
source to dispatch the next part of the commandline.
|
||||
|
||||
Overall, this is seen as unnecessarily complex, and dispatching whole sets of
|
||||
commands as a simpler solution.
|
||||
|
||||
### Naming Windows
|
||||
|
||||
It's not user-friendly to rely on automatically generated, invisible numbers to
|
||||
identify windows. There's not a great way of identifying which window is which.
|
||||
The user would need to track the IDs in their head manually. Instead, we'll
|
||||
allow the user to provide a string name for the window. This name can be used to
|
||||
address a window in addition to the ID.
|
||||
|
||||
Names can be provided on the commandline, in the original commandline. For
|
||||
example, `wt -w foo nt` would name the new window "foo". Names can also be set
|
||||
with a new action, `NameWindow`<sup>[[3]](#footnote-3)</sup>. `name-window`
|
||||
could also be used as a subcommand. For example, `wt -w 4 name-window bar` would
|
||||
name window 4 "bar".
|
||||
|
||||
To keep identities mentally distinct, we will disallow names that are integers
|
||||
(positive or negative). This will prevent users from renaming a window to `2`,
|
||||
then having `wt -w 2` be ambiguous as to which window it refers to.
|
||||
|
||||
Names must also be unique. If a user attempts to set the name of the window to
|
||||
an already-used name, we'll need to ignore the name change. We could also
|
||||
display a "toast" or some other type of low-impact message to the user. That
|
||||
message would have some text like: "Unable to rename window. Another window with
|
||||
that name already exists".
|
||||
|
||||
The Terminal will reserve the name `new`. It will also reserve any names
|
||||
starting with the character `_`. The user will not be allowed to set the window
|
||||
name to any of these reserved names. Reserving `_*` allows us to add other
|
||||
keywords in the future, without introducing a breaking change.
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
### `windowingBehavior` details
|
||||
|
||||
The following list gives greater breakdown of the values of `windowingBehavior`,
|
||||
and how they operate:
|
||||
|
||||
* `"windowingBehavior": "useExisting", "useExistingOnSameDesktop"`:
|
||||
**Browser-like glomming**
|
||||
- New instances open in the current window by default.
|
||||
- `newWindow` opens a new window.
|
||||
- Tabs can be torn out to create new windows.
|
||||
- `wt -w -1` opens a new window.
|
||||
* `"windowingBehavior": "useNew"`: No auto-glomming. This is **the current
|
||||
behavior** of the Terminal.
|
||||
- New instances open in new windows by default
|
||||
- `newWindow` opens a new window
|
||||
- Tabs can be torn out to create new windows.
|
||||
- `wt -w -1` opens a new window.
|
||||
|
||||
We'll be changing the default behavior from `useNew` to
|
||||
`useExistingOnSameDesktop`. This will be more consistent with other tabbed
|
||||
applications.
|
||||
|
||||
## Concerns
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><strong>Accessibility</strong></td>
|
||||
<td>
|
||||
|
||||
There is no expected accessibility impact from this feature. Each window will
|
||||
handle UIA access as it normally does.
|
||||
|
||||
In the future, we could consider exposing the window IDs and/or names via UIA.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Security</strong></td>
|
||||
<td>
|
||||
|
||||
Many security concerns have already be covered in greater detail in the parent
|
||||
spec, [Process Model 2.0 Spec].
|
||||
|
||||
When attempting to instantiate the Monarch, COM will only return the object from
|
||||
a server running at the same elevation level. We don't need to worry about
|
||||
unelevated peasants connecting to the elevated Monarch, or vice-versa.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Reliability</strong></td>
|
||||
<td>
|
||||
|
||||
We will need to be careful when working with objects hosted by another process.
|
||||
Any work we do with it MUST be in a try/catch, because at _any_ time, the other
|
||||
process could be killed. At any point, a window process could be killed. Both
|
||||
the monarch and peasant code will need to be redundant to such a scenario, and
|
||||
if the other process is killed, make sure to display an appropriate error and
|
||||
either recover or exit gracefully.
|
||||
|
||||
In any and all these situations, we will want to try and be as verbose as
|
||||
possible in the logging. This will make tracking which process had the error
|
||||
occur easier.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Compatibility</strong></td>
|
||||
<td>
|
||||
|
||||
We will be changing the default behavior of the Terminal to auto-glom to the
|
||||
most-recently used window on the same desktop in the course of this work, which
|
||||
will be a breaking UX change. This is behavior that can be reverted with the
|
||||
`"windowingBehavior": "useNew"` setting.
|
||||
|
||||
We acknowledge that this is a pretty massive change to the default experience of
|
||||
the Terminal. We're planning on doing some polling of users to determine which
|
||||
behavior they want by default. Additionally, we'll be staging the rollout of
|
||||
this feature, using the Preview builds of the Terminal. The release notes that
|
||||
first include it will call extra attention to this feature. We'll ask that users
|
||||
provide their feedback in a dedicated thread, so we have time to collect
|
||||
opinions from users before rolling the change out to all users.
|
||||
|
||||
We may choose to only change the default to `useExistingOnSameDesktop` once tab
|
||||
tear out is available, so users who are particularly unhappy about this change
|
||||
can still tear out the tab (if they can't be bothered to change the setting).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Performance, Power, and Efficiency</strong></td>
|
||||
<td>
|
||||
|
||||
There's no dramatic change expected here. There may be a minor delay in the
|
||||
spawning of new terminal instances, due to requiring cross-process hops for the
|
||||
communication between monarch and peasant processes.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Potential Issues
|
||||
|
||||
### Mixed Elevation Levels
|
||||
|
||||
As of December 2020, we're no longer pursuing a "mixed-elevation" scenario for
|
||||
the Terminal. This makes many of the cross-elevation scenarios simpler. Elevated
|
||||
and unelevated `wt` instances will always remain separate. The different
|
||||
elevation levels will maintain separate lists of window IDs. If the user is
|
||||
running both an elevated and unelevated window, then there will be two monarchs.
|
||||
One elevated, and the other unelevated.
|
||||
|
||||
There will also be some edge cases when handling the commandline that will need
|
||||
special care. Say the user wanted to open a new tab in the elevated window, from
|
||||
and unelevated `explorer.exe`. That would be a commandline like:
|
||||
|
||||
```sh
|
||||
wt -w 0 new-tab -d . --elevated
|
||||
```
|
||||
|
||||
Typically we first determine which window the commandline is intended for, then
|
||||
dispatch it to that window. In this case, the `-w 0` will cause us to pass the
|
||||
commandline to the current unelevated window. Then, that window will try to open
|
||||
an elevated tab, fail, and create a new `wt.exe` process. This second `wt.exe`
|
||||
process will lose the `-w 0` context. It won't inform the elevated monarch that
|
||||
this commandline should be run in the active session.
|
||||
|
||||
We will need to make sure that special care is taken when creating elevated
|
||||
instances that we maintain the `--window` parameter passed to the Terminal.
|
||||
|
||||
### `wt` Startup Commandline Options
|
||||
|
||||
There are a few commandline options which can be provided to `wt.exe` which
|
||||
don't make sense to pass to another session. These options include (but are not
|
||||
limited to):
|
||||
|
||||
* `--initialSize r,c`
|
||||
* `--initialPosition x,y`
|
||||
* `--fullscreen`, `--maximized`, etc.
|
||||
|
||||
When we're passing a commandline to another instance to handle, these arguments
|
||||
will be ignored. they only apply to the initial creation of a window.
|
||||
`--initialSize 32, 120` doesn't make sense if the window already has a size.
|
||||
|
||||
On startup of a new window, we currently assume that the first command is always
|
||||
`new-tab`. When passing commandlines to existing windows, we won't need to make
|
||||
that assumption anymore. There will already be existing tabs.
|
||||
|
||||
### Monarch MRU Window Tracking
|
||||
|
||||
As stated above, the monarch is responsible for tracking the MRU window stack.
|
||||
However, when the monarch is closed, this state will be lost. The new monarch
|
||||
will be elected, but it will be unable to ask the old monarch for the MRU
|
||||
order of the windows.
|
||||
|
||||
We had previously considered an _acceptable_ UX when this would occur. We would
|
||||
randomize the order (with the new monarch becoming the MRU window). If someone
|
||||
noticed this bug and complained, then we had a theoretical solution prepared.
|
||||
The peasants could inform not only the monarch, but _all other peasants_ when
|
||||
they become activated. This would mean all peasants are simultaneously tracking
|
||||
the MRU stack. This would mean that any given peasant would be prepared always
|
||||
to become the monarch.
|
||||
|
||||
A simpler solution though would be to not track the MRU stack in the Monarch at
|
||||
all. Instead, each peasant could just track internally when they were last
|
||||
activated. The Monarch wouldn't track any state itself. It would be distributed
|
||||
across all the peasants. The Monarch could then iterate over the list of
|
||||
peasants and find the one with the newest `LastActivated` timestamp.
|
||||
|
||||
Now, when a Monarch dies, the new Peasant doesn't have to come up with the stack
|
||||
itself. All the other Peasants keep their state. The new Monarch can query them
|
||||
and get the same answer the old Monarch would have.
|
||||
|
||||
We could further optimize this by having the Monarch also track the stack. Then,
|
||||
the monarch could query the MRU window quickly. The `LastActivated` timestamps
|
||||
would only be used by a new Monarch when it is elected, to reconstruct the MRU
|
||||
stack.
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
This is a list of actionable tasks generated as described by this spec:
|
||||
|
||||
* [ ] Add support for `wt.exe` processes to be Monarchs and Peasants, and
|
||||
communicate that state between themselves. This task does not otherwise add
|
||||
any user-facing features, merely an architectural update.
|
||||
* [ ] Add support for the `windowingBehavior` setting as a boolean. Opening new
|
||||
WT windows will conditionally glom to existing windows.
|
||||
* [ ] Add support for per-desktop `windowingBehavior`, by adding the support for
|
||||
the enum values `"useExisting"`, `"useExistingOnSameDesktop"` and `"useNew"`.
|
||||
* [ ] Add support for `wt.exe` to pass commandlines intended for another window
|
||||
to the monarch, then to the intended window, with the `--window,-w
|
||||
window-id` commandline parameter.
|
||||
* [ ] Add support for targeting and naming windows via the `-w` parameter on the
|
||||
commandline
|
||||
* [ ] Add a `NameWindow` action, subcommand that allows the user to set the name
|
||||
for the window.
|
||||
* [ ] Add an action that will cause all windows to briefly display a overlay
|
||||
with the current window ID and name. This would be something like the
|
||||
"identify" feature of the Windows "Display" settings.
|
||||
|
||||
## Future considerations
|
||||
|
||||
* What if the user wanted to pipe a command to a pane in an existing window?
|
||||
```sh
|
||||
man ping > wt -w 0 split-pane cat
|
||||
```
|
||||
Is there some way for WT to pass its stdin/out handles to the child process
|
||||
it's creating? This is _not_ related to the current spec at hand, just
|
||||
something the author considered while writing the spec. This likely belongs
|
||||
over in [#492], or in its own spec.
|
||||
- Or I suppose, with less confusion, someone could run `wt -w 0 split-pane --
|
||||
man ping > cat`. That's certainly more sensible, and wouldn't require any
|
||||
extra work.
|
||||
* "Single Instance Mode" is a scenario in which there is only ever one single WT
|
||||
window. A user might want this functionality to only ever allow a single
|
||||
terminal window to be open on their desktop. This is especially frequently
|
||||
requested in combination with "quake mode", as discussed in [#653]. When Single
|
||||
Instance Mode is active, and the user runs a new `wt.exe` commandline, it will
|
||||
always end up running in the existing window, if there is one.
|
||||
|
||||
An earlier version of this spec proposed a new value of `glomToLastWindow`.
|
||||
(`glomToLastWindow` was later renamed `windowingBehavior`). The `always` value
|
||||
would disable tab tear out<sup>[[1]](#footnote-1)</sup>. It would additionally
|
||||
disable the `newWindow` action, and prevent `wt -w new` from opening a new
|
||||
window.
|
||||
|
||||
In discussion, it was concluded that this setting didn't make sense. Why did the
|
||||
`glomToLastWindow` setting change the behavior of tear out? Single Instance Mode
|
||||
is most frequently requested in regards to quake mode. We're leaving the
|
||||
implementation of true single instance mode to that spec.
|
||||
* It was suggested in review that we could auto-generate names for windows, from
|
||||
some list of words. Prior art could be the URLS for gfycat.com or
|
||||
what3words.com, which use three random words. I believe `docker` also assigns
|
||||
names from a random selection of `adjective`+`name`. This is an interesting
|
||||
idea, and something that could be pursued in the future.
|
||||
- This would be a massive pain to localize though, hence why this is left as
|
||||
a future consideration.
|
||||
* We will _need_ to provide a commandline tool to list windows and their IDs &
|
||||
names. We're thinking a list of windows, their IDs, names, PIDs, and the title
|
||||
of the window.
|
||||
|
||||
Currently we're stuck with `wt.exe` which is a GUI application, and cannot
|
||||
print to the console. Our need is now fairly high for the ability to print
|
||||
info to the console. To remedy this, we'll need to ship another helper exe as
|
||||
a commandline tool for working with the terminal. The design for this is left
|
||||
for the future.
|
||||
|
||||
## Footnotes
|
||||
|
||||
<a name="footnote-1"><a>[1]: While tear-out is a separate track of work from
|
||||
session management in general, this setting could be implemented along with this
|
||||
set of features, and later used to control tear out as well.
|
||||
|
||||
<a name="footnote-2"><a>[2]: Since we're reserving the keyword `new` to mean "a
|
||||
new window", then we could also reserve `last` or `current` as an alias for "the
|
||||
current window".
|
||||
|
||||
<a name="footnote-3"><a>[3]: We currently have two actions for renaming _tabs_
|
||||
in the Terminal: `renameTab(name)`, and `openTabRenamer()`. We will likely
|
||||
similarly need `nameWindow(name)` and `openWindowNamer()`. `openWindowNamer`
|
||||
could display a dialog to allow the user to rename the current window at
|
||||
runtime.
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
* [Tab Tear-out in the community toolkit] - this document proved invaluable to
|
||||
the background of tearing a tab out of an application to create a new window.
|
||||
|
||||
<!-- Footnotes -->
|
||||
|
||||
[#5000]: https://github.com/microsoft/terminal/issues/5000
|
||||
[#1256]: https://github.com/microsoft/terminal/issues/1256
|
||||
[#4472]: https://github.com/microsoft/terminal/issues/4472
|
||||
[#2227]: https://github.com/microsoft/terminal/issues/2227
|
||||
[#653]: https://github.com/microsoft/terminal/issues/653
|
||||
[#1032]: https://github.com/microsoft/terminal/issues/1032
|
||||
[#632]: https://github.com/microsoft/terminal/issues/632
|
||||
[#492]: https://github.com/microsoft/terminal/issues/492
|
||||
[#4000]: https://github.com/microsoft/terminal/issues/4000
|
||||
[#7972]: https://github.com/microsoft/terminal/pull/7972
|
||||
[#961]: https://github.com/microsoft/terminal/issues/961
|
||||
[`30b8335`]: https://github.com/microsoft/terminal/commit/30b833547928d6dcbf88d49df0dbd5b3f6a7c879
|
||||
[Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff
|
||||
[Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107
|
||||
[`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle
|
||||
[Process Model 2.0 Spec]: https://github.com/microsoft/terminal/blob/main/doc/specs/%235000%20-%20Process%20Model%202.0/%235000%20-%20Process%20Model%202.0.md
|
||||