diff --git cmake/modules/KDE4Macros.cmake cmake/modules/KDE4Macros.cmake
index 073d726..ac58d58 100644
--- cmake/modules/KDE4Macros.cmake
+++ cmake/modules/KDE4Macros.cmake
@@ -836,6 +836,10 @@ macro (KDE4_ADD_KDEINIT_EXECUTABLE _target_NAME )
       kde4_add_executable(${_target_NAME} "${_nogui}" ${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_dummy.cpp ${_resourcefile})
       target_link_libraries(${_target_NAME} kdeinit_${_target_NAME})
    endif(WIN32)
+   if(_nogui)
+      set_target_properties(kdeinit_${_target_NAME} PROPERTIES COMPILE_FLAGS -DKDE_WITHOUT_GUI)
+      message(STATUS "Building \"kdeinit_${_target_NAME}\" with -DKDE_WITHOUT_GUI because \"${_nogui}\"")
+   endif(_nogui)
 
 endmacro (KDE4_ADD_KDEINIT_EXECUTABLE)
 
@@ -1010,6 +1014,11 @@ macro (KDE4_ADD_EXECUTABLE _target_NAME)
       add_executable(${_target_NAME} ${_add_executable_param} ${_SRCS})
    endif (KDE4_ENABLE_FINAL)
 
+    if(_nogui)
+        set_target_properties(${_target_NAME} PROPERTIES COMPILE_FLAGS -DKDE_WITHOUT_GUI)
+        message(STATUS "Building \"${_target_NAME}\" with -DKDE_WITHOUT_GUI because \"${_nogui}\"")
+    endif(_nogui)
+
    IF (KDE4_ENABLE_UAC_MANIFEST)
        _kde4_add_manifest(${_target_NAME})
    ENDIF(KDE4_ENABLE_UAC_MANIFEST)
diff --git kdeui/actions/kaction.cpp kdeui/actions/kaction.cpp
index 9e8f7fb..54088d2 100644
--- kdeui/actions/kaction.cpp
+++ kdeui/actions/kaction.cpp
@@ -140,6 +140,7 @@ KAction::KAction(QObject *parent)
   : QWidgetAction(parent), d(new KActionPrivate)
 {
   d->init(this);
+  setMenuRole(QAction::NoRole);
 }
 
 KAction::KAction(const QString &text, QObject *parent)
@@ -147,6 +148,7 @@ KAction::KAction(const QString &text, QObject *parent)
 {
   d->init(this);
   setText(text);
+  setMenuRole(QAction::NoRole);
 }
 
 KAction::KAction(const KIcon &icon, const QString &text, QObject *parent)
@@ -155,6 +157,7 @@ KAction::KAction(const KIcon &icon, const QString &text, QObject *parent)
   d->init(this);
   setIcon(icon);
   setText(text);
+  setMenuRole(QAction::NoRole);
 }
 
 KAction::~KAction()
diff --git kdeui/kernel/kapplication.cpp kdeui/kernel/kapplication.cpp
index b093034..ec1455f 100644
--- kdeui/kernel/kapplication.cpp
+++ kdeui/kernel/kapplication.cpp
@@ -138,6 +138,12 @@ static int kde_x_errhandler( Display *dpy, XErrorEvent *err )
 void KApplication_init_windows();
 #endif
 
+#ifdef KDE_WITHOUT_GUI
+#define GUIENABLED false
+#else
+#define GUIENABLED true
+#endif //KDE_WITHOUT_GUI
+
 /*
   Private data to make keeping binary compatibility easier
  */
@@ -205,9 +211,13 @@ public:
   void _k_slot_KToolInvocation_hook(QStringList&, QByteArray&);
 
   QString sessionConfigName() const;
-  void init(bool GUIenabled=true);
+  void init(bool GUIenabled=GUIENABLED);
   void parseCommandLine( ); // Handle KDE arguments (Using KCmdLineArgs)
+#ifdef Q_OS_MAC
+  static void preqapplicationhack(bool GUIenabled = GUIENABLED);
+#else
   static void preqapplicationhack();
+#endif
   static void preread_app_startup_id();
   void read_app_startup_id();
 
@@ -342,7 +352,11 @@ static SmcConn mySmcConnection = 0;
 #endif
 
 KApplication::KApplication(bool GUIenabled)
+#ifdef Q_OS_MAC
+    : QApplication((KApplicationPrivate::preqapplicationhack(GUIenabled),KCmdLineArgs::qtArgc()), KCmdLineArgs::qtArgv(), GUIenabled),
+#else
     : QApplication((KApplicationPrivate::preqapplicationhack(),KCmdLineArgs::qtArgc()), KCmdLineArgs::qtArgv(), GUIenabled),
