Index: trunk/src/VBox/Frontends/VirtualBox4/include/VBoxDefs.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox4/include/VBoxDefs.h	(revision 14907)
+++ trunk/src/VBox/Frontends/VirtualBox4/include/VBoxDefs.h	(revision 14908)
@@ -120,5 +120,7 @@
 #if defined (VBOX_GUI_WITH_SYSTRAY)
         CanShowTrayIconEventType,
-        ChangeTrayIconEventType,
+        ShowTrayIconEventType,
+        TrayIconChangeEventType,
+        MainWindowCountChangeEventType,
 #endif
         AddVDMUrlsEventType
Index: trunk/src/VBox/Frontends/VirtualBox4/include/VBoxGlobal.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox4/include/VBoxGlobal.h	(revision 14907)
+++ trunk/src/VBox/Frontends/VirtualBox4/include/VBoxGlobal.h	(revision 14908)
@@ -391,4 +391,15 @@
 
 #ifdef VBOX_GUI_WITH_SYSTRAY
+class VBoxMainWindowCountChangeEvent : public QEvent
+{
+public:
+    VBoxMainWindowCountChangeEvent (int aCount)
+        : QEvent ((QEvent::Type) VBoxDefs::MainWindowCountChangeEventType)
+        , mCount (aCount)
+        {}
+
+    const int mCount;
+};
+
 class VBoxCanShowTrayIconEvent : public QEvent
 {
@@ -402,13 +413,24 @@
 };
 
+class VBoxShowTrayIconEvent : public QEvent
+{
+public:
+    VBoxShowTrayIconEvent (bool aShow)
+        : QEvent ((QEvent::Type) VBoxDefs::ShowTrayIconEventType)
+        , mShow (aShow)
+        {}
+
+    const bool mShow;
+};
+
 class VBoxChangeTrayIconEvent : public QEvent
 {
 public:
-    VBoxChangeTrayIconEvent (bool aEnabled)
-        : QEvent ((QEvent::Type) VBoxDefs::ChangeTrayIconEventType)
-        , mEnabled (aEnabled)
+    VBoxChangeTrayIconEvent (bool aChanged)
+        : QEvent ((QEvent::Type) VBoxDefs::TrayIconChangeEventType)
+        , mChanged (aChanged)
         {}
 
-    const bool mEnabled;
+    const bool mChanged;
 };
 #endif
@@ -483,6 +505,7 @@
     bool isVMConsoleProcess() const { return !vmUuid.isNull(); }
 #ifdef VBOX_GUI_WITH_SYSTRAY
-    bool hasTrayIcon() const;
     bool isTrayMenu() const;
+    void setTrayMenu(bool aIsTrayMenu);
+    void trayIconShowSelector();
     bool trayIconInstall();
 #endif
@@ -956,5 +979,7 @@
     void snapshotChanged (const VBoxSnapshotEvent &e);
 #ifdef VBOX_GUI_WITH_SYSTRAY
+    void mainWindowCountChanged (const VBoxMainWindowCountChangeEvent &e);
     void trayIconCanShow (const VBoxCanShowTrayIconEvent &e);
+    void trayIconShow (const VBoxShowTrayIconEvent &e);
     void trayIconChanged (const VBoxChangeTrayIconEvent &e);
 #endif
@@ -1000,5 +1025,4 @@
 
 #ifdef VBOX_GUI_WITH_SYSTRAY
-    bool mHasTrayIcon;          /* Is current instance responsible for tray icon? */
     bool mIsTrayMenu;           /* Tray icon active/desired? */
 #endif
Index: trunk/src/VBox/Frontends/VirtualBox4/include/VBoxSelectorWnd.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox4/include/VBoxSelectorWnd.h	(revision 14907)
+++ trunk/src/VBox/Frontends/VirtualBox4/include/VBoxSelectorWnd.h	(revision 14908)
@@ -131,5 +131,7 @@
     void snapshotChanged (const VBoxSnapshotEvent &e);
 #ifdef VBOX_GUI_WITH_SYSTRAY
+    void mainWindowCountChanged (const VBoxMainWindowCountChangeEvent &aEvent);
     void trayIconCanShow (const VBoxCanShowTrayIconEvent &e);
+    void trayIconShow (const VBoxShowTrayIconEvent &e);
     void trayIconChanged (const VBoxChangeTrayIconEvent &e);
 #endif
