Original console buffer is not restored when closing a secondary one #22180

Closed
opened 2026-01-31 08:05:43 +00:00 by claunia · 15 comments
Owner

Originally created by @avih on GitHub (Aug 28, 2024).

Originally assigned to: @lhecker on GitHub.

Windows Terminal version

1.22.240823002-preview

Windows build number

10.0.19045

Other Software

No response

Steps to reproduce

Reduced test code (by lhecker):

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

int main() {
    const auto buffer = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, nullptr, CONSOLE_TEXTMODE_BUFFER, nullptr);
    SetConsoleActiveScreenBuffer(buffer);
    CloseHandle(buffer);
    return 0;
}

Run a program which creates and activates a new console screen buffer using CreateConsoleScreenBuffer and SetConsoleActiveScreenBuffer.

The following C program with argument value 0-4 does all combos:

// usage: *argv 0|1|2|3|4
// create+activate new screen buffer, print a message to it, sleep 1s, then before exit:
//   0: do nothing.
//   1: CloseHandle(newbuf).
//   2: SetConsoleActiveScreenBuffer(orig_con)
//   3: CloseHandle(newbuf), SetConsoleActiveScreenBuffer(orig_con)
//   4: SetConsoleActiveScreenBuffer(orig_con), CloseHandle(newbuf)
newbuf.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>


#define writecon(h, s) WriteConsole(h, (s), strlen(s), 0, 0)
#define ERR_EXIT(...) (fprintf(stderr, __VA_ARGS__), exit(1), 0)

// usage: *argv 0|1|2|3|4
// create+activate new screen buffer, print a message to it, sleep 1s, then before exit:
//   0: do nothing.
//   1: CloseHandle(newbuf).
//   2: SetConsoleActiveScreenBuffer(orig_con)
//   3: CloseHandle(newbuf), SetConsoleActiveScreenBuffer(orig_con)
//   4: SetConsoleActiveScreenBuffer(orig_con), CloseHandle(newbuf)

int main(int argc, char **argv)
{
	int mode = argc > 1 ? atoi(argv[1]) : 0;

	HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hcon == INVALID_HANDLE_VALUE)
		ERR_EXIT("can't get stdout handle\n");

	if (!writecon(hcon, "orig screen buffer\n"))
		ERR_EXIT("can't write to stdout console\n");

	HANDLE hnewbuf = CreateConsoleScreenBuffer(
		GENERIC_WRITE, FILE_SHARE_WRITE,
		0, CONSOLE_TEXTMODE_BUFFER, 0);
	if (hnewbuf == INVALID_HANDLE_VALUE)
		ERR_EXIT("can't create new screen buf\n");

	if (!SetConsoleActiveScreenBuffer(hnewbuf))
		ERR_EXIT("can't activete new screen buf\n");

	if (!writecon(hnewbuf, "new screen buffer\n"))
		ERR_EXIT("can't write to new screen buf\n");

	Sleep(1000);

	// all combos of "close new buf" and "restore orig buff", + reverse order.
	//
	// expected result:
	// - all combos restore the original buf on exit (maybe implicitly)
	//
	// actual result:
	// - Working as expected in conhost.exe or OpenConsole.exe (including 1.22)
	//   or Windows Terminal (up to and including 1.21).
	//
	// - in Windows Terminal 1.22: only 2 and 4 work as expected
	//   ("restore orig buf" without or before "close new buf")
	//   - 0: no close and no manual restore: not restored.
	//   - 1: close only: not restored.
	//   - 3: close and restored manually: not restored.

	switch (mode) {
		case 0:
			break;

		case 1:
			CloseHandle(hnewbuf);
			break;

		case 2:
			if (!SetConsoleActiveScreenBuffer(hcon))
				ERR_EXIT("can't restore orig screen buf\n");
			break;

		case 3:
			CloseHandle(hnewbuf);
			if (!SetConsoleActiveScreenBuffer(hcon))
				ERR_EXIT("can't restore orig screen buf\n");
			break;

		case 4:  // like 3 but in reverse order
			if (!SetConsoleActiveScreenBuffer(hcon))
				ERR_EXIT("can't restore orig screen buf\n");
			CloseHandle(hnewbuf);
			break;
	}

	return 0;
}

