From c797ccf97d3dc07ad60f0f3ea9208d508e835962 Mon Sep 17 00:00:00 2001 From: Yen Chi Hsuan Date: Tue, 29 Aug 2017 23:34:12 +0800 Subject: [PATCH] Handle keyboard commands properly It was hard-coded in TerminalDisplay.cpp - Shift+Up always results in ScrollLineUpCommand regardless of settings in *.keytab. Now those commands are correctly parsed by KeyboardTranslator. Fixes lxde/qterminal#348 This fix is similar to KDE/konsole@b88dfb402a8ba3afe317e4a0741bf999f84b68bc while I use signals and slots instead of introducing new pointers. That sounds more reliable :) --- CMakeLists.txt | 1 + lib/Emulation.cpp | 4 ++++ lib/Emulation.h | 4 +++- lib/ScreenWindow.cpp | 47 +++++++++++++++++++++++++++++++++++++++++ lib/ScreenWindow.h | 5 +++++ lib/TerminalDisplay.cpp | 45 +-------------------------------------- lib/Vt102Emulation.cpp | 5 ++++- 7 files changed, 65 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 345be80..13009e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,7 @@ set(UI set(HDRS_DISTRIB lib/qtermwidget.h lib/Emulation.h + lib/KeyboardTranslator.h lib/Filter.h ) diff --git a/lib/Emulation.cpp b/lib/Emulation.cpp index 5313c42..e599b21 100644 --- a/lib/Emulation.cpp +++ b/lib/Emulation.cpp @@ -109,6 +109,10 @@ ScreenWindow* Emulation::createWindow() connect(this , SIGNAL(outputChanged()), window , SLOT(notifyOutputChanged()) ); + + connect(this, &Emulation::handleCommandFromKeyboard, + window, &ScreenWindow::handleCommandFromKeyboard); + return window; } diff --git a/lib/Emulation.h b/lib/Emulation.h index 10aad66..4bb6a97 100644 --- a/lib/Emulation.h +++ b/lib/Emulation.h @@ -34,11 +34,11 @@ #include #include "qtermwidget_export.h" +#include "KeyboardTranslator.h" namespace Konsole { -class KeyboardTranslator; class HistoryType; class Screen; class ScreenWindow; @@ -442,6 +442,8 @@ signals: */ void cursorChanged(KeyboardCursorShape cursorShape, bool blinkingCursorEnabled); + void handleCommandFromKeyboard(KeyboardTranslator::Command command); + protected: virtual void setMode(int mode) = 0; virtual void resetMode(int mode) = 0; diff --git a/lib/ScreenWindow.cpp b/lib/ScreenWindow.cpp index c1187a6..a6ce7c2 100644 --- a/lib/ScreenWindow.cpp +++ b/lib/ScreenWindow.cpp @@ -292,4 +292,51 @@ void ScreenWindow::notifyOutputChanged() emit outputChanged(); } +void ScreenWindow::handleCommandFromKeyboard(KeyboardTranslator::Command command) +{ + // Keyboard-based navigation + bool update = false; + + // EraseCommand is handled in Vt102Emulation + if ( command & KeyboardTranslator::ScrollPageUpCommand ) + { + scrollBy( ScreenWindow::ScrollPages , -1 ); + update = true; + } + if ( command & KeyboardTranslator::ScrollPageDownCommand ) + { + scrollBy( ScreenWindow::ScrollPages , 1 ); + update = true; + } + if ( command & KeyboardTranslator::ScrollLineUpCommand ) + { + scrollBy( ScreenWindow::ScrollLines , -1 ); + update = true; + } + if ( command & KeyboardTranslator::ScrollLineDownCommand ) + { + scrollBy( ScreenWindow::ScrollLines , 1 ); + update = true; + } + if ( command & KeyboardTranslator::ScrollDownToBottomCommand ) + { + Q_EMIT scrollToEnd(); + update = true; + } + if ( command & KeyboardTranslator::ScrollUpToTopCommand) + { + scrollTo(0); + update = true; + } + // TODO: KeyboardTranslator::ScrollLockCommand + // TODO: KeyboardTranslator::SendCommand + + if ( update ) + { + setTrackOutput( atEndOfOutput() ); + + Q_EMIT outputChanged(); + } +} + //#include "ScreenWindow.moc" diff --git a/lib/ScreenWindow.h b/lib/ScreenWindow.h index 79613d7..3a75c08 100644 --- a/lib/ScreenWindow.h +++ b/lib/ScreenWindow.h @@ -27,6 +27,7 @@ // Konsole #include "Character.h" +#include "KeyboardTranslator.h" namespace Konsole { @@ -223,6 +224,8 @@ public slots: */ void notifyOutputChanged(); + void handleCommandFromKeyboard(KeyboardTranslator::Command command); + signals: /** * Emitted when the contents of the associated terminal screen (see screen()) changes. @@ -239,6 +242,8 @@ signals: /** Emitted when the selection is changed. */ void selectionChanged(); + void scrollToEnd(); + private: int endWindowLine() const; void fillUnusedArea(); diff --git a/lib/TerminalDisplay.cpp b/lib/TerminalDisplay.cpp index 79fd16b..0f6b2cc 100644 --- a/lib/TerminalDisplay.cpp +++ b/lib/TerminalDisplay.cpp @@ -142,6 +142,7 @@ void TerminalDisplay::setScreenWindow(ScreenWindow* window) connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateImage()) ); connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateFilters()) ); connect( _screenWindow , SIGNAL(scrolled(int)) , this , SLOT(updateFilters()) ); + connect( _screenWindow , &ScreenWindow::scrollToEnd , this , &TerminalDisplay::scrollToEnd ); window->setWindowLines(_lines); } } @@ -2736,50 +2737,6 @@ void TerminalDisplay::keyPressEvent( QKeyEvent* event ) { bool emitKeyPressSignal = true; - // Keyboard-based navigation - if ( event->modifiers() == Qt::ShiftModifier ) - { - bool update = true; - - if ( event->key() == Qt::Key_PageUp ) - { - _screenWindow->scrollBy( ScreenWindow::ScrollPages , -1 ); - } - else if ( event->key() == Qt::Key_PageDown ) - { - _screenWindow->scrollBy( ScreenWindow::ScrollPages , 1 ); - } - else if ( event->key() == Qt::Key_Up ) - { - _screenWindow->scrollBy( ScreenWindow::ScrollLines , -1 ); - } - else if ( event->key() == Qt::Key_Down ) - { - _screenWindow->scrollBy( ScreenWindow::ScrollLines , 1 ); - } - else if ( event->key() == Qt::Key_End) - { - scrollToEnd(); - } - else if ( event->key() == Qt::Key_Home) - { - _screenWindow->scrollTo(0); - } - else - update = false; - - if ( update ) - { - _screenWindow->setTrackOutput( _screenWindow->atEndOfOutput() ); - - updateLineProperties(); - updateImage(); - - // do not send key press to terminal - emitKeyPressSignal = false; - } - } - _actSel=0; // Key stroke implies a screen update, so TerminalDisplay won't // know where the current selection is. diff --git a/lib/Vt102Emulation.cpp b/lib/Vt102Emulation.cpp index 4a84767..85febc4 100644 --- a/lib/Vt102Emulation.cpp +++ b/lib/Vt102Emulation.cpp @@ -1079,8 +1079,11 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) if ( entry.command() != KeyboardTranslator::NoCommand ) { - if (entry.command() & KeyboardTranslator::EraseCommand) + if (entry.command() & KeyboardTranslator::EraseCommand) { textToSend += eraseChar(); + } else { + Q_EMIT handleCommandFromKeyboard(entry.command()); + } // TODO command handling }