+#endif
     d(new KApplicationPrivate(this))
 {
     d->read_app_startup_id();
diff --git kdeui/kernel/kapplication.h kdeui/kernel/kapplication.h
index fa2ab26..ff17f26 100644
--- kdeui/kernel/kapplication.h
+++ kdeui/kernel/kapplication.h
@@ -97,7 +97,11 @@ public:
    *  <li>Call KGlobal::locale(), if using multiple threads.</li>
    * </ul>
    */
+#ifdef KDE_WITHOUT_GUI
+  explicit KApplication(bool GUIenabled = false);
+#else
   explicit KApplication(bool GUIenabled = true);
+#endif // KDE_WITHOUT_GUI
 
 #ifdef Q_WS_X11
   /**
@@ -134,8 +138,13 @@ public:
    *
    * @param GUIenabled Set to false to disable all GUI stuff.
    */
+#ifdef KDE_WITHOUT_GUI
+  KApplication(Display *display, int& argc, char** argv, const QByteArray& rAppName,
+               bool GUIenabled=false);
+#else
   KApplication(Display *display, int& argc, char** argv, const QByteArray& rAppName,
                bool GUIenabled=true);
+#endif // KDE_WITHOUT_GUI
 #endif
 
   virtual ~KApplication();
diff --git kdeui/kernel/kuniqueapplication.h kdeui/kernel/kuniqueapplication.h
index e05dcd7..97fd942 100644
--- kdeui/kernel/kuniqueapplication.h
+++ kdeui/kernel/kuniqueapplication.h
@@ -65,8 +65,13 @@ public:
    *                 depend on the value of the "MultipleInstances"
    *                 key in the "KDE" group of the application config file.
    */
+#ifdef KDE_WITHOUT_GUI
+  explicit KUniqueApplication( bool GUIenabled=false,
+                               bool configUnique=false);
+#else
   explicit KUniqueApplication( bool GUIenabled=true,
                                bool configUnique=false);
+#endif //KDE_WITHOUT_GUI
 
 #ifdef Q_WS_X11
   /**
diff --git kdeui/notifications/kstatusnotifieritem.cpp kdeui/notifications/kstatusnotifieritem.cpp
index 1b15d40..1ed7de3 100644
--- kdeui/notifications/kstatusnotifieritem.cpp
+++ kdeui/notifications/kstatusnotifieritem.cpp
@@ -683,6 +683,9 @@ bool KStatusNotifierItemPrivate::checkVisibility(QPoint pos, bool perform)
 
         return false;
     }
+#else
+    Q_UNUSED(pos);
+    Q_UNUSED(perform);
 #endif
 
     return true;
@@ -745,8 +748,20 @@ void KStatusNotifierItemPrivate::init(const QString &extraId)
 
     //create a default menu, just like in KSystemtrayIcon
     KMenu *m = new KMenu(associatedWidget);
+#ifdef Q_OS_MAC
+    // emulate addTitle/setTitle by adding an inactive menu item.
+    titleAction = m->addAction( qApp->windowIcon(), KGlobal::mainComponent().aboutData()->programName() );
+    titleAction->setEnabled(false);
+    titleAction->setIconVisibleInMenu(true);
+    m->addAction( titleAction );
+    m->addSeparator();
+    kDebug() << "### Added SystemTray titleAction=" << titleAction;
+    kDebug() << "### SystemTray for app" << qApp << "=" << KGlobal::mainComponent().aboutData()->programName()
+        << "/" << KGlobal::caption() << "with icon" << qApp->windowIcon().name();
+#else
     titleAction = m->addTitle(qApp->windowIcon(), KGlobal::caption());
     m->setTitle(KGlobal::mainComponent().aboutData()->programName());
+#endif
     q->setContextMenu(m);
 
     KStandardAction::quit(q, SLOT(maybeQuit()), actionCollection);
diff --git kdeui/util/kwallet.h kdeui/util/kwallet.h
index d7f703f..895868a 100644
--- kdeui/util/kwallet.h
+++ kdeui/util/kwallet.h
@@ -481,7 +481,6 @@ class KDEUI_EXPORT Wallet : public QObject
 		 *  @param success True if the wallet was opened successfully.
 		 */
 		void walletOpened(bool success);
-
 	private Q_SLOTS:
 		/**
 		 *  @internal
diff --git kdeui/util/kwallet_mac.cpp kdeui/util/kwallet_mac.cpp
index 8344ebb..3d9c5a8 100644
--- kdeui/util/kwallet_mac.cpp
+++ kdeui/util/kwallet_mac.cpp
@@ -27,7 +27,9 @@
 #include <kdeversion.h>
 #include <QtGui/QApplication>
 #include <QtCore/QPointer>
+#include <QtCore/QSharedMemory>
 #include <QtGui/QWidget>
+#include <QtCore/QTimer>
 #include <ktoolinvocation.h>
 
 #include <kglobal.h>
@@ -39,9 +41,16 @@
 
 #include <sys/param.h>
 
+#define IDLETIMER_DEBUG
+#undef USE_KWALLETD
+
 #include "qosxkeychain.h"
 
-using namespace KWallet;
+#ifdef USE_KWALLETD
+#   include "kwallet_interface.h"
+#endif
+
+#include "kwallet_mac.h"
 
 typedef QMap<QString, QString> StringStringMap;
 Q_DECLARE_METATYPE(StringStringMap)
@@ -50,7 +59,87 @@ Q_DECLARE_METATYPE(StringToStringStringMapMap)
 typedef QMap<QString, QByteArray> StringByteArrayMap;
 Q_DECLARE_METATYPE(StringByteArrayMap)
 
-#ifdef OSX_KEYCHAIN_PORT_DISABLED
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <mach/mach_init.h>
+#include <sys/sysctl.h>
+
+static mach_timebase_info_data_t sTimebaseInfo;
+static double calibrator= 0, startTime = 0;
+static QSharedValue<double> sharedStartTime;
+
+double HRTime_Time()
+{
+    return mach_absolute_time() * calibrator - startTime;
+}
+
+void init_HRTime()
+{
+    if( !calibrator ){
+        mach_timebase_info(&sTimebaseInfo);
+        /* go from absolute time units to seconds (the timebase is calibrated in nanoseconds): */
+        calibrator= 1e-9 * sTimebaseInfo.numer / sTimebaseInfo.denom;
+        QString key = "kwalletWallClockStartTime";
+        sharedStartTime.attachOrCreate( key, HRTime_Time() );
+        sharedStartTime.getValue(startTime);
+        qDebug() << "init_HRTime(): connected to kwalletWallClock at t=" << HRTime_Time();
+    }
+}
+
+namespace KWallet
+{
+
+#ifdef USE_KWALLETD
+class KWalletDLauncher
+{
+public:
+    KWalletDLauncher();
+    ~KWalletDLauncher();
+    org::kde::KWallet &getInterface();
+
+    org::kde::KWallet *m_wallet;
+    KConfigGroup m_cgroup;
+};
+
+K_GLOBAL_STATIC(KWalletDLauncher, walletLauncher)
+static const char s_kwalletdServiceName[] = "org.kde.kwalletd";
+
+#else
+
+/**
+ * maps wallet name to a map of app name to <wallet,pid> instances
+ */
+// deserialising the WalletUsersList from a QDataStream works only for a few WalletInstancePtr types
+// We could store the Wallet* in a QByteArray, but that would make it impossible to dump the WalletUsersList
+// to the console for debugging. So we use a QVariant.
+typedef QVariant WalletInstancePtr;
+// typedef QList<QPair<WalletInstancePtr,pid_t> > WalletUsersListEntryData;
+class WalletUsersListEntryData : public QList<QPair<WalletInstancePtr,pid_t> >
+{
+public:
+    static WalletUsersListEntryData create(QPair<WalletInstancePtr,pid_t> &head)
+    {
+        WalletUsersListEntryData self;
+        self.clear();
+        self.append(head);
+        return self;
+    }
+    static WalletUsersListEntryData create(QPair<WalletInstancePtr,pid_t> head)
+    {
+        WalletUsersListEntryData self;
+        self.clear();
+        self.append(head);
+        return self;
+    }
+};
+
+typedef QMap<QString,WalletUsersListEntryData> WalletUsersListEntry;
+typedef QMap<QString,WalletUsersListEntry> WalletUsersList;
+static WalletUsersList walletUsers;
+
+#endif //USE_KWALLETD
+
+
 static QString appid()
 {
     KComponentData cData = KGlobal::mainComponent();
@@ -63,7 +152,6 @@ static QString appid()
     }
     return qApp->applicationName();
 }
-#endif
 
 /*static*/ const QString Wallet::LocalWallet()
 {
@@ -104,26 +192,250 @@ static QString appid()
     return "Form Data";
 }
 
+#ifndef USE_KWALLETD
+static QStringList getUsersFromRegistry(QString &name)
+{   QString app = appid();
+    QStringList users;
+    users.clear();
+    if( walletUsers.contains(name) ){
+        WalletUsersListEntry entry = walletUsers[name];
+        for( WalletUsersListEntry::const_iterator it = entry.constBegin() ; it != entry.constEnd() ; ++it ){
+            if( !it.value().isEmpty() ){
+                users.append(it.key());
+            }
+        }
+    }
+    return users;
+}
+
+static void removeFromRegistry( QString app, QString &name, WalletUsersListEntryData &entries )
+{
+    for( WalletUsersListEntryData::const_iterator it = entries.constBegin() ; it != entries.constEnd() ; ++it ){
+        QPair<WalletInstancePtr,pid_t> wdat = *it;
+        if( walletUsers.contains(name) && walletUsers[name].contains(app) ){
+            WalletUsersListEntry entry = walletUsers[name];
+            WalletUsersListEntryData appInstances = entry[app];
+            if( appInstances.contains(wdat) ){
+                appInstances.removeAll(wdat);
+                qDebug() << "removing application instance" << wdat << "from registry";
+            }
+            if( appInstances.isEmpty() ){
+                entry.remove(app);
+                qDebug() << "removing application" << app << "from registry";
+            }
+            else{
+                entry[app] = appInstances;
+            }
+            if( entry[app].isEmpty() ){
+                walletUsers.remove(name);
+                qDebug() << "removing wallet" << name << "from registry";
+            }
+            else{
+                walletUsers[name] = entry;
+            }
+        }
+    }
+}
+#endif //USE_KWALLETD
+
 #pragma mark ==== Wallet::WalletPrivate ====
