From 7e00edd5166096feb59ffa694b6a6ff858fe1924 Mon Sep 17 00:00:00 2001 From: Kurt Hindenburg Date: Fri, 5 Aug 2011 10:40:14 -0400 Subject: [PATCH] Make sure pty device has right size before terminal process queries it. Whenever TeminalDisplay is resized, konsole tells the underlying pty device its new size by calling Pty::setWindowSize(). However, current code can't guarantee when the terminal process starts and queries the pty device about its size, the pty device already has the right info. This has caused some long known bugs, such as #176902. This patch tries to guarantee that important assumption. It currently uses a hard-coded small delay, which works pretty well in practice although not that elegant. Patch by Jekyll Wu I think this is better than leaving the situation as it is. This may be backported if no issues are found. BUG: 173999 BUG: 176902 BUG: 203185 BUG: 229058 REVIEW: 102061 FIXED-IN: 4.8 --- src/Application.cpp | 1 - src/Emulation.cpp | 36 ++++++++++++++++++++++++++++++------ src/Emulation.h | 7 +++++++ src/Session.cpp | 1 + 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index 9351772ce..244ec5e23 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -442,7 +442,6 @@ Session* Application::createSession(Profile::Ptr profile, const QString& directo // a change in terminal size right after the session starts. some applications such as GNU Screen // and Midnight Commander don't like this happening view->createView(session); - session->run(); return session; } diff --git a/src/Emulation.cpp b/src/Emulation.cpp index e769833e6..f86b53dea 100644 --- a/src/Emulation.cpp +++ b/src/Emulation.cpp @@ -58,7 +58,8 @@ Emulation::Emulation() : _codec(0), _decoder(0), _keyTranslator(0), - _usesMouse(false) + _usesMouse(false), + _imageSizeInitialized(false) { // create screens with a default size _screen[0] = new Screen(40,80); @@ -347,14 +348,37 @@ void Emulation::setImageSize(int lines, int columns) QSize newSize(columns,lines); if (newSize == screenSize[0] && newSize == screenSize[1]) - return; + { + // If this method is called for the first time, always emit + // SIGNAL(imageSizeChange()), even if the new size is the same as the + // current size. See #176902 + if (!_imageSizeInitialized) + { + emit imageSizeChanged(lines,columns); + } + } + else + { + _screen[0]->resizeImage(lines,columns); + _screen[1]->resizeImage(lines,columns); - _screen[0]->resizeImage(lines,columns); - _screen[1]->resizeImage(lines,columns); + emit imageSizeChanged(lines,columns); - emit imageSizeChanged(lines,columns); + bufferedUpdate(); + } + + if (!_imageSizeInitialized) + { + _imageSizeInitialized = true; + + // FIXME + // a hard-coded, small delay is introduced to gurarantee Session::run() + // does not get triggered by SIGNAL(imageSizeInitialized()) before + // Pty::setWindowSize() is triggered by previously emitted + // SIGNAL(imageSizeChanged()); See #203185 + QTimer::singleShot(200, this, SIGNAL(imageSizeInitialized()) ); + } - bufferedUpdate(); } QSize Emulation::imageSize() const diff --git a/src/Emulation.h b/src/Emulation.h index 2a6c3715d..cb5fbcfa8 100644 --- a/src/Emulation.h +++ b/src/Emulation.h @@ -378,6 +378,12 @@ signals: */ void imageSizeChanged(int lineCount , int columnCount); + /** + * Emitted when the setImageSize() is called on this emulation for + * the first time. + */ + void imageSizeInitialized(); + /** * Emitted when the terminal program requests to change various properties * of the terminal display. @@ -462,6 +468,7 @@ private: bool _usesMouse; QTimer _bulkTimer1; QTimer _bulkTimer2; + bool _imageSizeInitialized; }; diff --git a/src/Session.cpp b/src/Session.cpp index 5890d5c7c..8b735e787 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -177,6 +177,7 @@ void Session::openTeletype(int fd) connect( _emulation,SIGNAL(useUtf8Request(bool)),_shellProcess,SLOT(setUtf8Mode(bool)) ); connect( _shellProcess,SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(done(int,QProcess::ExitStatus)) ); connect( _emulation,SIGNAL(imageSizeChanged(int,int)),this,SLOT(updateWindowSize(int,int)) ); + connect( _emulation,SIGNAL(imageSizeInitialized()),this,SLOT(run()) ); } WId Session::windowId() const