Expected Behavior

Original screen buffer is restored when the application exits (its content and original cursor position), regardless if the new screen buffer handle is closed or not, and regardless if the original screen buffer is re-activated before exit.

Actual Behavior

No issue in conhost.exe or OpenConsole.exe (even of 1.22), or Windows terminal up to and including 1.21.

With Windows terminal 1.22 (preview):

  • The original screen buffer is only restored if SetConsoleActiveScreenBuffer(orig_con) is invoked without or before CloseHandle(h_newbuf).
  • Specifically, it's not restored if:
    • Neither CloseHandle nor SetConsoleActiveScreenBuffer(orig_con) are used.
    • Only CloseHandle is used.
    • Both CloseHandle and SetConsoleActiveScreenBuffer(orig_con) are used in that order.
Originally created by @avih on GitHub (Aug 28, 2024). Originally assigned to: @lhecker on GitHub. ### Windows Terminal version 1.22.240823002-preview ### Windows build number 10.0.19045 ### Other Software _No response_ ### Steps to reproduce Reduced test code (by lhecker): ```cpp #define WIN32_LEAN_AND_MEAN #include <Windows.h> int main() { const auto buffer = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, nullptr, CONSOLE_TEXTMODE_BUFFER, nullptr); SetConsoleActiveScreenBuffer(buffer); CloseHandle(buffer); return 0; } ``` --- Run a program which creates and activates a new console screen buffer using `CreateConsoleScreenBuffer` and `SetConsoleActiveScreenBuffer`. The following C program with argument value 0-4 does all combos: ``` // usage: *argv 0|1|2|3|4 // create+activate new screen buffer, print a message to it, sleep 1s, then before exit: // 0: do nothing. // 1: CloseHandle(newbuf). // 2: SetConsoleActiveScreenBuffer(orig_con) // 3: CloseHandle(newbuf), SetConsoleActiveScreenBuffer(orig_con) // 4: SetConsoleActiveScreenBuffer(orig_con), CloseHandle(newbuf) ``` <details> <summary>newbuf.c</summary> ```c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <windows.h> #define writecon(h, s) WriteConsole(h, (s), strlen(s), 0, 0) #define ERR_EXIT(...) (fprintf(stderr, __VA_ARGS__), exit(1), 0) // usage: *argv 0|1|2|3|4 // create+activate new screen buffer, print a message to it, sleep 1s, then before exit: // 0: do nothing. // 1: CloseHandle(newbuf). // 2: SetConsoleActiveScreenBuffer(orig_con) // 3: CloseHandle(newbuf), SetConsoleActiveScreenBuffer(orig_con) // 4: SetConsoleActiveScreenBuffer(orig_con), CloseHandle(newbuf) int main(int argc, char **argv) { int mode = argc > 1 ? atoi(argv[1]) : 0; HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE); if (hcon == INVALID_HANDLE_VALUE) ERR_EXIT("can't get stdout handle\n"); if (!writecon(hcon, "orig screen buffer\n")) ERR_EXIT("can't write to stdout console\n"); HANDLE hnewbuf = CreateConsoleScreenBuffer( GENERIC_WRITE, FILE_SHARE_WRITE, 0, CONSOLE_TEXTMODE_BUFFER, 0); if (hnewbuf == INVALID_HANDLE_VALUE) ERR_EXIT("can't create new screen buf\n"); if (!SetConsoleActiveScreenBuffer(hnewbuf)) ERR_EXIT("can't activete new screen buf\n"); if (!writecon(hnewbuf, "new screen buffer\n")) ERR_EXIT("can't write to new screen buf\n"); Sleep(1000); // all combos of "close new buf" and "restore orig buff", + reverse order. // // expected result: // - all combos restore the original buf on exit (maybe implicitly) // // actual result: // - Working as expected in conhost.exe or OpenConsole.exe (including 1.22) // or Windows Terminal (up to and including 1.21). // // - in Windows Terminal 1.22: only 2 and 4 work as expected // ("restore orig buf" without or before "close new buf") // - 0: no close and no manual restore: not restored. // - 1: close only: not restored. // - 3: close and restored manually: not restored. switch (mode) { case 0: break; case 1: CloseHandle(hnewbuf); break; case 2: if (!SetConsoleActiveScreenBuffer(hcon)) ERR_EXIT("can't restore orig screen buf\n"); break; case 3: CloseHandle(hnewbuf); if (!SetConsoleActiveScreenBuffer(hcon)) ERR_EXIT("can't restore orig screen buf\n"); break; case 4: // like 3 but in reverse order if (!SetConsoleActiveScreenBuffer(hcon)) ERR_EXIT("can't restore orig screen buf\n"); CloseHandle(hnewbuf); break; } return 0; } ``` </details> ### Expected Behavior Original screen buffer is restored when the application exits (its content and original cursor position), regardless if the new screen buffer handle is closed or not, and regardless if the original screen buffer is re-activated before exit. ### Actual Behavior No issue in conhost.exe or OpenConsole.exe (even of 1.22), or Windows terminal up to and including 1.21. With Windows terminal 1.22 (preview): - The original screen buffer is only restored if `SetConsoleActiveScreenBuffer(orig_con)` is invoked without or before `CloseHandle(h_newbuf)`. - Specifically, it's not restored if: - Neither `CloseHandle` nor `SetConsoleActiveScreenBuffer(orig_con)` are used. - Only `CloseHandle` is used. - Both `CloseHandle` and `SetConsoleActiveScreenBuffer(orig_con)` are used in that order.
claunia added the Issue-BugIn-PRArea-VTNeeds-Tag-FixProduct-Conpty labels 2026-01-31 08:05:44 +00:00
Author
Owner

