Commit 6d2924e3 authored by Will Westrop's avatar Will Westrop Committed by Kurt Hindenburg
Browse files

Send notification when the session'a foreground process finishes

Add new option "Monitor for Process Finishing" which
will send a notification when the current session's
long running process finishes.

FEATURE: 420053
GUI:
FIXED-IN: 20.08.0
CHANGELOG: Send notification when the session's foreground process finishes
parent 724560da
......@@ -727,6 +727,16 @@ Comment[zh_CN]=被监视会话中检测到的静默
Comment[zh_TW]=監控工作階段中偵測到靜默時的行為
Action=Popup
[Event/ProcessFinishedHidden]
Name=Process finished in Non-Focused Monitored Session
Comment=Process finished in a non-focused monitored session
Action=Popup
[Event/ProcessFinished]
Name=Process finished in Monitored Session
Comment=Process finished in a monitored session
Action=Popup
[Event/Finished]
Name=Session Finished With Non-Zero Status
Name[af]=Sessie het geëindig met nie-zero status
......
<!DOCTYPE kpartgui>
<kpartgui name="session" version="27">
<kpartgui name="session" version="28">
<MenuBar>
<Menu name="file">
<Action name="file_save_as" group="session-operations"/>
......@@ -28,6 +28,7 @@
<Menu name="view">
<Action name="monitor-silence" group="session-view-operations"/>
<Action name="monitor-activity" group="session-view-operations"/>
<Action name="monitor-process-finish" group="session-view-operations"/>
<Separator group="session-view-operations"/>
<Action name="view-readonly" group="session-view-operations"/>
<Separator group="session-view-operations"/>
......
......@@ -239,6 +239,12 @@ bool Session::isRunning() const
return (_shellProcess != nullptr) && (_shellProcess->state() == QProcess::Running);
}
bool Session::hasFocus() const
{
return std::any_of(_views.constBegin(), _views.constEnd(),
[](const TerminalDisplay *display) { return display-> hasFocus(); });
}
void Session::setCodec(QTextCodec* codec)
{
if (isReadOnly()) {
......@@ -645,15 +651,7 @@ void Session::silenceTimerDone()
return;
}
bool hasFocus = false;
for (const TerminalDisplay *display : qAsConst(_views)) {
if (display->hasFocus()) {
hasFocus = true;
break;
}
}
KNotification::event(hasFocus ? QStringLiteral("Silence") : QStringLiteral("SilenceHidden"),
KNotification::event(hasFocus() ? QStringLiteral("Silence") : QStringLiteral("SilenceHidden"),
i18n("Silence in session '%1'", _nameTitle), QPixmap(),
QApplication::activeWindow(),
KNotification::CloseWhenWidgetActivated);
......@@ -1717,18 +1715,8 @@ void Session::handleActivity()
// TODO: should this hardcoded interval be user configurable?
const int activityMaskInSeconds = 15;
bool hasFocus = false;
// Don't notify if the terminal is active
const auto &displays = _views;
for (const TerminalDisplay *display: displays) {
if (display->hasFocus()) {
hasFocus = true;
break;
}
}
if (_monitorActivity && !_notifiedActivity) {
KNotification::event(hasFocus ? QStringLiteral("Activity") : QStringLiteral("ActivityHidden"),
KNotification::event(hasFocus() ? QStringLiteral("Activity") : QStringLiteral("ActivityHidden"),
i18n("Activity in session '%1'", _nameTitle), QPixmap(),
QApplication::activeWindow(),
KNotification::CloseWhenWidgetActivated);
......
......@@ -107,6 +107,12 @@ public:
*/
bool isRunning() const;
/**
* Returns true if the tab holding this session is currently selected
* and Konsole is the foreground window.
*/
bool hasFocus() const;
/**
* Adds a new view for this session.
*
......
......@@ -56,6 +56,7 @@
#include <KSharedConfig>
#include <KConfigGroup>
#include <KCodecAction>
#include <KNotification>
// Konsole
#include "EditProfileDialog.h"
......@@ -94,7 +95,6 @@ SessionController::SessionController(Session* session , TerminalDisplay* view, Q
, _profileList(nullptr)
, _sessionIcon(QIcon())
, _sessionIconName(QString())
, _previousState(-1)
, _searchFilter(nullptr)
, _urlFilter(nullptr)
, _fileFilter(nullptr)
......@@ -116,6 +116,7 @@ SessionController::SessionController(Session* session , TerminalDisplay* view, Q
, _isSearchBarEnabled(false)
, _editProfileDialog(nullptr)
, _searchBar(view->searchBar())
, _monitorProcessFinish(false)
{
Q_ASSERT(session);
Q_ASSERT(view);
......@@ -325,6 +326,19 @@ void SessionController::snapshot()
// apply new color
_session->setColor(color);
// check if foreground process ended and notify if this option was requested
if (_monitorProcessFinish) {
bool isForegroundProcessActive = _session->isForegroundProcessActive();
if (!_previousForegroundProcessName.isNull() && !isForegroundProcessActive) {
KNotification::event(_session->hasFocus() ? QStringLiteral("ProcessFinished") : QStringLiteral("ProcessFinishedHidden"),
i18n("The process '%1' has finished running in session '%2'", _previousForegroundProcessName, _session->nameTitle()),
QPixmap(),
QApplication::activeWindow(),
KNotification::CloseWhenWidgetActivated);
}
_previousForegroundProcessName = isForegroundProcessActive ? _session->foregroundProcessName() : QString();
}
// do not forget icon
updateSessionIcon();
}
......@@ -746,6 +760,10 @@ void SessionController::setupExtraActions()
action = collection->addAction(QStringLiteral("monitor-silence"), toggleAction);
connect(action, &QAction::toggled, this, &Konsole::SessionController::monitorSilence);
toggleAction = new KToggleAction(i18n("Monitor for Process Finishing"), this);
action = collection->addAction(QStringLiteral("monitor-process-finish"), toggleAction);
connect(action, &QAction::toggled, this, &Konsole::SessionController::monitorProcessFinish);
// Text Size
action = collection->addAction(QStringLiteral("enlarge-font"), this, SLOT(increaseFontSize()));
action->setText(i18n("Enlarge Font"));
......@@ -1598,6 +1616,10 @@ void SessionController::monitorSilence(bool monitor)
{
_session->setMonitorSilence(monitor);
}
void SessionController::monitorProcessFinish(bool monitor)
{
_monitorProcessFinish = monitor;
}
void SessionController::updateSessionIcon()
{
// If the default profile icon is being used, don't put it on the tab
......
......@@ -247,6 +247,7 @@ private Q_SLOTS:
void clearHistoryAndReset();
void monitorActivity(bool monitor);
void monitorSilence(bool monitor);
void monitorProcessFinish(bool monitor);
void renameSession();
void switchProfile(const Profile::Ptr &profile);
void handleWebShortcutAction();
......@@ -320,7 +321,6 @@ private:
QIcon _sessionIcon;
QString _sessionIconName;
int _previousState;
RegExpFilter *_searchFilter;
UrlFilter *_urlFilter;
......@@ -359,6 +359,9 @@ private:
QString _searchText;
QPointer<IncrementalSearchBar> _searchBar;
QString _previousForegroundProcessName;
bool _monitorProcessFinish;
};
inline bool SessionController::isValid() const
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment