From 78e963d94e9f788c56c77ff3c92982134bd86261 Mon Sep 17 00:00:00 2001 From: xiaoming <2014500726@smail.xtu.edu.cn> Date: Wed, 28 Aug 2024 12:29:11 +0800 Subject: [PATCH] Refactor qtermwidget Signed-off-by: xiaoming <2014500726@smail.xtu.edu.cn> --- lib/qtermwidget/ColorScheme.h | 2 - lib/qtermwidget/Emulation.cpp | 2 +- lib/qtermwidget/HistorySearch.h | 1 - lib/qtermwidget/Session.cpp | 490 ------------------ lib/qtermwidget/Session.h | 385 -------------- lib/qtermwidget/TerminalDisplay.cpp | 4 - lib/qtermwidget/TerminalDisplay.h | 11 - lib/qtermwidget/Vt102Emulation.cpp | 74 ++- lib/qtermwidget/Vt102Emulation.h | 17 + lib/qtermwidget/qtermwidget.cpp | 262 +++++++--- lib/qtermwidget/qtermwidget.h | 41 +- lib/qtermwidget/qtermwidget.pri | 2 - .../internalcommandwindow.cpp | 1 - src/sessionswindow/sessionswindow.cpp | 1 - 14 files changed, 307 insertions(+), 986 deletions(-) delete mode 100644 lib/qtermwidget/Session.cpp delete mode 100644 lib/qtermwidget/Session.h diff --git a/lib/qtermwidget/ColorScheme.h b/lib/qtermwidget/ColorScheme.h index 47591a88..f40c8e8a 100644 --- a/lib/qtermwidget/ColorScheme.h +++ b/lib/qtermwidget/ColorScheme.h @@ -77,8 +77,6 @@ class ColorScheme * * @param table Array into which the color entries for this color scheme * are copied. - * @param randomSeed Color schemes may allow certain colors in their - * palette to be randomized. The seed is used to pick the random color. */ void getColorTable(ColorEntry* table) const; diff --git a/lib/qtermwidget/Emulation.cpp b/lib/qtermwidget/Emulation.cpp index b8c30711..e51272c9 100644 --- a/lib/qtermwidget/Emulation.cpp +++ b/lib/qtermwidget/Emulation.cpp @@ -61,7 +61,7 @@ Emulation::Emulation() : this, &Emulation::bracketedPasteModeChanged); connect(this, &Emulation::cursorChanged, this, [this] (KeyboardCursorShape cursorShape, bool blinkingCursorEnabled) { - emit titleChanged( 50, QString(QLatin1String("CursorShape=%1;BlinkingCursorEnabled=%2")) + emit profileChangeCommandReceived(QString(QLatin1String("CursorShape=%1;BlinkingCursorEnabled=%2")) .arg(static_cast(cursorShape)).arg(blinkingCursorEnabled) ); }); } diff --git a/lib/qtermwidget/HistorySearch.h b/lib/qtermwidget/HistorySearch.h index 4a17484f..f373b6da 100644 --- a/lib/qtermwidget/HistorySearch.h +++ b/lib/qtermwidget/HistorySearch.h @@ -24,7 +24,6 @@ #include #include -#include #include #include "Emulation.h" diff --git a/lib/qtermwidget/Session.cpp b/lib/qtermwidget/Session.cpp deleted file mode 100644 index 1d0aa0c3..00000000 --- a/lib/qtermwidget/Session.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* - This file is part of Konsole - - Copyright (C) 2006-2007 by Robert Knight - Copyright (C) 1997,1998 by Lars Doelle - - Rewritten for QT4 by e_k , Copyright (C)2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ -#include "Session.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "TerminalDisplay.h" -#include "Vt102Emulation.h" - -int Session::lastSessionId = 0; - -Session::Session(QObject* parent) : - QObject(parent) - , _emulation(nullptr) - , _monitorActivity(false) - , _monitorSilence(false) - , _notifiedActivity(false) - , _wantedClose(false) - , _silenceSeconds(10) - , _isTitleChanged(false) - , _flowControl(true) - , _sessionId(0) - , _hasDarkBackground(false) - , _isPrimaryScreen(true) -{ - _sessionId = ++lastSessionId; - - //create emulation backend - _emulation = new Vt102Emulation(); - - connect( _emulation, &Emulation::titleChanged, this, &Session::setUserTitle); - connect( _emulation, &Emulation::stateSet, this, &Session::activityStateSet); - connect( _emulation, &Emulation::changeTabTextColorRequest, this, &Session::changeTabTextColorRequest); - connect( _emulation, &Emulation::profileChangeCommandReceived, this, &Session::profileChangeCommandReceived); - - connect(_emulation, &Emulation::primaryScreenInUse, this, [this](bool use){ - _isPrimaryScreen = use; - emit primaryScreenInUse(use); - }); - connect(_emulation, &Emulation::imageResizeRequest, this, [this](const QSize& size){ - setSize(size); - }); - connect(_emulation, &Emulation::imageSizeChanged, this, [this](int /*height*/, int /*width*/){ - updateTerminalSize(); - }); - connect(_emulation, &Vt102Emulation::cursorChanged, this, &Session::cursorChanged); - - //setup timer for monitoring session activity - _monitorTimer = new QTimer(this); - _monitorTimer->setSingleShot(true); - connect(_monitorTimer, &QTimer::timeout, this, &Session::monitorTimerDone); -} - -Session::~Session() -{ - delete _emulation; -} - -void Session::setDarkBackground(bool darkBackground) -{ - _hasDarkBackground = darkBackground; -} - -bool Session::hasDarkBackground() const -{ - return _hasDarkBackground; -} - -void Session::setCodec(QStringEncoder codec) const -{ - emulation()->setCodec(std::move(codec)); -} - -QList Session::views() const -{ - return _views; -} - -void Session::addView(TerminalDisplay * widget) -{ - Q_ASSERT( !_views.contains(widget) ); - - _views.append(widget); - - if ( _emulation != nullptr ) { - // connect emulation - view signals and slots - connect(widget, &TerminalDisplay::keyPressedSignal, _emulation, &Emulation::sendKeyEvent); - connect(widget, &TerminalDisplay::mouseSignal, _emulation, &Emulation::sendMouseEvent); - connect(widget, &TerminalDisplay::sendStringToEmu, this, [this](const char* s){ - _emulation->sendString(s); - }); - - // allow emulation to notify view when the foreground process - // indicates whether or not it is interested in mouse signals - connect(_emulation, &Emulation::programUsesMouseChanged, widget, &TerminalDisplay::setUsesMouse); - widget->setUsesMouse(_emulation->programUsesMouse() ); - connect(_emulation, &Emulation::programBracketedPasteModeChanged, widget, &TerminalDisplay::setBracketedPasteMode); - widget->setBracketedPasteMode(_emulation->programBracketedPasteMode()); - widget->setScreenWindow(_emulation->createWindow()); - } - - //connect view signals and slots - QObject::connect(widget, &TerminalDisplay::changedContentSizeSignal, this, [this](int /*height*/, int /*width*/){ - updateTerminalSize(); - }); - - QObject::connect(widget, &TerminalDisplay::destroyed, this, &Session::viewDestroyed); -//slot for close - QObject::connect(this, &Session::finished, widget, &TerminalDisplay::close); -//slot for primaryScreen - QObject::connect(this, &Session::primaryScreenInUse, widget, &TerminalDisplay::usingPrimaryScreen); -} - -void Session::viewDestroyed(QObject * view) -{ - TerminalDisplay * display = (TerminalDisplay *)view; - - Q_ASSERT( _views.contains(display) ); - - removeView(display); -} - -void Session::removeView(TerminalDisplay * widget) -{ - _views.removeAll(widget); - - disconnect(widget,nullptr,this,nullptr); - - if ( _emulation != nullptr ) { - // disconnect - // - key presses signals from widget - // - mouse activity signals from widget - // - string sending signals from widget - // - // ... and any other signals connected in addView() - disconnect( widget, nullptr, _emulation, nullptr); - - // disconnect state change signals emitted by emulation - disconnect( _emulation , nullptr , widget , nullptr); - } - - // close the session automatically when the last view is removed - if ( _views.count() == 0 ) { - close(); - } -} - -void Session::runEmptyPTY() -{ - emit started(); -} - -void Session::setUserTitle( int what, const QString & caption ) -{ - //set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle ) - bool modified = false; - - // (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; - } - } - - if ((what == 0) || (what == 1)) { - _isTitleChanged = true; - if ( _iconText != caption ) { - _iconText = caption; - modified = true; - } - } - - if (what == 11) { - QString colorString = caption.section(QLatin1Char(';'),0,0); - QColor backColor = QColor(colorString); - if (backColor.isValid()) { // change color via \033]11;Color\007 - if (backColor != _modifiedBackground) { - _modifiedBackground = backColor; - - // bail out here until the code to connect the terminal display - // to the changeBackgroundColor() signal has been written - // and tested - just so we don't forget to do this. - Q_ASSERT( 0 ); - - emit changeBackgroundColorRequest(backColor); - } - } - } - - if (what == 30) { - _isTitleChanged = true; - if ( _nameTitle != caption ) { - _nameTitle=caption; - return; - } - } - - if (what == 31) { - QString cwd=caption; - cwd=cwd.replace( QRegularExpression(QLatin1String("^~")), QDir::homePath() ); - emit openUrlRequest(cwd); - } - - // change icon via \033]32;Icon\007 - if (what == 32) { - _isTitleChanged = true; - if ( _iconName != caption ) { - _iconName = caption; - - modified = true; - } - } - - if (what == 50) { - emit profileChangeCommandReceived(caption); - return; - } - - if ( modified ) { - emit titleChanged(what,caption); - } -} - - -void Session::monitorTimerDone() -{ - //FIXME: The idea here is that the notification popup will appear to tell the user than output from - //the terminal has stopped and the popup will disappear when the user activates the session. - // - //This breaks with the addition of multiple views of a session. The popup should disappear - //when any of the views of the session becomes active - - - //FIXME: Make message text for this notification and the activity notification more descriptive. - if (_monitorSilence) { - emit silence(); - emit stateChanged(NOTIFYSILENCE); - } else { - emit stateChanged(NOTIFYNORMAL); - } - - _notifiedActivity=false; -} - -bool Session::isPrimaryScreen() -{ - return _isPrimaryScreen; -} - -void Session::activityStateSet(int state) -{ - if (state==NOTIFYBELL) { - emit bellRequest(tr("Bell in session '%1'").arg(_nameTitle)); - } else if (state==NOTIFYACTIVITY) { - if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); - } - - if ( _monitorActivity ) { - //FIXME: See comments in Session::monitorTimerDone() - if (!_notifiedActivity) { - _notifiedActivity=true; - emit activity(); - } - } - } - - if ( state==NOTIFYACTIVITY && !_monitorActivity ) { - state = NOTIFYNORMAL; - } - if ( state==NOTIFYSILENCE && !_monitorSilence ) { - state = NOTIFYNORMAL; - } - - emit stateChanged(state); -} - - -void Session::updateTerminalSize() -{ - QListIterator viewIter(_views); - - int minLines = -1; - int minColumns = -1; - - // minimum number of lines and columns that views require for - // their size to be taken into consideration ( to avoid problems - // with new view widgets which haven't yet been set to their correct size ) - const int VIEW_LINES_THRESHOLD = 2; - const int VIEW_COLUMNS_THRESHOLD = 2; - - //select largest number of lines and columns that will fit in all visible views - while ( viewIter.hasNext() ) { - TerminalDisplay * view = viewIter.next(); - if ( view->isHidden() == false && - view->lines() >= VIEW_LINES_THRESHOLD && - view->columns() >= VIEW_COLUMNS_THRESHOLD ) { - minLines = (minLines == -1) ? view->lines() : qMin( minLines , view->lines() ); - minColumns = (minColumns == -1) ? view->columns() : qMin( minColumns , view->columns() ); - } - } - - // backend emulation must have a _terminal of at least 1 column x 1 line in size - if ( minLines > 0 && minColumns > 0 ) { - _emulation->setImageSize( minLines , minColumns ); - } -} - -void Session::refresh() -{ - // attempt to get the shell process to redraw the display - // - // this requires the program running in the shell - // to cooperate by sending an update in response to - // a window size change - // - // the window size is changed twice, first made slightly larger and then - // resized back to its normal size so that there is actually a change - // in the window size (some shells do nothing if the - // new and old sizes are the same) - // - // if there is a more 'correct' way to do this, please - // send an email with method or patches to konsole-devel@kde.org -} - -void Session::close() -{ - _wantedClose = true; -} - -void Session::sendText(const QString & text) const -{ - _emulation->sendText(text); -} - -void Session::sendKeyEvent(QKeyEvent* e) const -{ - _emulation->sendKeyEvent(e, false); -} - -Emulation * Session::emulation() const -{ - return _emulation; -} - -QString Session::keyBindings() const -{ - return _emulation->keyBindings(); -} - -int Session::sessionId() const -{ - return _sessionId; -} - -void Session::setKeyBindings(const QString & id) -{ - _emulation->setKeyBindings(id); -} - -void Session::setHistoryType(const HistoryType & hType) -{ - _emulation->setHistory(hType); -} - -const HistoryType & Session::historyType() const -{ - return _emulation->history(); -} - -void Session::clearHistory() -{ - _emulation->clearHistory(); -} - -// unused currently -bool Session::isMonitorActivity() const -{ - return _monitorActivity; -} -// unused currently -bool Session::isMonitorSilence() const -{ - return _monitorSilence; -} - -void Session::setMonitorActivity(bool _monitor) -{ - _monitorActivity=_monitor; - _notifiedActivity=false; - - activityStateSet(NOTIFYNORMAL); -} - -void Session::setMonitorSilence(bool _monitor) -{ - if (_monitorSilence==_monitor) { - return; - } - - _monitorSilence=_monitor; - if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); - } else { - _monitorTimer->stop(); - } - - activityStateSet(NOTIFYNORMAL); -} - -void Session::setMonitorSilenceSeconds(int seconds) -{ - _silenceSeconds=seconds; - if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); - } -} - -void Session::setFlowControlEnabled(bool enabled) -{ - if (_flowControl == enabled) { - return; - } - - _flowControl = enabled; - - emit flowControlEnabledChanged(enabled); -} -bool Session::flowControlEnabled() const -{ - return _flowControl; -} - -void Session::onReceiveBlock( const char * buf, int len ) -{ - _emulation->receiveData( buf, len ); - emit receivedData( QString::fromLatin1( buf, len ) ); -} - -QSize Session::size() -{ - return _emulation->imageSize(); -} - -void Session::setSize(const QSize & size) -{ - if ((size.width() <= 1) || (size.height() <= 1)) { - return; - } - - emit resizeRequest(size); -} - -int Session::recvData(const char *buff, int len) -{ - onReceiveBlock(buff,len); - return len; -} - diff --git a/lib/qtermwidget/Session.h b/lib/qtermwidget/Session.h deleted file mode 100644 index e6ccb51e..00000000 --- a/lib/qtermwidget/Session.h +++ /dev/null @@ -1,385 +0,0 @@ -/* - This file is part of Konsole, an X terminal. - - Copyright (C) 2007 by Robert Knight - Copyright (C) 1997,1998 by Lars Doelle - - Rewritten for QT4 by e_k , Copyright (C)2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ - -#ifndef SESSION_H -#define SESSION_H - -#include -#include - -#include "Emulation.h" -#include "History.h" - -class Emulation; -class TerminalDisplay; - -/** - * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation. - * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole. - * The terminal emulation ( Emulation and subclasses ) processes the output stream from the - * PTY and produces a character image which is then shown on views connected to the session. - * - * Each Session can be connected to one or more views by using the addView() method. - * The attached views can then display output from the program running in the terminal - * or send input to the program in the terminal in the form of keypresses and mouse - * activity. - */ -class Session : public QObject { - Q_OBJECT - -public: - Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings) - Q_PROPERTY(QSize size READ size WRITE setSize) - - /** - * Constructs a new session. - */ - Session(QObject* parent = nullptr); - ~Session() override; - - /** - * Sets the profile associated with this session. - * - * @param profileKey A key which can be used to obtain the current - * profile settings from the SessionManager - */ - void setProfileKey(const QString & profileKey); - /** - * Returns the profile key associated with this session. - * This can be passed to the SessionManager to obtain the current - * profile settings. - */ - QString profileKey() const; - - /** - * Adds a new view for this session. - * - * The viewing widget will display the output from the terminal and - * input from the viewing widget (key presses, mouse activity etc.) - * will be sent to the terminal. - * - * Views can be removed using removeView(). The session is automatically - * closed when the last view is removed. - */ - void addView(TerminalDisplay * widget); - /** - * Removes a view from this session. When the last view is removed, - * the session will be closed automatically. - * - * @p widget will no longer display output from or send input - * to the terminal - */ - void removeView(TerminalDisplay * widget); - - /** - * Returns the views connected to this session - */ - QList views() const; - - /** - * Returns the terminal emulation instance being used to encode / decode - * characters to / from the process. - */ - Emulation * emulation() const; - - /** Returns the unique ID for this session. */ - int sessionId() const; - - /** - * Return the session title set by the user (ie. the program running - * in the terminal), or an empty string if the user has not set a custom title - */ - QString userTitle() const; - - /** - * Sets the type of history store used by this session. - * Lines of output produced by the terminal are added - * to the history store. The type of history store - * used affects the number of lines which can be - * remembered before they are lost and the storage - * (in memory, on-disk etc.) used. - */ - void setHistoryType(const HistoryType & type); - /** - * Returns the type of history store used by this session. - */ - const HistoryType & historyType() const; - /** - * Clears the history store used by this session. - */ - void clearHistory(); - - /** - * Enables monitoring for activity in the session. - * This will cause notifySessionState() to be emitted - * with the NOTIFYACTIVITY state flag when output is - * received from the terminal. - */ - void setMonitorActivity(bool); - /** Returns true if monitoring for activity is enabled. */ - bool isMonitorActivity() const; - - /** - * Enables monitoring for silence in the session. - * This will cause notifySessionState() to be emitted - * with the NOTIFYSILENCE state flag when output is not - * received from the terminal for a certain period of - * time, specified with setMonitorSilenceSeconds() - */ - void setMonitorSilence(bool); - /** - * Returns true if monitoring for inactivity (silence) - * in the session is enabled. - */ - bool isMonitorSilence() const; - /** See setMonitorSilence() */ - void setMonitorSilenceSeconds(int seconds); - - /** - * Sets the key bindings used by this session. The bindings - * specify how input key sequences are translated into - * the character stream which is sent to the terminal. - * - * @param id The name of the key bindings to use. The - * names of available key bindings can be determined using the - * KeyboardTranslatorManager class. - */ - void setKeyBindings(const QString & id); - /** Returns the name of the key bindings used by this session. */ - QString keyBindings() const; - - /** - * Sets whether flow control is enabled for this terminal - * session. - */ - void setFlowControlEnabled(bool enabled); - - /** Returns whether flow control is enabled for this terminal session. */ - bool flowControlEnabled() const; - - /** - * Sends @p text to the current foreground terminal program. - */ - void sendText(const QString & text) const; - - void sendKeyEvent(QKeyEvent* e) const; - - /** Returns the terminal session's window size in lines and columns. */ - QSize size(); - /** - * Emits a request to resize the session to accommodate - * the specified window size. - * - * @param size The size in lines and columns to request. - */ - void setSize(const QSize & size); - - /** Sets the text codec used by this session's terminal emulation. */ - void setCodec(QStringEncoder codec) const; - - /** - * Sets whether the session has a dark background or not. The session - * uses this information to set the COLORFGBG variable in the process's - * environment, which allows the programs running in the terminal to determine - * whether the background is light or dark and use appropriate colors by default. - * - * This has no effect once the session is running. - */ - void setDarkBackground(bool darkBackground); - /** - * Returns true if the session has a dark background. - * See setDarkBackground() - */ - bool hasDarkBackground() const; - - /** - * Attempts to get the shell program to redraw the current display area. - * This can be used after clearing the screen, for example, to get the - * shell to redraw the prompt line. - */ - void refresh(); - -// void startZModem(const QString &rz, const QString &dir, const QStringList &list); -// void cancelZModem(); -// bool isZModemBusy() { return _zmodemBusy; } - - /** - * Returns a pty slave file descriptor. - * This can be used for display and control - * a remote terminal. - */ - int recvData(const char *buff, int len); - - // Returns true if the current screen is the secondary/alternate one - // or false if it's the primary/normal buffer - bool isPrimaryScreen(); - -public slots: - /** - * Starts the terminal session for "as is" PTY - * (without the direction a data to internal terminal process). - * It can be used for control or display a remote/external terminal. - */ - void runEmptyPTY(); - - /** - * Closes the terminal session. This sends a hangup signal - * (SIGHUP) to the terminal process and causes the done(Session*) - * signal to be emitted. - */ - void close(); - - /** - * Changes the session title or other customizable aspects of the terminal - * emulation display. For a list of what may be changed see the - * Emulation::titleChanged() signal. - */ - void setUserTitle( int, const QString & caption ); - -signals: - /** Emitted when the terminal process starts. */ - void started(); - - /** - * Emitted when the terminal process exits. - */ - void finished(); - - /** - * Emitted when output is received from the terminal process. - */ - void receivedData( const QString & text ); - - /** Emitted when the session's title has changed. */ - void titleChanged(int title,const QString& newTitle); - - /** Emitted when the session's profile has changed. */ - void profileChanged(const QString & profile); - - /** - * Emitted when the activity state of this session changes. - * - * @param state The new state of the session. This may be one - * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY - */ - void stateChanged(int state); - - /** Emitted when a bell event occurs in the session. */ - void bellRequest( const QString & message ); - - /** - * Requests that the color the text for any tabs associated with - * this session should be changed; - * - * TODO: Document what the parameter does - */ - void changeTabTextColorRequest(int); - - /** - * Requests that the background color of views on this session - * should be changed. - */ - void changeBackgroundColorRequest(const QColor &); - - /** TODO: Document me. */ - void openUrlRequest(const QString & url); - - /** - * Emitted when the terminal process requests a change - * in the size of the terminal window. - * - * @param size The requested window size in terms of lines and columns. - */ - void resizeRequest(const QSize & size); - - /** - * Emitted when a profile change command is received from the terminal. - * - * @param text The text of the command. This is a string of the form - * "PropertyName=Value;PropertyName=Value ..." - */ - void profileChangeCommandReceived(const QString & text); - - /** - * Emitted when the flow control state changes. - * - * @param enabled True if flow control is enabled or false otherwise. - */ - void flowControlEnabledChanged(bool enabled); - - /** - * Emitted when the active screen is switched, to indicate whether the primary - * screen is in use. - * - * This signal serves as a relayer of Emulation::priamyScreenInUse(bool), - * making it usable for higher level component. - */ - void primaryScreenInUse(bool use); - - /** - * Broker for Emulation::cursorChanged() signal - */ - void cursorChanged(Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled); - - void silence(); - void activity(); - -private slots: - void onReceiveBlock( const char * buffer, int len ); - void monitorTimerDone(); - void activityStateSet(int); - //automatically detach views from sessions when view is destroyed - void viewDestroyed(QObject * view); - -private: - void updateTerminalSize(); - - int _uniqueIdentifier; - - Emulation * _emulation; - - QList _views; - - bool _monitorActivity; - bool _monitorSilence; - bool _notifiedActivity; - bool _masterMode; - bool _wantedClose; - QTimer * _monitorTimer; - int _silenceSeconds; - QString _nameTitle; - QString _userTitle; - QString _iconName; - QString _iconText; // as set by: echo -en '\033]1;IconText\007 - bool _isTitleChanged; ///< flag if the title/icon was changed by user - bool _flowControl; - int _sessionId; - // Color/Font Changes by ESC Sequences - QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 - bool _hasDarkBackground; - bool _isPrimaryScreen; - static int lastSessionId; -}; - -#endif diff --git a/lib/qtermwidget/TerminalDisplay.cpp b/lib/qtermwidget/TerminalDisplay.cpp index 815297d4..196f4384 100644 --- a/lib/qtermwidget/TerminalDisplay.cpp +++ b/lib/qtermwidget/TerminalDisplay.cpp @@ -324,7 +324,6 @@ TerminalDisplay::TerminalDisplay(QWidget *parent) ,_contentHeight(1) ,_contentWidth(1) ,_image(nullptr) -,_randomSeed(0) ,_resizing(false) ,_terminalSizeHint(false) ,_terminalSizeStartup(true) @@ -1089,9 +1088,6 @@ void TerminalDisplay::drawTextFragment(QPainter& painter , } } -void TerminalDisplay::setRandomSeed(uint randomSeed) { _randomSeed = randomSeed; } -uint TerminalDisplay::randomSeed() const { return _randomSeed; } - #if 0 /*! Set XIM Position diff --git a/lib/qtermwidget/TerminalDisplay.h b/lib/qtermwidget/TerminalDisplay.h index 3a2da2b7..6a338446 100644 --- a/lib/qtermwidget/TerminalDisplay.h +++ b/lib/qtermwidget/TerminalDisplay.h @@ -101,16 +101,6 @@ class TerminalDisplay : public QWidget const ColorEntry* colorTable() const; /** Sets the terminal color palette used by the display. */ void setColorTable(const ColorEntry table[]); - /** - * Sets the seed used to generate random colors for the display - * (in color schemes that support them). - */ - void setRandomSeed(uint seed); - /** - * Returns the seed used to generate random colors for the display - * (in color schemes that support them). - */ - uint randomSeed() const; /** Sets the opacity of the terminal display. */ void setOpacity(qreal opacity); @@ -825,7 +815,6 @@ private slots: QVector _lineProperties; ColorEntry _colorTable[TABLE_COLORS]; - uint _randomSeed; bool _resizing; bool _terminalSizeHint; diff --git a/lib/qtermwidget/Vt102Emulation.cpp b/lib/qtermwidget/Vt102Emulation.cpp index 1452a207..20cd3bb7 100644 --- a/lib/qtermwidget/Vt102Emulation.cpp +++ b/lib/qtermwidget/Vt102Emulation.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include "KeyboardTranslator.h" @@ -38,7 +40,8 @@ Vt102Emulation::Vt102Emulation() prevCC(0), _titleUpdateTimer(new QTimer(this)), _reportFocusEvents(false), - _toUtf8(QStringEncoder::Utf8) + _toUtf8(QStringEncoder::Utf8), + _isTitleChanged(false) { _titleUpdateTimer->setSingleShot(true); QObject::connect(_titleUpdateTimer, &QTimer::timeout, @@ -461,11 +464,78 @@ void Vt102Emulation::updateTitle() QListIterator iter( _pendingTitleUpdates.keys() ); while (iter.hasNext()) { int arg = iter.next(); - emit titleChanged( arg , _pendingTitleUpdates[arg] ); + doTitleChanged( arg , _pendingTitleUpdates[arg] ); } _pendingTitleUpdates.clear(); } +void Vt102Emulation::doTitleChanged( int what, const QString & caption ) +{ + //set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle ) + bool modified = false; + + // (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; + } + } + + if ((what == 0) || (what == 1)) { + _isTitleChanged = true; + if ( _iconText != caption ) { + _iconText = caption; + modified = true; + } + } + + if (what == 11) { + QString colorString = caption.section(QLatin1Char(';'),0,0); + QColor backColor = QColor(colorString); + if (backColor.isValid()) { // change color via \033]11;Color\007 + if (backColor != _modifiedBackground) { + _modifiedBackground = backColor; + emit changeBackgroundColorRequest(backColor); + } + } + } + + if (what == 30) { + _isTitleChanged = true; + if ( _nameTitle != caption ) { + _nameTitle=caption; + return; + } + } + + if (what == 31) { + QString cwd=caption; + cwd=cwd.replace( QRegularExpression(QLatin1String("^~")), QDir::homePath() ); + emit openUrlRequest(cwd); + } + + // change icon via \033]32;Icon\007 + if (what == 32) { + _isTitleChanged = true; + if ( _iconName != caption ) { + _iconName = caption; + + modified = true; + } + } + + if (what == 50) { + emit profileChangeCommandReceived(caption); + return; + } + + if ( modified ) { + emit titleChanged(what,caption); + } +} + // Interpreting Codes --------------------------------------------------------- /* diff --git a/lib/qtermwidget/Vt102Emulation.h b/lib/qtermwidget/Vt102Emulation.h index 4966a79d..a6c52993 100644 --- a/lib/qtermwidget/Vt102Emulation.h +++ b/lib/qtermwidget/Vt102Emulation.h @@ -83,6 +83,15 @@ Q_OBJECT void reset() override; char eraseChar() const override; +signals: + /** + * Requests that the background color of views on this session + * should be changed. + */ + void changeBackgroundColorRequest(const QColor &); + /** TODO: Document me. */ + void openUrlRequest(const QString & url); + public slots: // reimplemented from Emulation void sendString(const char*,int length = -1) override; @@ -104,6 +113,7 @@ private slots: void updateTitle(); private: + void doTitleChanged( int what, const QString & caption ); wchar_t applyCharset(wchar_t c); void setCharset(int n, int cs); void useCharset(int n); @@ -190,6 +200,13 @@ private slots: bool _reportFocusEvents; QStringEncoder _toUtf8; + + bool _isTitleChanged; ///< flag if the title/icon was changed by user + QString _userTitle; + QString _iconText; // as set by: echo -en '\033]1;IconText\007 + QString _nameTitle; + QString _iconName; + QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 }; #endif // VT102EMULATION_H diff --git a/lib/qtermwidget/qtermwidget.cpp b/lib/qtermwidget/qtermwidget.cpp index 865baa66..69f9afed 100644 --- a/lib/qtermwidget/qtermwidget.cpp +++ b/lib/qtermwidget/qtermwidget.cpp @@ -23,11 +23,11 @@ #include #include "ColorTables.h" -#include "Session.h" #include "Screen.h" #include "ScreenWindow.h" #include "Emulation.h" #include "TerminalDisplay.h" +#include "Vt102Emulation.h" #include "KeyboardTranslator.h" #include "ColorScheme.h" #include "SearchBar.h" @@ -49,36 +49,66 @@ QTermWidget::QTermWidget(QWidget *messageParentWidget, QWidget *parent) m_layout->setContentsMargins(0, 0, 0, 0); setLayout(m_layout); - m_session = new Session(this); - m_session->setCodec(QStringEncoder{QStringConverter::Encoding::Utf8}); - m_session->setFlowControlEnabled(true); - m_session->setHistoryType(HistoryTypeBuffer(1000)); - m_session->setDarkBackground(true); - m_session->setKeyBindings(QString()); - m_terminalDisplay = new TerminalDisplay(this); + m_emulation = new Vt102Emulation(); m_terminalDisplay->setBellMode(TerminalDisplay::NotifyBell); m_terminalDisplay->setTerminalSizeHint(true); m_terminalDisplay->setTripleClickMode(TerminalDisplay::SelectWholeLine); m_terminalDisplay->setTerminalSizeStartup(true); - m_terminalDisplay->setRandomSeed(m_session->sessionId() * 31); + + connect(m_terminalDisplay, &TerminalDisplay::keyPressedSignal, m_emulation, &Emulation::sendKeyEvent); + connect(m_terminalDisplay, &TerminalDisplay::mouseSignal, m_emulation, &Emulation::sendMouseEvent); + connect(m_terminalDisplay, &TerminalDisplay::sendStringToEmu, this, [this](const char* s){ + m_emulation->sendString(s); + }); + connect(m_emulation, &Emulation::stateSet, this, &QTermWidget::activityStateSet); + //setup timer for monitoring session activity + m_monitorTimer = new QTimer(this); + m_monitorTimer->setSingleShot(true); + connect(m_monitorTimer, &QTimer::timeout, this, &QTermWidget::monitorTimerDone); + // allow emulation to notify view when the foreground process + // indicates whether or not it is interested in mouse signals + connect(m_emulation, &Emulation::programUsesMouseChanged, m_terminalDisplay, &TerminalDisplay::setUsesMouse); + m_terminalDisplay->setUsesMouse(m_emulation->programUsesMouse() ); + connect(m_emulation, &Emulation::programBracketedPasteModeChanged, m_terminalDisplay, &TerminalDisplay::setBracketedPasteMode); + m_terminalDisplay->setBracketedPasteMode(m_emulation->programBracketedPasteMode()); + m_terminalDisplay->setScreenWindow(m_emulation->createWindow()); + connect(m_emulation, &Emulation::primaryScreenInUse, m_terminalDisplay, &TerminalDisplay::usingPrimaryScreen); + connect(m_emulation, &Emulation::imageSizeChanged, this, [this](int /*height*/, int /*width*/){ + updateTerminalSize(); + }); + connect(m_terminalDisplay, &TerminalDisplay::changedContentSizeSignal, this, [this](int /*height*/, int /*width*/){ + updateTerminalSize(); + }); + + setFlowControlEnabled(true); + m_emulation->setCodec(QStringEncoder{QStringConverter::Encoding::Utf8}); + m_emulation->setHistory(HistoryTypeBuffer(1000)); + m_emulation->setKeyBindings(QString()); m_layout->addWidget(m_terminalDisplay); m_terminalDisplay->setObjectName("terminalDisplay"); setMessageParentWidget(messageParentWidget?messageParentWidget:this); - connect(m_session, &Session::bellRequest, m_terminalDisplay, &TerminalDisplay::bell); connect(m_terminalDisplay, &TerminalDisplay::notifyBell, this, &QTermWidget::bell); connect(m_terminalDisplay, &TerminalDisplay::handleCtrlC, this, &QTermWidget::handleCtrlC); connect(m_terminalDisplay, &TerminalDisplay::changedContentCountSignal, this, &QTermWidget::termSizeChange); connect(m_terminalDisplay, &TerminalDisplay::mousePressEventForwarded, this, &QTermWidget::mousePressEventForwarded); - connect(m_session, &Session::activity, this, &QTermWidget::activity); - connect(m_session, &Session::silence, this, &QTermWidget::silence); - connect(m_session, &Session::profileChangeCommandReceived, this, &QTermWidget::profileChanged); - connect(m_session, &Session::receivedData, this, &QTermWidget::receivedData); - connect(m_session->emulation(), &Emulation::zmodemRecvDetected, this, &QTermWidget::zmodemRecvDetected); - connect(m_session->emulation(), &Emulation::zmodemSendDetected, this, &QTermWidget::zmodemSendDetected); - + connect(m_emulation, &Emulation::profileChangeCommandReceived, this, &QTermWidget::profileChanged); + connect(m_emulation, &Emulation::zmodemRecvDetected, this, &QTermWidget::zmodemRecvDetected); + connect(m_emulation, &Emulation::zmodemSendDetected, this, &QTermWidget::zmodemSendDetected); + connect(m_emulation, &Emulation::titleChanged, this, &QTermWidget::titleChanged); + // redirect data from TTY to external recipient + connect(m_emulation, &Emulation::sendData, this, [this](const char *buff, int len) { + if (m_echo) { + recvData(buff, len); + } + emit sendData(buff, len); + }); + connect( m_emulation, &Emulation::dupDisplayOutput, this, &QTermWidget::dupDisplayOutput); + connect( m_emulation, &Emulation::changeTabTextColorRequest, this, &QTermWidget::changeTabTextColorRequest); + connect( m_emulation, &Emulation::cursorChanged, this, &QTermWidget::cursorChanged); + // That's OK, FilterChain's dtor takes care of UrlFilter. urlFilter = new UrlFilter(); connect(urlFilter, &UrlFilter::activated, this, &QTermWidget::urlActivated); @@ -125,14 +155,12 @@ QTermWidget::QTermWidget(QWidget *messageParentWidget, QWidget *parent) setScrollBarPosition(NoScrollBar); setKeyboardCursorShape(Emulation::KeyboardCursorShape::BlockCursor); - m_session->addView(m_terminalDisplay); - - connect(m_session, &Session::resizeRequest, this, [this](const QSize & size){ + connect(m_emulation, &Emulation::imageResizeRequest, this, [this](const QSize& size){ + if ((size.width() <= 1) || (size.height() <= 1)) { + return; + } setSize(size); }); - connect(m_session, &Session::finished, this, &QTermWidget::finished); - connect(m_session, &Session::titleChanged, this, &QTermWidget::titleChanged); - connect(m_session, &Session::cursorChanged, this, &QTermWidget::cursorChanged); } QTermWidget::~QTermWidget() @@ -141,6 +169,7 @@ QTermWidget::~QTermWidget() clearHighLightTexts(); delete m_searchBar; emit destroyed(); + delete m_emulation; } void QTermWidget::selectionChanged(bool textSelected) @@ -174,7 +203,7 @@ void QTermWidget::search(bool forwards, bool next) regExp.setPatternOptions(m_searchBar->matchCase() ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption); HistorySearch *historySearch = - new HistorySearch(m_session->emulation(), regExp, forwards, startColumn, startLine, this); + new HistorySearch(m_emulation, regExp, forwards, startColumn, startLine, this); connect(historySearch, &HistorySearch::matchFound, this, [this](int startColumn, int startLine, int endColumn, int endLine){ ScreenWindow* sw = m_terminalDisplay->screenWindow(); //qDebug() << "Scroll to" << startLine; @@ -208,19 +237,6 @@ bool QTermWidget::terminalSizeHint() return m_terminalDisplay->terminalSizeHint(); } -void QTermWidget::startTerminalTeletype() -{ - m_session->runEmptyPTY(); - // redirect data from TTY to external recipient - connect( m_session->emulation(), &Emulation::sendData, this, [this](const char *buff, int len) { - if (m_echo) { - recvData(buff, len); - } - emit sendData(buff, len); - }); - connect( m_session->emulation(), &Emulation::dupDisplayOutput, this, &QTermWidget::dupDisplayOutput); -} - void QTermWidget::setTerminalFont(const QFont &font) { m_terminalDisplay->setVTFont(font); @@ -258,9 +274,7 @@ void QTermWidget::setTerminalBackgroundMode(int mode) void QTermWidget::setTextCodec(QStringEncoder codec) { - if (!m_session) - return; - m_session->setCodec(std::move(codec)); + m_emulation->setCodec(std::move(codec)); } void QTermWidget::setColorScheme(const QString& origName) @@ -301,7 +315,7 @@ void QTermWidget::setColorScheme(const QString& origName) ColorEntry table[TABLE_COLORS]; cs->getColorTable(table); m_terminalDisplay->setColorTable(table); - m_session->setDarkBackground(cs->hasDarkBackground()); + m_hasDarkBackground = cs->hasDarkBackground(); } QStringList QTermWidget::getAvailableColorSchemes() @@ -351,16 +365,16 @@ void QTermWidget::setSize(const QSize &size) void QTermWidget::setHistorySize(int lines) { if (lines < 0) - m_session->setHistoryType(HistoryTypeFile()); + m_emulation->setHistory(HistoryTypeFile()); else if (lines == 0) - m_session->setHistoryType(HistoryTypeNone()); + m_emulation->setHistory(HistoryTypeNone()); else - m_session->setHistoryType(HistoryTypeBuffer(lines)); + m_emulation->setHistory(HistoryTypeBuffer(lines)); } int QTermWidget::historySize() const { - const HistoryType& currentHistory = m_session->historyType(); + const HistoryType& currentHistory = m_emulation->history(); if (currentHistory.isEnabled()) { if (currentHistory.isUnlimited()) { @@ -385,12 +399,12 @@ void QTermWidget::scrollToEnd() void QTermWidget::sendText(const QString &text) { - m_session->sendText(text); + m_emulation->sendText(text); } void QTermWidget::sendKeyEvent(QKeyEvent *e) { - m_session->sendKeyEvent(e); + m_emulation->sendKeyEvent(e, false); } void QTermWidget::resizeEvent(QResizeEvent*) @@ -404,6 +418,111 @@ void QTermWidget::sessionFinished() emit finished(); } +void QTermWidget::updateTerminalSize() +{ + int minLines = -1; + int minColumns = -1; + + // minimum number of lines and columns that views require for + // their size to be taken into consideration ( to avoid problems + // with new view widgets which haven't yet been set to their correct size ) + const int VIEW_LINES_THRESHOLD = 2; + const int VIEW_COLUMNS_THRESHOLD = 2; + + //select largest number of lines and columns that will fit in all visible views + if ( m_terminalDisplay->isHidden() == false && + m_terminalDisplay->lines() >= VIEW_LINES_THRESHOLD && + m_terminalDisplay->columns() >= VIEW_COLUMNS_THRESHOLD ) { + minLines = (minLines == -1) ? m_terminalDisplay->lines() : qMin( minLines , m_terminalDisplay->lines() ); + minColumns = (minColumns == -1) ? m_terminalDisplay->columns() : qMin( minColumns , m_terminalDisplay->columns() ); + } + + // backend emulation must have a _terminal of at least 1 column x 1 line in size + if ( minLines > 0 && minColumns > 0 ) { + m_emulation->setImageSize( minLines , minColumns ); + } +} + +void QTermWidget::monitorTimerDone() +{ + //FIXME: The idea here is that the notification popup will appear to tell the user than output from + //the terminal has stopped and the popup will disappear when the user activates the session. + // + //This breaks with the addition of multiple views of a session. The popup should disappear + //when any of the views of the session becomes active + + + //FIXME: Make message text for this notification and the activity notification more descriptive. + if (m_monitorSilence) { + emit silence(); + emit stateChanged(NOTIFYSILENCE); + } else { + emit stateChanged(NOTIFYNORMAL); + } + + m_notifiedActivity=false; +} + +void QTermWidget::activityStateSet(int state) +{ + if (state==NOTIFYBELL) { + m_terminalDisplay->bell(tr("Bell in session")); + } else if (state==NOTIFYACTIVITY) { + if (m_monitorSilence) { + m_monitorTimer->start(m_silenceSeconds*1000); + } + + if ( m_monitorActivity ) { + //FIXME: See comments in Session::monitorTimerDone() + if (!m_notifiedActivity) { + m_notifiedActivity=true; + emit activity(); + } + } + } + + if ( state==NOTIFYACTIVITY && !m_monitorActivity ) { + state = NOTIFYNORMAL; + } + if ( state==NOTIFYSILENCE && !m_monitorSilence ) { + state = NOTIFYNORMAL; + } + + emit stateChanged(state); +} + +void QTermWidget::setMonitorActivity(bool enabled) +{ + m_monitorActivity=enabled; + m_notifiedActivity=false; + + activityStateSet(NOTIFYNORMAL); +} + +void QTermWidget::setMonitorSilence(bool enabled) +{ + if (m_monitorSilence==enabled) { + return; + } + + m_monitorSilence=enabled; + if (m_monitorSilence) { + m_monitorTimer->start(m_silenceSeconds*1000); + } else { + m_monitorTimer->stop(); + } + + activityStateSet(NOTIFYNORMAL); +} + +void QTermWidget::setSilenceTimeout(int seconds) +{ + m_silenceSeconds=seconds; + if (m_monitorSilence) { + m_monitorTimer->start(m_silenceSeconds*1000); + } +} + void QTermWidget::bracketText(QString& text) { m_terminalDisplay->bracketText(text); @@ -465,7 +584,7 @@ int QTermWidget::zoomOut() void QTermWidget::setKeyBindings(const QString & kb) { - m_session->setKeyBindings(kb); + m_emulation->setKeyBindings(kb); } void QTermWidget::clear() @@ -476,23 +595,34 @@ void QTermWidget::clear() void QTermWidget::clearScrollback() { - m_session->clearHistory(); + m_emulation->clearHistory(); } void QTermWidget::clearScreen() { - m_session->emulation()->reset(); - m_session->refresh(); + m_emulation->reset(); + /** + * TODO: + * Attempts to get the shell program to redraw the current display area. + * This can be used after clearing the screen, for example, to get the + * shell to redraw the prompt line. + */ } void QTermWidget::setFlowControlEnabled(bool enabled) { - m_session->setFlowControlEnabled(enabled); + if (m_flowControl == enabled) { + return; + } + + m_flowControl = enabled; + + emit flowControlEnabledChanged(enabled); } bool QTermWidget::flowControlEnabled(void) { - return m_session->flowControlEnabled(); + return m_flowControl; } void QTermWidget::setFlowControlWarningEnabled(bool enabled) @@ -510,7 +640,7 @@ QStringList QTermWidget::availableKeyBindings() QString QTermWidget::keyBindings() { - return m_session->keyBindings(); + return m_emulation->keyBindings(); } void QTermWidget::toggleShowSearchBar() @@ -568,21 +698,6 @@ QString QTermWidget::selectedText(bool preserveLineBreaks) return m_terminalDisplay->screenWindow()->screen()->selectedText(preserveLineBreaks); } -void QTermWidget::setMonitorActivity(bool enabled) -{ - m_session->setMonitorActivity(enabled); -} - -void QTermWidget::setMonitorSilence(bool enabled) -{ - m_session->setMonitorSilence(enabled); -} - -void QTermWidget::setSilenceTimeout(int seconds) -{ - m_session->setMonitorSilenceSeconds(seconds); -} - Filter::HotSpot* QTermWidget::getHotSpotAt(const QPoint &pos) const { int row = 0, column = 0; @@ -602,7 +717,8 @@ QList QTermWidget::filterActions(const QPoint& position) int QTermWidget::recvData(const char *buff, int len) const { - return m_session->recvData(buff,len); + m_emulation->receiveData( buff, len ); + return len; } void QTermWidget::setKeyboardCursorShape(KeyboardCursorShape shape) @@ -660,9 +776,9 @@ void QTermWidget::saveHistory(QTextStream *stream, int format, int start, int en start = 0; } if(end < 0) { - end = m_session->emulation()->lineCount(); + end = m_emulation->lineCount(); } - m_session->emulation()->writeToStream(decoder, start, end); + m_emulation->writeToStream(decoder, start, end); delete decoder; } @@ -798,7 +914,7 @@ void QTermWidget::setShowResizeNotificationEnabled(bool enabled) { } void QTermWidget::setEnableHandleCtrlC(bool enable) { - m_session->emulation()->setEnableHandleCtrlC(enable); + m_emulation->setEnableHandleCtrlC(enable); } int QTermWidget::lines() { diff --git a/lib/qtermwidget/qtermwidget.h b/lib/qtermwidget/qtermwidget.h index b7dcbdc8..9fe34682 100644 --- a/lib/qtermwidget/qtermwidget.h +++ b/lib/qtermwidget/qtermwidget.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "Emulation.h" #include "Filter.h" @@ -31,6 +32,7 @@ class QVBoxLayout; class SearchBar; class Session; class TerminalDisplay; +class Emulation; class QUrl; class QTermWidget : public QWidget { @@ -68,13 +70,6 @@ class QTermWidget : public QWidget { void setTerminalSizeHint(bool enabled); bool terminalSizeHint(); - /** - * Start terminal teletype as is - * and redirect data for external recipient. - * It can be used for display and control a remote terminal. - */ - void startTerminalTeletype(); - //look-n-feel, if you don`t like defaults // Terminal font @@ -282,6 +277,19 @@ class QTermWidget : public QWidget { void bell(const QString& message); void activity(); void silence(); + /** + * Emitted when the activity state of this session changes. + * + * @param state The new state of the session. This may be one + * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY + */ + void stateChanged(int state); + /** + * Emitted when the flow control state changes. + * + * @param enabled True if flow control is enabled or false otherwise. + */ + void flowControlEnabledChanged(bool enabled); /** * Emitted when emulator send data to the terminal process * (redirected for external recipient). It can be used for @@ -291,13 +299,9 @@ class QTermWidget : public QWidget { void dupDisplayOutput(const char* data,int len); void profileChanged(const QString & profile); void titleChanged(int title,const QString& newTitle); + void changeTabTextColorRequest(int); void termSizeChange(int lines, int columns); void mousePressEventForwarded(QMouseEvent* event); - /** - * Signals that we received new data from the process running in the - * terminal emulator - */ - void receivedData(const QString &text); void zmodemSendDetected(); void zmodemRecvDetected(); void handleCtrlC(void); @@ -338,7 +342,10 @@ public slots: protected slots: void sessionFinished(); + void updateTerminalSize(); void selectionChanged(bool textSelected); + void monitorTimerDone(); + void activityStateSet(int); private slots: /** @@ -366,13 +373,21 @@ private slots: int setZoom(int step); QWidget *messageParentWidget = nullptr; TerminalDisplay *m_terminalDisplay = nullptr; - Session *m_session = nullptr; + Emulation *m_emulation = nullptr; SearchBar* m_searchBar; QVBoxLayout *m_layout; QList m_highLightTexts; bool m_echo = false; UrlFilter *urlFilter = nullptr; bool m_UrlFilterEnable = true; + bool m_flowControl = true; + // Color/Font Changes by ESC Sequences + bool m_hasDarkBackground = true; + bool m_monitorActivity = false; + bool m_monitorSilence = false; + bool m_notifiedActivity = false; + QTimer* m_monitorTimer; + int m_silenceSeconds = 10; }; #endif diff --git a/lib/qtermwidget/qtermwidget.pri b/lib/qtermwidget/qtermwidget.pri index dd6aa6ce..1e278ab7 100644 --- a/lib/qtermwidget/qtermwidget.pri +++ b/lib/qtermwidget/qtermwidget.pri @@ -17,7 +17,6 @@ SOURCES += \ $$PWD/Screen.cpp \ $$PWD/ScreenWindow.cpp \ $$PWD/SearchBar.cpp \ - $$PWD/Session.cpp \ $$PWD/TerminalCharacterDecoder.cpp \ $$PWD/TerminalDisplay.cpp \ $$PWD/tools.cpp \ @@ -44,7 +43,6 @@ HEADERS += \ $$PWD/Screen.h \ $$PWD/ScreenWindow.h \ $$PWD/SearchBar.h \ - $$PWD/Session.h \ $$PWD/TerminalCharacterDecoder.h \ $$PWD/TerminalDisplay.h \ $$PWD/tools.h \ diff --git a/src/internalcommandwindow/internalcommandwindow.cpp b/src/internalcommandwindow/internalcommandwindow.cpp index 5a842c08..7ab637cb 100644 --- a/src/internalcommandwindow/internalcommandwindow.cpp +++ b/src/internalcommandwindow/internalcommandwindow.cpp @@ -171,7 +171,6 @@ InternalCommandWindow::InternalCommandWindow(QWidget *parent) show.exec(); }); - term->startTerminalTeletype(); process->start(); } diff --git a/src/sessionswindow/sessionswindow.cpp b/src/sessionswindow/sessionswindow.cpp index 8fe36014..6a9be7b5 100644 --- a/src/sessionswindow/sessionswindow.cpp +++ b/src/sessionswindow/sessionswindow.cpp @@ -90,7 +90,6 @@ SessionsWindow::SessionsWindow(SessionType tp, QWidget *parent) term->setScrollBarPosition(QTermWidget::ScrollBarRight); term->setBlinkingCursor(true); term->setMargin(0); - term->startTerminalTeletype(); term->setDrawLineChars(false); term->setSelectionOpacity(0.5);