-class Wallet::WalletPrivate : public OSXKeychain
+Wallet::WalletPrivate::WalletPrivate(Wallet *wallet, const QString &n, int h)
+    : OSXKeychain(n, &isNew), q(wallet), handle(h)
+    , idleTimer(NULL)
+#ifdef IDLETIMER_DEBUG
+    , idleTimerTriggered(0)
+#endif
+    , lastConfigCheckTime(-1)
 {
-public:
-    explicit WalletPrivate(const QString &n)
-        : OSXKeychain(n)
-    {
-        isKDEChain = ( n == LocalWallet() || n == NetworkWallet() || n.contains( "wallet", Qt::CaseInsensitive ) );
+    isKDEChain = ( n == LocalWallet() || n == NetworkWallet() || n.contains( "wallet", Qt::CaseInsensitive ) );
+    if( !calibrator ){
+        init_HRTime();
+    }
+    if( isKDEChain ){
+        if( !lastAccessTime.attachOrCreate( (QString&)n, QSharedMemory::ReadWrite) ){
+            qDebug() << "Couldn't create shared lastAccessTime member for wallet" << n
+                << "; idle timeouts will be per-client. Error" << lastAccessTime.errorString();
+        }
+        handleIdleTiming(__FUNCTION__);
     }
+}
+Wallet::WalletPrivate::~WalletPrivate()
+{
+#ifndef USE_KWALLETD
+    removeFromRegistry();
+#endif //USE_KWALLETD
+    deleteIdleTimer();
+}
 
-    // needed for compilation reasons
-    void walletServiceUnregistered()
-    {
+#ifndef USE_KWALLETD
+void Wallet::WalletPrivate::addToRegistry()
+{   QString app = appid();
+    QPair<WalletInstancePtr,pid_t> wdat = qMakePair(QVariant((qulonglong)q),getpid());
+    if( !walletUsers.contains(name) ){
+        // Unknown wallet name, so there ought not be an existing QMap<appName,walletInstanceList>
+        WalletUsersListEntryData detail;
+        detail.clear();
+        detail.append(wdat);
+        WalletUsersListEntry entry;
+        entry.clear();
+        entry[app] = detail;
+        walletUsers[name] = entry;
     }
-};
+    else{
+        WalletUsersListEntry entry = walletUsers[name];
+        WalletUsersListEntryData detail;
+        if( entry.contains(app) ){
+            detail = entry[app];
+        }
+        else{
+            detail.clear();
+        }
+        detail.append(wdat);
+        entry[app] = detail;
+        walletUsers[name] = entry;
+    }
+    QByteArray mapData;
+    QDataStream ds(&mapData, QIODevice::WriteOnly);
+    ds << walletUsers;
+    qDebug() << "@@@" << HRTime_Time() << "Added" << wdat << "for app" << app << "to wallet" << name << "in registry of len=" << mapData.length() << walletUsers;
+}
+
+void Wallet::WalletPrivate::removeFromRegistry()
+{
+    WalletUsersListEntryData entries = WalletUsersListEntryData::create(qMakePair(QVariant((qulonglong)q),getpid()));
+    KWallet::removeFromRegistry( appid(), name, entries );
+}
+
+QStringList Wallet::WalletPrivate::getUsersFromRegistry()
+{
+    return KWallet::getUsersFromRegistry(name);
+}
+#endif //USE_KWALLETD
+
+void Wallet::WalletPrivate::close()
+{
+//     // close the keychain wallet but only if we get here through the kwalletmanager
+//     // or TODO if wallets should be closed when the last client disconnects
+//     // and we are the last client.
+//     if( appid() == "KDE Wallet Manager" ){
+        deleteIdleTimer();
+        OSXKeychain::close();
+//     }
+}
+
+OSStatus Wallet::WalletPrivate::lock()
+{
+    if( idleTimer ){
+        idleTimer->stop();
+    }
+    return Lock(reference());
+}
+
+void Wallet::WalletPrivate::walletServiceUnregistered()
+{
+#ifdef USE_KWALLETD
+    if( handle >= 0 ){
+        q->slotWalletClosed(handle);
+    }
+#endif
+}
+
+void Wallet::WalletPrivate::deleteIdleTimer()
+{
+    if( idleTimer ){
+        idleTimer->stop();
+        idleTimer->deleteLater();
+        idleTimer = NULL;
+    }
+}
+
+// This function is to be called at every operation that is supposed to launch or reset
+// the idle timing.
+void Wallet::WalletPrivate::handleIdleTiming(const char *caller, bool touchAccessTime)
+{
+    if( !isKDEChain ){
+        return;
+    }
+    double now = HRTime_Time();
+    if( lastConfigCheckTime < 0 || (now - lastConfigCheckTime >= 10) ){
+        lastConfigCheckTime = now;
+        KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
+        if (cfg.readEntry("Close When Idle", true)) {
+            timeOut = cfg.readEntry( "Idle Timeout", ((int)0) );
+            if( caller && idleTimer ){
+                qDebug() << "###" << caller << "->handleIdleTiming: setting" << idleTimer << "for wallet" << name << "handle" << handle << "timeout to" << timeOut;
+            }
+        }
+        else{
+            timeOut = -1;
+        }
+    }
+    if( timeOut >= 0 ){
+        if( !idleTimer ){
+            idleTimer = new QTimer(0);
+            connect( idleTimer, SIGNAL(timeout()), this, SLOT(slotIdleTimedOut()), Qt::DirectConnection );
+        }
+        else{
+            idleTimer->stop();
+        }
+        // when the idle timer fires, the wallet is supposed to be closed. There is thus
+        // no reason to use a repeating timer.
+        idleTimer->setSingleShot(true);
+        if( touchAccessTime ){
+            if( !lastAccessTime.setValue(HRTime_Time()) ){
+                qDebug() << "Cannot set new lastAccessTime for wallet" << name << "error" << lastAccessTime.errorString();
+            }
+        }
+        idleTimer->start( timeOut * 60 * 1000 );
+    }
+    else{
+        timeOut = -1;
+        deleteIdleTimer();
+    }
+}
+
+void Wallet::WalletPrivate::slotIdleTimedOut()
+{   double lastTime = 0;
+    // check the last time anyone accessed this wallet:
+    if( !lastAccessTime.getValue(lastTime) ){
+        qDebug() << "Cannot get lastAccessTime for wallet" << name << "error" << lastAccessTime.errorString();
+    }
+    // the time elapsed since that last access, in minutes:
+    double elapsed = (HRTime_Time() - lastTime) / 60;
+#ifdef IDLETIMER_DEBUG
+    idleTimerTriggered += 1;
+    qDebug() << "###" << HRTime_Time() << appid() << "Idle timeout" << timeOut << "min. for" << q << name << "handle" << handle
+        << "; elapsed minutes=" << elapsed << "timer" << idleTimer << "triggered" << idleTimerTriggered << "times";
+#endif //IDLETIMER_DEBUG
+    if( elapsed >= timeOut ){
+        // we have a true timeout, i.e. we didn't access the wallet in timeOut minutes, and no one else did either.
+        q->slotWalletClosed(handle);
+    }
+    else{
+        // false alarm, reset the timer, but there's no need to count this as an access!
+        handleIdleTiming(__FUNCTION__, false);
+    }
+}
 
 Wallet::Wallet(int handle, const QString& name)
-    : QObject(0L), d(new WalletPrivate(name))
+    : QObject(0L), d(new WalletPrivate(this, name, handle))
 {
-    Q_UNUSED(handle);
+#ifdef USE_KWALLETD
+    QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(),
+                                                           QDBusServiceWatcher::WatchForUnregistration, this);
+    connect(watcher, SIGNAL(serviceUnregistered(QString)),
+            d, SLOT(walletServiceUnregistered()));
+
+    connect(&walletLauncher->getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int)));
+    connect(&walletLauncher->getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString)));
+    connect(&walletLauncher->getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString)));
+    connect(&walletLauncher->getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString)));
+#else
+    d->addToRegistry();
+#endif // USE_KWALLETD
+    if( d->handle != handle ){
+        qDebug() << "Wallet::Wallet(" << name << ") handle changed from" << handle << "to" << d->handle;
+    }
 }
 
 Wallet::~Wallet()
