[utilities/konsole] /: Add "Monitor for Prompt" action

Kurt Hindenburg null at kde.org
Sun May 14 19:59:49 BST 2023


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);



More information about the kde-doc-english mailing list