diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp
index 8b1b240cf17127e34d6f00572b1c546542200057..e7594707feb5df1bb43c8df5bb63bc9071e3ce31 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.cpp
+++ b/share/qtcreator/gdbmacros/gdbmacros.cpp
@@ -62,9 +62,10 @@ int qtGhVersion = QT_VERSION;
 #endif
 
 #if USE_QT_GUI
-#   include <QtGui/QWidget>
-#   include <QtGui/QPixmap>
+#   include <QtGui/QApplication>
 #   include <QtGui/QImage>
+#   include <QtGui/QPixmap>
+#   include <QtGui/QWidget>
 #endif
 
 #ifdef Q_OS_WIN
@@ -1457,7 +1458,9 @@ static void qDumpQHashNode(QDumper &d)
 static void qDumpQImage(QDumper &d)
 {
     const QImage &im = *reinterpret_cast<const QImage *>(d.data);
-    d.putItem("value", "(").put(im.width()).put("x").put(im.height()).put(")");
+    d.beginItem("value");
+        d.put("(").put(im.width()).put("x").put(im.height()).put(")");
+    d.endItem();
     d.putItem("type", NS"QImage");
     d.putItem("numchild", "1");
     if (d.dumpChildren) {
@@ -2234,7 +2237,9 @@ static void qDumpQObjectSlotList(QDumper &d)
 static void qDumpQPixmap(QDumper &d)
 {
     const QPixmap &im = *reinterpret_cast<const QPixmap *>(d.data);
-    d.putItem("value", "(").put(im.width()).put("x").put(im.height()).put(")");
+    d.beginItem("value");
+        d.put("(").put(im.width()).put("x").put(im.height()).put(")");
+    d.endItem();
     d.putItem("type", NS"QPixmap");
     d.putItem("numchild", "0");
     d.disarm();
@@ -3023,6 +3028,14 @@ static void handleProtocolVersion2and3(QDumper & d)
 } // anonymous namespace
 
 
+#if USE_QT_GUI
+extern "C" Q_DECL_EXPORT
+void *watchPoint(int x, int y)
+{
+    return QApplication::widgetAt(x, y);
+}
+#endif
+
 extern "C" Q_DECL_EXPORT
 void *qDumpObjectData440(
     int protocolVersion,
@@ -3115,7 +3128,7 @@ void *qDumpObjectData440(
          .put(""NS"QStringList=\"").put(sizeof(QStringList)).put("\",")
          .put(""NS"QObject=\"").put(sizeof(QObject)).put("\",")
 #if USE_QT_GUI
-         .put(""NS"QWidget=\"").put(sizeof(QWidget)<< "\",")
+         .put(""NS"QWidget=\"").put(sizeof(QWidget)).put("\",")
 #endif
 #ifdef Q_OS_WIN
          .put("string=\"").put(sizeof(std::string)).put("\",")
diff --git a/share/qtcreator/gdbmacros/gdbmacros.pro b/share/qtcreator/gdbmacros/gdbmacros.pro
index 67133e732e88e30dd557d051c5270f24641f39a5..d876af9387fa8f22dcd80f629cc0a2cf7d894025 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.pro
+++ b/share/qtcreator/gdbmacros/gdbmacros.pro
@@ -1,13 +1,12 @@
 TEMPLATE = lib
 CONFIG += shared
-QT = core
 linux-* {
 CONFIG -= release
 CONFIG += debug
 }
 SOURCES=gdbmacros.cpp
 
-true {
+false {
     DEFINES += USE_QT_GUI=0
     QT = core
 } else {
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index f32b815e4f00f80d21b093e8eb224dbb41df184f..693dcf4e6617ddf524d1acb4ffea165478b9a89c 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -165,6 +165,9 @@ DebuggerSettings *DebuggerSettings::instance()
     item = new SavedAction(instance);
     instance->insertItem(AssignType, item);
 
+    item = new SavedAction(instance);
+    instance->insertItem(WatchPoint, item);
+
     //
     // DebuggingHelper
     //
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index d466a78df3dd40b3adacc6a7090dbe40911be710..5f953b6d10e53dfdd5f6d251d33f27c119439b66 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -94,7 +94,7 @@ enum DebuggerActionCode
     WatchExpression,
     WatchExpressionInWindow,
     RemoveWatchExpression,
-    WatchModelUpdate,
+    WatchPoint,
     UseToolTips,
     AssignValue,
     AssignType,
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index e9226a7c42277767ba5aca980ea46e46f40e0c25..15c586b5bba226397c49f1cf81c3a15ef912e571 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -434,7 +434,8 @@ void DebuggerManager::init()
 
     connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()),
         this, SLOT(executeDebuggerCommand()));
-
+    connect(theDebuggerAction(WatchPoint), SIGNAL(triggered()),
+        this, SLOT(watchPoint()));
 
     m_breakDock = createDockForWidget(m_breakWindow);
 
@@ -1089,6 +1090,13 @@ void DebuggerManager::nextIExec()
     m_engine->nextIExec();
 }
 
+void DebuggerManager::watchPoint()
+{
+    if (QAction *action = qobject_cast<QAction *>(sender()))
+        if (m_engine)
+            m_engine->watchPoint(action->data().toPoint());
+}
+
 void DebuggerManager::executeDebuggerCommand()
 {
     if (QAction *action = qobject_cast<QAction *>(sender()))
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 23624c7d601ee2af1ebca6dfdab0ce955fa58f69..bfbfc10e93c1db79bbd7ca815595dc0318273016 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -318,6 +318,8 @@ public slots:
     void executeDebuggerCommand();
     void executeDebuggerCommand(const QString &command);
 
+    void watchPoint();
+
     void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
 
 private slots:
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index ed6e4b7a57eb5f9f8e18f773cd08de0ee23e6118..b564a5468a7c4149079bcb3e0304c3639a3e3e7d 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -103,6 +103,42 @@ static int &currentToken()
     return token;
 }
 
+// reads a MI-encoded item frome the consolestream
+static bool parseConsoleStream(const GdbResultRecord &record, GdbMi *contents)
+{
+    GdbMi output = record.data.findChild("consolestreamoutput");
+    QByteArray out = output.data();
+
+    int markerPos = out.indexOf('"') + 1; // position of 'success marker'
+    if (markerPos == 0 || out.at(markerPos) == 'f') {  // 't' or 'f'
+        // custom dumper produced no output
+        return false;
+    }
+
+    out = out.mid(markerPos +  1);
+    out = out.left(out.lastIndexOf('"'));
+    // optimization: dumper output never needs real C unquoting
+    out.replace('\\', "");
+    out = "dummy={" + out + "}";
+
+    contents->fromString(out);
+    //qDebug() << "CONTENTS" << contents->toString(true);
+    return contents->isValid();
+}
+
+static QByteArray parsePlainConsoleStream(const GdbResultRecord &record)
+{
+    GdbMi output = record.data.findChild("consolestreamoutput");
+    QByteArray out = output.data();
+    // FIXME: proper decoding needed
+    if (out.endsWith("\\n"))
+        out.chop(2);
+    while (out.endsWith('\n') || out.endsWith(' '))
+        out.chop(1);
+    int pos = out.indexOf(" = ");
+    return out.mid(pos + 3);
+}
+
 ///////////////////////////////////////////////////////////////////////
 //
 // GdbEngine
@@ -2823,6 +2859,7 @@ void GdbEngine::setUseDebuggingHelpers(const QVariant &on)
     //qDebug() << "SWITCHING ON/OFF DUMPER DEBUGGING:" << on;
     // FIXME: a bit too harsh, but otherwise the treeview sometimes look funny
     //m_expandedINames.clear();
+    Q_UNUSED(on);
     setTokenBarrier();
     updateLocals();
 }
@@ -3111,16 +3148,9 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const
 {
     m_dumperHelper.clear();
     //qDebug() << "DATA DUMPER TRIAL:" << record.toString();
-    GdbMi output = record.data.findChild("consolestreamoutput");
-    QByteArray out = output.data();
-    out = out.mid(out.indexOf('"') + 2); // + 1 is success marker
-    out = out.left(out.lastIndexOf('"'));
-    out.replace('\\', ""); // optimization: dumper output never needs real C unquoting
-    out = "dummy={" + out + "}";
-    //qDebug() << "OUTPUT:" << out;
 
     GdbMi contents;
-    contents.fromString(out);
+    QTC_ASSERT(parseConsoleStream(record, &contents), /**/);
     GdbMi simple = contents.findChild("dumpers");
 
     m_dumperHelper.setQtNamespace(_(contents.findChild("namespace").data()));
@@ -3281,11 +3311,7 @@ void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record,
     if (record.resultClass == GdbResultDone) {
         // ignore this case, data will follow
     } else if (record.resultClass == GdbResultError) {
-        // Record an extra result, as the socket result will be lost
-        // in transmission
-        //--m_pendingRequests;
         QString msg = QString::fromLocal8Bit(record.data.findChild("msg").data());
-        //qDebug() << "CUSTOM DUMPER ERROR MESSAGE:" << msg;
 #ifdef QT_DEBUG
         // Make debugging of dumpers easier
         if (theDebuggerBoolSetting(DebugDebuggingHelpers)
@@ -3296,12 +3322,6 @@ void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record,
             return;
         }
 #endif
-        //if (msg.startsWith("The program being debugged was sig"))
-        //    msg = strNotInScope;
-        //if (msg.startsWith("The program being debugged stopped while"))
-        //    msg = strNotInScope;
-        //data.setError(msg);
-        //insertData(data);
     }
 }
 
@@ -3310,6 +3330,7 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record,
 {
     WatchData data = cookie.value<WatchData>();
     QTC_ASSERT(data.isValid(), return);
+
     //qDebug() << "CUSTOM VALUE RESULT:" << record.toString();
     //qDebug() << "FOR DATA:" << data.toString() << record.resultClass;
     if (record.resultClass != GdbResultDone) {
@@ -3317,26 +3338,8 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record,
         return;
     }
 
-    GdbMi output = record.data.findChild("consolestreamoutput");
-    QByteArray out = output.data();
-
-    int markerPos = out.indexOf('"') + 1; // position of 'success marker'
-    if (markerPos == 0 || out.at(markerPos) == 'f') {  // 't' or 'f'
-        // custom dumper produced no output
-        data.setError(strNotInScope);
-        insertData(data);
-        return;
-    }
-
-    out = out.mid(markerPos +  1);
-    out = out.left(out.lastIndexOf('"'));
-    out.replace('\\', ""); // optimization: dumper output never needs real C unquoting
-    out = "dummy={" + out + "}";
-
     GdbMi contents;
-    contents.fromString(out);
-    //qDebug() << "CONTENTS" << contents.toString(true);
-    if (!contents.isValid()) {
+    if (!parseConsoleStream(record, &contents)) {
         data.setError(strNotInScope);
         insertData(data);
         return;
@@ -3759,60 +3762,6 @@ void GdbEngine::handleVarListChildren(const GdbResultRecord &record,
     }
 }
 
-/*
-void GdbEngine::handleToolTip(const GdbResultRecord &record,
-        const QVariant &cookie)
-{
-    const QByteArray &what = cookie.toByteArray();
-    //qDebug() << "HANDLE TOOLTIP:" << what << m_toolTip.toString();
-    //    << "record: " << record.toString();
-    if (record.resultClass == GdbResultError) {
-        if (what == "create") {
-            postCommand(_("ptype ") + m_toolTip.exp,
-                Discardable, CB(handleToolTip), QByteArray("ptype"));
-            return;
-        }
-        if (what == "evaluate") {
-            QByteArray msg = record.data.findChild("msg").data();
-            if (msg.startsWith("Cannot look up value of a typedef")) {
-                m_toolTip.value = tr("%1 is a typedef.").arg(m_toolTip.exp);
-                //return;
-            }
-        }
-    } else if (record.resultClass == GdbResultDone) {
-        if (what == "create") {
-            setWatchDataType(m_toolTip, record.data.findChild("type"));
-            setWatchDataChildCount(m_toolTip, record.data.findChild("numchild"));
-            if (hasDebuggingHelperForType(m_toolTip.type))
-                runDebuggingHelper(m_toolTip, false);
-            else
-                q->showStatusMessage(tr("Retrieving data for tooltip..."), 10000);
-                postCommand(_("-data-evaluate-expression ") + m_toolTip.exp,
-                    Discardable, CB(handleToolTip), QByteArray("evaluate"));
-            return;
-        }
-        if (what == "evaluate") {
-            m_toolTip.value = m_toolTip.type + _c(' ') + m_toolTip.exp
-                   + _(" = " + record.data.findChild("value").data());
-            //return;
-        }
-        if (what == "ptype") {
-            GdbMi mi = record.data.findChild("consolestreamoutput");
-            m_toolTip.value = extractTypeFromPTypeOutput(_(mi.data()));
-            //return;
-        }
-    }
-
-    m_toolTip.iname = tooltipIName;
-    m_toolTip.setChildrenUnneeded();
-    m_toolTip.setHasChildrenUnneeded();
-    insertData(m_toolTip);
-    qDebug() << "DATA INSERTED";
-    QTimer::singleShot(0, this, SLOT(updateWatchModel2()));
-    qDebug() << "HANDLE TOOLTIP END";
-}
-*/
-
 #if 0
 void GdbEngine::handleChangedItem(QStandardItem *item)
 {
@@ -3933,6 +3882,29 @@ bool GdbEngine::startModeAllowsDumpers() const
         || q->startMode() == AttachExternal;
 }
 
+void GdbEngine::watchPoint(const QPoint &pnt)
+{
+    //qDebug() << "WATCH " << pnt;
+    postCommand(_("call (void*)watchPoint(%1,%2)").arg(pnt.x()).arg(pnt.y()),
+        NeedsStop, CB(handleWatchPoint));
+}
+
+void GdbEngine::handleWatchPoint(const GdbResultRecord &record, const QVariant &)
+{
+    //qDebug() << "HANDLE WATCH POINT:" << record.toString();
+    if (record.resultClass == GdbResultDone) {
+        GdbMi contents = record.data.findChild("consolestreamoutput");
+        // "$5 = (void *) 0xbfa7ebfc\n"
+        QString str = _(parsePlainConsoleStream(record));
+        // "(void *) 0xbfa7ebfc"
+        QString addr = str.mid(9);
+        QString ns = m_dumperHelper.qtNamespace();
+        QString type = ns.isEmpty() ? _("QWidget*") : _("'%1QWidget'*").arg(ns);
+        QString exp = _("(*(%1)%2)").arg(type).arg(addr);
+        theDebuggerAction(WatchExpression)->trigger(exp);
+    }
+}
+
 IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
 {
     opts->push_back(new GdbOptionsPage);
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 47dbd655cfd8676a66c618be15c4a760bb3e36b9..84f8ab32f82a1af820a8f01c93291583686a7440 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -115,6 +115,7 @@ private:
 
     void assignValueInDebugger(const QString &expr, const QString &value);
     void executeDebuggerCommand(const QString & command);
+    void watchPoint(const QPoint &);
 
     void loadSymbols(const QString &moduleName);
     void loadAllSymbols();
@@ -220,6 +221,7 @@ private:
     void handleExit(const GdbResultRecord &, const QVariant &);
     void handleSetTargetAsync(const GdbResultRecord &, const QVariant &);
     void handleTargetRemote(const GdbResultRecord &, const QVariant &);
+    void handleWatchPoint(const GdbResultRecord &, const QVariant &);
     void debugMessage(const QString &msg);
     bool showToolTip();
 
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index 8a7187b77f281181092fb48d11c535e41f791bbf..dbbdb14314385c5baa7da767c8423468aec055ee 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -93,6 +93,8 @@ public:
 
     virtual void reloadSourceFiles() = 0;
     virtual void reloadFullStack() = 0;
+
+    virtual void watchPoint(const QPoint &) {}
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index 7fedf1520bfe0e27ec8c3a24df76020595e4c18e..feab5a2989cb9350b886587d8836978f5116cc01 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -114,6 +114,8 @@ public:
 WatchWindow::WatchWindow(Type type, QWidget *parent)
     : QTreeView(parent), m_alwaysResizeColumnsToContents(true), m_type(type)
 {
+    m_grabbing = false;
+
     QAction *act = theDebuggerAction(UseAlternatingRowColors);
     setWindowTitle(tr("Locals and Watchers"));
     setAlternatingRowColors(act->isChecked());
@@ -219,6 +221,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     QAction *act3 = new QAction(tr("Insert new watch item"), &menu); 
     menu.addAction(act3);
+    QAction *act4 = new QAction(tr("Select widget to watch"), &menu);
+    menu.addAction(act4);
 
     menu.addSeparator();
     menu.addAction(theDebuggerAction(RecheckDebuggingHelpers));
@@ -233,7 +237,12 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
     else if (act == act2)
         setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
     else if (act == act3)
-        theDebuggerAction(WatchExpression)->trigger(WatchHandler::watcherEditPlaceHolder());
+        theDebuggerAction(WatchExpression)
+            ->trigger(WatchHandler::watcherEditPlaceHolder());
+    else if (act == act4) {
+        grabMouse(Qt::CrossCursor);
+        m_grabbing = true;
+    }
 }
 
 void WatchWindow::resizeColumnsToContents()
@@ -253,6 +262,17 @@ void WatchWindow::setAlwaysResizeColumnsToContents(bool on)
     header()->setResizeMode(1, mode);
 }
 
+bool WatchWindow::event(QEvent *ev)
+{
+    if (m_grabbing && ev->type() == QEvent::MouseButtonPress) {
+        QMouseEvent *mev = static_cast<QMouseEvent *>(ev);
+        m_grabbing = false;
+        releaseMouse();
+        theDebuggerAction(WatchPoint)->trigger(mapToGlobal(mev->pos()));
+    }
+    return QTreeView::event(ev);
+}
+
 void WatchWindow::editItem(const QModelIndex &idx)
 {
     Q_UNUSED(idx); // FIXME
diff --git a/src/plugins/debugger/watchwindow.h b/src/plugins/debugger/watchwindow.h
index af8cf163f6a15fc6c8fbd94dda447f3c7edfa240..b32319b64539e7e3cf27a5a0ae175cf2e9961308 100644
--- a/src/plugins/debugger/watchwindow.h
+++ b/src/plugins/debugger/watchwindow.h
@@ -69,13 +69,14 @@ private:
     void dragEnterEvent(QDragEnterEvent *ev);
     void dropEvent(QDropEvent *ev);
     void dragMoveEvent(QDragMoveEvent *ev);
+    bool event(QEvent *ev);
 
     void editItem(const QModelIndex &idx);
-
     void resetHelper(const QModelIndex &idx);
 
     bool m_alwaysResizeColumnsToContents;
     Type m_type;
+    bool m_grabbing;
 };