@@ -172,6 +484,9 @@ Wallet::~Wallet()
 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     return walletLauncher->getInterface().isOpen(name); // default is false
 #else
+#ifdef USE_KWALLETD
+    walletLauncher->getInterface().isOpen(name);
+#endif // USE_KWALLETD
     return OSXKeychain::IsOpen(name);
 #endif
 }
@@ -181,6 +496,11 @@ bool Wallet::isOpen() const
 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     return d->handle != -1;
 #else
+    d->handleIdleTiming(__FUNCTION__);
+
+#ifdef USE_KWALLETD
+    QDBusReply<bool> r = walletLauncher->getInterface().isOpen(d->name);
+#endif // USE_KWALLETD
     return d->isOpen();
 #endif
 }
@@ -193,7 +513,12 @@ bool Wallet::isOpen() const
     return r.isValid() ? r : -1;
 #else
     Q_UNUSED(force);
-    return OSXKeychain::Lock(name);
+#ifdef USE_KWALLETD
+    QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
+#endif // USE_KWALLETD
+    // emit a signal that we just closed the wallet
+    Wallet(0, name).slotWalletClosed(0);
+    return OSXKeychain::IsOpen(name);
 #endif
 }
 
@@ -213,10 +538,25 @@ bool Wallet::isOpen() const
 {
     Q_UNUSED(w);
     Q_UNUSED(ot);
-    Wallet *wallet = new Wallet(-1, name);
-    QMetaObject::invokeMethod( wallet, "emitWalletOpened", Qt::QueuedConnection );
-    OSStatus err = wallet->d->unLock();
-    kDebug() << "Opened wallet '" << name << "': " << wallet << " error=" << err;
+    Wallet *wallet = new Wallet((int)w, name);
+    if( wallet ){
+#ifdef USE_KWALLETD
+        // connect the daemon's opened signal to the slot filtering the
+        // signals we need
+        connect(&walletLauncher->getInterface(), SIGNAL(walletAsyncOpened(int,int)),
+                wallet, SLOT(walletAsyncOpened(int,int)));
+#endif
+        OSStatus err = wallet->d->unLock();
+        if( !err && wallet->d->isKDEChain && wallet->d->isNew ){
+            wallet->d->setLockSettings( false, 0 );
+        }
+        kDebug() << "Opened wallet '" << name << "': " << wallet << " error=" << err;
+#ifdef USE_KWALLETD
+        wallet->emitWalletOpened();
+#else
+        QMetaObject::invokeMethod( wallet, "emitWalletOpened", Qt::QueuedConnection );
+#endif
+    }
     return wallet;
 }
 
@@ -226,8 +566,13 @@ bool Wallet::isOpen() const
 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     return walletLauncher->getInterface().disconnectApplication(wallet, app); // default is false
 #else
-    kWarning() << "Wallet::disconnectApplication unimplemented, '" << app << "' from '" << wallet << "'";
-    return true;
+    kWarning() << "Wallet::disconnectApplication unimplemented, '" << app << "' from '" << wallet << "'"
+#ifdef USE_KWALLETD
+        << walletLauncher->getInterface().disconnectApplication(wallet, app)
+#endif // USE_KWALLETD
+        ;
+    // app disconnect is done/possible only when the app in question closes its wallet.
+    return false;
 #endif
 }
 
@@ -237,8 +582,13 @@ bool Wallet::isOpen() const
 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     return walletLauncher->getInterface().users(name); // default is QStringList()
 #else
-    kWarning() << "Wallet::users unimplemented, '" << name << "'";
-    return QStringList();
+#ifdef USE_KWALLETD
+    QStringList ul = walletLauncher->getInterface().users(name);
+    kWarning() << "Wallet::users unimplemented, '" << name << "'" << ul;
+    return ul;
+#else
+    return KWallet::getUsersFromRegistry((QString&)name);
+#endif // USE_KWALLETD
 #endif
 }
 
@@ -250,8 +600,12 @@ int Wallet::sync()
         return -1;
     }
 
-    walletLauncher->getInterface().sync(d->handle, appid());
 #endif
+    d->handleIdleTiming(__FUNCTION__);
+
+#ifdef USE_KWALLETD
+    walletLauncher->getInterface().sync(d->handle, appid());
+#endif // USE_KWALLETD
     return 0;
 }
 
@@ -272,13 +626,17 @@ int Wallet::lockWallet()
     }
 #else
     d->currentService.clear();
+    d->handle = -1;
 #endif
-    return d->lock();
+    d->lock();
+    emit walletClosed();
+    return 1;
 }
 
 
 const QString& Wallet::walletName() const
 {
+    d->handleIdleTiming(__FUNCTION__);
     return d->name;
 }
 
@@ -295,6 +653,7 @@ void Wallet::requestChangePassword(WId w)
     walletLauncher->getInterface().changePassword(d->name, (qlonglong)w, appid());
 #else
     Q_UNUSED(w);
+    d->handleIdleTiming(__FUNCTION__);
     kWarning() << "Wallet::requestChangePassword unimplemented '" << d->name << "'";
 #endif
 }
@@ -310,9 +669,18 @@ void Wallet::slotWalletClosed(int handle)
         emit walletClosed();
     }
 #else
-    Q_UNUSED(handle);
-    kWarning() << "Wallet::slotWalletClosed unimplemented '" << d->name << "'";
-    d->currentService.clear();
+//     kWarning() << "Wallet::slotWalletClosed unimplemented '" << d->name << "'";
+    if( d->handle == handle ){
+        d->handle = -1;
+        d->currentService.clear();
+        kDebug() << "Wallet::slotWalletClosed '" << d->name << "'";
+        // TODO remove ourselves from the WalletUsersList here!
+        d->close();
+        emit walletClosed();
+    }
+    else{
+        qDebug() << "Wallet::slotWalletClosed '" << d->name << "' ignored because handle" << d->handle << "!=" << handle;
+    }
 #endif
 }
 
