diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index d44b883206e94302073d75f80d2d852f048fa0fe..5f9cd189a1161948a10bfbbe54b38a82de533c2c 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -72,11 +72,16 @@ public:
         for (int index = 0; index < _metaObject->propertyCount(); ++index) {
             QMetaProperty prop = _metaObject->property(index);
 
-            processor->process(prop.name(), propertyValue(prop));
+            processor->processProperty(prop.name(), propertyValue(prop));
         }
 
         for (int index = 0; index < _metaObject->methodCount(); ++index) {
             QMetaMethod meth = _metaObject->method(index);
+            if (meth.methodType() != QMetaMethod::Signal)
+                continue;
+            if (meth.access() == QMetaMethod::Private)
+                continue;
+
             const QString signature = QString::fromUtf8(meth.signature());
 
             int indexOfParen = signature.indexOf(QLatin1Char('('));
@@ -88,7 +93,9 @@ public:
             slotName += QLatin1String("on");
             slotName += signalName.at(0).toUpper();
             slotName += signalName.midRef(1);
-            processor->process(slotName, engine()->undefinedValue()); // ### FIXME: assign a decent type to the property
+
+            processor->processSignal(signalName, engine()->undefinedValue()); // ### FIXME: assign a decent type to the signal
+            processor->processSlot(slotName, engine()->undefinedValue()); // ### FIXME: assign a decent type to the slot
         }
 
         ObjectValue::processMembers(processor);
@@ -554,6 +561,29 @@ void StringValue::accept(ValueVisitor *visitor) const
     visitor->visit(this);
 }
 
+MemberProcessor::MemberProcessor()
+{
+}
+
+MemberProcessor::~MemberProcessor()
+{
+}
+
+bool MemberProcessor::processProperty(const QString &, const Value *)
+{
+    return true;
+}
+
+bool MemberProcessor::processSignal(const QString &, const Value *)
+{
+    return true;
+}
+
+bool MemberProcessor::processSlot(const QString &, const Value *)
+{
+    return true;
+}
+
 ObjectValue::ObjectValue(Engine *engine)
     : _engine(engine), _prototype(0), _scope(0)
 {
@@ -653,7 +683,7 @@ void ObjectValue::processMembers(MemberProcessor *processor) const
     while (it.hasNext()) {
         it.next();
 
-        if (! processor->process(it.key(), it.value()))
+        if (! processor->processProperty(it.key(), it.value()))
             break;
     }
 }
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 2b2338e7641eb9ad998651c866e7f0517af33192..b8bdb46d9fd1ef2ccadfa0edaa9a990c2a11f0bc 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -198,11 +198,13 @@ class QMLJS_EXPORT MemberProcessor
     void operator = (const MemberProcessor &other);
 
 public:
-    MemberProcessor() {}
-    virtual ~MemberProcessor() {}
+    MemberProcessor();
+    virtual ~MemberProcessor();
 
     // Returns false to stop the processor.
-    virtual bool process(const QString &name, const Value *value) = 0;
+    virtual bool processProperty(const QString &name, const Value *value);
+    virtual bool processSignal(const QString &name, const Value *value);
+    virtual bool processSlot(const QString &name, const Value *value);
 };
 
 class QMLJS_EXPORT ObjectValue: public Value, public Environment
diff --git a/src/plugins/qmljseditor/qmlcodecompletion.cpp b/src/plugins/qmljseditor/qmlcodecompletion.cpp
index 2fe7c2f5f8fb6f9786c80d723543e402b0a49b2e..820d14e49eaa8073936fc2752538dcbc59c9ebf0 100644
--- a/src/plugins/qmljseditor/qmlcodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmlcodecompletion.cpp
@@ -381,8 +381,19 @@ class EnumerateProperties: private Interpreter::MemberProcessor
 {
     QSet<const Interpreter::ObjectValue *> _processed;
     QHash<QString, const Interpreter::Value *> _properties;
+    bool _globalCompletion;
 
 public:
+    EnumerateProperties()
+        : _globalCompletion(false)
+    {
+    }
+
+    void setGlobalCompletion(bool globalCompletion)
+    {
+        _globalCompletion = globalCompletion;
+    }
+
     QHash<QString, const Interpreter::Value *> operator()(const Interpreter::Value *value,
                                                           bool lookAtScope = false)
     {
@@ -393,12 +404,19 @@ public:
     }
 
 private:
-    virtual bool process(const QString &name, const Interpreter::Value *value)
+    virtual bool processProperty(const QString &name, const Interpreter::Value *value)
     {
         _properties.insert(name, value);
         return true;
     }
 
+    virtual bool processSlot(const QString &name, const Interpreter::Value *value)
+    {
+        if (_globalCompletion)
+            _properties.insert(name, value);
+        return true;
+    }
+
     void enumerateProperties(const Interpreter::Value *value, bool lookAtScope)
     {
         if (! value)
@@ -881,6 +899,7 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
         }
 
         EnumerateProperties enumerateProperties;
+        enumerateProperties.setGlobalCompletion(true);
         QHashIterator<QString, const Interpreter::Value *> it(enumerateProperties(scope, /* lookAtScope = */ true));
         while (it.hasNext()) {
             it.next();