Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WriteConsoleOutput() does not write at expected position when console window is maximized/restored #17527

Closed
tigrouind opened this issue Jul 8, 2024 · 1 comment
Assignees
Labels
Area-Server Down in the muck of API call servicing, interprocess communication, eventing, etc. Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Tag-Fix Doesn't match tag requirements Product-Conhost For issues in the Console codebase

Comments

@tigrouind
Copy link

tigrouind commented Jul 8, 2024

Windows Terminal version

1.20.11381.0

Windows build number

10.0.22631.3737

Other Software

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
	internal class Program
	{
		[DllImport("Kernel32.dll")]
		static extern IntPtr CreateFile(
			string fileName,
			[MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
			[MarshalAs(UnmanagedType.U4)] FileShare fileShare,
			IntPtr securityAttributes,
			[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
			[MarshalAs(UnmanagedType.U4)] FileAttributes flags,
			IntPtr template);

		[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
		static extern bool WriteConsoleOutput(
			IntPtr hConsoleOutput,
			CharInfo[] lpBuffer,
			Coord dwBufferSize,
			Coord dwBufferCoord,
			ref SmallRect lpWriteRegion);

		const uint GENERIC_WRITE = 0x40000000;

		[StructLayout(LayoutKind.Sequential)]
		public struct Coord
		{
			public short X;
			public short Y;
		};

		[StructLayout(LayoutKind.Sequential)]
		public struct SmallRect
		{
			public short Left;
			public short Top;
			public short Right;
			public short Bottom;
		}

		[StructLayout(LayoutKind.Explicit)]
		public struct CharInfo
		{
			[FieldOffset(0)] public char Char;
			[FieldOffset(2)] public short Attributes;
		}

		static void Main()
		{
			int backgroundColor = 1;
			var handle = CreateFile("CONOUT$", (FileAccess)GENERIC_WRITE, FileShare.Write, 
						IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);

			while (true)
			{
				int width = Console.WindowWidth;
				int height = Console.WindowHeight;

				CharInfo[] buffer = new CharInfo[width * height];
				for (int i = 0; i < buffer.Length; i++)
				{
					buffer[i] = new CharInfo() { 
						Char = ' ', 
						Attributes = (short)((backgroundColor % 3 + 1) << 4) 
					};
				}

				var rect = new SmallRect() { 
					Left = 0, 
					Top = 0, 
					Right = (short)(width - 1), 
					Bottom = (short)(height - 1) 
				};
				//Console.SetCursorPosition(1, 0); //fix the issue
				WriteConsoleOutput(handle, buffer, new Coord() {
					X = (short)width,
					Y = (short)height 
				}, new Coord() { X = 0, Y = 0 }, ref rect);
				Console.Beep(500, 250);
				System.Threading.Thread.Sleep(1000);
				backgroundColor++;			
			}
		}
	}
}

Steps to reproduce

Run the program above.
It outputs a new background color every second, along with a beep.
Maximize console window (eg: double click on title)
Restore console window (eg: double click on title again)

Expected Behavior

Right after console window is restored, the background color is updated.

Actual Behavior

The background color stay the same.

WriteConsoleOutput() render characters at the top of the console area, which is invisible (you have to scroll up to see it).
Instead, it should render characters in the visible portion of the console.
Setting the console cursor at a position other than (0, 0) fix the issue. That probably why some project like Terminal.Gui are not affected (eg: cursor is usually set inside active control).
The old command prompt does not have this bug. Using AtlasEngine does not fix the issue.

@tigrouind tigrouind added Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Jul 8, 2024
@tigrouind tigrouind changed the title WriteConsoleOutput() does not produce expected result, unless cursor is not at (0, 0) WriteConsoleOutput() does not write at expected position when console window is maximized/restored Jul 9, 2024
@carlos-zamora carlos-zamora added this to the Terminal v1.22 milestone Jul 17, 2024
@carlos-zamora carlos-zamora added Product-Conhost For issues in the Console codebase Area-Server Down in the muck of API call servicing, interprocess communication, eventing, etc. and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Jul 24, 2024
@lhecker
Copy link
Member

lhecker commented Aug 22, 2024

This issue was partially addressed with v1.21 (not entirely sure which PR did that) and will be fully addressed in v1.22 (due to #17510). v1.22 will be released as the next Preview version next week.

@lhecker lhecker closed this as completed Aug 22, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Tag-Fix Doesn't match tag requirements label Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Server Down in the muck of API call servicing, interprocess communication, eventing, etc. Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Tag-Fix Doesn't match tag requirements Product-Conhost For issues in the Console codebase
Projects
None yet
Development

No branches or pull requests

3 participants