@@ -327,6 +695,7 @@ QStringList Wallet::folderList()
     QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle, appid());
     return r;
 #else
+    d->handleIdleTiming(__FUNCTION__);
     return QStringList(d->folderList());
 #endif
 }
@@ -342,6 +711,8 @@ QStringList Wallet::entryList()
     QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder, appid());
     return r;
 #else
+    d->handleIdleTiming(__FUNCTION__);
+
     QStringList r = QStringList();
     d->itemList(r);
     return r;
@@ -359,6 +730,7 @@ bool Wallet::hasFolder(const QString& f)
     QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f, appid());
     return r; // default is false
 #else
+    d->handleIdleTiming(__FUNCTION__);
     d->folderList();
     return d->serviceList.contains(f);
 #endif
@@ -379,6 +751,7 @@ bool Wallet::createFolder(const QString& f)
 
     return true;				// folder already exists
 #else
+    d->handleIdleTiming(__FUNCTION__);
     return setFolder(f);
 #endif
 }
@@ -407,6 +780,7 @@ bool Wallet::setFolder(const QString &f)
 
     return rc;
 #else
+    d->handleIdleTiming(__FUNCTION__);
     // act as if we just changed folders even if we have no such things; the property
     // is stored as the ServiceItemAttr (which shows up as the "Where" field in the Keychain Utility).
     if( f.size() == 0 ){
@@ -434,6 +808,7 @@ bool Wallet::removeFolder(const QString& f)
 
     return r;					// default is false
 #else
+    d->handleIdleTiming(__FUNCTION__);
     kWarning() << "Wallet::removeFolder unimplemented (returns true) '" << d->name << "'";
     if( d->currentService == f ){
         d->currentService.clear();
@@ -448,13 +823,16 @@ const QString& Wallet::currentFolder() const
 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     return d->folder;
 #else
+    d->handleIdleTiming(__FUNCTION__);
     return d->currentService;
 #endif
 }
 
 
 int Wallet::readEntry(const QString &key, QByteArray &value)
-{   OSStatus err = d->readItem( key, &value, NULL );
+{   OSStatus err;
+    d->handleIdleTiming(__FUNCTION__);
+    err = d->readItem( key, &value, NULL );
     kDebug() << "Wallet::readEntry '" << key << "' from wallet " << d->name << ", error=" << ((err)? -1 : 0);
     return (err)? -1 : 0;
 }
@@ -485,6 +863,7 @@ int Wallet::readEntryList(const QString& key, QMap<QString, QByteArray>& value)
 #else
     Q_UNUSED(key);
     Q_UNUSED(value);
+    d->handleIdleTiming(__FUNCTION__);
     kWarning() << "Wallet::readEntryList unimplemented (returns -1) '" << d->name << "'";
     return -1;
 #endif
@@ -507,6 +886,7 @@ int Wallet::renameEntry(const QString& oldName, const QString& newName)
 
     return rc;
 #else
+    d->handleIdleTiming(__FUNCTION__);
     return d->renameItem( oldName, newName );
 #endif
 }
@@ -514,6 +894,8 @@ int Wallet::renameEntry(const QString& oldName, const QString& newName)
 
 int Wallet::readMap(const QString &key, QMap<QString,QString> &value)
 {
+    d->handleIdleTiming(__FUNCTION__);
+
     QByteArray v;
     const int ret = (d->readItem( key, &v, NULL ))? -1 : 0;
     if( ret != 0 ){
@@ -560,6 +942,7 @@ int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString>
 #else
     Q_UNUSED(key);
     Q_UNUSED(value);
+    d->handleIdleTiming(__FUNCTION__);
     kWarning() << "Wallet::readMapList unimplemented (returns -1) '" << d->name << "'";
     return -1;
 #endif
@@ -568,6 +951,8 @@ int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString>
 
 int Wallet::readPassword(const QString& key, QString& value)
 {
+    d->handleIdleTiming(__FUNCTION__);
+
     QByteArray ba;
     const int ret = (d->readItem( key, &ba, NULL ))? -1 : 0;
     if ( ret == 0 ){
@@ -582,18 +967,23 @@ int Wallet::readPasswordList(const QString& key, QMap<QString, QString>& value)
 {
     Q_UNUSED(key);
     Q_UNUSED(value);
+    d->handleIdleTiming(__FUNCTION__);
     kWarning() << "Wallet::readPasswordList unimplemented (returns -1) '" << d->name << "'";
     return -1;
 }
 
 int Wallet::writeEntry(const QString& key, const QByteArray& password )
-{   int ret = d->writeItem( key, password );
+{   int ret;
+    d->handleIdleTiming(__FUNCTION__);
+    ret = d->writeItem( key, password );
     kDebug() << "wrote entry '" << key << "' to wallet " << d->name << ", error=" << ret;
     return ret;
 }
 
 int Wallet::writeEntry(const QString& key, const QByteArray& password, EntryType entryType)
 {
+    d->handleIdleTiming(__FUNCTION__);
+
     OSXKeychain::EntryType entryCode;
 	switch( entryType ){
 		case Wallet::Password:
@@ -616,6 +1006,8 @@ int Wallet::writeEntry(const QString& key, const QByteArray& password, EntryType
 
 int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value)
 {
+    d->handleIdleTiming(__FUNCTION__);
+
     QByteArray mapData;
     QDataStream ds(&mapData, QIODevice::WriteOnly);
     ds << value;
@@ -630,7 +1022,10 @@ int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value)
 
 
 int Wallet::writePassword(const QString &key, const QString& value)
-{   OSXKeychain::EntryType etype = OSXKeychain::Password;
+{   OSXKeychain::EntryType etype;
+
+    d->handleIdleTiming(__FUNCTION__);
+    etype = OSXKeychain::Password;
     int ret = d->writeItem( key, value.toUtf8(), &etype );
     kDebug() << "wrote password '" << key << "' to wallet " << d->name << ", error=" << ret;
     return ret;
@@ -638,13 +1033,19 @@ int Wallet::writePassword(const QString &key, const QString& value)
 
 
 bool Wallet::hasEntry(const QString &key)
-{   bool ret = d->hasItem( key, NULL );
+{   bool ret;
+
+    d->handleIdleTiming(__FUNCTION__);
+    ret = d->hasItem( key, NULL );
     kDebug() << "wallet '" << d->name << "'" << ((ret)? " has" : " does not have") << " entry '" << key << "'";
     return ret;
 }
 
 int Wallet::removeEntry(const QString& key)
-{   int ret = d->removeItem( key );
+{   int ret;
+
+    d->handleIdleTiming(__FUNCTION__);
+    ret = d->removeItem( key );
     kDebug() << "removed entry '" << key << "' from wallet " << d->name << ", error=" << ret;
     return ret;
 }
@@ -666,6 +1067,8 @@ Wallet::EntryType Wallet::entryType(const QString& key)
 
     return static_cast<EntryType>(rc);
 #else
+    d->handleIdleTiming(NULL);
+
     // RJVB: a priori, entries are always 'password' on OS X, but since we also do use them for storing
     // maps, it may be best to return Wallet::Unknown to leave some uncertainty and not mislead our caller.
     OSXKeychain::EntryType etype;
@@ -690,6 +1093,7 @@ Wallet::EntryType Wallet::entryType(const QString& key)
 void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder)
 {
     if (d->name == wallet) {
+        kDebug() << "emit folderUpdated" << folder;
         emit folderUpdated(folder);
     }
 }
@@ -698,6 +1102,7 @@ void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder)
 void Wallet::slotFolderListUpdated(const QString& wallet)
 {
     if (d->name == wallet) {
+        kDebug() << "emit foldeListrUpdated" << wallet;
         emit folderListUpdated();
     }
 }
@@ -705,17 +1110,19 @@ void Wallet::slotFolderListUpdated(const QString& wallet)
 
 void Wallet::slotApplicationDisconnected(const QString& wallet, const QString& application)
 {
-#ifdef OSX_KEYCHAIN_PORT_DISABLED
-    if (d->handle >= 0
+#ifdef USE_KWALLETD
+    qDebug() << "slotApplicationDisconnected(" << wallet << "," << application << "); handle="
+        << d->handle << "name=" << d->name << "appid=" << appid();
+    if( d->handle >= 0
         && d->name == wallet
-        && application == appid()) {
+        && application == appid()
+    ){
         slotWalletClosed(d->handle);
     }
 #else
     Q_UNUSED(wallet);
     Q_UNUSED(application);
-	kWarning() << "Wallet::slotApplicationDisconnected unimplemented '" << d->name << "'";
-#endif
+#endif //USE_KWALLETD
 }
 
 void Wallet::walletAsyncOpened(int tId, int handle)
@@ -733,23 +1140,33 @@ void Wallet::walletAsyncOpened(int tId, int handle)
     emit walletOpened(handle > 0);
 #else
     Q_UNUSED(tId);
-    Q_UNUSED(handle);
-	kWarning() << "Wallet::walletAsyncOpened unimplemented '" << d->name << "'";
+    d->handleIdleTiming(__FUNCTION__);
+#ifdef USE_KWALLETD
+    // disconnect the async signal
+    disconnect(this, SLOT(walletAsyncOpened(int,int)));
+    qDebug() << "walletAsyncOpened: emit walletOpened(true), handle=" << handle;
+    emit walletOpened(true);
+#endif // USE_KWALLETD
+    d->handle = handle;
 #endif
 }
 
 void Wallet::emitWalletAsyncOpenError()
 {
+    d->handleIdleTiming(__FUNCTION__);
+    kDebug() << "emitWalletAsyncOpenError: emit walletOpened(false)";
     emit walletOpened(false);
 }
 
 void Wallet::emitWalletOpened()
 {
-  emit walletOpened(true);
+    d->handleIdleTiming(__FUNCTION__);
+    kDebug() << "emitWalletOpened: emit walletOpened(true)";
+    emit walletOpened(true);
 }
 
 
-bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
+/*static*/ bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
 {
 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
@@ -764,7 +1181,7 @@ bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
 }
 
 
-bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
+/*static*/ bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
 {
 #ifdef OSX_KEYCHAIN_PORT_DISABLED
     QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
@@ -784,7 +1201,8 @@ bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const
 void Wallet::slotCollectionStatusChanged(int status)
 {
     Q_UNUSED(status);
-	kWarning() << "Wallet::slotCollectionStatusChanged unimplemented '" << d->name << "' status=" << status;
+    d->handleIdleTiming(__FUNCTION__);
+    kWarning() << "Wallet::slotCollectionStatusChanged unimplemented '" << d->name << "' status=" << status;
 }
 
 void Wallet::slotCollectionDeleted()
@@ -795,6 +1213,7 @@ void Wallet::slotCollectionDeleted()
     d->currentService.clear();
 #endif
     kDebug() << "Wallet::slotCollectionDeleted: closing private data '" << d->name;
+    // TODO remove ourselves from the WalletUsersList here!
     d->close();
     emit walletClosed();
 }
@@ -805,4 +1224,51 @@ void Wallet::virtual_hook(int, void*)
     //BASE::virtual_hook( id, data );
 }
 
+#ifdef USE_KWALLETD
+KWalletDLauncher::KWalletDLauncher()
+    : m_wallet(0),
+    m_cgroup(KSharedConfig::openConfig("kwalletrc", KConfig::NoGlobals)->group("Wallet"))
+{
+    m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), "/modules/kwalletd", QDBusConnection::sessionBus());
+}
+
+KWalletDLauncher::~KWalletDLauncher()
+{
+    delete m_wallet;
+}
+
+org::kde::KWallet &KWalletDLauncher::getInterface()
+{
+    Q_ASSERT(m_wallet != 0);
+
+    // check if kwalletd is already running
+    if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName)))
+    {
+        // not running! check if it is enabled.
+        bool walletEnabled = m_cgroup.readEntry("Enabled", true);
+        if (walletEnabled) {
+            // wallet is enabled! try launching it
+            QString error;
+            int ret = KToolInvocation::startServiceByDesktopPath("kwalletd.desktop", QStringList(), &error);
+            if (ret > 0){
+                kError(285) << "Couldn't start kwalletd: " << error << endl;
+            }
+
+            if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) {
+                kDebug(285) << "The kwalletd service is still not registered";
+            } else {
+                kDebug(285) << "The kwalletd service has been registered";
+            }
+        } else {
+            kError(285) << "The kwalletd service has been disabled";
+        }
+    }
+
+    return *m_wallet;
+}
+#endif //USE_KWALLETD
+
+} // namespace KWallet
+
+#include "kwallet_mac.moc"
 #include "kwallet.moc"
diff --git kdeui/util/qosxkeychain.cpp kdeui/util/qosxkeychain.cpp
index 7cb9a22..708c728 100644
--- kdeui/util/qosxkeychain.cpp
+++ kdeui/util/qosxkeychain.cpp
@@ -161,7 +161,7 @@ OSXKeychain::OSXKeychain()
     serviceList.append("");
 }
 
-OSXKeychain::OSXKeychain(const QString &n)
+OSXKeychain::OSXKeychain(const QString &n, bool *isNew)
     : name(n)
 {   QString errMsg;
     OSStatus err = openKeychain( n, &keyChainRef );
@@ -170,6 +170,12 @@ OSXKeychain::OSXKeychain(const QString &n)
         kWarning() << "Keychain '" << n << "' does not exist: attempting to create it";
         err = SecKeychainCreate( n.toUtf8(), 0, NULL, true, NULL, &keyChainRef );
         isKDEChain = true;
+        if( !err && isNew ){
+            *isNew = true;
+        }
+    }
+    else if( !err && isNew ){
+        *isNew = false;
     }
 
     if( isError( err, &errMsg ) ){
@@ -197,14 +203,58 @@ OSXKeychain::OSXKeychain(const QString &n)
 void OSXKeychain::close()
 {
     if( keyChainRef ){
+        Lock(keyChainRef);
         CFRelease(keyChainRef);
         keyChainRef = NULL;
+        serviceList.clear();
     }
 }
 
 OSXKeychain::~OSXKeychain()
 {
-    close();
+    if( keyChainRef ){
+        CFRelease(keyChainRef);
+        keyChainRef = NULL;
+    }
+    serviceList.clear();
+}
+
+OSStatus OSXKeychain::lockSettings(int &closeWhenIdle, unsigned int &idleTimeoutMin)
+{   QString errMsg;
+    SecKeychainSettings kcSettings= { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
+    OSStatus err = SecKeychainCopySettings( keyChainRef, &kcSettings );
+    if( isError( err, &errMsg ) ){
+        kWarning() << "Error getting settings for" << name << err << "=" << qPrintable(errMsg);
+    }
+    else{
+        closeWhenIdle = kcSettings.useLockInterval;
+        idleTimeoutMin = (int)(kcSettings.lockInterval / 60 + 0.5);
+    }
+    return err;
+}
+
+OSStatus OSXKeychain::setLockSettings(int closeWhenIdle, unsigned int idleTimeoutMin)
+{   QString errMsg;
+    SecKeychainSettings kcSettings = { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
+    OSStatus err;
+
+    // to switch (or keep) off idle timeout locking set useLockInterval=false and lockInterval=INT_MAX
+    // if lockInterval has any other value, SecKeychainSetSettings() will force useLockInterval=true
+    if( closeWhenIdle ){
+        kcSettings.useLockInterval = 1;
+        kcSettings.lockInterval = idleTimeoutMin * 60;
+    }
+    err = SecKeychainSetSettings( keyChainRef, &kcSettings );
+//     if( !err ){
+//         SecKeychainSettings ks = { SEC_KEYCHAIN_SETTINGS_VERS1, 0, 0, INT_MAX };
+//         ks.useLockInterval = !closeWhenIdle;
+//         SecKeychainCopySettings( keyChainRef, &ks );
+//         qDebug() << "Keychain settings set to useLockInterval=" << ks.useLockInterval << "lockInterval=" << ks.lockInterval;
+//     }
+//     else{
+//         qDebug() << "Error setting keychain settings:" << err;
+//     }
+    return err;
 }
 
 OSStatus OSXKeychain::renameItem(const QString &currentKey, const QString &newKey)
@@ -330,7 +380,7 @@ OSStatus OSXKeychain::Lock(const QString &walletName)
     OSStatus err = openKeychain( walletName, &keychain );
     if( !err && keychain ){
         err = Lock(keychain);
-	   CFRelease(keychain);
+        CFRelease(keychain);
     }
     return err;
 }
@@ -377,7 +427,7 @@ bool OSXKeychain::HasItem(const QString &key,
 	        *errReturn = err;
 	    }
     }
-    kDebug() << ((found)? "Found" : "Did not find") << "item '" << key << "' in keychain " << (void*) keychain << ", error=" << err << " " << qPrintable(errMsg);
+    kDebug() << "item '" << key << ((found)? "found" : "not found") << "' in keychain " << (void*) keychain << ", error=" << err << " " << qPrintable(errMsg);
     return found;
 }
 
diff --git kdeui/util/qosxkeychain.h kdeui/util/qosxkeychain.h
index d0934e6..7370418 100644
--- kdeui/util/qosxkeychain.h
+++ kdeui/util/qosxkeychain.h
@@ -18,6 +18,8 @@
  * Boston, MA 02110-1301, USA.
  */
 
+#ifndef _QOSXKEYCHAIN_H
+
 #include <Security/Security.h>
 #include <Security/SecKeychain.h>
 
@@ -59,17 +61,23 @@ namespace {
 }
 
 static inline QString asQString( CFStringRef sr )
-{   CFIndex len = CFStringGetLength(sr)*2;
-    const CPPArrayDeleter<char*> buff(new char[len]);
-    if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingUTF8 ) ){
-        return QString::fromUtf8(buff.ptr); //RJVB: use UTF8
-    }
-    else if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingNonLossyASCII ) ){
-        return QString::fromLocal8Bit(buff.ptr);
+{
+    if( sr ){
+        CFIndex len = CFStringGetLength(sr)*2;
+        const CPPArrayDeleter<char*> buff(new char[len]);
+        if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingUTF8 ) ){
+            return QString::fromUtf8(buff.ptr); //RJVB: use UTF8
+        }
+        else if( CFStringGetCString( sr, buff.ptr, len, kCFStringEncodingNonLossyASCII ) ){
+            return QString::fromLocal8Bit(buff.ptr);
+        }
+        else{
+            CFStringGetCString( sr, buff.ptr, len, NULL );
+            return QString::fromLatin1(buff.ptr);
+        }
     }
     else{
-        CFStringGetCString( sr, buff.ptr, len, NULL );
-        return QString::fromLatin1(buff.ptr);
+        return QString();
     }
 }
 
