Kate-like touchscreen scrolling support

Adds minimalistic touchscreen scrolling support. This is an adaptation
of Daniel Tang's MR 123 that was submitted to Kate/KWrite.

BUG: 437553
wilder
Henry Heino 4 years ago committed by Tomaz Canabrava
parent 97f949eea0
commit b2ceb4684b
  1. 83
      src/terminalDisplay/TerminalDisplay.cpp
  2. 11
      src/terminalDisplay/TerminalDisplay.h

@ -27,6 +27,9 @@
#include <QMimeData> #include <QMimeData>
#include <QPainter> #include <QPainter>
#include <QPixmap> #include <QPixmap>
#include <QScrollEvent>
#include <QScrollPrepareEvent>
#include <QScroller>
#include <QStyle> #include <QStyle>
#include <QTimer> #include <QTimer>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -292,6 +295,19 @@ TerminalDisplay::TerminalDisplay(QWidget *parent)
// that TerminalDisplay will handle repainting its entire area. // that TerminalDisplay will handle repainting its entire area.
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_AcceptTouchEvents, true);
QScrollerProperties prop;
prop.setScrollMetric(QScrollerProperties::DecelerationFactor, 0.3);
prop.setScrollMetric(QScrollerProperties::MaximumVelocity, 1);
// Workaround for QTBUG-88249 (non-flick gestures recognized as accelerating flick)
prop.setScrollMetric(QScrollerProperties::AcceleratingFlickMaximumTime, 0.2);
prop.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
prop.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
prop.setScrollMetric(QScrollerProperties::DragStartDistance, 0.0);
QScroller::scroller(this)->setScrollerProperties(prop);
QScroller::scroller(this)->grabGesture(this);
// Add the stretch item once, the KMessageWidgets are inserted at index 0. // Add the stretch item once, the KMessageWidgets are inserted at index 0.
_verticalLayout->addWidget(_headerBar); _verticalLayout->addWidget(_headerBar);
_verticalLayout->addStretch(); _verticalLayout->addStretch();
@ -1220,6 +1236,11 @@ QSharedPointer<HotSpot> TerminalDisplay::filterActions(const QPoint &position)
void TerminalDisplay::mouseMoveEvent(QMouseEvent *ev) void TerminalDisplay::mouseMoveEvent(QMouseEvent *ev)
{ {
if (QScroller::scroller(this)->state() != QScroller::Inactive) {
// Touchscreen is handled by scrollEvent()
return;
}
if (!hasFocus() && KonsoleSettings::focusFollowsMouse()) { if (!hasFocus() && KonsoleSettings::focusFollowsMouse()) {
setFocus(); setFocus();
} }
@ -1910,6 +1931,16 @@ out:
return {x, y}; return {x, y};
} }
bool TerminalDisplay::isInTerminalRegion(const QPoint &point) const
{
// clang-format off
const bool inMessageSuspendedWidget = _outputSuspendedMessageWidget &&
_outputSuspendedMessageWidget->isVisible() &&
_outputSuspendedMessageWidget->frameGeometry().contains(point);
// clang-format on
return !(!visibleRegion().contains(point) || _scrollBar->frameGeometry().contains(point) || inMessageSuspendedWidget);
}
Screen::DecodingOptions TerminalDisplay::currentDecodingOptions() Screen::DecodingOptions TerminalDisplay::currentDecodingOptions()
{ {
Screen::DecodingOptions decodingOptions; Screen::DecodingOptions decodingOptions;
@ -2055,6 +2086,50 @@ bool TerminalDisplay::bracketedPasteMode() const
return _bracketedPasteMode; return _bracketedPasteMode;
} }
/* ------------------------------------------------------------------------- */
/* */
/* Touch & Scroll */
/* */
/* ------------------------------------------------------------------------- */
void TerminalDisplay::scrollPrepareEvent(QScrollPrepareEvent *event)
{
// Ignore scroller events that were triggered in regions that we
// expect to handle the input different (e.g. the find dialog)
if (!isInTerminalRegion(event->startPos().toPoint())) {
return;
}
const int lineHeight = _terminalFont->fontHeight() + _terminalFont->lineSpacing();
// clang-format off
const QRect scrollableRegion = imageToWidget(QRect(
// Allow a line of overscroll in either direction: We'll be rounding the
// values QScroller gives us and still want to be able to scroll to every line.
0, 0,
0, _screenWindow->lineCount() + 1));
// clang-format on
// Give Qt the viewport and content window size
event->setViewportSize(contentsRect().size());
event->setContentPosRange(scrollableRegion);
event->setContentPos(QPointF(0.0, _screenWindow->currentLine() * lineHeight));
event->accept();
}
void TerminalDisplay::scrollEvent(QScrollEvent *event)
{
const int lineHeight = _terminalFont->fontHeight() + _terminalFont->lineSpacing();
const int targetLine = int(event->contentPos().y() / lineHeight);
const int linesScrolled = targetLine - _screenWindow->currentLine();
if (linesScrolled != 0) {
scrollScreenWindow(ScreenWindow::RelativeScrollMode::ScrollLines, linesScrolled);
}
event->accept();
}
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* */ /* */
/* Clipboard */ /* Clipboard */
@ -2555,6 +2630,14 @@ bool TerminalDisplay::event(QEvent *event)
} }
update(); update();
break; break;
case QEvent::ScrollPrepare:
scrollPrepareEvent(static_cast<QScrollPrepareEvent *>(event));
break;
case QEvent::Scroll:
scrollEvent(static_cast<QScrollEvent *>(event));
break;
default: default:
break; break;
} }

@ -34,9 +34,12 @@ class QTimer;
class QEvent; class QEvent;
class QVBoxLayout; class QVBoxLayout;
class QKeyEvent; class QKeyEvent;
class QScroller;
class QShowEvent; class QShowEvent;
class QHideEvent; class QHideEvent;
class QTimerEvent; class QTimerEvent;
class QScrollEvent;
class QScrollPrepareEvent;
class KMessageWidget; class KMessageWidget;
namespace Konsole namespace Konsole
@ -532,6 +535,8 @@ protected:
void mouseMoveEvent(QMouseEvent *ev) override; void mouseMoveEvent(QMouseEvent *ev) override;
void wheelEvent(QWheelEvent *ev) override; void wheelEvent(QWheelEvent *ev) override;
bool focusNextPrevChild(bool next) override; bool focusNextPrevChild(bool next) override;
void scrollPrepareEvent(QScrollPrepareEvent *);
void scrollEvent(QScrollEvent *);
void extendSelection(const QPoint &position); void extendSelection(const QPoint &position);
@ -611,6 +616,12 @@ private:
QPoint findWordStart(const QPoint &pnt); QPoint findWordStart(const QPoint &pnt);
QPoint findWordEnd(const QPoint &pnt); QPoint findWordEnd(const QPoint &pnt);
/**
* @param pnt A point, relative to this.
* @return true if the given point is in the area with the main terminal content and not in some other widget.
*/
bool isInTerminalRegion(const QPoint &pnt) const;
// Uses the current settings for trimming whitespace and preserving linebreaks to create a proper flag value for Screen // Uses the current settings for trimming whitespace and preserving linebreaks to create a proper flag value for Screen
Screen::DecodingOptions currentDecodingOptions(); Screen::DecodingOptions currentDecodingOptions();

Loading…
Cancel
Save