@avih commented on GitHub (Aug 29, 2024):

zadjii-msft added this to the Terminal v1.23 milestone

While it's not mine to decide, and personally I can wait for a build with this fixed, I'd think it would be nice to fix it in 1.22, because it's still relatively early and only one preview build was released of 1.22, and it does affect the default behavior of existing applications, such as less.exe, and I'm guessing possibly more editors and pagers.

@avih commented on GitHub (Aug 29, 2024): > [zadjii-msft](https://github.com/zadjii-msft) added this to the [Terminal v1.23](https://github.com/microsoft/terminal/milestone/57) milestone While it's not mine to decide, and personally I can wait for a build with this fixed, I'd think it would be nice to fix it in 1.22, because it's still relatively early and only one preview build was released of 1.22, and it does affect the default behavior of existing applications, such as `less.exe`, and I'm guessing possibly more editors and pagers.
Author
Owner

@lhecker commented on GitHub (Aug 29, 2024):

The milestone for us just indicates in what period we're working on it. Now that 1.22 was released we're in the 1.23 development period and so on. We usually spend the beginning of each period for fixing bugs in the just released versions. That will also be the case for this issue.

In short, I'm going to fix this soon. 🙂

@lhecker commented on GitHub (Aug 29, 2024): The milestone for us just indicates in what period we're working on it. Now that 1.22 was released we're in the 1.23 development period and so on. We usually spend the beginning of each period for fixing bugs in the just released versions. That will also be the case for this issue. In short, I'm going to fix this soon. 🙂
Author
Owner

@avih commented on GitHub (Aug 29, 2024):

Now that 1.22 was released

Was it?

Yesterday 1.21 had the first stable release: "Terminal 1.21 is finally stable!...". and 1.22 had the first preview build.

Doesn't that mean that 1.21 is now ready for most users, but that there's still work to bugfix before 1.22 becomes stable and ready for public consumption? I.e. that "stable" is for most users, and that "preview" is for early adopters which can test it and report issues which would hopefully get fixed before 1.22 is considered "Ready" and distributed to the larger public?

The store page says about "Windows Terminal Preview":

This is the preview build of the Windows Terminal, which contains the latest features as they are developed.

I.e. that there's still work to be done before the preview version is considered "ready"?

In short, I'm going to fix this soon. 🙂

That's nice, though my main concern was/is that there would be a "stable" version which is distributed to a large number of people which has this issue...

Or am I missing something with the "stable"/"preview" terminology and/or pipeline?

@avih commented on GitHub (Aug 29, 2024): > Now that 1.22 was released Was it? Yesterday 1.21 had the first stable release: "Terminal 1.21 is finally stable!...". and 1.22 had the first preview build. Doesn't that mean that 1.21 is now ready for most users, but that there's still work to bugfix before 1.22 becomes stable and ready for public consumption? I.e. that "stable" is for most users, and that "preview" is for early adopters which can test it and report issues which would hopefully get fixed before 1.22 is considered "Ready" and distributed to the larger public? The store page says about "Windows Terminal Preview": > This is the preview build of the Windows Terminal, which contains the latest features as they are developed. I.e. that there's still work to be done before the preview version is considered "ready"? > In short, I'm going to fix this soon. 🙂 That's nice, though my main concern was/is that there would be a "stable" version which is distributed to a large number of people which has this issue... Or am I missing something with the "stable"/"preview" terminology and/or pipeline?
Author
Owner

@ehoogeveen-medweb commented on GitHub (Aug 29, 2024):

which contains the latest features as they are developed

This could be rephrased to something like "contains the latest features that we think are ready, but may not be entirely stable yet" (though there's a philosophical question about whether any software is ever truly "stable", as pretty much all software contains bugs 😄).

Basically, both "Windows Terminal" (current version 1.21.x) and "Windows Terminal Preview" (current version 1.22.x) receive bugfixes, but new features are developed for the main branch. The Preview version can be used by anyone but is more likely to have issues, especially shortly after a release.

@ehoogeveen-medweb commented on GitHub (Aug 29, 2024): > which contains the latest features as they are developed This could be rephrased to something like "contains the latest features that we think are ready, but may not be entirely stable yet" (though there's a philosophical question about whether any software is ever truly "stable", as pretty much all software contains bugs 😄). Basically, both "Windows Terminal" (current version `1.21.x`) and "Windows Terminal Preview" (current version `1.22.x`) receive bugfixes, but new features are developed for the main branch. The Preview version can be used by anyone but is more likely to have issues, especially shortly after a release.
Author
Owner

@avih commented on GitHub (Aug 29, 2024):

Basically, both "Windows Terminal" (current version 1.21.x) and "Windows Terminal Preview" (current version 1.22.x) receive bugfixes, but new features are developed for the main branch. The Preview version can be used by anyone but is more likely to have issues, especially shortly after a release.

Yeah, that's what I thought too.

So do you consider "restore screen buffer correctly like it behaved in 1.21" a new feature?

To me that's more like a bugfix in 1.22. Is it not?

(that's not to say that it must be fixed in 1.22. I marely expressed hope that it could get fixed in 1.22 before it becomes stable).

@avih commented on GitHub (Aug 29, 2024): > Basically, both "Windows Terminal" (current version `1.21.x`) and "Windows Terminal Preview" (current version `1.22.x`) receive bugfixes, but new features are developed for the main branch. The Preview version can be used by anyone but is more likely to have issues, especially shortly after a release. Yeah, that's what I thought too. So do you consider "restore screen buffer correctly like it behaved in 1.21" a new feature? To me that's more like a bugfix in 1.22. Is it not? (that's not to say that it must be fixed in 1.22. I marely expressed hope that it could get fixed in 1.22 before it becomes stable).
Author
Owner

@ehoogeveen-medweb commented on GitHub (Aug 29, 2024):

Well, I would certainly consider it a bugfix (though I'm not part of the team), but I think the point is that the milestone just indicates that the fix will be developed on the branch for 1.23. It would then presumably be cherry-picked or backported to 1.22 assuming the fix isn't riskier than the impact of the bug.

@ehoogeveen-medweb commented on GitHub (Aug 29, 2024): Well, I would certainly consider it a bugfix (though I'm not part of the team), but I think the point is that the milestone just indicates that the fix will be *developed* on the branch for 1.23. It would then presumably be cherry-picked or backported to 1.22 assuming the fix isn't riskier than the impact of the bug.
Author
Owner

@avih commented on GitHub (Aug 29, 2024):

It would then presumably be cherry-picked or backported to 1.22 assuming the fix isn't riskier than the impact of the bug.

Right. That was my missing link. That makes sense to me. Thanks.

@avih commented on GitHub (Aug 29, 2024): > It would then presumably be cherry-picked or backported to 1.22 assuming the fix isn't riskier than the impact of the bug. Right. That was my missing link. That makes sense to me. Thanks.
Author
Owner

@zadjii-msft commented on GitHub (Aug 29, 2024):

That's all correct.

  • This regressed in 1.22
  • 1.22 was released to preview this week
  • Preview builds are "mostly ready but likely with more bugs than stable" (and is typically high enough quality to be a daily driver)
  • This bug is in the 1.23 milestone (which just tracks when we will work on it)
  • This one is tagged up for servicing back to 1.22.
    • The project board that shows servicing bugs isn't publicly visible, but we're also actively working on updating that to make it cleaner. So it doesn't really need to be public to see our WIP on that.
@zadjii-msft commented on GitHub (Aug 29, 2024): That's all correct. * This regressed in 1.22 * 1.22 was released to preview this week * Preview builds are "mostly ready but likely with more bugs than stable" (and is typically high enough quality to be a daily driver) * This bug is in the 1.23 milestone (which just tracks _when_ we will work on it) * This one is tagged up for servicing back to 1.22. * The project board that shows servicing bugs isn't publicly visible, but we're also actively working on updating that to make it cleaner. So it doesn't really need to be public to see our WIP on that.
Author
Owner

@richardeid commented on GitHub (Aug 30, 2024):

I'm on 1.21 and I can't get the buffer to restore. Open windows from a previous session is set. Am I doing something wrong?

@richardeid commented on GitHub (Aug 30, 2024): I'm on 1.21 and I can't get the buffer to restore. Open windows from a previous session is set. Am I doing something wrong?
Author
Owner

@avih commented on GitHub (Aug 30, 2024):

Open windows from a previous session is set.

This issue is not about restoring the content from a previous session when opening a new terminal window.

It's about restoring the screen content after an application (like an editor, or pager) creates and works in a new screen buffer, and then exits.

@avih commented on GitHub (Aug 30, 2024): > Open windows from a previous session is set. This issue is not about restoring the content from a previous session when opening a new terminal window. It's about restoring the screen content after an application (like an editor, or pager) creates and works in a new screen buffer, and then exits.
Author
Owner

@lhecker commented on GitHub (Sep 3, 2024):

@richardeid If you still have this issue, please open a discussion or open another issue. We'll then try to help you.

@lhecker commented on GitHub (Sep 3, 2024): @richardeid If you still have this issue, please open a discussion or open another issue. We'll then try to help you.
Author
Owner

@richardeid commented on GitHub (Sep 3, 2024):

@lhecker I think I misunderstood what this was. I was expecting my console history to restore. Thank you for following up

@richardeid commented on GitHub (Sep 3, 2024): @lhecker I think I misunderstood what this was. I was expecting my console history to restore. Thank you for following up
Author
Owner

@avih commented on GitHub (Sep 4, 2024):

I can confirm that the build artifact of #17853 has this issue fixed.

Tested with the C test progam given above, and also other use cases with less.exe for windows, which are broken in 1.22-preview but work OK in the PR artifact.

@avih commented on GitHub (Sep 4, 2024): I can confirm that the build artifact of #17853 has this issue fixed. Tested with the C test progam given above, and also other use cases with `less.exe` for windows, which are broken in 1.22-preview but work OK in the PR artifact.
Author
Owner

@avih commented on GitHub (Sep 6, 2024):

Thanks. Confirmed build artifact of 544452da is fixed.

@avih commented on GitHub (Sep 6, 2024): Thanks. Confirmed build artifact of 544452da is fixed.
Author
Owner

@avih commented on GitHub (Sep 29, 2024):

It would then presumably be cherry-picked or backported to 1.22 assuming the fix isn't riskier than the impact of the bug.

Right. That was my missing link. That makes sense to me. Thanks.

Can confirm this is fixed in the latest Preview v1.22.2702.0 .
Thanks!

@avih commented on GitHub (Sep 29, 2024): > > It would then presumably be cherry-picked or backported to 1.22 assuming the fix isn't riskier than the impact of the bug. > > Right. That was my missing link. That makes sense to me. Thanks. Can confirm this is fixed in the latest Preview v1.22.2702.0 . Thanks!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#22180