@@ -87,8 +95,9 @@ static inline bool isError( OSStatus s, QString *errMsg )
     return s != 0;
 }
 
-class OSXKeychain
+class OSXKeychain //: protected QObject
 {
+//    Q_OBJECT
 private:
     SecKeychainRef keyChainRef;
     QString keyChainPath;
@@ -102,7 +111,7 @@ public:
     bool isKDEChain;
 
     OSXKeychain();
-    OSXKeychain(const QString &name);
+    OSXKeychain(const QString &name, bool *isNew=NULL);
     virtual ~OSXKeychain();
 
     inline SecKeychainRef reference()
@@ -119,54 +128,113 @@ public:
     }
     inline bool isOpen()
     {
-        return IsOpen(keyChainRef);
+        // we're either a KDE wallet/keychain and we have a valid keyChainRef,
+        // or we're not KDE and IsOpen will return the state of the default
+        // keychain if keyChainRef==NULL.
+        if( !isKDEChain || keyChainRef ){
+            return IsOpen(keyChainRef);
+        }
+        else{
+            return false;
+        }
     }
     inline OSStatus lock()
     {
-        return Lock(keyChainRef);
+        if( !isKDEChain || keyChainRef ){
+            return Lock(keyChainRef);
+        }
+        else{
+            return 0;
+        }
     }
     inline OSStatus unLock()
     {
-        return UnLock(keyChainRef);
+        if( !isKDEChain || keyChainRef ){
+            return UnLock(keyChainRef);
+        }
+        else{
+            return 0;
+        }
     }
