Replies: 6 comments
-
We might need more details on the scenario here. A more concrete repro case. I don't think that conpty should be re-emitting a resize for the size it was just resized to. What OS version is ConPTY running on/? There's all sorts of code around |
Beta Was this translation helpful? Give feedback.
-
This is the test code, it's can repro the case:
The output file : out.txt |
Beta Was this translation helpful? Give feedback.
-
You should only write things into If you want to resize the console host (which will trigger the correct kind of window resize message sent to the client), you should use |
Beta Was this translation helpful? Give feedback.
-
Other bugs: On line 76 you are using |
Beta Was this translation helpful? Give feedback.
-
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. |
Beta Was this translation helpful? Give feedback.
-
I changed the test codes as you said, and ran it on my one machine( Windows 11). #include <Windows.h>
#include <stdio.h>
#include <assert.h>
#include <string>
#include <memory>
#include <time.h>
int main(int argc, char* argv[])
{
HPCON hPC = 0;
PROCESS_INFORMATION pi = { 0 };
HANDLE outPipeOurSide = nullptr, inPipeOurSide = nullptr;
HANDLE outPipePseudoConsoleSide = nullptr, inPipePseudoConsoleSide = nullptr;
int err;
bool success;
// create pty
CreatePipe(&inPipePseudoConsoleSide, &inPipeOurSide, NULL, 0);
CreatePipe(&outPipeOurSide, &outPipePseudoConsoleSide, NULL, 0);
CONSOLE_SCREEN_BUFFER_INFOEX info = { 0 };
info.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
success = GetConsoleScreenBufferInfoEx(GetStdHandle(STD_OUTPUT_HANDLE), &info);
assert(success);
short w = info.srWindow.Right - info.srWindow.Left + 1;
short h = info.srWindow.Bottom - info.srWindow.Top + 1;
err = CreatePseudoConsole(COORD{ w, h }, inPipePseudoConsoleSide, outPipePseudoConsoleSide, 0, &hPC);
assert(err == S_OK);
STARTUPINFOEXW si;
memset(&si, 0, sizeof(si));
si.StartupInfo.cb = sizeof(STARTUPINFOEXW);
size_t size;
InitializeProcThreadAttributeList(NULL, 1, 0, &size);
si.lpAttributeList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(new BYTE[size]);
success = InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, (PSIZE_T)&size);
assert(success);
success = UpdateProcThreadAttribute(
si.lpAttributeList,
0,
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
hPC,
sizeof(hPC),
NULL,
NULL);
assert(success);
std::wstring commandline = L"cmd.exe";
std::unique_ptr<wchar_t> bufCommandline(new wchar_t[commandline.length() + 1]);
memcpy(bufCommandline.get(), commandline.c_str(), (commandline.length() + 1) * sizeof(wchar_t));
success = CreateProcessW(
nullptr,
bufCommandline.get(),
nullptr,
nullptr,
TRUE,
EXTENDED_STARTUPINFO_PRESENT,
nullptr,
nullptr,
&si.StartupInfo,
&pi);
assert(success);
DeleteProcThreadAttributeList(si.lpAttributeList);
DWORD settings;
HANDLE hConsole;
//print output
success = SetConsoleOutputCP(65001); //change code page
assert(success);
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
assert(hConsole != INVALID_HANDLE_VALUE);
success = GetConsoleMode(hConsole, &settings);
assert(success);
settings |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
success = SetConsoleMode(hConsole, settings);
assert(success);
const int BUF_LEN = 4096;
std::unique_ptr<char> buf(new char[BUF_LEN]);
time_t t = time(NULL);
bool writtenResize = false;
do
{
DWORD n = 0;
success = PeekNamedPipe(outPipeOurSide, nullptr, 0, nullptr, &n, nullptr);
assert(success);
if (n)
{
if (n > BUF_LEN)
n = BUF_LEN;
DWORD l;
success = ReadFile(outPipeOurSide, buf.get(), n, &l, nullptr);
assert(success);
for (int i = 0; i < l; i++)
printf("%c", buf.get()[i]);
FILE* pf = nullptr;
{
errno_t err = fopen_s(&pf, "e:/out2.txt", "ab");
assert(pf);
}
int ret = fwrite(buf.get(), l, 1, pf);
assert(ret == 1);
fclose(pf);
}
if (time(NULL) - t > 5 && !writtenResize) // after 5 seconds, write resize command
{
//type command
short width = 600, height = 400;
/*std::string command;
command.append(1, 0x1b).append("[8;").append(std::to_string(width)).append(";").append(std::to_string(height)).append(1, 't');
DWORD l;
success = WriteFile(inPipeOurSide, command.c_str(), command.length(), &l, nullptr);
assert(success && l == command.length());*/
ResizePseudoConsole(hPC, { width, height });
writtenResize = true;
}
} while (true);
CloseHandle(pi.hProcess);
CloseHandle(outPipeOurSide);
CloseHandle(inPipeOurSide);
CloseHandle(outPipePseudoConsoleSide);
CloseHandle(inPipePseudoConsoleSide);
ClosePseudoConsole(hPC);
return 0;
}
It still echoes the size change event. out2.txt
Line 126 (at new test, it's line 130) just simulates the client window doing resize, and the ‘conpty’ synchronize it. |
Beta Was this translation helpful? Give feedback.
-
I am coding two programs, using ConPTY as a server-side run on windows, and a client runs on Linux. when the client console window size changed, the client will send '\e[8;w;ht'(w is the window real width, h is the window real height) to the server. The server received the message and writes it into the pty, but the message '\e[8;w;ht....... ' will be output back from pty and sent to the client. the client received the message and print it, and resize the window for the VT100 command, a new 'screen buffer size changed' event occurs from the client, ...... infinite loop.
Beta Was this translation helpful? Give feedback.
All reactions