Merge remote-tracking branch 'upstream/master' into unstable

This commit is contained in:
Filippo Scognamiglio
2018-10-16 00:18:25 +02:00
109 changed files with 6729 additions and 2380 deletions
+62 -52
View File
@@ -26,7 +26,6 @@
#include "Session.h"
// Standard
#include <assert.h>
#include <stdlib.h>
// Qt
@@ -62,6 +61,7 @@ Session::Session(QObject* parent) :
, _autoClose(true)
, _wantedClose(false)
, _silenceSeconds(10)
, _isTitleChanged(false)
, _addToUtmp(false) // disabled by default because of a bug encountered on certain systems
// which caused Konsole to hang when closing a tab and then opening a new
// one. A 'QProcess destroyed while still running' warning was being
@@ -84,6 +84,7 @@ Session::Session(QObject* parent) :
//create teletype for I/O with shell process
_shellProcess = new Pty();
ptySlaveFd = _shellProcess->pty()->slaveFd();
//create emulation backend
_emulation = new Vt102Emulation();
@@ -98,9 +99,13 @@ Session::Session(QObject* parent) :
this, SIGNAL( changeTabTextColorRequest( int ) ) );
connect( _emulation, SIGNAL(profileChangeCommandReceived(const QString &)),
this, SIGNAL( profileChangeCommandReceived(const QString &)) );
// TODO
// connect( _emulation,SIGNAL(imageSizeChanged(int,int)) , this ,
// SLOT(onEmulationSizeChange(int,int)) );
connect(_emulation, SIGNAL(imageResizeRequest(QSize)),
this, SLOT(onEmulationSizeChange(QSize)));
connect(_emulation, SIGNAL(imageSizeChanged(int, int)),
this, SLOT(onViewSizeChange(int, int)));
connect(_emulation, &Vt102Emulation::cursorChanged,
this, &Session::cursorChanged);
//connect teletype to emulation backend
_shellProcess->setUtf8Mode(_emulation->utf8());
@@ -123,24 +128,11 @@ Session::Session(QObject* parent) :
WId Session::windowId() const
{
// Returns a window ID for this session which is used
// to set the WINDOWID environment variable in the shell
// process.
//
// Sessions can have multiple views or no views, which means
// that a single ID is not always going to be accurate.
//
// If there are no views, the window ID is just 0. If
// there are multiple views, then the window ID for the
// top-level window which contains the first view is
// returned
if ( _views.count() == 0 ) {
return 0;
} else {
QQuickWindow * window = _views.first()->window();
return (window ? window->winId() : 0);
}
// On Qt5, requesting window IDs breaks QQuickWidget and the likes,
// for example, see the following bug reports:
// https://bugreports.qt.io/browse/QTBUG-40765
// https://codereview.qt-project.org/#/c/94880/
return 0;
}
void Session::setDarkBackground(bool darkBackground)
@@ -201,6 +193,11 @@ void Session::addView(TerminalDisplay * widget)
widget->setUsesMouse( _emulation->programUsesMouse() );
connect( _emulation , SIGNAL(programBracketedPasteModeChanged(bool)) ,
widget , SLOT(setBracketedPasteMode(bool)) );
widget->setBracketedPasteMode(_emulation->programBracketedPasteMode());
widget->setScreenWindow(_emulation->createWindow());
}
@@ -251,53 +248,40 @@ void Session::removeView(TerminalDisplay * widget)
void Session::run()
{
//check that everything is in place to run the session
if (_program.isEmpty()) {
qDebug() << "Session::run() - program to run not set.";
}
else {
qDebug() << "Session::run() - program:" << _program;
}
if (_arguments.isEmpty()) {
qDebug() << "Session::run() - no command line arguments specified.";
}
else {
qDebug() << "Session::run() - arguments:" << _arguments;
}
// Upon a KPty error, there is no description on what that error was...
// Check to see if the given program is executable.
/* ok iam not exactly sure where _program comes from - however it was set to /bin/bash on my system
* Thats bad for BSD as its /usr/local/bin/bash there - its also bad for arch as its /usr/bin/bash there too!
* So i added a check to see if /bin/bash exists - if no then we use $SHELL - if that does not exist either, we fall back to /bin/sh
* As far as i know /bin/sh exists on every unix system.. You could also just put some ifdef __FREEBSD__ here but i think these 2 filechecks are worth
* their computing time on any system - especially with the problem on arch linux beeing there too.
*/
QString exec = QFile::encodeName(_program);
QString exec = QString::fromLocal8Bit(QFile::encodeName(_program));
// if 'exec' is not specified, fall back to default shell. if that
// is not set then fall back to /bin/sh
// here we expect full path. If there is no fullpath let's expect it's
// a custom shell (eg. python, etc.) available in the PATH.
if (exec.startsWith("/"))
if (exec.startsWith(QLatin1Char('/')) || exec.isEmpty())
{
const QString defaultShell{QLatin1String("/bin/sh")};
QFile excheck(exec);
if ( exec.isEmpty() || !excheck.exists() ) {
exec = getenv("SHELL");
exec = QString::fromLocal8Bit(qgetenv("SHELL"));
}
excheck.setFileName(exec);
if ( exec.isEmpty() || !excheck.exists() ) {
exec = "/bin/sh";
qWarning() << "Neither default shell nor $SHELL is set to a correct path. Fallback to" << defaultShell;
exec = defaultShell;
}
}
// _arguments sometimes contain ("") so isEmpty()
// or count() does not work as expected...
QString argsTmp(_arguments.join(" ").trimmed());
QString argsTmp(_arguments.join(QLatin1Char(' ')).trimmed());
QStringList arguments;
arguments << exec;
if (argsTmp.length())
@@ -317,7 +301,7 @@ void Session::run()
// tell the terminal exactly which colors are being used, but instead approximates
// the color scheme as "black on white" or "white on black" depending on whether
// the background color is deemed dark or not
QString backgroundColorHint = _hasDarkBackground ? "COLORFGBG=15;0" : "COLORFGBG=0;15";
QString backgroundColorHint = _hasDarkBackground ? QLatin1String("COLORFGBG=15;0") : QLatin1String("COLORFGBG=0;15");
/* if we do all the checking if this shell exists then we use it ;)
* Dont know about the arguments though.. maybe youll need some more checking im not sure
@@ -335,7 +319,20 @@ void Session::run()
}
_shellProcess->setWriteable(false); // We are reachable via kwrited.
qDebug() << "started!";
emit started();
}
void Session::runEmptyPTY()
{
_shellProcess->setFlowControlEnabled(_flowControl);
_shellProcess->setErase(_emulation->eraseChar());
_shellProcess->setWriteable(false);
// disconnet send data from emulator to internal terminal process
disconnect( _emulation,SIGNAL(sendData(const char *,int)),
_shellProcess, SLOT(sendData(const char *,int)) );
_shellProcess->setEmptyPTYProperties();
emit started();
}
@@ -346,6 +343,7 @@ void Session::setUserTitle( int what, const QString & caption )
// (btw: what=0 changes _userTitle and icon, what=1 only icon, what=2 only _nameTitle
if ((what == 0) || (what == 2)) {
_isTitleChanged = true;
if ( _userTitle != caption ) {
_userTitle = caption;
modified = true;
@@ -353,6 +351,7 @@ void Session::setUserTitle( int what, const QString & caption )
}
if ((what == 0) || (what == 1)) {
_isTitleChanged = true;
if ( _iconText != caption ) {
_iconText = caption;
modified = true;
@@ -360,8 +359,8 @@ void Session::setUserTitle( int what, const QString & caption )
}
if (what == 11) {
QString colorString = caption.section(';',0,0);
qDebug() << __FILE__ << __LINE__ << ": setting background colour to " << colorString;
QString colorString = caption.section(QLatin1Char(';'),0,0);
//qDebug() << __FILE__ << __LINE__ << ": setting background colour to " << colorString;
QColor backColor = QColor(colorString);
if (backColor.isValid()) { // change color via \033]11;Color\007
if (backColor != _modifiedBackground) {
@@ -378,6 +377,7 @@ void Session::setUserTitle( int what, const QString & caption )
}
if (what == 30) {
_isTitleChanged = true;
if ( _nameTitle != caption ) {
setTitle(Session::NameRole,caption);
return;
@@ -386,12 +386,13 @@ void Session::setUserTitle( int what, const QString & caption )
if (what == 31) {
QString cwd=caption;
cwd=cwd.replace( QRegExp("^~"), QDir::homePath() );
cwd=cwd.replace( QRegExp(QLatin1String("^~")), QDir::homePath() );
emit openUrlRequest(cwd);
}
// change icon via \033]32;Icon\007
if (what == 32) {
_isTitleChanged = true;
if ( _iconName != caption ) {
_iconName = caption;
@@ -467,8 +468,8 @@ void Session::activityStateSet(int state)
if ( _monitorActivity ) {
//FIXME: See comments in Session::monitorTimerDone()
if (!_notifiedActivity) {
emit activity();
_notifiedActivity=true;
emit activity();
}
}
}
@@ -487,9 +488,9 @@ void Session::onViewSizeChange(int /*height*/, int /*width*/)
{
updateTerminalSize();
}
void Session::onEmulationSizeChange(int lines , int columns)
void Session::onEmulationSizeChange(QSize size)
{
setSize( QSize(lines,columns) );
setSize(size);
}
void Session::updateTerminalSize()
@@ -592,7 +593,7 @@ QString Session::profileKey() const
void Session::done(int exitStatus)
{
if (!_autoClose) {
_userTitle = ("This session is done. Finished");
_userTitle = QString::fromLatin1("This session is done. Finished");
emit titleChanged();
return;
}
@@ -695,6 +696,11 @@ QString Session::iconText() const
return _iconText;
}
bool Session::isTitleChanged() const
{
return _isTitleChanged;
}
void Session::setHistoryType(const HistoryType & hType)
{
_emulation->setHistory(hType);
@@ -961,6 +967,10 @@ int Session::processId() const
{
return _shellProcess->pid();
}
int Session::getPtySlaveFd() const
{
return ptySlaveFd;
}
SessionGroup::SessionGroup()
: _masterMode(0)