-    void close();
+    virtual void close();
+    OSStatus lockSettings(int &closeWhenIdle, unsigned int &idleTimeoutMin);
+    OSStatus setLockSettings(int closeWhenIdle, unsigned int idleTimeoutMin);
     inline bool hasItem(const QString &key, OSStatus *errReturn, SecKeychainItemRef *itemRef=NULL)
     {
-	    // qDebug() << "OSXKeychain::hasItem(" << key << "): scanning '" << name << "'=" << (void*) keyChainRef;
-	    return OSXKeychain::HasItem( key, keyChainRef, errReturn, itemRef );
+        if( !isKDEChain || keyChainRef ){
+            return OSXKeychain::HasItem( key, keyChainRef, errReturn, itemRef );
+        }
+        else{
+            return false;
+        }
     }
     inline OSStatus readItem(const QString &key, QByteArray *value, SecKeychainItemRef *itemRef=NULL)
     {
-        return ReadItem( key, value, keyChainRef, itemRef, this );
+        if( !isKDEChain || keyChainRef ){
+            return ReadItem( key, value, keyChainRef, itemRef, this );
+        }
+        else{
+            return 0;
+        }
     }
     inline OSStatus itemType(const QString &key, EntryType *entryType)
     {
-        return ItemType( key, entryType, keyChainRef );
+        if( !isKDEChain || keyChainRef ){
+            return ItemType( key, entryType, keyChainRef );
+        }
+        else{
+            return 0;
+        }
     }
     inline OSStatus removeItem(const QString &key)
     {
-        return RemoveItem( key, keyChainRef );
+        if( !isKDEChain || keyChainRef ){
+            return RemoveItem( key, keyChainRef );
+        }
+        else{
+            return 0;
+        }
     }
     inline OSStatus writeItem( const QString &key, const QByteArray &value, EntryType *entryType=NULL )
     {
-        return WriteItem( key, value, keyChainRef, NULL, entryType, this );
+        if( !isKDEChain || keyChainRef ){
+            return WriteItem( key, value, keyChainRef, NULL, entryType, this );
+        }
+        else{
+            return 0;
+        }
     }
     inline OSStatus writeItem( const QString &key, const QByteArray &value, const QString &comment,
                                EntryType *entryType=NULL )
     {
-        return WriteItem( key, value, comment, keyChainRef, entryType, this );
+        if( !isKDEChain || keyChainRef ){
+            return WriteItem( key, value, comment, keyChainRef, entryType, this );
+        }
+        else{
+            return 0;
+        }
     }
     inline OSStatus itemList( QStringList &keyList )
     {
-        return ItemList( keyChainRef, keyList, this );
+        if( !isKDEChain || keyChainRef ){
+            return ItemList( keyChainRef, keyList, this );
+        }
+        else{
+            return 0;
+        }
     }
     inline QStringList folderList()
     {
-        QStringList r;
-        CacheOldValue<bool> gFL(generateFolderList, true);
-        ItemList( keyChainRef, r, this );
-        r.clear();
-        return serviceList;
+        if( !isKDEChain || keyChainRef ){
+            QStringList r;
+            CacheOldValue<bool> gFL(generateFolderList, true);
+            ItemList( keyChainRef, r, this );
+            r.clear();
+            return serviceList;
+        }
+        else{
+            return QStringList();
+        }
     }
     OSStatus renameItem(const QString &currentKey, const QString &newKey);
 