Index: trunk/src/VBox/Frontends/VirtualBox4/src/VBoxGlobal.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox4/src/VBoxGlobal.cpp	(revision 14907)
+++ trunk/src/VBox/Frontends/VirtualBox4/src/VBoxGlobal.cpp	(revision 14908)
@@ -864,4 +864,6 @@
                     QApplication::postEvent (&mGlobal, new VBoxChangeGUILanguageEvent (sVal));
 #ifdef VBOX_GUI_WITH_SYSTRAY
+                if (sKey == "GUI/MainWindowCount")
+                    QApplication::postEvent (&mGlobal, new VBoxMainWindowCountChangeEvent (sVal.toInt()));
                 if (sKey == VBoxDefs::GUI_TrayIconWinID)
                 {
@@ -1244,5 +1246,4 @@
     , mUpdDlg (NULL)
 #ifdef VBOX_GUI_WITH_SYSTRAY
-    , mHasTrayIcon (false)
     , mIsTrayMenu (false)
 #endif
@@ -1415,13 +1416,4 @@
 
 /**
- *  Returns true if the current instance is responsible of showing/handling
- *  the tray icon.
- */
-bool VBoxGlobal::hasTrayIcon() const
-{
-    return mHasTrayIcon;
-}
-
-/**
  *  Returns true if the current instance a systray menu only (started with
  *  "-systray" parameter).
@@ -1429,32 +1421,70 @@
 bool VBoxGlobal::isTrayMenu() const
 {
-    return (mHasTrayIcon && mIsTrayMenu);
+    return mIsTrayMenu;
+}
+
+void VBoxGlobal::setTrayMenu(bool aIsTrayMenu)
+{
+    mIsTrayMenu = aIsTrayMenu;
+}
+
+/**
+ *  Spawns a new selector window (process).
+ */
+void VBoxGlobal::trayIconShowSelector()
+{
+    /* Get the path to the executable. */
+    char path [RTPATH_MAX];
+    RTPathAppPrivateArch (path, RTPATH_MAX);
+    size_t sz = strlen (path);
+    path [sz++] = RTPATH_DELIMITER;
+    path [sz] = 0;
+    char *cmd = path + sz;
+    sz = RTPATH_MAX - sz;
+
+    int rc = 0;
+    RTPROCESS pid = NIL_RTPROCESS;
+    RTENV env = RTENV_DEFAULT;
+
+    const char VirtualBox_exe[] = "VirtualBox" HOSTSUFF_EXE;
+    Assert (sz >= sizeof (VirtualBox_exe));
+    strcpy (cmd, VirtualBox_exe);
+# ifdef RT_OS_WINDOWS /** @todo drop this once the RTProcCreate bug has been fixed */
+    const char * args[] = {path, 0 };
+# else
+    const char * args[] = {path, 0 };
+# endif
+    rc = RTProcCreate (path, args, env, 0, &pid);
+    if (RT_FAILURE (rc))
+        LogRel(("Systray: Failed to start new selector window! Path=%s, rc=%Rrc\n", path, rc));
 }
 
 /**
  *  Tries to install the tray icon using the current instance (singleton).
- *  Returns true on success, false on failure.
+ *  Returns true if this instance is the tray icon, false if not.
  */
 bool VBoxGlobal::trayIconInstall()
 {
-    bool bActive = mIsTrayMenu;
-    if (false == bActive)
-        bActive = vboxGlobal().settings().trayIconEnabled();
+    int rc = 0;
+    QString strTrayWinID = mVBox.GetExtraData (VBoxDefs::GUI_TrayIconWinID);
+    if (false == strTrayWinID.isEmpty())
+    {
+        /* Check if current tray icon is alive by writing some bogus value. */
+        mVBox.SetExtraData (VBoxDefs::GUI_TrayIconWinID, "0");
+        if (mVBox.isOk())
+        {
+            /* Current tray icon died - clean up. */
+            mVBox.SetExtraData (VBoxDefs::GUI_TrayIconWinID, NULL);
+            strTrayWinID.clear();
+        }
+    }
 
     /* Is there already a tray icon or is tray icon not active? */
-    QString strTrayWinID = mVBox.GetExtraData (VBoxDefs::GUI_TrayIconWinID);
-    if (   (bActive == false)
-        || (QSystemTrayIcon::isSystemTrayAvailable() == false)
-        || (strTrayWinID.isEmpty() == false))
-    {
-        return false;
-    }
-
-    int rc = 0;
-    if (isVMConsoleProcess())
-    {
-        // Spawn new selector window instance
-
-        // Get the path to the executable
+    if (   (mIsTrayMenu == false)
+        && (vboxGlobal().settings().trayIconEnabled())
+        && (QSystemTrayIcon::isSystemTrayAvailable())
+        && (strTrayWinID.isEmpty()))
+    {
+        /* Get the path to the executable. */
         char path [RTPATH_MAX];
         RTPathAppPrivateArch (path, RTPATH_MAX);
@@ -1471,17 +1501,18 @@
         Assert (sz >= sizeof (VirtualBox_exe));
         strcpy (cmd, VirtualBox_exe);
-# ifdef RT_OS_WINDOWS /** @todo drop this once the RTProcCreate bug has been fixed */
+    # ifdef RT_OS_WINDOWS /** @todo drop this once the RTProcCreate bug has been fixed */
         const char * args[] = {path, "-systray", 0 };
-# else
+    # else
         const char * args[] = {path, "-systray", 0 };
-# endif
+    # endif
         rc = RTProcCreate (path, args, env, 0, &pid);
         if (RT_FAILURE (rc))
         {
-            LogRel(("Failed to start systray window! Path=%s, rc=%Rrc\n", path, rc));
+            LogRel(("Systray: Failed to start systray window! Path=%s, rc=%Rrc\n", path, rc));
             return false;
         }
     }
-    else
+
+    if (mIsTrayMenu)
     {
         // Use this selector for displaying the tray icon
@@ -1493,10 +1524,10 @@
         if (mVBox.isOk())
         {
-            mHasTrayIcon = true;
-            emit trayIconChanged (*(new VBoxChangeTrayIconEvent (vboxGlobal().settings().trayIconEnabled())));
-        }
-    }
-
-    return mHasTrayIcon;
+            emit trayIconShow (*(new VBoxShowTrayIconEvent (true)));
+            return true;
+        }
+    }
+
+    return false;
 }
 
