Terminal: Support Ctrl+C/V on Windows

When a selection is present, let Ctrl+C work as copy
on Windows.

Remove sending ESC key in clearSelection as it interfered
with a Paste after copy.

Change-Id: I92db7f263e1eb433bca8aa5500fcecb637a23f90
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-08-31 10:50:08 +02:00
parent 95a3087a7b
commit 616a0c0f77
4 changed files with 29 additions and 20 deletions

View File

@@ -283,6 +283,8 @@ void TerminalView::copyToClipboard()
qCDebug(selectionLog) << "Copied to clipboard: " << text; qCDebug(selectionLog) << "Copied to clipboard: " << text;
setClipboard(text); setClipboard(text);
clearSelection();
} }
void TerminalView::pasteFromClipboard() void TerminalView::pasteFromClipboard()
@@ -310,7 +312,7 @@ std::optional<TerminalView::Selection> TerminalView::selection() const
void TerminalView::clearSelection() void TerminalView::clearSelection()
{ {
setSelection(std::nullopt); setSelection(std::nullopt);
d->m_surface->sendKey(Qt::Key_Escape); //d->m_surface->sendKey(Qt::Key_Escape);
} }
void TerminalView::zoomIn() void TerminalView::zoomIn()

View File

@@ -9,6 +9,7 @@
#include <algorithm> #include <algorithm>
#include <QAction>
#include <QGuiApplication> #include <QGuiApplication>
#include <QKeyEvent> #include <QKeyEvent>
#include <QLoggingCategory> #include <QLoggingCategory>
@@ -216,8 +217,6 @@ QKeySequence::SequenceMatch ShortcutMap::state()
*/ */
bool ShortcutMap::tryShortcut(QKeyEvent *e) bool ShortcutMap::tryShortcut(QKeyEvent *e)
{ {
Q_D(ShortcutMap);
if (e->key() == Qt::Key_unknown) if (e->key() == Qt::Key_unknown)
return false; return false;
@@ -234,14 +233,8 @@ bool ShortcutMap::tryShortcut(QKeyEvent *e)
// but we need to say we did, so that we get the follow-up key-presses. // but we need to say we did, so that we get the follow-up key-presses.
return true; return true;
case QKeySequence::ExactMatch: { case QKeySequence::ExactMatch: {
// Save number of identical matches before dispatching
// to keep ShortcutMap and tryShortcut reentrant.
const int identicalMatches = d->identicals.size();
resetState(); resetState();
dispatchEvent(e); return dispatchEvent(e);
// If there are no identicals we've only found disabled shortcuts, and
// shouldn't say that we handled the event.
return identicalMatches > 0;
} }
} }
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
@@ -510,11 +503,11 @@ QList<const ShortcutEntry *> ShortcutMap::matches() const
/*! \internal /*! \internal
Dispatches QShortcutEvents to widgets who grabbed the matched key sequence. Dispatches QShortcutEvents to widgets who grabbed the matched key sequence.
*/ */
void ShortcutMap::dispatchEvent(QKeyEvent *e) bool ShortcutMap::dispatchEvent(QKeyEvent *e)
{ {
Q_D(ShortcutMap); Q_D(ShortcutMap);
if (!d->identicals.size()) if (!d->identicals.size())
return; return false;
const QKeySequence &curKey = d->identicals.at(0)->keyseq; const QKeySequence &curKey = d->identicals.at(0)->keyseq;
if (d->prevSequence != curKey) { if (d->prevSequence != curKey) {
@@ -541,7 +534,7 @@ void ShortcutMap::dispatchEvent(QKeyEvent *e)
// Don't trigger shortcut if we're autorepeating and the shortcut is // Don't trigger shortcut if we're autorepeating and the shortcut is
// grabbed with not accepting autorepeats. // grabbed with not accepting autorepeats.
if (!next || (e->isAutoRepeat() && !next->autorepeat)) if (!next || (e->isAutoRepeat() && !next->autorepeat))
return; return false;
// Dispatch next enabled // Dispatch next enabled
if (lcShortcutMap().isDebugEnabled()) { if (lcShortcutMap().isDebugEnabled()) {
if (ambiguousShortcuts.size() > 1) { if (ambiguousShortcuts.size() > 1) {
@@ -559,6 +552,12 @@ void ShortcutMap::dispatchEvent(QKeyEvent *e)
} }
QShortcutEvent se(next->keyseq, next->id, enabledShortcuts > 1); QShortcutEvent se(next->keyseq, next->id, enabledShortcuts > 1);
QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se); QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se);
QAction *action = qobject_cast<QAction *>(next->owner);
if (action)
return action->isEnabled();
return true;
} }
} // namespace Terminal::Internal } // namespace Terminal::Internal

View File

@@ -40,7 +40,7 @@ public:
private: private:
void resetState(); void resetState();
QKeySequence::SequenceMatch nextState(QKeyEvent *e); QKeySequence::SequenceMatch nextState(QKeyEvent *e);
void dispatchEvent(QKeyEvent *e); bool dispatchEvent(QKeyEvent *e);
QKeySequence::SequenceMatch find(QKeyEvent *e, int ignoredModifiers = 0); QKeySequence::SequenceMatch find(QKeyEvent *e, int ignoredModifiers = 0);
QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const; QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const;

View File

@@ -605,13 +605,21 @@ void TerminalWidget::initActions()
moveCursorWordRight.setText(Tr::tr("Move Cursor Word Right")); moveCursorWordRight.setText(Tr::tr("Move Cursor Word Right"));
close.setText(Tr::tr("Close Terminal")); close.setText(Tr::tr("Close Terminal"));
ActionManager::registerAction(&copy, Constants::COPY, context) auto copyCmd = ActionManager::registerAction(&copy, Constants::COPY, context);
->setDefaultKeySequences({QKeySequence( auto pasteCmd = ActionManager::registerAction(&paste, Constants::PASTE, context);
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+C") : QLatin1String("Ctrl+Shift+C"))});
ActionManager::registerAction(&paste, Constants::PASTE, context) if (HostOsInfo::isMacHost()) {
->setDefaultKeySequences({QKeySequence( copyCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+C")));
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+V") : QLatin1String("Ctrl+Shift+V"))}); pasteCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+V")));
} else if (HostOsInfo::isLinuxHost()) {
copyCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+Shift+C")));
pasteCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+Shift+V")));
} else if (HostOsInfo::isWindowsHost()) {
copyCmd->setDefaultKeySequences(
{QKeySequence(QLatin1String("Ctrl+C")), QKeySequence(QLatin1String("Ctrl+Shift+C"))});
pasteCmd->setDefaultKeySequences(
{QKeySequence(QLatin1String("Ctrl+V")), QKeySequence(QLatin1String("Ctrl+Shift+V"))});
}
ActionManager::registerAction(&clearSelection, Constants::CLEARSELECTION, context); ActionManager::registerAction(&clearSelection, Constants::CLEARSELECTION, context);