@@ -197,4 +265,11 @@ public:
     static OSStatus ItemList( const SecKeychainRef keychain, QStringList &keyList, OSXKeychain *osxKeyChain=NULL );
     static OSStatus Destroy( SecKeychainRef *keychain );
     static OSStatus Destroy( const QString &walletName );
+
+// private Q_SLOTS:
+//     virtual void slotIdleTimedOut()
+//     {}
 };
+
+#define _QOSXKEYCHAIN_H
+#endif
\ No newline at end of file
diff --git kdeui/widgets/kmenu.cpp kdeui/widgets/kmenu.cpp
index 7dab149..9b64236 100644
--- kdeui/widgets/kmenu.cpp
+++ kdeui/widgets/kmenu.cpp
@@ -42,6 +42,11 @@
 #include <klocale.h>
 #include <kacceleratormanager.h>
 
+#ifdef Q_OS_MAC
+#include <kmainwindow.h>
+#include <kmenubar.h>
+#endif //Q_OS_MAC
+
 static const char KMENU_TITLE[] = "kmenu_title";
 
 class KMenu::KMenuPrivate
@@ -172,25 +177,100 @@ QAction* KMenu::addTitle(const QString &text, QAction* before)
     return addTitle(QIcon(), text, before);
 }
 
+#ifdef Q_OS_MAC
+static bool isMenubarMenu(QMenu *m)
+{   bool ret = false;
+        static int level = -1;
+    QList<QMenu*> checkList;
+    level += 1;
+    if (m && m->menuAction()) {
+        QAction *mAct = m->menuAction();
+        qDebug() << "##" << level << "isMenubarMenu(" << m << m->title() << ") menuAction=" << mAct << mAct->text();
+        foreach (QWidget *w, mAct->associatedWidgets()) {
+            if (w == m) {
+                goto done;
+            }
+            qDebug() << "###" << level << "associated widget" << w << w->windowTitle() << "parent=" << w->parentWidget();
+            if (QMenuBar *mb = qobject_cast<QMenuBar*>(w)) {
+                qDebug() << "#### widget is QMenuBar" << mb << mb->windowTitle() << "with parent" << mb->parentWidget();
+                ret = true;
+                goto done;
+            }
+            else if (QMenu *mm = qobject_cast<QMenu*>(w)) {
+                if (checkList.contains(mm)) {
+                    continue;
+                }
+                checkList.append(mm);
+                qDebug() << "####" << level << "widget is QMenu" << mm << mm->title() << "with parent" << mm->parentWidget();
+                if (isMenubarMenu(mm)) {
+                    ret = true;
+                    goto done;
+                }
+            }
+        }
+    }
+done:;
+    level -= 1;
+    return ret;
+}
+#endif
+
 QAction* KMenu::addTitle(const QIcon &icon, const QString &text, QAction* before)
 {
-    QAction *buttonAction = new QAction(this);
-    QFont font = buttonAction->font();
-    font.setBold(true);
-    buttonAction->setFont(font);
-    buttonAction->setText(text);
-    buttonAction->setIcon(icon);
-
-    QWidgetAction *action = new QWidgetAction(this);
-    action->setObjectName(KMENU_TITLE);
-    QToolButton *titleButton = new QToolButton(this);
-    titleButton->installEventFilter(d); // prevent clicks on the title of the menu
-    titleButton->setDefaultAction(buttonAction);
-    titleButton->setDown(true); // prevent hover style changes in some styles
-    titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
-    action->setDefaultWidget(titleButton);
-
-    insertAction(before, action);
+#ifdef Q_OS_MAC
+    bool isMacMenuBar = isMenubarMenu(this);
+#else
+    bool isMacMenuBar = false;
+#endif // Q_OS_MAC
+    QAction *action = new QAction(this);
+    action->setText(text);
+    action->setIcon(icon);
+#ifdef Q_OS_MAC
+    if (isMacMenuBar) {
+        action->setEnabled(false);
+        if (before && actions().contains(before)) {
+            QAction *sepLow = new QAction(this);
+            sepLow->setSeparator(true);
+            insertAction(before, sepLow);
+            insertAction(sepLow, action);
+            if (!actions().startsWith(action)) {
+                QAction *sepHigh = new QAction(this);
+                sepHigh->setSeparator(true);
+                insertAction(action,sepHigh);
+                qDebug() << "#### inserted high separator before" << action << action->text() << "before low separator before" << before;
+            }
+            else{
+                qDebug() << "#### inserted" << action << action->text() << "before low separator before" << before;
+            }
+        }
+        else{
+            if (actions().size()) {
+                addSeparator();
+            }
+            addAction(action);
+            addSeparator();
+            qDebug() << "#### appended low separator after" << action << action->text() << "after existing" << actions().size()-2 << "items (before=" << before;
+        }
+    }
+    else
+#endif // Q_OS_MAC
+    {
+        QFont font = action->font();
+        font.setBold(true);
+        action->setFont(font);
+
+        QWidgetAction *styledAction = new QWidgetAction(this);
+        styledAction->setObjectName(KMENU_TITLE);
+        QToolButton *titleButton = new QToolButton(this);
+        titleButton->installEventFilter(d); // prevent clicks on the title of the menu
+        titleButton->setDefaultAction(action);
+        titleButton->setDown(true); // prevent hover style changes in some styles
+        titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+        styledAction->setDefaultWidget(titleButton);
+
+        insertAction(before, styledAction );
+        action = styledAction;
+    }
     return action;
 }
 
