1
0
mirror of https://github.com/Swordfish90/cool-retro-term.git synced 2025-02-21 20:39:00 +00:00

Merge pull request #103 from Swordfish90/improvemouse

Improved mouse behavior. Enabled mouse support for applications.
This commit is contained in:
Filippo Scognamiglio 2014-08-30 01:38:58 +02:00
commit 98b2511660
8 changed files with 1003 additions and 561 deletions

View File

@ -133,41 +133,34 @@ Item{
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
anchors.fill: parent anchors.fill: parent
onWheel:{ onWheel:{
var coord = correctDistortion(wheel.x, wheel.y); if(wheel.modifiers & Qt.ControlModifier){
var lines = wheel.angleDelta.y > 0 ? -2 : 2; wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();
kterminal.scrollWheel(coord.width, coord.height, lines); } else {
} var coord = correctDistortion(wheel.x, wheel.y);
onClicked: { var lines = wheel.angleDelta.y > 0 ? -1 : 1;
if (mouse.button == Qt.RightButton){ kterminal.scrollWheelEvent(coord, lines);
contextmenu.popup();
} else if (mouse.button == Qt.MiddleButton){
kterminal.pasteSelection();
} }
} }
onDoubleClicked: { onDoubleClicked: {
if (mouse.button == Qt.LeftButton){ var coord = correctDistortion(mouse.x, mouse.y);
var coord = correctDistortion(mouse.x, mouse.y); kterminal.mouseDoubleClickEvent(coord, mouse.button, mouse.modifiers);
kterminal.mouseDoubleClick(coord.width, coord.height);
}
}
onPositionChanged: {
if (pressedButtons & Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseMove(coord.width, coord.height);
}
} }
onPressed: { onPressed: {
if (mouse.button == Qt.LeftButton){ if((!kterminal.usesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) {
contextmenu.popup();
} else {
var coord = correctDistortion(mouse.x, mouse.y); var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mousePress(coord.width, coord.height); kterminal.mousePressEvent(coord, mouse.button, mouse.modifiers)
} }
} }
onReleased: { onReleased: {
if (mouse.button == Qt.LeftButton){ var coord = correctDistortion(mouse.x, mouse.y);
var coord = correctDistortion(mouse.x, mouse.y); kterminal.mouseReleaseEvent(coord, mouse.button, mouse.modifiers);
kterminal.mouseRelease(coord.width, coord.height);
}
} }
onPositionChanged: {
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseMoveEvent(coord, mouse.button, mouse.buttons, mouse.modifiers);
}
//Frame displacement properties //Frame displacement properties
property real dtop: frame.item.displacementTop property real dtop: frame.item.displacementTop
@ -185,7 +178,7 @@ Item{
var cc = Qt.size(0.5 - x, 0.5 - y); var cc = Qt.size(0.5 - x, 0.5 - y);
var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion; var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion;
return Qt.size((x - cc.width * (1+distortion) * distortion) * width, return Qt.point((x - cc.width * (1+distortion) * distortion) * width,
(y - cc.height * (1+distortion) * distortion) * height) (y - cc.height * (1+distortion) * distortion) * height)
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
This file is part of Konsole, KDE's terminal. This file is part of Konsole, KDE's terminal.
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com> Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de> Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
@ -53,7 +53,7 @@ static const int LINE_DOUBLEHEIGHT = (1 << 2);
class Character class Character
{ {
public: public:
/** /**
* Constructs a new character. * Constructs a new character.
* *
* @param _c The unicode character value of this character. * @param _c The unicode character value of this character.
@ -71,25 +71,25 @@ public:
{ {
/** The unicode character value for this character. */ /** The unicode character value for this character. */
quint16 character; quint16 character;
/** /**
* Experimental addition which allows a single Character instance to contain more than * Experimental addition which allows a single Character instance to contain more than
* one unicode character. * one unicode character.
* *
* charSequence is a hash code which can be used to look up the unicode * charSequence is a hash code which can be used to look up the unicode
* character sequence in the ExtendedCharTable used to create the sequence. * character sequence in the ExtendedCharTable used to create the sequence.
*/ */
quint16 charSequence; quint16 charSequence;
}; };
/** A combination of RENDITION flags which specify options for drawing the character. */ /** A combination of RENDITION flags which specify options for drawing the character. */
quint8 rendition; quint8 rendition;
/** The foreground color used to draw this character. */ /** The foreground color used to draw this character. */
CharacterColor foregroundColor; CharacterColor foregroundColor;
/** The color used to draw this character's background. */ /** The color used to draw this character's background. */
CharacterColor backgroundColor; CharacterColor backgroundColor;
/** /**
* Returns true if this character has a transparent background when * Returns true if this character has a transparent background when
* it is drawn with the specified @p palette. * it is drawn with the specified @p palette.
*/ */
@ -97,16 +97,16 @@ public:
/** /**
* Returns true if this character should always be drawn in bold when * Returns true if this character should always be drawn in bold when
* it is drawn with the specified @p palette, independent of whether * it is drawn with the specified @p palette, independent of whether
* or not the character has the RE_BOLD rendition flag. * or not the character has the RE_BOLD rendition flag.
*/ */
ColorEntry::FontWeight fontWeight(const ColorEntry* base) const; ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
/** /**
* returns true if the format (color, rendition flag) of the compared characters is equal * returns true if the format (color, rendition flag) of the compared characters is equal
*/ */
bool equalsFormat(const Character &other) const; bool equalsFormat(const Character &other) const;
/** /**
* Compares two characters and returns true if they have the same unicode character value, * Compares two characters and returns true if they have the same unicode character value,
* rendition and colors. * rendition and colors.
*/ */
@ -119,36 +119,36 @@ public:
}; };
inline bool operator == (const Character& a, const Character& b) inline bool operator == (const Character& a, const Character& b)
{ {
return a.character == b.character && return a.character == b.character &&
a.rendition == b.rendition && a.rendition == b.rendition &&
a.foregroundColor == b.foregroundColor && a.foregroundColor == b.foregroundColor &&
a.backgroundColor == b.backgroundColor; a.backgroundColor == b.backgroundColor;
} }
inline bool operator != (const Character& a, const Character& b) inline bool operator != (const Character& a, const Character& b)
{ {
return a.character != b.character || return a.character != b.character ||
a.rendition != b.rendition || a.rendition != b.rendition ||
a.foregroundColor != b.foregroundColor || a.foregroundColor != b.foregroundColor ||
a.backgroundColor != b.backgroundColor; a.backgroundColor != b.backgroundColor;
} }
inline bool Character::isTransparent(const ColorEntry* base) const inline bool Character::isTransparent(const ColorEntry* base) const
{ {
return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent) base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
|| ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent); base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
} }
inline bool Character::equalsFormat(const Character& other) const inline bool Character::equalsFormat(const Character& other) const
{ {
return return
backgroundColor==other.backgroundColor && backgroundColor==other.backgroundColor &&
foregroundColor==other.foregroundColor && foregroundColor==other.foregroundColor &&
rendition==other.rendition; rendition==other.rendition;
} }
inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
{ {
@ -193,7 +193,7 @@ public:
* which was added to the table using createExtendedChar(). * which was added to the table using createExtendedChar().
* *
* @param hash The hash key returned by createExtendedChar() * @param hash The hash key returned by createExtendedChar()
* @param length This variable is set to the length of the * @param length This variable is set to the length of the
* character sequence. * character sequence.
* *
* @return A unicode character sequence of size @p length. * @return A unicode character sequence of size @p length.
@ -205,7 +205,7 @@ public:
private: private:
// calculates the hash key of a sequence of unicode points of size 'length' // calculates the hash key of a sequence of unicode points of size 'length'
ushort extendedCharHash(ushort* unicodePoints , ushort length) const; ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
// tests whether the entry in the table specified by 'hash' matches the // tests whether the entry in the table specified by 'hash' matches the
// character sequence 'unicodePoints' of size 'length' // character sequence 'unicodePoints' of size 'length'
bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const; bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
// internal, maps hash keys to character sequence buffers. The first ushort // internal, maps hash keys to character sequence buffers. The first ushort

View File

@ -376,6 +376,12 @@ signals:
*/ */
void imageSizeChanged(int lineCount , int columnCount); void imageSizeChanged(int lineCount , int columnCount);
/**
* Emitted after receiving the escape sequence which asks to change
* the terminal emulator's size
*/
void imageResizeRequest(const QSize& sizz);
/** /**
* Emitted when the terminal program requests to change various properties * Emitted when the terminal program requests to change various properties
* of the terminal display. * of the terminal display.

View File

@ -48,9 +48,10 @@
#include "ShellCommand.h" // REUSE THIS #include "ShellCommand.h" // REUSE THIS
#include "Vt102Emulation.h" // REUSE THIS #include "Vt102Emulation.h" // REUSE THIS
int Session::lastSessionId = 0; int Session::lastSessionId = 0;
using namespace Konsole;
Session::Session() : Session::Session() :
_shellProcess(0) _shellProcess(0)
, _emulation(0) , _emulation(0)
@ -199,14 +200,9 @@ void Session::addView(KTerminalDisplay * widget)
// allow emulation to notify view when the foreground process // allow emulation to notify view when the foreground process
// indicates whether or not it is interested in mouse signals // indicates whether or not it is interested in mouse signals
connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
// TODO Disabled since at the moment it is not working properly. SLOT(setUsesMouse(bool)) );
// Remember to reenable that once it' is's working. widget->setUsesMouse( _emulation->programUsesMouse() );
//connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
// SLOT(setUsesMouse(bool)) );
//widget->setUsesMouse( _emulation->programUsesMouse() );
widget->setScreenWindow(_emulation->createWindow()); widget->setScreenWindow(_emulation->createWindow());
} }

View File

@ -447,92 +447,377 @@ QStringList KTerminalDisplay::availableColorSchemes()
return ret; return ret;
} }
void KTerminalDisplay::scrollWheel(qreal x, qreal y, int lines){ void KTerminalDisplay::scrollWheelEvent(QPoint position, int lines){
if(_mouseMarks){ if(_mouseMarks){
int charLine;
int charColumn;
getCharacterPosition(QPoint(x,y) , charLine , charColumn);
emit mouseSignal(lines > 0 ? 5 : 4,
charColumn + 1,
charLine + 1,
0);
} else {
if(_screenWindow->lineCount() == _screenWindow->windowLines()){ if(_screenWindow->lineCount() == _screenWindow->windowLines()){
const int keyCode = lines > 0 ? Qt::Key_Down : Qt::Key_Up; const int keyCode = lines > 0 ? Qt::Key_Down : Qt::Key_Up;
QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier); QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier);
emit keyPressedSignal(&keyEvent); emit keyPressedSignal(&keyEvent);
emit keyPressedSignal(&keyEvent);
} else { } else {
_screenWindow->scrollBy( ScreenWindow::ScrollLines, lines ); _screenWindow->scrollBy( ScreenWindow::ScrollLines, lines );
_screenWindow->scrollCount(); _screenWindow->scrollCount();
updateImage(); updateImage();
} }
} else {
int charLine;
int charColumn;
getCharacterPosition(position, charLine, charColumn);
emit mouseSignal(lines > 0 ? 5 : 4,
charColumn + 1,
charLine + 1,
0);
} }
} }
void KTerminalDisplay::mousePress(qreal x, qreal y){ void KTerminalDisplay::doPaste(QString text, bool appendReturn)
if (m_focusOnClick) forcedFocus(); {
if (m_showVKBonClick) ShowVKB(true); if (!_screenWindow)
return;
if (appendReturn)
text.append("\r");
if (!text.isEmpty()) {
text.replace('\n', '\r');
// if (bracketedPasteMode()) {
// text.prepend("\e[200~");
// text.append("\e[201~");
// }
// perform paste by simulating keypress events
QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text);
emit keyPressedSignal(&e);
}
}
void KTerminalDisplay::pasteFromClipboard(bool appendEnter)
{
QString text = QGuiApplication::clipboard()->text(QClipboard::Clipboard);
doPaste(text, appendEnter);
}
void KTerminalDisplay::pasteFromX11Selection(bool appendEnter)
{
QString text = QGuiApplication::clipboard()->text(QClipboard::Selection);
doPaste(text, appendEnter);
}
void KTerminalDisplay::processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers)
{
if (_mouseMarks || (modifiers & Qt::ShiftModifier)) {
const bool appendEnter = modifiers & Qt::ControlModifier;
if (true /*_middleClickPasteMode == Enum::PasteFromX11Selection*/) {
pasteFromX11Selection(appendEnter);
} else if (false /*_middleClickPasteMode == Enum::PasteFromClipboard*/) {
pasteFromClipboard(appendEnter);
} else {
Q_ASSERT(false);
}
} else {
int charLine = 0;
int charColumn = 0;
getCharacterPosition(position, charLine, charColumn);
emit mouseSignal(1, charColumn + 1, charLine + 1, 0);
//emit mouseSignal(1, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
}
}
void KTerminalDisplay::mousePressEvent(QPoint position, int but, int mod)
{
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
// if (_possibleTripleClick && (ev->button() == Qt::LeftButton)) {
// mouseTripleClickEvent(ev);
// return;
// }
if (!_screenWindow) return;
int charLine; int charLine;
int charColumn; int charColumn;
getCharacterPosition(QPoint(x,y), charLine, charColumn); getCharacterPosition(position, charLine, charColumn);
QPoint pos = QPoint(charColumn, charLine);
_wordSelectionMode = false; if (button == Qt::LeftButton) {
_lineSelectionMode = false; _lineSelectionMode = false;
_wordSelectionMode = false;
if(_mouseMarks){ _preserveLineBreaks = !((modifiers & Qt::ControlModifier) && !(modifiers & Qt::AltModifier));
emit mouseSignal(0, charColumn + 1, charLine + 1, 0); _columnSelectionMode = (modifiers & Qt::AltModifier) && (modifiers & Qt::ControlModifier);
} else {
QPoint pos = QPoint(charColumn, charLine);
_screenWindow->clearSelection(); if (_mouseMarks || (modifiers == Qt::ShiftModifier)) {
_iPntSel = _pntSel = pos; // Only extend selection for programs not interested in mouse
_actSel = 1; // left mouse button pressed but nothing selected yet. if (_mouseMarks && (modifiers == Qt::ShiftModifier)) {
extendSelection(position);
} else {
_screenWindow->clearSelection();
//pos.ry() += _scrollBar->value();
_iPntSel = _pntSel = pos;
_actSel = 1; // left mouse button pressed but nothing selected yet.
}
} else {
emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
}
} else if (button == Qt::MidButton) {
processMidButtonClick(position, modifiers);
} else if (button == Qt::RightButton) {
if (!_mouseMarks)
emit mouseSignal(2, charColumn + 1, charLine + 1, 0);
} }
} }
void KTerminalDisplay::mouseMove(qreal x, qreal y){ void KTerminalDisplay::mouseMoveEvent(QPoint position, int but, int buts, int mod)
QPoint pos(x, y); {
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
Qt::MouseButtons buttons = (Qt::MouseButtons) buts;
if(_mouseMarks){ int charLine = 0;
int charLine; int charColumn = 0;
int charColumn; getCharacterPosition(position, charLine, charColumn);
getCharacterPosition(pos, charLine, charColumn);
emit mouseSignal(0, charColumn + 1, charLine + 1, 1); // for auto-hiding the cursor, we need mouseTracking
} else { if (buttons == Qt::NoButton) return;
extendSelection(pos);
// if the terminal is interested in mouse movements
// then emit a mouse movement signal, unless the shift
// key is being held down, which overrides this.
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier)) {
int button = 3;
if (buttons & Qt::LeftButton)
button = 0;
if (buttons & Qt::MidButton)
button = 1;
if (buttons & Qt::RightButton)
button = 2;
emit mouseSignal(button, charColumn + 1, charLine + 1, 1);
return;
} }
if (_actSel == 0) return;
// don't extend selection while pasting
if (buttons & Qt::MidButton) return;
extendSelection(position);
} }
void KTerminalDisplay::mouseDoubleClick(qreal x, qreal y){
QPoint pos(x, y);
if(_mouseMarks){ QPoint KTerminalDisplay::findWordEnd(const QPoint &pnt)
int charLine; {
int charColumn; const int regSize = qMax(_screenWindow->windowLines(), 10);
getCharacterPosition(pos, charLine, charColumn); const int curLine = _screenWindow->currentLine();
int i = pnt.y();
int x = pnt.x();
int y = i + curLine;
int j = loc(x, i);
QVector<LineProperty> lineProperties = _lineProperties;
Screen *screen = _screenWindow->screen();
Character *image = _image;
Character *tmp_image = NULL;
const QChar selClass = charClass(image[j]);
const int imageSize = regSize * _columns;
const int maxY = _screenWindow->lineCount() - 1;
const int maxX = _columns - 1;
emit mouseSignal(0, charColumn + 1, charLine + 1, 0); while (true) {
//emit mouseSignal(0, charColumn + 1, charLine + 1, 0); const int lineCount = lineProperties.count();
} else { for (;;j++, x++) {
_wordSelectionMode = true; if (x < maxX) {
extendSelection(pos); if (charClass(image[j + 1]) == selClass)
continue;
goto out;
} else if (i < lineCount - 1) {
if (lineProperties[i] & LINE_WRAPPED &&
charClass(image[j + 1]) == selClass) {
x = -1;
i++;
y++;
continue;
}
goto out;
} else if (y < maxY) {
if (i < lineCount && !(lineProperties[i] & LINE_WRAPPED))
goto out;
break;
} else {
goto out;
}
}
int newRegEnd = qMin(y + regSize - 1, maxY);
lineProperties = screen->getLineProperties(y, newRegEnd);
i = 0;
if (!tmp_image) {
tmp_image = new Character[imageSize];
image = tmp_image;
}
screen->getImage(tmp_image, imageSize, y, newRegEnd);
x--;
j = loc(x, i);
} }
out:
y -= curLine;
// In word selection mode don't select @ (64) if at end of word.
if (((image[j].rendition & RE_EXTENDED_CHAR) == 0) &&
(QChar(image[j].character) == '@') &&
(y > pnt.y() || x > pnt.x())) {
if (x > 0) {
x--;
} else {
y--;
}
}
if (tmp_image) {
delete[] tmp_image;
}
return QPoint(x, y);
} }
void KTerminalDisplay::mouseRelease(qreal x, qreal y){ QPoint KTerminalDisplay::findWordStart(const QPoint &pnt)
_actSel = 0; {
const int regSize = qMax(_screenWindow->windowLines(), 10);
const int curLine = _screenWindow->currentLine();
int i = pnt.y();
int x = pnt.x();
int y = i + curLine;
int j = loc(x, i);
QVector<LineProperty> lineProperties = _lineProperties;
Screen *screen = _screenWindow->screen();
Character *image = _image;
Character *tmp_image = NULL;
const QChar selClass = charClass(image[j]);
const int imageSize = regSize * _columns;
if(_mouseMarks){ while (true) {
int charLine; for (;;j--, x--) {
int charColumn; if (x > 0) {
getCharacterPosition(QPoint(x,y), charLine, charColumn); if (charClass(image[j - 1]) == selClass)
continue;
goto out;
} else if (i > 0) {
if (lineProperties[i - 1] & LINE_WRAPPED &&
charClass(image[j - 1]) == selClass) {
x = _columns;
i--;
y--;
continue;
}
goto out;
} else if (y > 0) {
break;
} else {
goto out;
}
}
int newRegStart = qMax(0, y - regSize);
lineProperties = screen->getLineProperties(newRegStart, y - 1);
i = y - newRegStart;
if (!tmp_image) {
tmp_image = new Character[imageSize];
image = tmp_image;
}
screen->getImage(tmp_image, imageSize, newRegStart, y - 1);
j = loc(x, i);
}
out:
if (tmp_image) {
delete[] tmp_image;
}
return QPoint(x, y - curLine);
}
emit mouseSignal(0, charColumn + 1, charLine + 1, 2);
void KTerminalDisplay::mouseDoubleClickEvent(QPoint position, int but, int mod)
{
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
if (button != Qt::LeftButton) return;
if (!_screenWindow) return;
int charLine = 0;
int charColumn = 0;
getCharacterPosition(position, charLine, charColumn);
// If the application is interested in mouse events. They have already been forwarded.
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier))
return;
_screenWindow->clearSelection();
_wordSelectionMode = true;
_actSel = 2; // within selection
_iPntSel = QPoint(charColumn, charLine);
const QPoint bgnSel = findWordStart(_iPntSel);
const QPoint endSel = findWordEnd(_iPntSel);
_screenWindow->setSelectionStart(bgnSel.x() , bgnSel.y() , false);
_screenWindow->setSelectionEnd(endSel.x() , endSel.y());
copyToX11Selection();
//TODO implement triple click.
// _possibleTripleClick = true;
// QTimer::singleShot(QApplication::doubleClickInterval(), this,
// SLOT(tripleClickTimeout()));
}
void KTerminalDisplay::copyToX11Selection()
{
if (!_screenWindow)
return;
QString text = _screenWindow->selectedText(_preserveLineBreaks);
if (text.isEmpty())
return;
QGuiApplication::clipboard()->setText(text, QClipboard::Selection);
}
void KTerminalDisplay::mouseReleaseEvent(QPoint position, int but, int mod)
{
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
if (!_screenWindow)
return;
int charLine;
int charColumn;
getCharacterPosition(position, charLine, charColumn);
if (button == Qt::LeftButton) {
if (_actSel > 1) {
copyToX11Selection();
}
_actSel = 0;
//FIXME: emits a release event even if the mouse is
// outside the range. The procedure used in `mouseMoveEvent'
// applies here, too.
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier))
emit mouseSignal(0, charColumn + 1, charLine + 1 , 2);
}
if (!_mouseMarks &&
(button == Qt::RightButton || button == Qt::MidButton) &&
!(modifiers & Qt::ShiftModifier)) {
emit mouseSignal(button == Qt::MidButton ? 1 : 2, charColumn + 1, charLine + 1, 2);
} }
} }
@ -546,7 +831,12 @@ void KTerminalDisplay::scrollScreenWindow(enum ScreenWindow::RelativeScrollMode
void KTerminalDisplay::setUsesMouse(bool usesMouse){ void KTerminalDisplay::setUsesMouse(bool usesMouse){
_mouseMarks = !usesMouse; _mouseMarks = usesMouse;
emit usesMouseChanged();
}
bool KTerminalDisplay::getUsesMouse(){
return !_mouseMarks;
} }
void KTerminalDisplay::setAutoFocus(bool au) void KTerminalDisplay::setAutoFocus(bool au)
@ -1361,16 +1651,33 @@ void KTerminalDisplay::updateLineProperties()
_lineProperties = _screenWindow->getLineProperties(); _lineProperties = _screenWindow->getLineProperties();
} }
QChar KTerminalDisplay::charClass(QChar qch) const QChar KTerminalDisplay::charClass(const Character& ch) const
{ {
if ( qch.isSpace() ) return ' '; if (ch.rendition & RE_EXTENDED_CHAR) {
ushort extendedCharLength = 0;
const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(ch.character, extendedCharLength);
if (chars && extendedCharLength > 0) {
const QString s = QString::fromUtf16(chars, extendedCharLength);
if (_wordCharacters.contains(s, Qt::CaseInsensitive))
return 'a';
bool allLetterOrNumber = true;
for (int i = 0; allLetterOrNumber && i < s.size(); ++i)
allLetterOrNumber = s.at(i).isLetterOrNumber();
return allLetterOrNumber ? 'a' : s.at(0);
}
return 0;
} else {
const QChar qch(ch.character);
if (qch.isSpace()) return ' ';
if ( qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive ) ) if (qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive))
return 'a'; return 'a';
return qch; return qch;
}
} }
void KTerminalDisplay::setWordCharacters(const QString& wc) void KTerminalDisplay::setWordCharacters(const QString& wc)
{ {
_wordCharacters = wc; _wordCharacters = wc;

View File

@ -70,6 +70,7 @@ class KONSOLEPRIVATE_EXPORT KTerminalDisplay : public QQuickPaintedItem
Q_PROPERTY(bool ShowIMEOnClick READ autoVKB WRITE setAutoVKB NOTIFY changedAutoVKB) Q_PROPERTY(bool ShowIMEOnClick READ autoVKB WRITE setAutoVKB NOTIFY changedAutoVKB)
Q_PROPERTY(QSize terminalSize READ getTerminalSize NOTIFY terminalSizeChanged) Q_PROPERTY(QSize terminalSize READ getTerminalSize NOTIFY terminalSizeChanged)
Q_PROPERTY(QSize paintedFontSize READ getFontSize NOTIFY paintedFontSizeChanged) Q_PROPERTY(QSize paintedFontSize READ getFontSize NOTIFY paintedFontSizeChanged)
Q_PROPERTY(bool usesMouse READ getUsesMouse NOTIFY usesMouseChanged)
public: public:
@ -311,15 +312,10 @@ public slots:
void setColorScheme(const QString &name); void setColorScheme(const QString &name);
QStringList availableColorSchemes(); QStringList availableColorSchemes();
void scrollWheel(qreal x, qreal y, int lines);
void mousePress(qreal x, qreal y);
void mouseMove(qreal x, qreal y);
void mouseDoubleClick(qreal x, qreal y);
void mouseRelease(qreal x, qreal y);
void scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode, int amount); void scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode, int amount);
void setUsesMouse(bool usesMouse); void setUsesMouse(bool usesMouse);
bool getUsesMouse(void);
bool autoFocus() { return m_focusOnClick; } bool autoFocus() { return m_focusOnClick; }
void setAutoFocus(bool au); void setAutoFocus(bool au);
@ -425,6 +421,8 @@ signals:
void mouseSignal(int,int,int,int); void mouseSignal(int,int,int,int);
void usesMouseChanged();
void terminalSizeChanged(); void terminalSizeChanged();
void paintedFontSizeChanged(); void paintedFontSizeChanged();
@ -477,7 +475,11 @@ protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
QRect geometryRound(const QRectF &r) const; QRect geometryRound(const QRectF &r) const;
//void mousePressEvent(QMouseEvent*ev); Q_INVOKABLE void mousePressEvent(QPoint position, int but, int mod);
Q_INVOKABLE void mouseReleaseEvent(QPoint position, int but, int mod);
Q_INVOKABLE void mouseDoubleClickEvent(QPoint position, int but, int mod);
Q_INVOKABLE void mouseMoveEvent(QPoint position, int but, int buts, int mod);
Q_INVOKABLE void scrollWheelEvent(QPoint position, int lines);
//void mouseReleaseEvent( QMouseEvent* ); //void mouseReleaseEvent( QMouseEvent* );
//void mouseMoveEvent( QMouseEvent* ); //void mouseMoveEvent( QMouseEvent* );
@ -497,7 +499,7 @@ protected:
// - A space (returns ' ') // - A space (returns ' ')
// - Part of a word (returns 'a') // - Part of a word (returns 'a')
// - Other characters (returns the input character) // - Other characters (returns the input character)
QChar charClass(QChar ch) const; QChar charClass(const Character& ch) const;
void clearImage(); void clearImage();
@ -594,6 +596,14 @@ private:
// redraws the cursor // redraws the cursor
void updateCursor(); void updateCursor();
QPoint findWordStart(const QPoint &pnt);
QPoint findWordEnd(const QPoint &pnt);
void processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers);
void copyToX11Selection();
void pasteFromClipboard(bool appendEnter);
void pasteFromX11Selection(bool appendEnter);
void doPaste(QString text, bool appendReturn);
bool handleShortcutOverrideEvent(QKeyEvent* event); bool handleShortcutOverrideEvent(QKeyEvent* event);
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
This file is part of Konsole, an X terminal. This file is part of Konsole, an X terminal.
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com> Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de> Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
@ -23,168 +23,169 @@
#ifndef VT102EMULATION_H #ifndef VT102EMULATION_H
#define VT102EMULATION_H #define VT102EMULATION_H
// Standard Library
#include <stdio.h>
// Qt // Qt
#include <QtGui/QKeyEvent>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QTimer>
// Konsole // Konsole
#include "Emulation.h" #include "Emulation.h"
#include "Screen.h" #include "Screen.h"
#include "ScreenWindow.h"
#include "TerminalDisplay.h" class QTimer;
class QKeyEvent;
#define MODE_AppScreen (MODES_SCREEN+0) // Mode #1 #define MODE_AppScreen (MODES_SCREEN+0) // Mode #1
#define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM) #define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM)
#define MODE_AppKeyPad (MODES_SCREEN+2) // #define MODE_AppKeyPad (MODES_SCREEN+2) //
#define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release #define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release
#define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking #define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking
#define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking #define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking
#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking #define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking
#define MODE_Ansi (MODES_SCREEN+7) // Use US Ascii for character sets G0-G3 (DECANM) #define MODE_Mouse1005 (MODES_SCREEN+7) // Xterm-style extended coordinates
#define MODE_132Columns (MODES_SCREEN+8) // 80 <-> 132 column mode switch (DECCOLM) #define MODE_Mouse1006 (MODES_SCREEN+8) // 2nd Xterm-style extended coordinates
#define MODE_Allow132Columns (MODES_SCREEN+9) // Allow DECCOLM mode #define MODE_Mouse1015 (MODES_SCREEN+9) // Urxvt-style extended coordinates
#define MODE_total (MODES_SCREEN+10) #define MODE_Ansi (MODES_SCREEN+10) // Use US Ascii for character sets G0-G3 (DECANM)
#define MODE_132Columns (MODES_SCREEN+11) // 80 <-> 132 column mode switch (DECCOLM)
#define MODE_Allow132Columns (MODES_SCREEN+12) // Allow DECCOLM mode
#define MODE_BracketedPaste (MODES_SCREEN+13) // Xterm-style bracketed paste mode
#define MODE_total (MODES_SCREEN+14)
namespace Konsole
struct CharCodes
{ {
// coding info extern unsigned short vt100_graphics[32];
char charset[4]; //
int cu_cs; // actual charset. struct CharCodes {
bool graphic; // Some VT100 tricks // coding info
bool pound ; // Some VT100 tricks char charset[4]; //
bool sa_graphic; // saved graphic int cu_cs; // actual charset.
bool sa_pound; // saved pound bool graphic; // Some VT100 tricks
bool pound; // Some VT100 tricks
bool sa_graphic; // saved graphic
bool sa_pound; // saved pound
}; };
/** /**
* Provides an xterm compatible terminal emulation based on the DEC VT102 terminal. * Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
* A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/ * A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/
* *
* In addition, various additional xterm escape sequences are supported to provide * In addition, various additional xterm escape sequences are supported to provide
* features such as mouse input handling. * features such as mouse input handling.
* See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape * See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape
* sequences. * sequences.
* *
*/ */
class Vt102Emulation : public Emulation class Vt102Emulation : public Emulation
{ {
Q_OBJECT Q_OBJECT
public: public:
/** Constructs a new emulation */ /** Constructs a new emulation */
Vt102Emulation(); Vt102Emulation();
~Vt102Emulation(); ~Vt102Emulation();
// reimplemented from Emulation // reimplemented from Emulation
virtual void clearEntireScreen(); virtual void clearEntireScreen();
virtual void reset(); virtual void reset();
virtual char eraseChar() const; virtual char eraseChar() const;
public slots: public slots:
// reimplemented from Emulation // reimplemented from Emulation
virtual void sendString(const char*,int length = -1); virtual void sendString(const char*, int length = -1);
virtual void sendText(const QString& text); virtual void sendText(const QString& text);
virtual void sendKeyEvent(QKeyEvent*); virtual void sendKeyEvent(QKeyEvent*);
virtual void sendMouseEvent(int buttons, int column, int line, int eventType); virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
protected: protected:
// reimplemented from Emulation // reimplemented from Emulation
virtual void setMode(int mode); virtual void setMode(int mode);
virtual void resetMode(int mode); virtual void resetMode(int mode);
virtual void receiveChar(int cc); virtual void receiveChar(int cc);
private slots: private slots:
//causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
//used to buffer multiple title updates //used to buffer multiple title updates
void updateTitle(); void updateTitle();
private: private:
unsigned short applyCharset(unsigned short c); unsigned short applyCharset(unsigned short c);
void setCharset(int n, int cs); void setCharset(int n, int cs);
void useCharset(int n); void useCharset(int n);
void setAndUseCharset(int n, int cs); void setAndUseCharset(int n, int cs);
void saveCursor(); void saveCursor();
void restoreCursor(); void restoreCursor();
void resetCharset(int scrno); void resetCharset(int scrno);
void setMargins(int top, int bottom); void setMargins(int top, int bottom);
//set margins for all screens back to their defaults //set margins for all screens back to their defaults
void setDefaultMargins(); void setDefaultMargins();
// returns true if 'mode' is set or false otherwise // returns true if 'mode' is set or false otherwise
bool getMode (int mode); bool getMode(int mode);
// saves the current boolean value of 'mode' // saves the current boolean value of 'mode'
void saveMode (int mode); void saveMode(int mode);
// restores the boolean value of 'mode' // restores the boolean value of 'mode'
void restoreMode(int mode); void restoreMode(int mode);
// resets all modes // resets all modes
// (except MODE_Allow132Columns) // (except MODE_Allow132Columns)
void resetModes(); void resetModes();
void resetTokenizer(); void resetTokenizer();
#define MAX_TOKEN_LENGTH 80 #define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title)
void addToCurrentToken(int cc); void addToCurrentToken(int cc);
int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow? int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow?
int tokenBufferPos; int tokenBufferPos;
#define MAXARGS 15 #define MAXARGS 15
void addDigit(int dig); void addDigit(int dig);
void addArgument(); void addArgument();
int argv[MAXARGS]; int argv[MAXARGS];
int argc; int argc;
void initTokenizer(); void initTokenizer();
// Set of flags for each of the ASCII characters which indicates // Set of flags for each of the ASCII characters which indicates
// what category they fall into (printable character, control, digit etc.) // what category they fall into (printable character, control, digit etc.)
// for the purposes of decoding terminal output // for the purposes of decoding terminal output
int charClass[256]; int charClass[256];
void reportDecodingError(); void reportDecodingError();
void processToken(int code, int p, int q); void processToken(int code, int p, int q);
void processWindowAttributeChange(); void processWindowAttributeChange();
void reportTerminalType(); void reportTerminalType();
void reportSecondaryAttributes(); void reportSecondaryAttributes();
void reportStatus(); void reportStatus();
void reportAnswerBack(); void reportAnswerBack();
void reportCursorPosition(); void reportCursorPosition();
void reportTerminalParms(int p); void reportTerminalParms(int p);
void onScrollLock(); // clears the screen and resizes it to the specified
void scrollLock(const bool lock); // number of columns
void clearScreenAndSetColumns(int columnCount);
// clears the screen and resizes it to the specified CharCodes _charset[2];
// number of columns
void clearScreenAndSetColumns(int columnCount);
CharCodes _charset[2]; class TerminalState
{
public:
// Initializes all modes to false
TerminalState() {
memset(&mode, false, MODE_total * sizeof(bool));
}
class TerminalState bool mode[MODE_total];
{ };
public:
// Initializes all modes to false
TerminalState()
{ memset(&mode,false,MODE_total * sizeof(bool)); }
bool mode[MODE_total]; TerminalState _currentModes;
}; TerminalState _savedModes;
TerminalState _currentModes; //hash table and timer for buffering calls to the session instance
TerminalState _savedModes; //to update the name of the session
//or window title.
//hash table and timer for buffering calls to the session instance //these calls occur when certain escape sequences are seen in the
//to update the name of the session //output from the terminal
//or window title. QHash<int, QString> _pendingTitleUpdates;
//these calls occur when certain escape sequences are seen in the QTimer* _titleUpdateTimer;
//output from the terminal
QHash<int,QString> _pendingTitleUpdates;
QTimer* _titleUpdateTimer;
}; };
}
#endif // VT102EMULATION_H #endif // VT102EMULATION_H