Git commit 542a04560dfb2417989ecfb29717f46efe6384e6 by Kurt Hindenburg, on behalf of Matan Ziv-Av. Committed on 14/05/2023 at 14:15. Pushed by hindenburg into branch 'master'.
Add "Monitor for Prompt" action When semantic shell integration is enabled, Konsole will generate a notification when a shell prompt is displayed. M +10 -0 desktop/konsole.notifyrc M +2 -1 desktop/sessionui.rc M +14 -2 doc/manual/index.docbook M +14 -1 src/Screen.cpp M +1 -0 src/Screen.h M +12 -0 src/session/Session.cpp M +12 -0 src/session/Session.h M +31 -1 src/session/SessionController.cpp M +6 -0 src/session/SessionController.h https://invent.kde.org/utilities/konsole/commit/542a04560dfb2417989ecfb29717f46efe6384e6 diff --git a/desktop/konsole.notifyrc b/desktop/konsole.notifyrc index aef724b31..267c2b425 100644 --- a/desktop/konsole.notifyrc +++ b/desktop/konsole.notifyrc @@ -1300,3 +1300,13 @@ Comment[x-test]=xxNotification emitted by a process in a non-focused sessionxx Comment[zh_CN]=通知由一个位于非焦点会话中的进程发出 Comment[zh_TW]=未取得焦點的工作階段中處理程序發出的通知 Action=Popup + +[Event/PromptHidden] +Name=Shell prompt triggered a notification in a non-focused session +Comment=Shell prompt triggered a notification in a non-focused session +Action=Popup + +[Event/Prompt] +Name=Shell prompt triggered a notification +Comment=Shell prompt triggered a notification +Action=Popup diff --git a/desktop/sessionui.rc b/desktop/sessionui.rc index 2b239f1b8..992517f11 100644 --- a/desktop/sessionui.rc +++ b/desktop/sessionui.rc @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!DOCTYPE gui SYSTEM "kpartgui.dtd"> -<gui name="session" version="33"> +<gui name="session" version="34"> <MenuBar> <Menu name="file"> <Action name="file_save_as" group="session-operations"/> @@ -28,6 +28,7 @@ <Action name="edit_find_prev" group="session-edit-operations"/> </Menu> <Menu name="view"> + <Action name="monitor-prompt" group="session-view-operations"/> <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"/> diff --git a/doc/manual/index.docbook b/doc/manual/index.docbook index 2137d8227..1a81bc382 100644 --- a/doc/manual/index.docbook +++ b/doc/manual/index.docbook @@ -52,8 +52,8 @@ <legalnotice>&FDLNotice;</legalnotice> -<date>2023-02-10</date> -<releaseinfo>KDE Gear 23.04</releaseinfo> +<date>2023-04-25</date> +<releaseinfo>KDE Gear 23.08</releaseinfo> <abstract><para>&konsole; is &kde;'s terminal emulator.</para></abstract> @@ -899,6 +899,18 @@ menu item earlier.</action> The default layouts (2x2, 2x1, and 1x2) can be loade </para></listitem> </varlistentry> +<varlistentry> +<term><menuchoice> +<shortcut><keycombo action="simul">&Ctrl;&Shift;<keycap>R</keycap></keycombo></shortcut> +<guimenu>View</guimenu><guimenuitem>Monitor for +Prompt</guimenuitem></menuchoice></term> +<listitem><para><action>Toggles the monitoring of the current tab for +a shell prompt.</action> +</para><para> +When a shell prompt is displayed, &konsole; will show a notification. This option is shown only when semantic integration is enabled in the shell. +</para></listitem> +</varlistentry> + <varlistentry> <term><menuchoice> <shortcut><keycombo action="simul">&Ctrl;&Shift;<keycap>I</keycap></keycombo></shortcut> diff --git a/src/Screen.cpp b/src/Screen.cpp index 9709a893c..63b37402a 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -79,6 +79,7 @@ Screen::Screen(int lines, int columns) , _bottomMargin(0) , _replMode(REPL_None) , _hasRepl(false) + , _replHadOutput(false) , _replLastOutputStart(std::pair(-1, -1)) , _tabStops(QBitArray()) , _selBegin(0) @@ -2373,12 +2374,24 @@ void Screen::setReplMode(int mode) } else if (_replMode == REPL_PROMPT) { _lineProperties[_cuY].counter = ++commandCounter; } + if (mode == REPL_PROMPT) { + if (_replHadOutput) { + _currentTerminalDisplay->sessionController()->notifyPrompt(); + _replHadOutput = false; + } + } + if (mode == REPL_OUTPUT) { + _replHadOutput = true; + } _replMode = mode; _replModeStart = std::make_pair(_cuY, _cuX); _replModeEnd = std::make_pair(_cuY, _cuX); } if (mode != REPL_None) { - _hasRepl = true; + if (!_hasRepl) { + _hasRepl = true; + _currentTerminalDisplay->sessionController()->setVisible(QStringLiteral("monitor-prompt"), true); + } Q_EMIT _currentTerminalDisplay->screenWindow()->selectionChanged(); // Enable copy action setLineProperty(LINE_PROMPT_START << (mode - REPL_PROMPT), true); } diff --git a/src/Screen.h b/src/Screen.h index ce664f0da..af8803317 100644 --- a/src/Screen.h +++ b/src/Screen.h @@ -842,6 +842,7 @@ private: int _savedModes[MODES_SCREEN]; int _replMode; bool _hasRepl; + bool _replHadOutput; std::pair<int, int> _replModeStart; std::pair<int, int> _replModeEnd; std::pair<int, int> _replLastOutputStart; diff --git a/src/session/Session.cpp b/src/session/Session.cpp index c6b7f9b5e..d4fc12e6f 100644 --- a/src/session/Session.cpp +++ b/src/session/Session.cpp @@ -1457,6 +1457,10 @@ QString Session::program() const return _program; } +bool Session::isMonitorPrompt() const +{ + return _monitorPrompt; +} bool Session::isMonitorActivity() const { return _monitorActivity; @@ -1466,6 +1470,14 @@ bool Session::isMonitorSilence() const return _monitorSilence; } +void Session::setMonitorPrompt(bool monitor) +{ + if (_monitorPrompt == monitor) { + return; + } + _monitorPrompt = monitor; +} + void Session::setMonitorActivity(bool monitor) { if (_monitorActivity == monitor) { diff --git a/src/session/Session.h b/src/session/Session.h index b30560759..cb97befd4 100644 --- a/src/session/Session.h +++ b/src/session/Session.h @@ -494,6 +494,17 @@ public Q_SLOTS: */ void setSessionAttribute(int what, const QString &caption); + /** + * Enables monitoring for a shell prompt in the session. + * This will cause notifySessionState() to be emitted + * with the NOTIFYACTIVITY state flag when a prompt is shown + * (requires semantic shell suport). + */ + Q_SCRIPTABLE void setMonitorPrompt(bool); + + /** Returns true if monitoring for prompt is enabled. */ + Q_SCRIPTABLE bool isMonitorPrompt() const; + /** * Enables monitoring for activity in the session. * This will cause notifySessionState() to be emitted @@ -819,6 +830,7 @@ private: QList<TerminalDisplay *> _views; // monitor activity & silence + bool _monitorPrompt = false; bool _monitorActivity = false; bool _monitorSilence = false; bool _notifiedActivity = false; diff --git a/src/session/SessionController.cpp b/src/session/SessionController.cpp index 636f88e30..fa5a033b8 100644 --- a/src/session/SessionController.cpp +++ b/src/session/SessionController.cpp @@ -884,7 +884,14 @@ void SessionController::setupExtraActions() collection->setDefaultShortcut(action, Qt::CTRL | Qt::ALT | Qt::Key_U); // Monitor - KToggleAction *toggleAction = new KToggleAction(i18n("Monitor for &Activity"), this); + KToggleAction *toggleAction = new KToggleAction(i18n("Monitor for &Prompt"), this); + collection->setDefaultShortcut(toggleAction, Konsole::ACCEL | Qt::Key_R); + action = collection->addAction(QStringLiteral("monitor-prompt"), toggleAction); + connect(action, &QAction::toggled, this, &Konsole::SessionController::monitorPrompt); + action->setIcon(QIcon::fromTheme(QStringLiteral("tools-media-optical-burn"))); + action->setVisible(false); + + toggleAction = new KToggleAction(i18n("Monitor for &Activity"), this); collection->setDefaultShortcut(toggleAction, Konsole::ACCEL | Qt::Key_A); action = collection->addAction(QStringLiteral("monitor-activity"), toggleAction); connect(action, &QAction::toggled, this, &Konsole::SessionController::monitorActivity); @@ -1825,6 +1832,24 @@ void SessionController::resetFontSize() view()->terminalFont()->resetFontSize(); } +void SessionController::notifyPrompt() +{ + if (session()->isMonitorPrompt()) { + KNotification *notification = KNotification::event(session()->hasFocus() ? QStringLiteral("Prompt") : QStringLiteral("PromptHidden"), + i18n("The shell prompt is displayed in session '%1'", session()->nameTitle()), + QPixmap(), + view(), + KNotification::CloseWhenWidgetActivated); + notification->setDefaultAction(i18n("Show session")); + connect(notification, &KNotification::defaultActivated, this, [this, notification]() { + view()->notificationClicked(notification->xdgActivationToken()); + }); + } +} +void SessionController::monitorPrompt(bool monitor) +{ + session()->setMonitorPrompt(monitor); +} void SessionController::monitorActivity(bool monitor) { session()->setMonitorActivity(monitor); @@ -2132,3 +2157,8 @@ bool SessionController::isValid() const { return _sessionDisplayConnection->isValid(); } + +void SessionController::setVisible(QString name, bool visible) +{ + actionCollection()->action(name)->setVisible(visible); +} diff --git a/src/session/SessionController.h b/src/session/SessionController.h index 6e78f8c2a..b59ea199b 100644 --- a/src/session/SessionController.h +++ b/src/session/SessionController.h @@ -147,6 +147,11 @@ public: /* Set/reset selection mode */ void setSelectMode(bool mode); + /* Send notification when a shell prompt is displayed */ + void notifyPrompt(); + + void setVisible(QString name, bool visible); + Q_SIGNALS: /** * Emitted when the view associated with the controller is focused. @@ -260,6 +265,7 @@ private Q_SLOTS: void showHistoryOptions(); void clearHistory(); void clearHistoryAndReset(); + void monitorPrompt(bool monitor); void monitorActivity(bool monitor); void monitorSilence(bool monitor); void monitorProcessFinish(bool monitor);
