diff --git a/components/Button.qml b/components/Button.qml
index 19dd394aaba2bd7e92cd83969e38a30f1429c235..10908b7f43098202750b3041029be427e52101a5 100644
--- a/components/Button.qml
+++ b/components/Button.qml
@@ -45,7 +45,6 @@ import QtDesktop 0.2
 BasicButton {
     id: button
 
-    property alias containsMouse: tooltip.containsMouse
     property bool defaultbutton: false
     property string styleHint
     property string text
@@ -55,13 +54,6 @@ BasicButton {
 
     Keys.onSpacePressed:animateClick()
 
-    TooltipArea {
-        // Note this will eat hover events
-        id: tooltip
-        anchors.fill: parent
-        text: button.tooltip
-    }
-
     delegate: StyleItem {
         id: styleitem
         anchors.fill: parent
diff --git a/components/CheckBox.qml b/components/CheckBox.qml
index a97e505256ec8119e7398c2a83dd8e2a4c8f4d64..c4c152dee7153bfd9bff4a827d9606348832188b 100644
--- a/components/CheckBox.qml
+++ b/components/CheckBox.qml
@@ -47,7 +47,7 @@ FocusScope {
 
     signal clicked
 
-    property alias pressed: behavior.pressed
+    property alias pressed: behavior.effectivePressed
     property alias checked: behavior.checked
     property alias containsMouse: behavior.containsMouse
 
diff --git a/components/ToolButton.qml b/components/ToolButton.qml
index 5952a6f439dffc45726e6fe9af68f77ffd1d18e0..55dd7bbc8143476d1d1cb73b8fc4879f568a79e7 100644
--- a/components/ToolButton.qml
+++ b/components/ToolButton.qml
@@ -45,19 +45,11 @@ import "private" as Private
 Private.BasicButton {
     id:button
 
-    property alias containsMouse: tooltip.containsMouse
     property string iconName
     property string styleHint
     property url iconSource
     property string text
 
-    TooltipArea {
-        // Note this will eat hover events
-        id: tooltip
-        anchors.fill: parent
-        text: button.tooltip
-    }
-
     delegate: StyleItem {
         id: styleitem
         anchors.fill: parent
diff --git a/components/private/BasicButton.qml b/components/private/BasicButton.qml
index 2427060cedced707afdd4f997a2c8ecc2953715c..daa17adfe7087d598f6b87675e761fda978f07df 100644
--- a/components/private/BasicButton.qml
+++ b/components/private/BasicButton.qml
@@ -39,12 +39,13 @@
 ****************************************************************************/
 
 import QtQuick 2.0
+import QtDesktop.Internal 0.2 as Internal
 
 Item {
     id: button
 
     signal clicked
-    property alias pressed: behavior.pressed
+    property alias pressed: behavior.effectivePressed
     property alias containsMouse: behavior.containsMouse
     property alias checkable: behavior.checkable  // button toggles between checked and !checked
     property alias checked: behavior.checked
@@ -67,15 +68,15 @@ Item {
     implicitHeight: loader.item.implicitHeight
 
     function animateClick() {
-        behavior.pressed = true
-        behavior.clicked()
+        behavior.keyPressed = true
+        button.clicked()
         animateClickTimer.start()
     }
 
     Timer {
         id: animateClickTimer
         interval: 250
-        onTriggered: behavior.pressed = false
+        onTriggered: behavior.keyPressed = false
     }
 
     Loader {
@@ -90,13 +91,14 @@ Item {
         id: behavior
         anchors.fill: parent
         onClicked: button.clicked()
-        onPressedChanged: if (activeFocusOnPress) button.focus = true
-        onMouseMoved: {tiptimer.restart()}
-        Timer{
-            id: tiptimer
-            interval:1000
-            running:containsMouse && tooltip.length
-            onTriggered: button.toolTipTriggered()
+        onExited: Internal.hideToolTip()
+        onCanceled: Internal.hideToolTip()
+        onPressed: if (activeFocusOnPress) button.focus = true
+
+        Timer {
+            interval: 1000
+            running: containsMouse && !pressed && tooltip.length
+            onTriggered: Internal.showToolTip(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
         }
     }
 
diff --git a/components/private/ButtonBehavior.qml b/components/private/ButtonBehavior.qml
index 4942d62fd78166d9577b7b2d233b83d4a5d43f8d..fdf0c79c2c8691791c40a1db5a3582495490fb94 100644
--- a/components/private/ButtonBehavior.qml
+++ b/components/private/ButtonBehavior.qml
@@ -40,34 +40,21 @@
 
 import QtQuick 2.0
 
-Item {
-    id: behavior
-
-    signal clicked
-    property bool pressed: false    // Can't be alias of mouseArea.pressed because the latter is read-only
-    property alias containsMouse: mouseArea.containsMouse
+MouseArea {
     property bool checkable: false
     property bool checked: false
-    property bool triState: false
-    signal mouseMoved
+    property bool keyPressed: false
+    property bool effectivePressed: pressed && containsMouse || keyPressed
+
+    hoverEnabled: true
+
+    onCheckableChanged: {
+        if (!checkable)
+            checked = false;
+    }
 
-    onCheckableChanged: { if(!checkable) checked = false }
-    MouseArea {
-        id: mouseArea
-        anchors.fill: parent
-        hoverEnabled: true
-        onPositionChanged: behavior.mouseMoved()
-        onPressed: behavior.pressed = true  // needed when hover is enabled
-        onEntered: if(pressed && enabled) behavior.pressed = true
-        onExited: behavior.pressed = false
-        onCanceled: behavior.pressed = false    // mouse stolen e.g. by Flickable
-        onReleased: {
-            if(behavior.pressed && behavior.enabled) { // No click if release outside area
-                behavior.pressed = false
-                if(behavior.checkable)
-                    behavior.checked = !behavior.checked;
-                behavior.clicked()
-            }
-        }
+    onReleased: {
+        if (checkable && containsMouse)
+            checked = !checked;
     }
 }
diff --git a/src/qtooltiparea.cpp b/src/qquickcomponentsprivate.cpp
similarity index 66%
rename from src/qtooltiparea.cpp
rename to src/qquickcomponentsprivate.cpp
index 9b97d8fe52e79ffaa7412fda87162f1915590a49..2f424ca31bf351b305652ddce5de1b5c722e6e31 100644
--- a/src/qtooltiparea.cpp
+++ b/src/qquickcomponentsprivate.cpp
@@ -38,54 +38,26 @@
 **
 ****************************************************************************/
 
-#include "qtooltiparea.h"
-#include <QtWidgets/QToolTip>
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QGraphicsSceneEvent>
+#include "qquickcomponentsprivate.h"
+#include <QToolTip>
+#include <QQuickCanvas>
 
-QTooltipArea::QTooltipArea(QQuickItem *parent) :
-    QQuickItem(parent),
-    m_containsMouse(false)
-{
-    setAcceptHoverEvents(true);
-    connect(&m_tiptimer, SIGNAL(timeout()), this, SLOT(timeout()));
-}
 
-void QTooltipArea::setText(const QString &t)
+QQuickComponentsPrivate::QQuickComponentsPrivate(QObject *parent)
+    : QObject(parent)
 {
-    if (t != m_text) {
-        m_text = t;
-        emit textChanged();
-    }
-}
 
-void QTooltipArea::showToolTip(const QString &str) const
-{
-    Q_UNUSED(str);
-    //QToolTip::showText(cursor().pos(), str);
 }
 
-void QTooltipArea::hoverEnterEvent(QHoverEvent *event)
-
+void QQuickComponentsPrivate::showToolTip(QQuickItem *item, const QPointF &pos, const QString &str)
 {
-    Q_UNUSED(event);
-    m_tiptimer.start(1000);
-
-    m_containsMouse = true;
-    emit containsMouseChanged();
-    //QQuickItem::hoverEnterEvent(event);
-}
+    if (!item || !item->canvas())
+        return;
 
-void QTooltipArea::hoverLeaveEvent(QHoverEvent *event)
-{
-    Q_UNUSED(event);
-    m_tiptimer.stop();
-    m_containsMouse = false;
-    emit containsMouseChanged();
-    //QQuickItem::hoverLeaveEvent(event);
+    QToolTip::showText(item->canvas()->mapToGlobal(item->mapToScene(pos).toPoint()), str);
 }
 
-void QTooltipArea::timeout()
+void QQuickComponentsPrivate::hideToolTip()
 {
-    showToolTip(m_text);
+    QToolTip::hideText();
 }
diff --git a/src/qtooltiparea.h b/src/qquickcomponentsprivate.h
similarity index 71%
rename from src/qtooltiparea.h
rename to src/qquickcomponentsprivate.h
index 5352ab941b4342c2424df1b8b7d653ecf790dca3..2f9c9ecff3f3a24125dbc4d356f335fb02e4cc1a 100644
--- a/src/qtooltiparea.h
+++ b/src/qquickcomponentsprivate.h
@@ -38,40 +38,21 @@
 **
 ****************************************************************************/
 
-#ifndef QTOOLTIPAREA_H
-#define QTOOLTIPAREA_H
+#ifndef QQUICKCOMPONENTSPRIVATE_H
+#define QQUICKCOMPONENTSPRIVATE_H
 
+#include <QObject>
 #include <QQuickItem>
-#include <QTimer>
-#include <QtWidgets/QGraphicsSceneHoverEvent>
 
-class QTooltipArea : public QQuickItem
+class QQuickComponentsPrivate : public QObject
 {
     Q_OBJECT
-    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
-    Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged)
 
 public:
-    QTooltipArea(QQuickItem *parent = 0);
-    void setText(const QString &t);
-    QString text() const {return m_text;}
-    bool containsMouse() const {return m_containsMouse;}
-    void showToolTip(const QString &str) const;
-    void hoverEnterEvent(QHoverEvent *event);
-    void hoverLeaveEvent(QHoverEvent *event);
+    QQuickComponentsPrivate(QObject *parent = 0);
 
-public slots:
-    void timeout();
-
-signals:
-    void textChanged();
-    void containsMouseChanged();
-
-private:
-
-    QTimer m_tiptimer;
-    QString m_text;
-    bool m_containsMouse;
+    Q_INVOKABLE void showToolTip(QQuickItem *item, const QPointF &pos, const QString &text);
+    Q_INVOKABLE void hideToolTip();
 };
 
-#endif // QTOOLTIPAREA_H
+#endif
diff --git a/src/qstyleplugin.cpp b/src/qstyleplugin.cpp
index e375d25383611bcc62e8b78ebb0ff63a54ca477d..4cf7a825fdcacc2f86e0a1f31849569becbf484b 100644
--- a/src/qstyleplugin.cpp
+++ b/src/qstyleplugin.cpp
@@ -49,9 +49,9 @@
 #include "qdesktopitem.h"
 #include "qwheelarea.h"
 #include "qcursorarea.h"
-#include "qtooltiparea.h"
 #include "qtsplitterbase.h"
 #include "qquicklinearlayout.h"
+#include "qquickcomponentsprivate.h"
 #include <qqmlextensionplugin.h>
 
 #include <qqmlengine.h>
@@ -79,12 +79,20 @@ public:
     }
 };
 
+QObject *registerPrivateModule(QQmlEngine *engine, QJSEngine *jsEngine)
+{
+    Q_UNUSED(engine);
+    Q_UNUSED(jsEngine);
+    return new QQuickComponentsPrivate();
+}
 
 void StylePlugin::registerTypes(const char *uri)
 {
+    qmlRegisterModuleApi<QQuickComponentsPrivate>(QByteArray(uri) + ".Internal",
+                                                  0, 2, registerPrivateModule);
+
     qmlRegisterType<QStyleItem>(uri, 0, 2, "StyleItem");
     qmlRegisterType<QCursorArea>(uri, 0, 2, "CursorArea");
-    qmlRegisterType<QTooltipArea>(uri, 0, 2, "TooltipArea");
     qmlRegisterType<QRangeModel>(uri, 0, 2, "RangeModel");
     qmlRegisterType<QWheelArea>(uri, 0, 2, "WheelArea");
 
diff --git a/src/src.pro b/src/src.pro
index 353ab5ccb96b0f8b04aefc175d1395b7273be422..54fe2cc34c812dce55c415ec75ce8285a9a23f71 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -25,7 +25,7 @@ HEADERS += qtmenu.h \
            qquicklayoutengine_p.h \
            qquicklayout.h \
            qquicklinearlayout.h \
-           qtooltiparea.h \
+           qquickcomponentsprivate.h \
            qtsplitterbase.h
 
 SOURCES += qtmenu.cpp \
@@ -39,10 +39,10 @@ SOURCES += qtmenu.cpp \
            qdesktopitem.cpp \
            qtoplevelwindow.cpp \
            qcursorarea.cpp \
-           qtooltiparea.cpp \
            qquicklayout.cpp \
            qquicklayoutengine.cpp \
            qquicklinearlayout.cpp \
+           qquickcomponentsprivate.cpp \
            qtsplitterbase.cpp
 
 TARGETPATH = QtDesktop/plugin