Properly handle mouse in read-only mode

Summary:
* Do not send mouse events and emulated up/down keys to programs when
   read-only mode is enabled.
* Set the currentTerminalDisplay before sending key events, like in
   keyPressEvent.
* wheelEvent code is restructured a bit to easily separate code not
   allowed in read-only mode.

Test Plan:
* Start Konsole
* Run `man man`, do not press any key after enter
* Turn on read only mode
* Try to scroll using mouse wheel.
* Expected result: scrolling does not work in read-only mode
* Actual result: scrolling works in read only mode (but only when no key
   has been pressed before on 2nd terminal screen)

* Start konsole
* Run a program which uses mouse events, e.g. `vim`
   (enable mouse with `:set mouse=a`)
* Make the program state suitable for using mouse events, e.g. enter a few
   lines of text
* Confirm that mouse events (clicks, selection, wheel) work in the program
* Turn on read-only mode
* Try:
  * Click (left/right/middle button), double click
  * Mouse wheel
  * Click and move (selecting)
* Expected result: mouse events are not passed to the program in read-only
   mode; nothing happens
* Actual result: mouse events are passed to the program

Reviewers: #konsole, hindenburg

Reviewed By: #konsole, hindenburg

Subscribers: hindenburg, #konsole

Tags: #konsole

Differential Revision: https://phabricator.kde.org/D11763
wilder-portage
Mariusz Glebocki 8 years ago committed by Kurt Hindenburg
parent 23af1ed449
commit 0ca1391cf5
  1. 90
      src/TerminalDisplay.cpp

@ -2174,7 +2174,9 @@ void TerminalDisplay::mousePressEvent(QMouseEvent* ev)
_actSel = 1; // left mouse button pressed but nothing selected yet.
}
} else {
emit mouseSignal(0, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
if(!_readOnly) {
emit mouseSignal(0, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
}
}
if ((_openLinksByDirectClick || ((ev->modifiers() & Qt::ControlModifier) != 0u))) {
@ -2192,7 +2194,9 @@ void TerminalDisplay::mousePressEvent(QMouseEvent* ev)
if (_mouseMarks || ((ev->modifiers() & Qt::ShiftModifier) != 0u)) {
emit configureRequest(ev->pos());
} else {
emit mouseSignal(2, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
if(!_readOnly) {
emit mouseSignal(2, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
}
}
}
}
@ -2618,11 +2622,13 @@ void TerminalDisplay::processMidButtonClick(QMouseEvent* ev)
Q_ASSERT(false);
}
} else {
int charLine = 0;
int charColumn = 0;
getCharacterPosition(ev->pos(), charLine, charColumn);
if(!_readOnly) {
int charLine = 0;
int charColumn = 0;
getCharacterPosition(ev->pos(), charLine, charColumn);
emit mouseSignal(1, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
emit mouseSignal(1, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
}
}
}
@ -2650,11 +2656,13 @@ void TerminalDisplay::mouseDoubleClickEvent(QMouseEvent* ev)
// pass on double click as two clicks.
if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier)) {
// Send just _ONE_ click event, since the first click of the double click
// was already sent by the click handler
emit mouseSignal(0, charColumn + 1,
charLine + 1 + _scrollBar->value() - _scrollBar->maximum(),
0); // left button
if(!_readOnly) {
// Send just _ONE_ click event, since the first click of the double click
// was already sent by the click handler
emit mouseSignal(0, charColumn + 1,
charLine + 1 + _scrollBar->value() - _scrollBar->maximum(),
0); // left button
}
return;
}
@ -2733,10 +2741,10 @@ void TerminalDisplay::wheelEvent(QWheelEvent* ev)
const int modifiers = ev->modifiers();
_scrollWheelState.addWheelEvent(ev);
// ctrl+<wheel> for zooming, like in konqueror and firefox
if (((modifiers & Qt::ControlModifier) != 0u) && mouseWheelZoom()) {
_scrollWheelState.addWheelEvent(ev);
int steps = _scrollWheelState.consumeLegacySteps(ScrollState::DEFAULT_ANGLE_SCROLL_LINE);
for (;steps > 0; --steps) {
// wheel-up for increasing font size
@ -2746,21 +2754,22 @@ void TerminalDisplay::wheelEvent(QWheelEvent* ev)
// wheel-down for decreasing font size
decreaseFontSize();
}
} else if (_mouseMarks && (_scrollBar->maximum() > 0)) {
// If the program running in the terminal is not interested in mouse events,
// send the event to the scrollbar if the slider has room to move
return;
}
_scrollWheelState.addWheelEvent(ev);
_scrollBar->event(ev);
_sessionController->setSearchStartToWindowCurrentLine();
_scrollWheelState.clearAll();
} else if (!_readOnly) {
_scrollWheelState.addWheelEvent(ev);
if(_mouseMarks && !_isPrimaryScreen) {
// Send simulated up / down key presses to the terminal program
// for the benefit of programs such as 'less' (which use the alternate screen)
// If the program running in the terminal is not interested in mouse events:
// - Send the event to the scrollbar if the slider has room to move
// - Otherwise, send simulated up / down key presses to the terminal program
// for the benefit of programs such as 'less' (which use the alternate screen)
if (_mouseMarks) {
const bool canScroll = _scrollBar->maximum() > 0;
if (canScroll) {
_scrollBar->event(ev);
_sessionController->setSearchStartToWindowCurrentLine();
_scrollWheelState.clearAll();
} else if (!_isPrimaryScreen) {
// assume that each Up / Down key event will cause the terminal application
// to scroll by one line.
//
@ -2773,22 +2782,23 @@ void TerminalDisplay::wheelEvent(QWheelEvent* ev)
QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier);
for (int i = 0; i < abs(lines); i++) {
_screenWindow->screen()->setCurrentTerminalDisplay(this);
emit keyPressedSignal(&keyEvent);
}
}
} else {
// terminal program wants notification of mouse activity
int charLine;
int charColumn;
getCharacterPosition(ev->pos() , charLine , charColumn);
const int steps = _scrollWheelState.consumeLegacySteps(ScrollState::DEFAULT_ANGLE_SCROLL_LINE);
const int button = (steps > 0) ? 4 : 5;
for (int i = 0; i < abs(steps); ++i) {
emit mouseSignal(button,
charColumn + 1,
charLine + 1 + _scrollBar->value() - _scrollBar->maximum() ,
0);
} else if (!_mouseMarks) {
// terminal program wants notification of mouse activity
int charLine;
int charColumn;
getCharacterPosition(ev->pos() , charLine , charColumn);
const int steps = _scrollWheelState.consumeLegacySteps(ScrollState::DEFAULT_ANGLE_SCROLL_LINE);
const int button = (steps > 0) ? 4 : 5;
for (int i = 0; i < abs(steps); ++i) {
emit mouseSignal(button,
charColumn + 1,
charLine + 1 + _scrollBar->value() - _scrollBar->maximum() ,
0);
}
}
}
}

Loading…
Cancel
Save