@@ -5204,4 +5235,9 @@
         }
 #ifdef VBOX_GUI_WITH_SYSTRAY
+        case VBoxDefs::MainWindowCountChangeEventType:
+
+            emit mainWindowCountChanged (*(VBoxMainWindowCountChangeEvent *) e);
+            return true;
+
         case VBoxDefs::CanShowTrayIconEventType:
         {
@@ -5209,5 +5245,10 @@
             return true;
         }
-        case VBoxDefs::ChangeTrayIconEventType:
+        case VBoxDefs::ShowTrayIconEventType:
+        {
+            emit trayIconShow (*(VBoxShowTrayIconEvent *) e);
+            return true;
+        }
+        case VBoxDefs::TrayIconChangeEventType:
         {
             emit trayIconChanged (*(VBoxChangeTrayIconEvent *) e);
Index: trunk/src/VBox/Frontends/VirtualBox4/src/VBoxGlobalSettings.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox4/src/VBoxGlobalSettings.cpp	(revision 14907)
+++ trunk/src/VBox/Frontends/VirtualBox4/src/VBoxGlobalSettings.cpp	(revision 14908)
@@ -60,5 +60,5 @@
     languageId  = QString::null;
     maxGuestRes = "auto";
-    trayIconEnabled = true;
+    trayIconEnabled = false;
 }
 
Index: trunk/src/VBox/Frontends/VirtualBox4/src/VBoxSelectorWnd.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox4/src/VBoxSelectorWnd.cpp	(revision 14907)
+++ trunk/src/VBox/Frontends/VirtualBox4/src/VBoxSelectorWnd.cpp	(revision 14908)
@@ -680,6 +680,10 @@
              this, SLOT (snapshotChanged (const VBoxSnapshotEvent &)));
 #ifdef VBOX_GUI_WITH_SYSTRAY
+    connect (&vboxGlobal(), SIGNAL (mainWindowCountChanged (const VBoxMainWindowCountChangeEvent &)),
+             this, SLOT (mainWindowCountChanged (const VBoxMainWindowCountChangeEvent &)));
     connect (&vboxGlobal(), SIGNAL (trayIconCanShow (const VBoxCanShowTrayIconEvent &)),
              this, SLOT (trayIconCanShow (const VBoxCanShowTrayIconEvent &)));
+    connect (&vboxGlobal(), SIGNAL (trayIconShow (const VBoxShowTrayIconEvent &)),
+             this, SLOT (trayIconShow (const VBoxShowTrayIconEvent &)));
     connect (&vboxGlobal(), SIGNAL (trayIconChanged (const VBoxChangeTrayIconEvent &)),
              this, SLOT (trayIconChanged (const VBoxChangeTrayIconEvent &)));
@@ -1087,5 +1091,5 @@
 
 #ifdef VBOX_GUI_WITH_SYSTRAY
