diff --git a/app/PreprocessedTerminal.qml b/app/PreprocessedTerminal.qml
index 59a96b6..8e27c17 100644
--- a/app/PreprocessedTerminal.qml
+++ b/app/PreprocessedTerminal.qml
@@ -137,37 +137,36 @@ Item{
             var lines = wheel.angleDelta.y > 0 ? -2 : 2;
             kterminal.scrollWheel(coord.width, coord.height, lines);
         }
-        onClicked: {
-            if (mouse.button == Qt.RightButton){
-                contextmenu.popup();
-            } else if (mouse.button == Qt.MiddleButton){
-                kterminal.pasteSelection();
-            }
-        }
+        //onClicked: {
+        //    if (mouse.button == Qt.RightButton){
+        //        contextmenu.popup();
+        //    } else if (mouse.button == Qt.MiddleButton){
+        //        kterminal.pasteSelection();
+        //    }
+        //}
         onDoubleClicked: {
-            if (mouse.button == Qt.LeftButton){
-                var coord = correctDistortion(mouse.x, mouse.y);
-                kterminal.mouseDoubleClick(coord.width, coord.height);
-            }
-        }
-        onPositionChanged: {
-            if (pressedButtons & Qt.LeftButton){
-                var coord = correctDistortion(mouse.x, mouse.y);
-                kterminal.mouseMove(coord.width, coord.height);
-            }
+            var coord = correctDistortion(mouse.x, mouse.y);
+            console.log("Double click");
+            kterminal.mouseDoubleClickEvent(coord, mouse.button, mouse.modifiers);
         }
+        //onPositionChanged: {
+        //    if (pressedButtons & Qt.LeftButton){
+        //        var coord = correctDistortion(mouse.x, mouse.y);
+        //        kterminal.mouseMove(coord.width, coord.height);
+        //    }
+        //}
         onPressed: {
-            if (mouse.button == Qt.LeftButton){
-                var coord = correctDistortion(mouse.x, mouse.y);
-                kterminal.mousePress(coord.width, coord.height);
-            }
+            var coord = correctDistortion(mouse.x, mouse.y);
+            kterminal.mousePressEvent(coord, mouse.button, mouse.modifiers)
         }
         onReleased: {
-            if (mouse.button == Qt.LeftButton){
-                var coord = correctDistortion(mouse.x, mouse.y);
-                kterminal.mouseRelease(coord.width, coord.height);
-            }
+            var coord = correctDistortion(mouse.x, mouse.y);
+            kterminal.mouseReleaseEvent(coord, mouse.button, mouse.modifiers);
         }
+	onPositionChanged: {
+	    var coord = correctDistortion(mouse.x, mouse.y);
+	    kterminal.mouseMoveEvent(coord, mouse.button, mouse.buttons, mouse.modifiers);
+	}
 
         //Frame displacement properties
         property real dtop: frame.item.displacementTop
@@ -185,7 +184,7 @@ Item{
             var cc = Qt.size(0.5 - x, 0.5 - y);
             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)
         }
     }
diff --git a/konsole-qml-plugin/src/TerminalDisplay.cpp b/konsole-qml-plugin/src/TerminalDisplay.cpp
index 642a1f8..1c36399 100644
--- a/konsole-qml-plugin/src/TerminalDisplay.cpp
+++ b/konsole-qml-plugin/src/TerminalDisplay.cpp
@@ -472,67 +472,513 @@ void KTerminalDisplay::scrollWheel(qreal x, qreal y, int lines){
     }
 }
 
