diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index ffa8862aab455f3de5a0a6003aefce944989a6c9..8176f838026182241995be4a3e8893fb226b0ac3 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -648,6 +648,9 @@ void BaseTextEditor::slotSelectionChanged()
         d->m_blockSelectionExtraX = 0;
     if (!d->m_selectBlockAnchor.isNull() && !textCursor().hasSelection())
         d->m_selectBlockAnchor = QTextCursor();
+
+    // Clear any link which might be showing when the selection changes
+    clearLink();
 }
 
 void BaseTextEditor::gotoBlockStart()
@@ -1470,7 +1473,7 @@ BaseTextEditorPrivate::BaseTextEditorPrivate()
     m_requestMarkEnabled(true),
     m_lineSeparatorsAllowed(false),
     m_visibleWrapColumn(0),
-    m_showingLink(false),
+    m_linkPressed(false),
     m_editable(0),
     m_actionHack(0),
     m_inBlockSelectionMode(false),
@@ -2864,35 +2867,11 @@ void BaseTextEditorPrivate::clearVisibleCollapsedBlock()
     }
 }
 
-
 void BaseTextEditor::mouseMoveEvent(QMouseEvent *e)
 {
     d->m_lastEventWasBlockSelectionEvent = (e->modifiers() & Qt::AltModifier);
 
-    bool linkFound = false;
-
-    if (d->m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier) {
-        // Link emulation behaviour for 'go to definition'
-        const QTextCursor cursor = cursorForPosition(e->pos());
-
-        // Check that the mouse was actually on the text somewhere
-        bool onText = cursorRect(cursor).right() >= e->x();
-        if (!onText) {
-            QTextCursor nextPos = cursor;
-            nextPos.movePosition(QTextCursor::Right);
-            onText = cursorRect(nextPos).right() >= e->x();
-        }
-
-        const Link link = findLinkAt(cursor, false);
-
-        if (onText && link.isValid()) {
-            showLink(link);
-            linkFound = true;
-        }
-    }
-
-    if (!linkFound)
-        clearLink();
+    updateLink(e);
 
     if (e->buttons() == Qt::NoButton) {
         const QTextBlock collapsedBlock = collapsedBlockAt(e->pos());
@@ -2936,16 +2915,23 @@ void BaseTextEditor::mousePressEvent(QMouseEvent *e)
             toggleBlockVisible(collapsedBlock);
             viewport()->setCursor(Qt::IBeamCursor);
         }
+
+        updateLink(e);
+
+        if (d->m_currentLink.isValid())
+            d->m_linkPressed = true;
     }
     QPlainTextEdit::mousePressEvent(e);
 }
 
 void BaseTextEditor::mouseReleaseEvent(QMouseEvent *e)
 {
-    if (d->m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier
+    if (d->m_mouseNavigationEnabled
+        && d->m_linkPressed
+        && e->modifiers() & Qt::ControlModifier
         && !(e->modifiers() & Qt::ShiftModifier)
-        && e->button() == Qt::LeftButton) {
-
+        && e->button() == Qt::LeftButton
+        ) {
         const QTextCursor cursor = cursorForPosition(e->pos());
         if (openLink(findLinkAt(cursor))) {
             clearLink();
@@ -3461,8 +3447,39 @@ bool BaseTextEditor::openLink(const Link &link)
     return openEditorAt(link.fileName, link.line, link.column);
 }
 
+void BaseTextEditor::updateLink(QMouseEvent *e)
+{
+    bool linkFound = false;
+
+    if (d->m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier) {
+        // Link emulation behaviour for 'go to definition'
+        const QTextCursor cursor = cursorForPosition(e->pos());
+
+        // Check that the mouse was actually on the text somewhere
+        bool onText = cursorRect(cursor).right() >= e->x();
+        if (!onText) {
+            QTextCursor nextPos = cursor;
+            nextPos.movePosition(QTextCursor::Right);
+            onText = cursorRect(nextPos).right() >= e->x();
+        }
+
+        const Link link = findLinkAt(cursor, false);
+
+        if (onText && link.isValid()) {
+            showLink(link);
+            linkFound = true;
+        }
+    }
+
+    if (!linkFound)
+        clearLink();
+}
+
 void BaseTextEditor::showLink(const Link &link)
 {
+    if (d->m_currentLink == link)
+        return;
+
     QTextEdit::ExtraSelection sel;
     sel.cursor = textCursor();
     sel.cursor.setPosition(link.pos);
@@ -3471,25 +3488,26 @@ void BaseTextEditor::showLink(const Link &link)
     sel.format.setFontUnderline(true);
     setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel);
     viewport()->setCursor(Qt::PointingHandCursor);
-    d->m_showingLink = true;
+    d->m_currentLink = link;
+    d->m_linkPressed = false;
 }
 
 void BaseTextEditor::clearLink()
 {
-    if (!d->m_showingLink)
+    if (!d->m_currentLink.isValid())
         return;
 
     setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
     viewport()->setCursor(Qt::IBeamCursor);
-    d->m_showingLink = false;
+    d->m_currentLink = Link();
+    d->m_linkPressed = false;
 }
 
 void BaseTextEditorPrivate::updateMarksBlock(const QTextBlock &block)
 {
     if (const TextBlockUserData *userData = TextEditDocumentLayout::testUserData(block))
-       foreach (ITextMark *mrk, userData->marks()) {
+        foreach (ITextMark *mrk, userData->marks())
             mrk->updateBlock(block);
-        }
 }
 
 void BaseTextEditorPrivate::updateMarksLineNumber()
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index 69b74fad1e0214c7add6c19cb1775cb590af1023..fbd1e977e720a08a75124a57875d1055b236c818 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -538,6 +538,9 @@ protected:
         bool isValid() const
         { return !(pos == -1 || length == -1); }
 
+        bool operator==(const Link &other) const
+        { return pos == other.pos && length == other.length; }
+
         int pos;           // Link position
         int length;        // Link length
 
@@ -593,6 +596,7 @@ private:
 
     QTextBlock collapsedBlockAt(const QPoint &pos, QRect *box = 0) const;
 
+    void updateLink(QMouseEvent *e);
     void showLink(const Link &);
     void clearLink();
 
diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h
index 0ef9a1272c2dd633eb4fc27a35fab9f87b799b5c..a1829e70f8179999cafb2199ea4dd3499c8c1120 100644
--- a/src/plugins/texteditor/basetexteditor_p.h
+++ b/src/plugins/texteditor/basetexteditor_p.h
@@ -204,7 +204,8 @@ public:
     int m_visibleWrapColumn;
 
     QTextCharFormat m_linkFormat;
-    bool m_showingLink;
+    BaseTextEditor::Link m_currentLink;
+    bool m_linkPressed;
 
     QTextCharFormat m_ifdefedOutFormat;