MauiKit Terminal

ksession.cpp
1/*
2 This file is part of Konsole QML plugin,
3 which is a terminal emulator from KDE.
4
5Copyright 2013 by Dmitry Zagnoyko <hiroshidi@gmail.com>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301 USA.
21*/
22
23// Own
24#include "ksession.h"
25#include <KShell>
26
27// Qt
28#include <QtCore5Compat/QTextCodec>
29
30#include <QDir>
31#include <QDebug>
32
33// Konsole
34#include "KeyboardTranslator.h"
35#include "HistorySearch.h"
36
37
38KSession::KSession(QObject *parent) : QObject(parent)
39 ,m_session(createSession(QString()))
40{
41 connect(m_session.get(), &Konsole::Session::started, this, &KSession::started);
42 connect(m_session.get(), &Konsole::Session::finished, this, &KSession::sessionFinished);
45 connect(m_session.get(), &Konsole::Session::stateChanged, [this](int state)
46 {
47 qDebug() << m_session->iconText() << m_session->iconName() << m_session->isMonitorSilence() << m_session->program() << state;
48
49 Q_EMIT hasActiveProcessChanged();
50
51 if(m_processName != m_session->foregroundProcessName())
52 {
53 m_processName = m_session->foregroundProcessName();
54 Q_EMIT foregroundProcessNameChanged();
55 }
56 });
57
58 // m_session->setMonitorSilence(true);
59 m_session->setMonitorSilenceSeconds(30);
60
61 connect(m_session.get(), &Konsole::Session::bellRequest, [this](QString message)
62 {
63 Q_EMIT bellRequest(message);
64 });
65
66 connect(m_session.get(), &Konsole::Session::changeTabTextColorRequest, [this](int state)
67 {
68 qDebug() << "changeTabTextColorRequest" << state;
69 });
70
71 connect(m_session.get(), &Konsole::Session::changeTabTextColorRequest, [this](int state)
72 {
73 qDebug() << "changeTabTextColorRequest" << state;
74 });
75
77 {
78 qDebug() << "changeBackgroundColorRequest" << state;
79 });
80
81 connect(m_session.get(), &Konsole::Session::openUrlRequest, [this](QString state)
82 {
83 qDebug() << "openUrlRequest" << state;
84 });
85
86 connect(m_session.get(), &Konsole::Session::activity, [this]()
87 {
88 qDebug() << "activity";
89 Q_EMIT processHasSilent(false);
90 });
91
92 connect(m_session.get(), &Konsole::Session::silence, [this]()
93 {
94 qDebug() << "silence";
95 Q_EMIT processHasSilent(true);
96 });
97}
98
99KSession::~KSession()
100{
101 if (m_session)
102 {
103 m_session->close();
104 m_session->disconnect();
105 }
106}
107
109{
110 if(m_session->isMonitorSilence() == value)
111 return;
112
113 m_session->setMonitorSilence(value);
115}
116
118{
119 return m_session->isMonitorSilence();
120}
121
123{
124 m_session->setTitle(Session::NameRole, name);
125}
126
127std::unique_ptr<Session> KSession::createSession(QString name)
128{
129 auto session = std::make_unique<Session>();
130
131 session->setTitle(Session::NameRole, name);
132
133 /* Thats a freaking bad idea!!!!
134 * /bin/bash is not there on every system
135 * better set it to the current $SHELL
136 * Maybe you can also make a list available and then let the widget-owner decide what to use.
137 * By setting it to $SHELL right away we actually make the first filecheck obsolete.
138 * But as iam not sure if you want to do anything else ill just let both checks in and set this to $SHELL anyway.
139 */
140
141 //cool-old-term: There is another check in the code. Not sure if useful.
142
143 QString envshell = getenv("SHELL");
144 QString shellProg = !envshell.isNull() ? envshell : QStringLiteral("/bin/bash");
145 session->setProgram(shellProg);
146
147 setenv("TERM", "xterm-256color", 1);
148
149 //session->setProgram();
150
152 session->setArguments(args);
153 session->setAutoClose(true);
154
155 session->setCodec(QTextCodec::codecForName("UTF-8"));
156
157 session->setFlowControlEnabled(true);
158 session->setHistoryType(HistoryTypeBuffer(1000));
159
160 session->setDarkBackground(true);
161
162 session->setKeyBindings(QString());
163
164 return session;
165}
166
167/////////////////////////////////////////////////////////////////////////////////////
168/////////////////////////////////////////////////////////////////////////////////////
169
170
171int KSession::getRandomSeed()
172{
173 return m_session->sessionId() * 31;
174}
175
177{
178 m_session->setView(display);
179}
180
182{
183 m_session->removeView(display);
184}
185
186void KSession::sessionFinished()
187{
189}
190
191void KSession::selectionChanged(bool textSelected)
192{
193 Q_UNUSED(textSelected)
194}
195
197{
198 if (m_session->isRunning())
199 {
200 return;
201 }
202
203 m_session->run();
204}
205
206bool KSession::sendSignal(int signal)
207{
208 if (!m_session->isRunning())
209 {
210 return false;
211 }
212
213 return m_session->sendSignal(signal);
214}
215
217{
218 return m_session->processId();
219}
220
222{
223 if(currentDir() == dir)
224 return;
225 /*
226 this is a very hackish way of trying to determine if the shell is in
227 the foreground before attempting to change the directory. It may not
228 be portable to anything other than Linux.
229 */
230 QString strCmd;
231 strCmd.setNum(getShellPID());
232 strCmd.prepend(u"ps -j ");
233 strCmd.append(u" | tail -1 | awk '{ print $5 }' | grep -q \\+");
234 int retval = system(strCmd.toStdString().c_str());
235
236 if (!retval)
237 {
238 // Send prior Ctrl-E, Ctrl-U to ensure the line is empty. This is
239 // mandatory, otherwise sending a 'cd x\n' to a prompt with 'rm -rf *'
240 // would result in data loss.
241 sendText(QStringLiteral("\x05\x15"));
242
243 sendText(u"cd " + KShell::quoteArg(dir) + '\r');
245 }
246}
247
248void KSession::setEnvironment(const QStringList &environment)
249{
250 m_session->setEnvironment(environment);
251}
252
254{
255 if(m_session->program() == progname)
256 return;
257
258 m_session->setProgram(progname);
260}
261
263{
264 return m_session->program();
265}
266
268{
269 if(_initialWorkingDirectory != dir)
270 {
271 _initialWorkingDirectory = dir;
272 m_session->setInitialWorkingDirectory(dir);
275 }
276}
277
278QString KSession::getInitialWorkingDirectory()
279{
280 return _initialWorkingDirectory;
281}
282
284{
285 if(m_session->arguments() == args)
286 return;
287
288 m_session->setArguments(args);
290}
291
292void KSession::setTextCodec(QTextCodec *codec)
293{
294 m_session->setCodec(codec);
295}
296
298{
299 if(historySize() != lines )
300 {
301 if (lines < 0)
302 m_session->setHistoryType(HistoryTypeFile());
303 else
304 m_session->setHistoryType(HistoryTypeBuffer(lines));
305
307 }
308}
309
310int KSession::historySize() const
311{
312 if(m_session->historyType().isUnlimited())
313 {
314 return -1;
315 } else {
316 return m_session->historyType().maximumLineCount();
317 }
318}
319
320QString KSession::getHistory() const
321{
322 QString history;
323 QTextStream historyStream(&history);
324 PlainTextDecoder historyDecoder;
325
326 historyDecoder.begin(&historyStream);
327 m_session->emulation()->writeToStream(&historyDecoder);
328 historyDecoder.end();
329
330 return history;
331}
332
334{
335 m_session->sendText(text);
336}
337
338void KSession::sendKey(int rep, int key, int mod) const
339{
340 Q_UNUSED(rep);
341 Q_UNUSED(key);
342 Q_UNUSED(mod);
343
344 //TODO implement or remove this function.
345 // Qt::KeyboardModifier kbm = Qt::KeyboardModifier(mod);
346
347 // QKeyEvent qkey(QEvent::KeyPress, key, kbm);
348
349 // while (rep > 0){
350 // m_session->sendKey(&qkey);
351 // --rep;
352 // }
353}
354
356{
357 m_session->emulation()->clearEntireScreen();
358}
359
360void KSession::search(const QString &regexp, int startLine, int startColumn, bool forwards)
361{
362 HistorySearch *history = new HistorySearch(QPointer<Emulation>(m_session->emulation()), QRegExp(regexp), forwards, startColumn, startLine, this);
363 connect(history, &HistorySearch::matchFound, this, &KSession::matchFound);
364 connect(history, &HistorySearch::noMatchFound, this, &KSession::noMatchFound);
365 history->search();
366}
367
369{
370 m_session->setFlowControlEnabled(enabled);
371}
372
374{
375 return m_session->flowControlEnabled();
376}
377
379{
380 m_session->setKeyBindings(kb);
382}
383
384QString KSession::getKeyBindings()
385{
386 return m_session->keyBindings();
387}
388
393
395{
396 return m_session->keyBindings();
397}
398
399QString KSession::getTitle()
400{
401 // if (m_session->currentDir() == QDir::homePath()) {
402 // return m_session->currentDir();
403 // }
404 //
405 // if (m_session->currentDir() == "/")
406 // return m_session->currentDir();
407 //
408 // return QDir(m_session->currentDir()).dirName();
409
410 return m_session->userTitle();
411}
412
414{
415 return m_session->processId() != m_session->foregroundProcessId();
416}
417
419{
420 return m_session->foregroundProcessName();
421}
422
424{
425 return m_session->currentDir();
426}
427
429{
430 return m_session->arguments();
431}
QString history
The commands history.
Definition ksession.h:69
void clearScreen()
clearScreen
Definition ksession.cpp:355
void titleChanged()
titleChanged
void removeView(TerminalDisplay *display)
removeView
Definition ksession.cpp:181
void startShellProgram()
startShellProgram
Definition ksession.cpp:196
void addView(TerminalDisplay *display)
addView
Definition ksession.cpp:176
void search(const QString &regexp, int startLine=0, int startColumn=0, bool forwards=true)
Search history.
Definition ksession.cpp:360
bool sendSignal(int signal)
sendSignal
Definition ksession.cpp:206
void noMatchFound()
noMatchFound
void initialWorkingDirectoryChanged()
initialWorkingDirectoryChanged
QString keyBindings()
Return current key bindings.
Definition ksession.cpp:394
QString currentDir
The current directory of the session.
Definition ksession.h:84
void setTitle(QString name)
setTitle
Definition ksession.cpp:122
void changedKeyBindings(QString kb)
changedKeyBindings
QString foregroundProcessName
The name of the current process running.
Definition ksession.h:79
void setInitialWorkingDirectory(const QString &dir)
Initial working directory.
Definition ksession.cpp:267
void changeDir(const QString &dir)
changeDir
Definition ksession.cpp:221
void setArgs(const QStringList &args)
Shell program args, default is none.
Definition ksession.cpp:283
void setShellProgram(const QString &progname)
Shell program, default is /bin/bash
Definition ksession.cpp:253
void monitorSilenceChanged()
monitorSilenceChanged
void sendKey(int rep, int key, int mod) const
Emulate a key press.
Definition ksession.cpp:338
bool hasActiveProcess
Whether the session has an active process running.
Definition ksession.h:74
int historySize
Allows to set the amount of lines to store in the history.
Definition ksession.h:89
void setEnvironment(const QStringList &environment)
Set the custom enviroment variables.
Definition ksession.cpp:248
void matchFound(int startColumn, int startLine, int endColumn, int endLine)
matchFound
void shellProgramChanged()
shellProgramChanged
void setKeyBindings(const QString &kb)
Set named key binding for the session.
Definition ksession.cpp:378
QStringList args() const
args
Definition ksession.cpp:428
int getShellPID()
getShellPID
Definition ksession.cpp:216
void currentDirChanged()
currentDirChanged
void setHistorySize(int lines)
History size for scrolling.
Definition ksession.cpp:297
void setMonitorSilence(bool value)
setMonitorSilence
Definition ksession.cpp:108
void finished()
finished
void setFlowControlEnabled(bool enabled)
Sets whether flow control is enabled.
Definition ksession.cpp:368
void started()
started
bool flowControlEnabled(void)
Returns whether flow control is enabled.
Definition ksession.cpp:373
static QStringList availableKeyBindings()
Sets whether the flow control warning box should be shown when the flow control stop key (Ctrl+S) is ...
Definition ksession.cpp:389
void argsChanged()
argsChanged
void setTextCodec(QTextCodec *codec)
Text codec, default is UTF-8.
Definition ksession.cpp:292
void historySizeChanged()
historySizeChanged
void sendText(QString text)
Send some text to terminal.
Definition ksession.cpp:333
QString shellProgram
Allows to change the default shell program, by default bash is used.
Definition ksession.h:59
bool monitorSilence
Whether to monitor when the session has gone silent.
Definition ksession.h:94
QList< QString > allTranslators()
Returns a list of the names of available keyboard translators.
static KeyboardTranslatorManager * instance()
Returns the global KeyboardTranslatorManager instance.
void end() override
End decoding.
void begin(QTextStream *output) override
Begin decoding characters.
void started()
Emitted when the terminal process starts.
void finished()
Emitted when the terminal process exits.
void titleChanged()
Emitted when the session's title has changed.
void openUrlRequest(const QString &url)
TODO: Document me.
void changeTabTextColorRequest(int)
Requests that the color the text for any tabs associated with this session should be changed;.
void stateChanged(int state)
Emitted when the activity state of this session changes.
void changeBackgroundColorRequest(const QColor &)
Requests that the background color of views on this session should be changed.
@ NameRole
The name of the session.
Definition Session.h:262
void bellRequest(const QString &message)
Emitted when a bell event occurs in the session.
A widget which displays output from a terminal emulation and sends input keypresses and mouse activit...
KCOREADDONS_EXPORT QString quoteArg(const QString &arg)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString & append(QChar ch)
bool isNull() const const
QString & prepend(QChar ch)
QString & setNum(double n, char format, int precision)
std::string toStdString() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 21 2025 11:50:35 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.