File indexing completed on 2025-03-16 08:11:28
0001 /* 0002 This file is part of Konsole, an X terminal. 0003 0004 SPDX-FileCopyrightText: 2007 Robert Knight <robertknight@gmail.com> 0005 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de> 0006 0007 Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0019 02110-1301 USA. 0020 */ 0021 0022 #ifndef SESSION_H 0023 #define SESSION_H 0024 0025 #include <QStringList> 0026 #include <QWidget> 0027 0028 #include "Emulation.h" 0029 #include "History.h" 0030 #include "ProcessInfo.h" 0031 0032 class KProcess; 0033 0034 namespace Konsole 0035 { 0036 0037 class Emulation; 0038 class Pty; 0039 class TerminalDisplay; 0040 // class ZModemDialog; 0041 0042 /** 0043 * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation. 0044 * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole. 0045 * The terminal emulation ( Emulation and subclasses ) processes the output stream from the 0046 * PTY and produces a character image which is then shown on views connected to the session. 0047 * 0048 * Each Session can be connected to one or more views by using the addView() method. 0049 * The attached views can then display output from the program running in the terminal 0050 * or send input to the program in the terminal in the form of keypresses and mouse 0051 * activity. 0052 */ 0053 class Session : public QObject 0054 { 0055 Q_OBJECT 0056 0057 public: 0058 Q_PROPERTY(QString name READ nameTitle) 0059 Q_PROPERTY(int processId READ processId) 0060 Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings) 0061 Q_PROPERTY(QSize size READ size WRITE setSize) 0062 0063 /** 0064 * Constructs a new session. 0065 * 0066 * To start the terminal process, call the run() method, 0067 * after specifying the program and arguments 0068 * using setProgram() and setArguments() 0069 * 0070 * If no program or arguments are specified explicitly, the Session 0071 * falls back to using the program specified in the SHELL environment 0072 * variable. 0073 */ 0074 Session(QObject *parent = nullptr); 0075 ~Session() override; 0076 0077 /** 0078 * Returns true if the session is currently running. This will be true 0079 * after run() has been called successfully. 0080 */ 0081 bool isRunning() const; 0082 0083 /** 0084 * Sets the profile associated with this session. 0085 * 0086 * @param profileKey A key which can be used to obtain the current 0087 * profile settings from the SessionManager 0088 */ 0089 void setProfileKey(const QString &profileKey); 0090 /** 0091 * Returns the profile key associated with this session. 0092 * This can be passed to the SessionManager to obtain the current 0093 * profile settings. 0094 */ 0095 QString profileKey() const; 0096 0097 /** 0098 * Adds a new view for this session. 0099 * 0100 * The viewing widget will display the output from the terminal and 0101 * input from the viewing widget (key presses, mouse activity etc.) 0102 * will be sent to the terminal. 0103 * 0104 * Views can be removed using removeView(). The session is automatically 0105 * closed when the last view is removed. 0106 */ 0107 void setView(TerminalDisplay *widget); 0108 /** 0109 * Removes a view from this session. When the last view is removed, 0110 * the session will be closed automatically. 0111 * 0112 * @p widget will no longer display output from or send input 0113 * to the terminal 0114 */ 0115 void removeView(TerminalDisplay *widget); 0116 0117 /** 0118 * Returns the view connected to this session 0119 */ 0120 TerminalDisplay *view() const; 0121 0122 /** 0123 * Returns the terminal emulation instance being used to encode / decode 0124 * characters to / from the process. 0125 */ 0126 Emulation *emulation() const; 0127 0128 /** 0129 * Returns the environment of this session as a list of strings like 0130 * VARIABLE=VALUE 0131 */ 0132 QStringList environment() const; 0133 /** 0134 * Sets the environment for this session. 0135 * @p environment should be a list of strings like 0136 * VARIABLE=VALUE 0137 */ 0138 void setEnvironment(const QStringList &environment); 0139 0140 /** Returns the unique ID for this session. */ 0141 int sessionId() const; 0142 0143 /** 0144 * Return the session title set by the user (ie. the program running 0145 * in the terminal), or an empty string if the user has not set a custom title 0146 */ 0147 QString userTitle() const; 0148 0149 /** 0150 * This enum describes the contexts for which separate 0151 * tab title formats may be specified. 0152 */ 0153 enum TabTitleContext { 0154 /** Default tab title format */ 0155 LocalTabTitle, 0156 /** 0157 * Tab title format used session currently contains 0158 * a connection to a remote computer (via SSH) 0159 */ 0160 RemoteTabTitle 0161 }; 0162 /** 0163 * Sets the format used by this session for tab titles. 0164 * 0165 * @param context The context whoose format should be set. 0166 * @param format The tab title format. This may be a mixture 0167 * of plain text and dynamic elements denoted by a '%' character 0168 * followed by a letter. (eg. %d for directory). The dynamic 0169 * elements available depend on the @p context 0170 */ 0171 void setTabTitleFormat(TabTitleContext context, const QString &format); 0172 /** Returns the format used by this session for tab titles. */ 0173 QString tabTitleFormat(TabTitleContext context) const; 0174 0175 /** Returns the arguments passed to the shell process when run() is called. */ 0176 QStringList arguments() const; 0177 /** Returns the program name of the shell process started when run() is called. */ 0178 QString program() const; 0179 0180 /** 0181 * Sets the command line arguments which the session's program will be passed when 0182 * run() is called. 0183 */ 0184 void setArguments(const QStringList &arguments); 0185 /** Sets the program to be executed when run() is called. */ 0186 void setProgram(const QString &program); 0187 0188 /** Returns the session's current working directory. */ 0189 QString initialWorkingDirectory() 0190 { 0191 return _initialWorkingDir; 0192 } 0193 0194 /** 0195 * Sets the initial working directory for the session when it is run 0196 * This has no effect once the session has been started. 0197 */ 0198 void setInitialWorkingDirectory(const QString &dir); 0199 0200 /** 0201 * Sets the type of history store used by this session. 0202 * Lines of output produced by the terminal are added 0203 * to the history store. The type of history store 0204 * used affects the number of lines which can be 0205 * remembered before they are lost and the storage 0206 * (in memory, on-disk etc.) used. 0207 */ 0208 void setHistoryType(const HistoryType &type); 0209 /** 0210 * Returns the type of history store used by this session. 0211 */ 0212 const HistoryType &historyType() const; 0213 /** 0214 * Clears the history store used by this session. 0215 */ 0216 void clearHistory(); 0217 0218 /** 0219 * Enables monitoring for activity in the session. 0220 * This will cause notifySessionState() to be emitted 0221 * with the NOTIFYACTIVITY state flag when output is 0222 * received from the terminal. 0223 */ 0224 void setMonitorActivity(bool); 0225 /** Returns true if monitoring for activity is enabled. */ 0226 bool isMonitorActivity() const; 0227 0228 /** 0229 * Enables monitoring for silence in the session. 0230 * This will cause notifySessionState() to be emitted 0231 * with the NOTIFYSILENCE state flag when output is not 0232 * received from the terminal for a certain period of 0233 * time, specified with setMonitorSilenceSeconds() 0234 */ 0235 void setMonitorSilence(bool); 0236 /** 0237 * Returns true if monitoring for inactivity (silence) 0238 * in the session is enabled. 0239 */ 0240 bool isMonitorSilence() const; 0241 /** See setMonitorSilence() */ 0242 void setMonitorSilenceSeconds(int seconds); 0243 0244 /** 0245 * Sets the key bindings used by this session. The bindings 0246 * specify how input key sequences are translated into 0247 * the character stream which is sent to the terminal. 0248 * 0249 * @param id The name of the key bindings to use. The 0250 * names of available key bindings can be determined using the 0251 * KeyboardTranslatorManager class. 0252 */ 0253 void setKeyBindings(const QString &id); 0254 /** Returns the name of the key bindings used by this session. */ 0255 QString keyBindings() const; 0256 0257 /** 0258 * This enum describes the available title roles. 0259 */ 0260 enum TitleRole { 0261 /** The name of the session. */ 0262 NameRole, 0263 /** The title of the session which is displayed in tabs etc. */ 0264 DisplayedTitleRole 0265 }; 0266 0267 /** Sets the session's title for the specified @p role to @p title. */ 0268 void setTitle(TitleRole role, const QString &title); 0269 /** Returns the session's title for the specified @p role. */ 0270 QString title(TitleRole role) const; 0271 /** Convenience method used to read the name property. Returns title(Session::NameRole). */ 0272 QString nameTitle() const 0273 { 0274 return title(Session::NameRole); 0275 } 0276 0277 /** Sets the name of the icon associated with this session. */ 0278 void setIconName(const QString &iconName); 0279 /** Returns the name of the icon associated with this session. */ 0280 QString iconName() const; 0281 0282 /** Sets the text of the icon associated with this session. */ 0283 void setIconText(const QString &iconText); 0284 /** Returns the text of the icon associated with this session. */ 0285 QString iconText() const; 0286 0287 /** Flag if the title/icon was changed by user/shell. */ 0288 bool isTitleChanged() const; 0289 0290 /** Specifies whether a utmp entry should be created for the pty used by this session. */ 0291 void setAddToUtmp(bool); 0292 0293 /** Sends the specified @p signal to the terminal process. */ 0294 bool sendSignal(int signal); 0295 0296 /** 0297 * Specifies whether to close the session automatically when the terminal 0298 * process terminates. 0299 */ 0300 void setAutoClose(bool b) 0301 { 0302 _autoClose = b; 0303 } 0304 0305 /** 0306 * Sets whether flow control is enabled for this terminal 0307 * session. 0308 */ 0309 void setFlowControlEnabled(bool enabled); 0310 0311 /** Returns whether flow control is enabled for this terminal session. */ 0312 bool flowControlEnabled() const; 0313 0314 /** 0315 * Sends @p text to the current foreground terminal program. 0316 */ 0317 void sendText(const QString &text) const; 0318 0319 void sendKeyEvent(QKeyEvent *e) const; 0320 0321 /** 0322 * Returns the process id of the terminal process. 0323 * This is the id used by the system API to refer to the process. 0324 */ 0325 int processId() const; 0326 0327 /** 0328 * Returns the process id of the terminal's foreground process. 0329 * This is initially the same as processId() but can change 0330 * as the user starts other programs inside the terminal. 0331 */ 0332 int foregroundProcessId() const; 0333 0334 /** 0335 * Returns the name of the terminal's foreground process. 0336 */ 0337 QString foregroundProcessName(); 0338 0339 /** 0340 * Returns the current working directory of the process. 0341 */ 0342 QString currentDir(); 0343 0344 /** Returns the terminal session's window size in lines and columns. */ 0345 QSize size(); 0346 /** 0347 * Emits a request to resize the session to accommodate 0348 * the specified window size. 0349 * 0350 * @param size The size in lines and columns to request. 0351 */ 0352 void setSize(const QSize &size); 0353 0354 /** Sets the text codec used by this session's terminal emulation. */ 0355 void setCodec(QTextCodec *codec) const; 0356 0357 /** 0358 * Sets whether the session has a dark background or not. The session 0359 * uses this information to set the COLORFGBG variable in the process's 0360 * environment, which allows the programs running in the terminal to determine 0361 * whether the background is light or dark and use appropriate colors by default. 0362 * 0363 * This has no effect once the session is running. 0364 */ 0365 void setDarkBackground(bool darkBackground); 0366 /** 0367 * Returns true if the session has a dark background. 0368 * See setDarkBackground() 0369 */ 0370 bool hasDarkBackground() const; 0371 0372 /** 0373 * Attempts to get the shell program to redraw the current display area. 0374 * This can be used after clearing the screen, for example, to get the 0375 * shell to redraw the prompt line. 0376 */ 0377 void refresh(); 0378 0379 // void startZModem(const QString &rz, const QString &dir, const QStringList &list); 0380 // void cancelZModem(); 0381 // bool isZModemBusy() { return _zmodemBusy; } 0382 0383 /** 0384 * Returns a pty slave file descriptor. 0385 * This can be used for display and control 0386 * a remote terminal. 0387 */ 0388 int getPtySlaveFd() const; 0389 0390 public Q_SLOTS: 0391 0392 /** 0393 * Starts the terminal session. 0394 * 0395 * This creates the terminal process and connects the teletype to it. 0396 */ 0397 void run(); 0398 0399 /** 0400 * Starts the terminal session for "as is" PTY 0401 * (without the direction a data to internal terminal process). 0402 * It can be used for control or display a remote/external terminal. 0403 */ 0404 void runEmptyPTY(); 0405 0406 /** 0407 * Closes the terminal session. This sends a hangup signal 0408 * (SIGHUP) to the terminal process and causes the done(Session*) 0409 * signal to be emitted. 0410 */ 0411 void close(); 0412 0413 /** 0414 * Changes the session title or other customizable aspects of the terminal 0415 * emulation display. For a list of what may be changed see the 0416 * Emulation::titleChanged() signal. 0417 */ 0418 void setUserTitle(int, const QString &caption); 0419 0420 Q_SIGNALS: 0421 0422 /** Emitted when the terminal process starts. */ 0423 void started(); 0424 0425 /** 0426 * Emitted when the terminal process exits. 0427 */ 0428 void finished(); 0429 0430 /** 0431 * Emitted when output is received from the terminal process. 0432 */ 0433 void receivedData(const QString &text); 0434 0435 /** Emitted when the session's title has changed. */ 0436 void titleChanged(); 0437 0438 /** Emitted when the session's profile has changed. */ 0439 void profileChanged(const QString &profile); 0440 0441 /** 0442 * Emitted when the activity state of this session changes. 0443 * 0444 * @param state The new state of the session. This may be one 0445 * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY 0446 */ 0447 void stateChanged(int state); 0448 0449 /** Emitted when a bell event occurs in the session. */ 0450 void bellRequest(const QString &message); 0451 0452 /** 0453 * Requests that the color the text for any tabs associated with 0454 * this session should be changed; 0455 * 0456 * TODO: Document what the parameter does 0457 */ 0458 void changeTabTextColorRequest(int); 0459 0460 /** 0461 * Requests that the background color of views on this session 0462 * should be changed. 0463 */ 0464 void changeBackgroundColorRequest(const QColor &); 0465 0466 /** TODO: Document me. */ 0467 void openUrlRequest(const QString &url); 0468 0469 /** TODO: Document me. */ 0470 // void zmodemDetected(); 0471 0472 /** 0473 * Emitted when the terminal process requests a change 0474 * in the size of the terminal window. 0475 * 0476 * @param size The requested window size in terms of lines and columns. 0477 */ 0478 void resizeRequest(const QSize &size); 0479 0480 /** 0481 * Emitted when a profile change command is received from the terminal. 0482 * 0483 * @param text The text of the command. This is a string of the form 0484 * "PropertyName=Value;PropertyName=Value ..." 0485 */ 0486 void profileChangeCommandReceived(const QString &text); 0487 0488 /** 0489 * Emitted when the flow control state changes. 0490 * 0491 * @param enabled True if flow control is enabled or false otherwise. 0492 */ 0493 void flowControlEnabledChanged(bool enabled); 0494 0495 /** 0496 * Broker for Emulation::cursorChanged() signal 0497 */ 0498 void cursorChanged(Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled); 0499 0500 void silence(); 0501 void activity(); 0502 0503 private Q_SLOTS: 0504 void done(int); 0505 0506 // void fireZModemDetected(); 0507 0508 void onReceiveBlock(const char *buffer, int len); 0509 void monitorTimerDone(); 0510 0511 void onViewSizeChange(int height, int width); 0512 void onEmulationSizeChange(QSize); 0513 0514 void activityStateSet(int); 0515 0516 // automatically detach views from sessions when view is destroyed 0517 void viewDestroyed(QObject *view); 0518 0519 // void zmodemReadStatus(); 0520 // void zmodemReadAndSendBlock(); 0521 // void zmodemRcvBlock(const char *data, int len); 0522 // void zmodemFinished(); 0523 0524 private: 0525 void updateTerminalSize(); 0526 bool updateForegroundProcessInfo(); 0527 WId windowId() const; 0528 0529 int _uniqueIdentifier; 0530 0531 std::unique_ptr<Pty> _shellProcess; 0532 std::unique_ptr<Emulation> _emulation; 0533 0534 TerminalDisplay *_view = nullptr; 0535 0536 bool _monitorActivity; 0537 bool _monitorSilence; 0538 bool _notifiedActivity; 0539 bool _masterMode; 0540 bool _autoClose; 0541 bool _wantedClose; 0542 QTimer *_monitorTimer; 0543 0544 int _silenceSeconds; 0545 0546 QString _nameTitle; 0547 QString _displayTitle; 0548 QString _userTitle; 0549 0550 QString _localTabTitleFormat; 0551 QString _remoteTabTitleFormat; 0552 0553 QString _iconName; 0554 QString _iconText; // as set by: echo -en '\033]1;IconText\007 0555 bool _isTitleChanged; ///< flag if the title/icon was changed by user 0556 bool _addToUtmp; 0557 bool _flowControl; 0558 bool _fullScripting; 0559 0560 QString _program; 0561 QStringList _arguments; 0562 0563 QStringList _environment; 0564 int _sessionId; 0565 0566 QString _initialWorkingDir; 0567 0568 // ZModem 0569 // bool _zmodemBusy; 0570 // KProcess* _zmodemProc; 0571 // ZModemDialog* _zmodemProgress; 0572 0573 // Color/Font Changes by ESC Sequences 0574 0575 QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 0576 0577 QString _profileKey; 0578 0579 bool _hasDarkBackground; 0580 0581 std::unique_ptr<ProcessInfo> _foregroundProcessInfo; 0582 int _foregroundPid; 0583 static int lastSessionId; 0584 int ptySlaveFd; 0585 }; 0586 0587 /** 0588 * Provides a group of sessions which is divided into master and slave sessions. 0589 * Activity in master sessions can be propagated to all sessions within the group. 0590 * The type of activity which is propagated and method of propagation is controlled 0591 * by the masterMode() flags. 0592 */ 0593 class SessionGroup : public QObject 0594 { 0595 Q_OBJECT 0596 0597 public: 0598 /** Constructs an empty session group. */ 0599 SessionGroup(); 0600 /** Destroys the session group and removes all connections between master and slave sessions. */ 0601 ~SessionGroup() override; 0602 0603 /** Adds a session to the group. */ 0604 void addSession(Session *session); 0605 /** Removes a session from the group. */ 0606 void removeSession(Session *session); 0607 0608 /** Returns the list of sessions currently in the group. */ 0609 QList<Session *> sessions() const; 0610 0611 /** 0612 * Sets whether a particular session is a master within the group. 0613 * Changes or activity in the group's master sessions may be propagated 0614 * to all the sessions in the group, depending on the current masterMode() 0615 * 0616 * @param session The session whoose master status should be changed. 0617 * @param master True to make this session a master or false otherwise 0618 */ 0619 void setMasterStatus(Session *session, bool master); 0620 /** Returns the master status of a session. See setMasterStatus() */ 0621 bool masterStatus(Session *session) const; 0622 0623 /** 0624 * This enum describes the options for propagating certain activity or 0625 * changes in the group's master sessions to all sessions in the group. 0626 */ 0627 enum MasterMode { 0628 /** 0629 * Any input key presses in the master sessions are sent to all 0630 * sessions in the group. 0631 */ 0632 CopyInputToAll = 1 0633 }; 0634 0635 /** 0636 * Specifies which activity in the group's master sessions is propagated 0637 * to all sessions in the group. 0638 * 0639 * @param mode A bitwise OR of MasterMode flags. 0640 */ 0641 void setMasterMode(int mode); 0642 /** 0643 * Returns a bitwise OR of the active MasterMode flags for this group. 0644 * See setMasterMode() 0645 */ 0646 int masterMode() const; 0647 0648 private: 0649 void connectPair(Session *master, Session *other) const; 0650 void disconnectPair(Session *master, Session *other) const; 0651 void connectAll(bool connect); 0652 QList<Session *> masters() const; 0653 0654 // maps sessions to their master status 0655 QHash<Session *, bool> _sessions; 0656 0657 int _masterMode; 0658 }; 0659 0660 } 0661 0662 #endif