-void KTerminalDisplay::mousePress(qreal x, qreal y){
-    if (m_focusOnClick) forcedFocus();
-    if (m_showVKBonClick) ShowVKB(true);
+void KTerminalDisplay::doPaste(QString text, bool appendReturn)
+{
+    if (!_screenWindow)
+        return;
+
+    if (appendReturn)
+        text.append("\r");
+
+//    if (text.length() > 8000) {
+//        if (KMessageBox::warningContinueCancel(window(),
+//                        i18np("Are you sure you want to paste %1 character?",
+//                              "Are you sure you want to paste %1 characters?",
+//                              text.length()),
+//                        i18n("Confirm Paste"),
+//                        KStandardGuiItem::cont(),
+//                        KStandardGuiItem::cancel(),
+//                        "ShowPasteHugeTextWarning") == KMessageBox::Cancel)
+//            return;
+//    }
+
+    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 (!contentsRect().contains(ev->pos())) return;
+
+    if (!_screenWindow) return;
 
     int charLine;
     int charColumn;
-    getCharacterPosition(QPoint(x,y), charLine, charColumn);
+    getCharacterPosition(position, charLine, charColumn);
+    QPoint pos = QPoint(charColumn, charLine);
 
-    _wordSelectionMode = false;
-    _lineSelectionMode = false;
+    if (button == Qt::LeftButton) {
+        // request the software keyboard, if any
+//        if (qApp->autoSipEnabled()) {
+//            QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
+//                        style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
+//            if (hasFocus() || behavior == QStyle::RSIP_OnMouseClick) {
+//                QEvent event(QEvent::RequestSoftwareInputPanel);
+//                QApplication::sendEvent(this, &event);
+//            }
+//        }
 
-    if(_mouseMarks){
-        emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
-    } else {
-        QPoint pos = QPoint(charColumn, charLine);
+        _lineSelectionMode = false;
+        _wordSelectionMode = false;
 
-        _screenWindow->clearSelection();
-        _iPntSel = _pntSel = pos;
-        _actSel = 1; // left mouse button pressed but nothing selected yet.
+        // The user clicked inside selected text
+        //bool selected =  _screenWindow->isSelected(pos.x(), pos.y());
+
+        // Drag only when the Control key is held
+//        if ((!_ctrlRequiredForDrag || ev->modifiers() & Qt::ControlModifier) && selected) {
+//            _dragInfo.state = diPending;
+//            _dragInfo.start = ev->pos();
+//        } else {
+            // No reason to ever start a drag event
+            //_dragInfo.state = diNone;
+
+            _preserveLineBreaks = !((modifiers & Qt::ControlModifier) && !(modifiers & Qt::AltModifier));
+            _columnSelectionMode = (modifiers & Qt::AltModifier) && (modifiers & Qt::ControlModifier);
+
+            if (_mouseMarks || (modifiers == Qt::ShiftModifier)) {
+                // Only extend selection for programs not interested in mouse
+                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);
+                //emit mouseSignal(0, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
+            }
+
+//            if (_underlineLinks && (_openLinksByDirectClick || (ev->modifiers() & Qt::ControlModifier))) {
+//                Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine, charColumn);
+//                if (spot && spot->type() == Filter::HotSpot::Link) {
+//                    QObject action;
+//                    action.setObjectName("open-action");
+//                    spot->activate(&action);
+//                }
+//            }
+
+    } else if (button == Qt::MidButton) {
+        processMidButtonClick(position, modifiers);
+    } else if (button == Qt::RightButton) {
+        if (_mouseMarks || (modifiers & Qt::ShiftModifier))
+            ;//emit configureRequest(ev->pos());
+        else
+            emit mouseSignal(2, charColumn + 1, charLine + 1, 0);
+            //emit mouseSignal(2, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
     }
 }
 
-void KTerminalDisplay::mouseMove(qreal x, qreal y){
-    QPoint pos(x, y);
+void KTerminalDisplay::mouseMoveEvent(QPoint position, int but, int buts, int mod)
+{
+    Qt::MouseButton button = (Qt::MouseButton) but;
+    Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
+    Qt::MouseButtons buttons = (Qt::MouseButtons) buts;
 
-    if(_mouseMarks){
-        int charLine;
-        int charColumn;
-        getCharacterPosition(pos, charLine, charColumn);
+    int charLine = 0;
+    int charColumn = 0;
+    getCharacterPosition(position, charLine, charColumn);
 
-        emit mouseSignal(0, charColumn + 1, charLine + 1, 1);
-    } else {
-        extendSelection(pos);
+    // handle filters
+    // change link hot-spot appearance on mouse-over
+//    Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine, charColumn);
+//    if (spot && spot->type() == Filter::HotSpot::Link) {
+//        if (_underlineLinks) {
+//            QRegion previousHotspotArea = _mouseOverHotspotArea;
+//            _mouseOverHotspotArea = QRegion();
+//            QRect r;
+//            if (spot->startLine() == spot->endLine()) {
+//                r.setCoords(spot->startColumn()*_fontWidth + _contentRect.left(),
+//                            spot->startLine()*_fontHeight + _contentRect.top(),
+//                            (spot->endColumn())*_fontWidth + _contentRect.left() - 1,
+//                            (spot->endLine() + 1)*_fontHeight + _contentRect.top() - 1);
+//                _mouseOverHotspotArea |= r;
+//            } else {
+//                r.setCoords(spot->startColumn()*_fontWidth + _contentRect.left(),
+//                            spot->startLine()*_fontHeight + _contentRect.top(),
+//                            (_columns)*_fontWidth + _contentRect.left() - 1,
+//                            (spot->startLine() + 1)*_fontHeight + _contentRect.top() - 1);
+//                _mouseOverHotspotArea |= r;
+//                for (int line = spot->startLine() + 1 ; line < spot->endLine() ; line++) {
+//                    r.setCoords(0 * _fontWidth + _contentRect.left(),
+//                                line * _fontHeight + _contentRect.top(),
+//                                (_columns)*_fontWidth + _contentRect.left() - 1,
+//                                (line + 1)*_fontHeight + _contentRect.top() - 1);
+//                    _mouseOverHotspotArea |= r;
+//                }
+//                r.setCoords(0 * _fontWidth + _contentRect.left(),
+//                            spot->endLine()*_fontHeight + _contentRect.top(),
+//                            (spot->endColumn())*_fontWidth + _contentRect.left() - 1,
+//                            (spot->endLine() + 1)*_fontHeight + _contentRect.top() - 1);
+//                _mouseOverHotspotArea |= r;
+//            }
+
+//            if ((_openLinksByDirectClick || (ev->modifiers() & Qt::ControlModifier)) && (cursor().shape() != Qt::PointingHandCursor))
+//                setCursor(Qt::PointingHandCursor);
+
+//            update(_mouseOverHotspotArea | previousHotspotArea);
+//        }
+//    } else if (!_mouseOverHotspotArea.isEmpty()) {
+//        if ((_underlineLinks && (_openLinksByDirectClick || (ev->modifiers() & Qt::ControlModifier))) || (cursor().shape() == Qt::PointingHandCursor))
+//            setCursor(_mouseMarks ? Qt::IBeamCursor : Qt::ArrowCursor);
+
+//        update(_mouseOverHotspotArea);
+//        // set hotspot area to an invalid rectangle
+//        _mouseOverHotspotArea = QRegion();
+//    }
+
+    // for auto-hiding the cursor, we need mouseTracking
+    if (buttons == Qt::NoButton) return;
+
+    // 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);
+//        emit mouseSignal(button,
+//                         charColumn + 1,
+//                         charLine + 1 + _scrollBar->value() - _scrollBar->maximum(),
+//                         1);
+
+        return;
     }
+
+//    if (_dragInfo.state == diPending) {
+//        // we had a mouse down, but haven't confirmed a drag yet
+//        // if the mouse has moved sufficiently, we will confirm
+
+//        const int distance = KGlobalSettings::dndEventDelay();
+//        if (ev->x() > _dragInfo.start.x() + distance || ev->x() < _dragInfo.start.x() - distance ||
+//                ev->y() > _dragInfo.start.y() + distance || ev->y() < _dragInfo.start.y() - distance) {
+//            // we've left the drag square, we can start a real drag operation now
+
+//            _screenWindow->clearSelection();
+//            doDrag();
+//        }
+//        return;
+//    } else if (_dragInfo.state == diDragging) {
+//        // this isn't technically needed because mouseMoveEvent is suppressed during
+//        // Qt drag operations, replaced by dragMoveEvent
+//        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){
-        int charLine;
-        int charColumn;
-        getCharacterPosition(pos, charLine, charColumn);
+QPoint KTerminalDisplay::findWordEnd(const QPoint &pnt)
+{
+    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;
+    const int maxY = _screenWindow->lineCount() - 1;
+    const int maxX = _columns - 1;
 
-        emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
-        //emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
-    } else {
-        _wordSelectionMode = true;
-        extendSelection(pos);
+    while (true) {
+        const int lineCount = lineProperties.count();
+        for (;;j++, x++) {
+            if (x < maxX) {
+                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){
-    _actSel = 0;
+QPoint KTerminalDisplay::findWordStart(const QPoint &pnt)
+{
+    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){
-        int charLine;
-        int charColumn;
-        getCharacterPosition(QPoint(x,y), charLine, charColumn);
+    while (true) {
+        for (;;j--, x--) {
+            if (x > 0) {
+                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;
+
+    // Yes, successive middle click can trigger this event
+    if (button == Qt::MidButton) {
+        processMidButtonClick(position, modifiers);
+        return;
+    }
+
+    if (button != Qt::LeftButton) return;
+    if (!_screenWindow) return;
+
+    int charLine = 0;
+    int charColumn = 0;
+
+    getCharacterPosition(position, charLine, charColumn);
+
+    // pass on double click as two clicks.
+    if (!_mouseMarks && !(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,
+                         0);
+        /*emit mouseSignal(0, charColumn + 1,
+                         charLine + 1 + _scrollBar->value() - _scrollBar->maximum(),
+                         0); */ // left button
+        return;
+    }
+
+    _screenWindow->clearSelection();
+
+    _wordSelectionMode = true;
+    _actSel = 2; // within selection
+
+    _iPntSel = QPoint(charColumn, charLine);
+    const QPoint bgnSel = findWordStart(_iPntSel);
+    const QPoint endSel = findWordEnd(_iPntSel);
+    //_iPntSel.ry() += _scrollBar->value();
+
+    _screenWindow->setSelectionStart(bgnSel.x() , bgnSel.y() , false);
+    _screenWindow->setSelectionEnd(endSel.x() , endSel.y());
+    copyToX11Selection();
+
+//    _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);
+
+//    if (_autoCopySelectedText)
+//        QApplication::clipboard()->setText(text, QClipboard::Clipboard);
+}
+
+
+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 (_dragInfo.state == diPending) {
+            // We had a drag event pending but never confirmed.  Kill selection
+//            _screenWindow->clearSelection();
+//        } else {
+            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);
+//                emit mouseSignal(0,
+//                                 charColumn + 1,
+//                                 charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 2);
+//        }
+//        _dragInfo.state = diNone;
+    }
+
+    if (!_mouseMarks &&
+            (button == Qt::RightButton || button == Qt::MidButton) &&
+            !(modifiers & Qt::ShiftModifier)) {
+        emit mouseSignal(button == Qt::MidButton ? 1 : 2,
+                         charColumn + 1,
+                         charLine + 1,
+                         2);
+//        emit mouseSignal(ev->button() == Qt::MidButton ? 1 : 2,
+//                         charColumn + 1,
+//                         charLine + 1 + _scrollBar->value() - _scrollBar->maximum() ,
+//                         2);
     }
 }
 
@@ -1361,16 +1807,33 @@ void KTerminalDisplay::updateLineProperties()
     _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 ) )
-        return 'a';
+        if (qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive))
+            return 'a';
 
-    return qch;
+        return qch;
+    }
 }
 
+
 void KTerminalDisplay::setWordCharacters(const QString& wc)
 {
     _wordCharacters = wc;
diff --git a/konsole-qml-plugin/src/TerminalDisplay.h b/konsole-qml-plugin/src/TerminalDisplay.h
index 693fb85..d7b41d6 100644
--- a/konsole-qml-plugin/src/TerminalDisplay.h
+++ b/konsole-qml-plugin/src/TerminalDisplay.h
@@ -312,10 +312,6 @@ public slots:
     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);
 
@@ -477,7 +473,10 @@ protected:
     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
     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);
     //void mouseReleaseEvent( QMouseEvent* );
     //void mouseMoveEvent( QMouseEvent* );
 
@@ -497,7 +496,7 @@ protected:
     //     - A space (returns ' ')
     //     - Part of a word (returns 'a')
     //     - Other characters (returns the input character)
-    QChar charClass(QChar ch) const;
+    QChar charClass(const Character& ch) const;
 
     void clearImage();
 
@@ -594,6 +593,14 @@ private:
     // redraws the cursor
     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);
     /////////////////////////////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////////////////////////