mirror of
https://github.com/KDE/konsole.git
synced 2025-12-23 23:38:08 -05:00
Support ConEnmu progress OSC
The 9;4 sequences can be used to show and hide progress on the tab bar. The error, indeterminate, and paused states are not implemented yet. If a tab has a custom color, its color is used for the progress, otherwise the standard highlight color is used. [1] https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
This commit is contained in:
@@ -428,6 +428,20 @@ Q_SIGNALS:
|
||||
*/
|
||||
void updateDroppedLines(int droppedLines);
|
||||
|
||||
/**
|
||||
* Emitted after receiving the escape sequence which asks to
|
||||
* display progress.
|
||||
*
|
||||
* @param progress The progress in percent (0-100)
|
||||
*/
|
||||
void progressChanged(int progress);
|
||||
|
||||
/**
|
||||
* Emitted after receiving the escape sequence which asks to
|
||||
* hide progress.
|
||||
*/
|
||||
void progressHidden();
|
||||
|
||||
protected:
|
||||
virtual void setMode(int mode) = 0;
|
||||
virtual void resetMode(int mode) = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
// Own
|
||||
#include "MainWindow.h"
|
||||
#include "config-konsole.h"
|
||||
|
||||
// Qt
|
||||
#include <QMenu>
|
||||
@@ -13,6 +14,10 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
#if HAVE_DBUS
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#endif
|
||||
|
||||
// KDE
|
||||
#include <KAcceleratorManager>
|
||||
@@ -229,6 +234,7 @@ void MainWindow::disconnectController(SessionController *controller)
|
||||
disconnect(controller, &Konsole::SessionController::titleChanged, this, &Konsole::MainWindow::activeViewTitleChanged);
|
||||
disconnect(controller, &Konsole::SessionController::rawTitleChanged, this, &Konsole::MainWindow::updateWindowCaption);
|
||||
disconnect(controller, &Konsole::SessionController::iconChanged, this, &Konsole::MainWindow::updateWindowIcon);
|
||||
disconnect(controller, &Konsole::SessionController::progressChanged, this, &Konsole::MainWindow::updateProgress);
|
||||
|
||||
if (auto view = controller->view()) {
|
||||
view->removeEventFilter(this);
|
||||
@@ -275,6 +281,7 @@ void MainWindow::activeViewChanged(SessionController *controller)
|
||||
connect(controller, &Konsole::SessionController::titleChanged, this, &Konsole::MainWindow::activeViewTitleChanged);
|
||||
connect(controller, &Konsole::SessionController::rawTitleChanged, this, &Konsole::MainWindow::updateWindowCaption);
|
||||
connect(controller, &Konsole::SessionController::iconChanged, this, &Konsole::MainWindow::updateWindowIcon);
|
||||
connect(controller, &Konsole::SessionController::progressChanged, this, &Konsole::MainWindow::updateProgress);
|
||||
|
||||
// to prevent shortcuts conflict
|
||||
if (auto hamburgerMenu = _hamburgerMenu->menu()) {
|
||||
@@ -287,8 +294,9 @@ void MainWindow::activeViewChanged(SessionController *controller)
|
||||
// update session title to match newly activated session
|
||||
activeViewTitleChanged(controller);
|
||||
|
||||
// Update window icon to newly activated session's icon
|
||||
// Update window icon and progress to newly activated session's icon
|
||||
updateWindowIcon();
|
||||
updateProgress();
|
||||
|
||||
for (IKonsolePlugin *plugin : _plugins) {
|
||||
plugin->activeViewChanged(controller, this);
|
||||
@@ -331,6 +339,43 @@ void MainWindow::updateWindowIcon()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateProgress()
|
||||
{
|
||||
#if HAVE_DBUS
|
||||
std::optional<int> progress;
|
||||
if (KonsoleSettings::showProgressInTaskBar() && _pluggedController) {
|
||||
progress = _pluggedController->progress();
|
||||
}
|
||||
|
||||
if (_progress == progress) {
|
||||
return;
|
||||
}
|
||||
|
||||
_progress = progress;
|
||||
|
||||
QString launcherId;
|
||||
launcherId.append(QLatin1String("application://"));
|
||||
launcherId.append(qApp->desktopFileName());
|
||||
if (constexpr QLatin1String suffix{".desktop"}; !launcherId.endsWith(suffix)) {
|
||||
launcherId.append(suffix);
|
||||
}
|
||||
|
||||
QVariantMap properties;
|
||||
if (progress) {
|
||||
properties.insert(QStringLiteral("progress"), *progress / 100.0);
|
||||
properties.insert(QStringLiteral("progress-visible"), true);
|
||||
} else {
|
||||
properties.insert(QStringLiteral("progress-visible"), false);
|
||||
}
|
||||
|
||||
QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/org/kde/konsole/UnityLauncher"),
|
||||
QStringLiteral("com.canonical.Unity.LauncherEntry"),
|
||||
QStringLiteral("Update"));
|
||||
message.setArguments({launcherId, properties});
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::setupActions()
|
||||
{
|
||||
KActionCollection *collection = actionCollection();
|
||||
@@ -947,6 +992,7 @@ void MainWindow::applyKonsoleSettings()
|
||||
setAutoSaveSettings();
|
||||
|
||||
updateWindowCaption();
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
void MainWindow::activateMenuBar()
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <QPointer>
|
||||
#include <QUrl>
|
||||
|
||||
// STL
|
||||
#include <optional>
|
||||
|
||||
// KDE
|
||||
#include <KXmlGuiWindow>
|
||||
|
||||
@@ -173,6 +176,7 @@ private Q_SLOTS:
|
||||
|
||||
void updateWindowIcon();
|
||||
void updateWindowCaption();
|
||||
void updateProgress();
|
||||
void openUrls(const QList<QUrl> &urls);
|
||||
|
||||
// Sets the list of profiles to be displayed under the "New Tab" action
|
||||
@@ -225,6 +229,7 @@ private:
|
||||
QPointer<SessionController> _pluggedController;
|
||||
std::vector<IKonsolePlugin *> _plugins;
|
||||
QList<QAction *> _pluginsActions;
|
||||
std::optional<int> _progress;
|
||||
bool _blurEnabled = false;
|
||||
bool _firstShowEvent = true;
|
||||
|
||||
|
||||
@@ -86,6 +86,14 @@ void ViewProperties::setIdentifier(int id)
|
||||
_viewProperties.insert(id, this);
|
||||
}
|
||||
|
||||
void ViewProperties::setProgress(const std::optional<int> &progress)
|
||||
{
|
||||
if (_progress != progress) {
|
||||
_progress = progress;
|
||||
Q_EMIT progressChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
QString ViewProperties::title() const
|
||||
{
|
||||
return _title;
|
||||
@@ -106,4 +114,9 @@ QColor ViewProperties::color() const
|
||||
return _color;
|
||||
}
|
||||
|
||||
std::optional<int> ViewProperties::progress() const
|
||||
{
|
||||
return _progress;
|
||||
}
|
||||
|
||||
#include "moc_ViewProperties.cpp"
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
// STL
|
||||
#include <optional>
|
||||
|
||||
// Konsole
|
||||
#include "konsoleprivate_export.h"
|
||||
#include "session/Session.h"
|
||||
@@ -41,6 +44,8 @@ public:
|
||||
QString title() const;
|
||||
/** Returns the color associated with a view */
|
||||
QColor color() const;
|
||||
/** Returns the progress associated with a view */
|
||||
std::optional<int> progress() const;
|
||||
|
||||
/**
|
||||
* Returns the URL current associated with a view.
|
||||
@@ -89,6 +94,8 @@ Q_SIGNALS:
|
||||
void readOnlyChanged(ViewProperties *item);
|
||||
/** Emitted when "copy input" state changes */
|
||||
void copyInputChanged(ViewProperties *item);
|
||||
/** Emitted when the progress changes */
|
||||
void progressChanged(ViewProperties *item);
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
@@ -119,6 +126,8 @@ protected:
|
||||
void setColor(const QColor &color);
|
||||
/** Subclasses may call this method to change the identifier. */
|
||||
void setIdentifier(int id);
|
||||
/** Subclass may call this method to change the progress. */
|
||||
void setProgress(const std::optional<int> &progress);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(ViewProperties)
|
||||
@@ -127,7 +136,7 @@ private:
|
||||
QString _title;
|
||||
QColor _color;
|
||||
int _identifier;
|
||||
|
||||
std::optional<int> _progress;
|
||||
static QHash<int, ViewProperties *> _viewProperties;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1678,6 +1678,43 @@ void Vt102Emulation::processSessionAttributeRequest(const int tokenSize, const u
|
||||
int rows = -1, cols = -1;
|
||||
_currentScreen->addPlacement(pixmap, rows, cols, -1, -1, TerminalGraphicsPlacement_t::iTerm, true, moveCursor);
|
||||
}
|
||||
|
||||
if (attribute == ConEmu) {
|
||||
const auto list = QStringView(value).split(QLatin1Char(';'));
|
||||
if (list.size() >= 2) {
|
||||
// Progress indicator.
|
||||
if (list.at(0) == QLatin1Char('4')) {
|
||||
bool ok;
|
||||
const int st = list.at(1).toInt(&ok);
|
||||
if (ok) {
|
||||
switch (st) {
|
||||
case 0:
|
||||
Q_EMIT progressHidden();
|
||||
break;
|
||||
case 1:
|
||||
if (list.size() >= 3) {
|
||||
const int pr = list.at(2).toInt(&ok);
|
||||
if (ok && pr >= 0 && pr <= 100) {
|
||||
Q_EMIT progressChanged(pr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// TODO error state.
|
||||
break;
|
||||
case 3:
|
||||
// TODO indeterminate state.
|
||||
Q_EMIT progressHidden();
|
||||
break;
|
||||
case 4:
|
||||
// TODO paused state.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_pendingSessionAttributesUpdates[attribute] = value;
|
||||
_sessionAttributesUpdateTimer->start(20);
|
||||
}
|
||||
|
||||
@@ -190,6 +190,8 @@ private:
|
||||
// https://chromium.googlesource.com/apps/libapps/+/master/hterm/doc/ControlSequences.md#OSC
|
||||
Notification = 777,
|
||||
Image = 1337,
|
||||
// https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
|
||||
ConEmu = 9,
|
||||
};
|
||||
|
||||
ParserStates _state = Ground;
|
||||
|
||||
@@ -230,6 +230,13 @@ SessionController::SessionController(Session *sessionParam, TerminalDisplay *vie
|
||||
// xterm '11;?' request
|
||||
connect(session(), &Konsole::Session::getBackgroundColor, this, &Konsole::SessionController::sendBackgroundColor);
|
||||
|
||||
connect(session()->emulation(), &Konsole::Emulation::progressChanged, this, [this](int progress) {
|
||||
setProgress(progress);
|
||||
});
|
||||
connect(session()->emulation(), &Konsole::Emulation::progressHidden, this, [this] {
|
||||
setProgress(std::nullopt);
|
||||
});
|
||||
|
||||
_allControllers.insert(this);
|
||||
|
||||
// A list of programs that accept Ctrl+C to clear command line used
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
// Own
|
||||
#include "GeneralSettings.h"
|
||||
#include "config-konsole.h"
|
||||
|
||||
#include <KMessageBox>
|
||||
|
||||
@@ -15,6 +16,9 @@ GeneralSettings::GeneralSettings(QWidget *aParent)
|
||||
: QWidget(aParent)
|
||||
{
|
||||
setupUi(this);
|
||||
#if !HAVE_DBUS
|
||||
kcfg_ShowProgressInTaskBar->hide();
|
||||
#endif
|
||||
|
||||
connect(enableAllMessagesButton, &QPushButton::clicked, this, &Konsole::GeneralSettings::slotEnableAllMessages);
|
||||
}
|
||||
|
||||
@@ -37,26 +37,47 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="16" column="0" alignment="Qt::AlignmentFlag::AlignRight">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Notifications:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_EnableSecuritySensitiveDBusAPI">
|
||||
<property name="text">
|
||||
<string>Enable the security sensitive parts of the DBus API</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchReverseSearch">
|
||||
<widget class="QCheckBox" name="kcfg_SearchHighlightMatches">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Sets whether search should start from the bottom</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Search backwards</string>
|
||||
<string>Highlight all matches</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0" alignment="Qt::AlignmentFlag::AlignRight">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Notifications:</string>
|
||||
<string>Process and window:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_ListenForZModemTerminalCodes">
|
||||
<property name="text">
|
||||
<string>Listen for ZModem terminal codes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -67,6 +88,42 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_ShowWindowTitleOnTitleBar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show window title on the titlebar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_RemoveWindowTitleBarAndFrame">
|
||||
<property name="text">
|
||||
<string>Remove window titlebar and frame</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_AllowMenuAccelerators">
|
||||
<property name="sizePolicy">
|
||||
@@ -80,21 +137,23 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" alignment="Qt::AlignmentFlag::AlignRight">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_UseSingleInstance">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When launching Konsole re-use existing process if possible</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@item:intext Search options">Search:</string>
|
||||
<string>Run all Konsole windows in a single process</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_RemoveWindowTitleBarAndFrame">
|
||||
<property name="text">
|
||||
<string>Remove window titlebar and frame</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<item row="16" column="1">
|
||||
<layout class="QHBoxLayout" stretch="0,1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
@@ -130,49 +189,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchHighlightMatches">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Highlight all matches</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_ShowWindowTitleOnTitleBar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show window title on the titlebar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchNoWrap">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Sets whether search should stop instead of wrapping</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No wrap</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<item row="9" column="1">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
@@ -188,18 +205,8 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Process and window:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_UseSingleInstance">
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchCaseSensitive">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -207,10 +214,62 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When launching Konsole re-use existing process if possible</string>
|
||||
<string>Sets whether the search is case sensitive</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Run all Konsole windows in a single process</string>
|
||||
<string>Case sensitive</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchReverseSearch">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Sets whether search should start from the bottom</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Search backwards</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchRegExpression">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Match using regular expressions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" alignment="Qt::AlignmentFlag::AlignRight">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string comment="@item:intext Search options">Search:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchNoWrap">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Sets whether search should stop instead of wrapping</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No wrap</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -230,62 +289,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_EnableSecuritySensitiveDBusAPI">
|
||||
<property name="text">
|
||||
<string>Enable the security sensitive parts of the DBus API</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchCaseSensitive">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Sets whether the search is case sensitive</string>
|
||||
</property>
|
||||
<widget class="QCheckBox" name="kcfg_ShowProgressInTaskBar">
|
||||
<property name="text">
|
||||
<string>Case sensitive</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_SearchRegExpression">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Match using regular expressions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_ListenForZModemTerminalCodes">
|
||||
<property name="text">
|
||||
<string>Listen for ZModem terminal codes</string>
|
||||
<string>Show progress in taskbar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
<tooltip>When launching Konsole re-use existing process if possible</tooltip>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="ShowProgressInTaskBar" type="Bool">
|
||||
<label>Show progress in task bar</label>
|
||||
<tooltip>When a script reports its progress, it will be shown in the task bar</tooltip>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="EnableSecuritySensitiveDBusAPI" type="Bool">
|
||||
<label>Enable the security sensitive parts of the DBus API</label>
|
||||
<tooltip>DBus API like runCommand will be enabled</tooltip>
|
||||
|
||||
@@ -32,14 +32,41 @@ DetachableTabBar::DetachableTabBar(QWidget *parent)
|
||||
|
||||
void DetachableTabBar::setColor(int idx, const QColor &color)
|
||||
{
|
||||
setTabData(idx, color);
|
||||
update();
|
||||
DetachableTabData data = tabData(idx).value<DetachableTabData>();
|
||||
if (data.color != color) {
|
||||
data.color = color;
|
||||
setDetachableTabData(idx, data);
|
||||
update(tabRect(idx));
|
||||
}
|
||||
}
|
||||
|
||||
void DetachableTabBar::removeColor(int idx)
|
||||
{
|
||||
setTabData(idx, QVariant());
|
||||
update();
|
||||
DetachableTabData data = tabData(idx).value<DetachableTabData>();
|
||||
if (data.color.isValid()) {
|
||||
data.color = QColor();
|
||||
setDetachableTabData(idx, data);
|
||||
update(tabRect(idx));
|
||||
}
|
||||
}
|
||||
|
||||
void DetachableTabBar::setProgress(int idx, const std::optional<int> &progress)
|
||||
{
|
||||
DetachableTabData data = tabData(idx).value<DetachableTabData>();
|
||||
if (data.progress != progress) {
|
||||
data.progress = progress;
|
||||
setDetachableTabData(idx, data);
|
||||
update(tabRect(idx));
|
||||
}
|
||||
}
|
||||
|
||||
void DetachableTabBar::setDetachableTabData(int idx, const DetachableTabData &data)
|
||||
{
|
||||
if ((data.color.isValid() && data.color.alpha() > 0) || data.progress.has_value()) {
|
||||
setTabData(idx, QVariant::fromValue(data));
|
||||
} else {
|
||||
setTabData(idx, QVariant());
|
||||
}
|
||||
}
|
||||
|
||||
void DetachableTabBar::middleMouseButtonClickAt(const QPoint &pos)
|
||||
@@ -170,18 +197,34 @@ void DetachableTabBar::paintEvent(QPaintEvent *event)
|
||||
continue;
|
||||
}
|
||||
|
||||
QColor varColor = data.value<QColor>();
|
||||
if (!varColor.isValid() || varColor.alpha() == 0) {
|
||||
const DetachableTabData tabData = data.value<DetachableTabData>();
|
||||
|
||||
const bool colorValid = tabData.color.isValid() && tabData.color.alpha() > 0;
|
||||
|
||||
if (!colorValid && !tabData.progress.has_value()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
painter.setBrush(varColor);
|
||||
const QColor color = colorValid ? tabData.color : palette().highlight().color();
|
||||
|
||||
painter.setBrush(color);
|
||||
QRect tRect = tabRect(tabIndex);
|
||||
tRect.setTop(painter.fontMetrics().height() + 6); // Color bar top position consider a height the font and fixed spacing of 6px
|
||||
tRect.setHeight(4);
|
||||
tRect.setLeft(tRect.left() + 6);
|
||||
tRect.setWidth(tRect.width() - 6);
|
||||
painter.drawRect(tRect);
|
||||
|
||||
// Draw progress, if any, ontop of a faint bar.
|
||||
if (tabData.progress.has_value()) {
|
||||
painter.setOpacity(0.3);
|
||||
painter.drawRect(tRect);
|
||||
painter.setOpacity(1.0);
|
||||
|
||||
tRect.setWidth(tRect.width() * tabData.progress.value() / 100.0);
|
||||
painter.drawRect(tRect);
|
||||
} else {
|
||||
painter.drawRect(tRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,20 @@
|
||||
#include <QCursor>
|
||||
#include <QTabBar>
|
||||
|
||||
#include <optional>
|
||||
|
||||
class QColor;
|
||||
class QPaintEvent;
|
||||
|
||||
namespace Konsole
|
||||
{
|
||||
class TabbedViewContainer;
|
||||
|
||||
struct DetachableTabData {
|
||||
QColor color;
|
||||
std::optional<int> progress;
|
||||
};
|
||||
|
||||
class DetachableTabBar : public QTabBar
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -30,6 +38,9 @@ public:
|
||||
|
||||
void setColor(int idx, const QColor &color);
|
||||
void removeColor(int idx);
|
||||
|
||||
void setProgress(int idx, const std::optional<int> &progress);
|
||||
|
||||
Q_SIGNALS:
|
||||
void detachTab(int index);
|
||||
void moveTabToWindow(int tabIndex, QWidget *otherWindow);
|
||||
@@ -47,6 +58,8 @@ protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
void setDetachableTabData(int idx, const DetachableTabData &data);
|
||||
|
||||
DragType dragType;
|
||||
QCursor _originalCursor;
|
||||
QList<TabbedViewContainer *> _containers;
|
||||
@@ -54,4 +67,6 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(Konsole::DetachableTabData)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -85,6 +85,8 @@ TabbedViewContainer::TabbedViewContainer(ViewManager *connectedViewManager, QWid
|
||||
connect(this, &TabbedViewContainer::setColor, tabBarWidget, &DetachableTabBar::setColor);
|
||||
connect(this, &TabbedViewContainer::removeColor, tabBarWidget, &DetachableTabBar::removeColor);
|
||||
|
||||
connect(this, &TabbedViewContainer::setProgress, tabBarWidget, &DetachableTabBar::setProgress);
|
||||
|
||||
// The context menu of tab bar
|
||||
_contextPopupMenu = new QMenu(tabBar());
|
||||
connect(_contextPopupMenu, &QMenu::aboutToHide, this, [this]() {
|
||||
@@ -406,6 +408,8 @@ void TabbedViewContainer::connectTerminalDisplay(TerminalDisplay *display)
|
||||
connect(item, &Konsole::ViewProperties::readOnlyChanged, this, &Konsole::TabbedViewContainer::updateSpecialState);
|
||||
|
||||
connect(item, &Konsole::ViewProperties::copyInputChanged, this, &Konsole::TabbedViewContainer::updateSpecialState);
|
||||
|
||||
connect(item, &Konsole::ViewProperties::progressChanged, this, &Konsole::TabbedViewContainer::updateProgress);
|
||||
}
|
||||
|
||||
void TabbedViewContainer::disconnectTerminalDisplay(TerminalDisplay *display)
|
||||
@@ -689,6 +693,15 @@ void TabbedViewContainer::updateSpecialState(ViewProperties *item)
|
||||
updateIcon(item);
|
||||
}
|
||||
|
||||
void TabbedViewContainer::updateProgress(ViewProperties *item)
|
||||
{
|
||||
auto controller = qobject_cast<SessionController *>(item);
|
||||
auto topLevelSplitter = qobject_cast<ViewSplitter *>(controller->view()->parentWidget())->getToplevelSplitter();
|
||||
const int index = indexOf(topLevelSplitter);
|
||||
|
||||
Q_EMIT setProgress(index, item->progress());
|
||||
}
|
||||
|
||||
void TabbedViewContainer::currentSessionControllerChanged(SessionController *controller)
|
||||
{
|
||||
auto topLevelSplitter = qobject_cast<ViewSplitter *>(controller->view()->parentWidget())->getToplevelSplitter();
|
||||
|
||||
@@ -77,6 +77,8 @@ public:
|
||||
void updateNotification(ViewProperties *item, Konsole::Session::Notification notification, bool enabled);
|
||||
/** Sets tab special state (copy input or read-only) */
|
||||
void updateSpecialState(ViewProperties *item);
|
||||
/** Sets tab progress */
|
||||
void updateProgress(ViewProperties *item);
|
||||
|
||||
/** Changes the active view to the next view */
|
||||
void activateNextView();
|
||||
@@ -209,6 +211,9 @@ Q_SIGNALS:
|
||||
/** remove the color tab */
|
||||
void removeColor(int idx);
|
||||
|
||||
/** set the tab progress */
|
||||
void setProgress(int idx, const std::optional<int> &progress);
|
||||
|
||||
protected:
|
||||
// close tabs and unregister
|
||||
void closeTerminalTab(int idx);
|
||||
|
||||
Reference in New Issue
Block a user