-    if (vboxGlobal().hasTrayIcon())
+    if (vboxGlobal().isTrayMenu())
         mTrayIcon->refresh();
 #endif
@@ -1131,5 +1135,5 @@
         case QSystemTrayIcon::DoubleClick:
 
-            showWindow();
+            vboxGlobal().trayIconShowSelector();
             break;
 
@@ -1188,22 +1192,11 @@
 {
 #ifdef VBOX_GUI_WITH_SYSTRAY
+    /* Needed for breaking out of the while() loop in main(). */
     if (vboxGlobal().isTrayMenu())
-    {
-        hide();
-        if (vboxGlobal().mainWindowCount() == 0)
-        {
-            emit closing();
-            QMainWindow::closeEvent (aEvent);
-        }
-        else aEvent->ignore();
-    }
-    else
-    {
+        vboxGlobal().setTrayMenu (false);
 #endif
-        emit closing();
-        QMainWindow::closeEvent (aEvent);
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    }
-#endif
+
+    emit closing();
+    QMainWindow::closeEvent (aEvent);
 }
 
@@ -1328,5 +1321,5 @@
 
 #ifdef VBOX_GUI_WITH_SYSTRAY
-    if (vboxGlobal().hasTrayIcon())
+    if (vboxGlobal().isTrayMenu())
     {
         mTrayIcon->retranslateUi();
@@ -1638,4 +1631,10 @@
 #ifdef VBOX_GUI_WITH_SYSTRAY
 
+void VBoxSelectorWnd::mainWindowCountChanged (const VBoxMainWindowCountChangeEvent &aEvent)
+{
+    if (vboxGlobal().isTrayMenu() && aEvent.mCount <= 1)
+        fileExit();
+}
+
 void VBoxSelectorWnd::trayIconCanShow (const VBoxCanShowTrayIconEvent &aEvent)
 {
@@ -1643,8 +1642,13 @@
 }
 
+void VBoxSelectorWnd::trayIconShow (const VBoxShowTrayIconEvent &aEvent)
+{
+    if (vboxGlobal().isTrayMenu() && mTrayIcon)
+        mTrayIcon->trayIconShow (aEvent.mShow);
+}
+
 void VBoxSelectorWnd::trayIconChanged (const VBoxChangeTrayIconEvent &aEvent)
 {
-    if (mTrayIcon)
-        mTrayIcon->trayIconShow (aEvent.mEnabled);
+    /* Not used yet. */
 }
 
@@ -1962,5 +1966,5 @@
 void VBoxTrayIcon::trayIconShow (bool aShow)
 {
-    if (!vboxGlobal().hasTrayIcon())
+    if (!vboxGlobal().isTrayMenu())
         return;
 
@@ -1973,6 +1977,11 @@
     setVisible (mActive);
 
-    if (!mActive && vboxGlobal().isTrayMenu())
+    if (!mActive)
+    {
+        VBoxGlobalSettings s = vboxGlobal().settings();
+        s.setTrayIconEnabled (false);
+        s.save(vboxGlobal().virtualBox());
         mParent->fileExit();
+    }
 }
 
Index: trunk/src/VBox/Frontends/VirtualBox4/src/main.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox4/src/main.cpp	(revision 14907)
+++ trunk/src/VBox/Frontends/VirtualBox4/src/main.cpp	(revision 14908)
@@ -363,6 +363,5 @@
                 vboxGlobal().setMainWindow (&vboxGlobal().consoleWnd());
 #ifdef VBOX_GUI_WITH_SYSTRAY
-                if (   vboxGlobal().trayIconInstall()
-                    && vboxGlobal().hasTrayIcon())
+                if (vboxGlobal().trayIconInstall())
                 {
                     /* Nothing to do here yet. */
@@ -380,6 +379,5 @@
                 vboxGlobal().setMainWindow (&vboxGlobal().selectorWnd());
 #ifdef VBOX_GUI_WITH_SYSTRAY
-                if (   vboxGlobal().trayIconInstall()
-                    && vboxGlobal().hasTrayIcon())
+                if (vboxGlobal().trayIconInstall())
                 {
                     /* Nothing to do here yet. */
@@ -395,5 +393,12 @@
                 vboxGlobal().showUpdateDialog (false /* aForce */);
 #endif
-                rc = a.exec();
+#ifdef VBOX_GUI_WITH_SYSTRAY
+                do
+                {
+#endif
+                    rc = a.exec();
+#ifdef VBOX_GUI_WITH_SYSTRAY
+                } while (vboxGlobal().isTrayMenu());
+#endif
             }
         }
