diff --git a/Common/onelab.h b/Common/onelab.h
index 477c39725ce663e55ba505a3d5501f35718cac1e..42ac105f3e5abd0c0e6e6ed5ef0edfdeac6aea9c 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -31,7 +31,7 @@
 #include <map>
 #include <iostream>
 #include <sstream>
-#include "GmshSocket.h";
+#include "GmshSocket.h"
 
 namespace onelab{
 
@@ -454,6 +454,7 @@ namespace onelab{
     virtual ~client(){}
     std::string getName(){ return _name; }
     virtual bool run(const std::string &what){ return false; }
+    virtual bool isNetworkClient(){ return false; }
     virtual bool kill(){ return false; }
     virtual void sendInfo(const std::string &msg){ std::cout << msg << std::endl; }
     virtual void sendWarning(const std::string &msg){ std::cerr << msg << std::endl; }
@@ -572,6 +573,7 @@ namespace onelab{
     localNetworkClient(const std::string &name, const std::string &commandLine)
       : localClient(name), _commandLine(commandLine), _pid(-1) {}
     virtual ~localNetworkClient(){}
+    virtual bool isNetworkClient(){ return true; }
     const std::string &getCommandLine(){ return _commandLine; }
     void setCommandLine(const std::string &s){ _commandLine = s; }
     int getPid(){ return _pid; }
@@ -663,6 +665,7 @@ namespace onelab{
         _gmshClient = 0;
       }
     }
+    virtual bool isNetworkClient(){ return true; }
     virtual bool set(number &p, bool value=true){ return _set(p); }
     virtual bool set(string &p, bool value=true){ return _set(p); }
     virtual bool set(function &p, bool value=true){ return _set(p); }
diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index 2bb959e7433016d207a9bba63651a44c96c6c9d9..0cf56a376d4f7fffc34eaabc7bf861caae0e022d 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -652,12 +652,6 @@ int FlGui::testGlobalShortcuts(int event)
     show = !show;
     status = 2;
   }
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-  else if(Fl::test_shortcut('@')) {
-    onelab_cb(0, (void*)"initial check");
-    status = 1;
-  }
-#endif
   else if(testArrowShortcuts()) {
     status = 1;
   }
@@ -816,8 +810,13 @@ void FlGui::storeCurrentWindowsInfo()
   CTX::instance()->manipPosition[1] = manip->win->y();
   CTX::instance()->ctxPosition[0] = geoContext->win->x();
   CTX::instance()->ctxPosition[1] = meshContext->win->y();
+#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
+  CTX::instance()->solverPosition[0] = onelab->x();
+  CTX::instance()->solverPosition[1] = onelab->y();
+#else
   CTX::instance()->solverPosition[0] = solver[0]->win->x();
   CTX::instance()->solverPosition[1] = solver[0]->win->y();
+#endif
   fileChooserGetPosition(&CTX::instance()->fileChooserPosition[0],
                          &CTX::instance()->fileChooserPosition[1]);
 }
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp
index 93cd75c57a5a693f9d8158bf0ed151d6c090015b..741d196c318505ac716fc61b329b6bb480d2ff24 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabWindow.cpp
@@ -228,7 +228,7 @@ bool onelab::localNetworkClient::kill()
   return false;
 }
 
-static void save_mesh(onelab::client *c)
+static void onelab_save_mesh(onelab::client *c)
 {
   std::vector<onelab::string> ps;
   c->get(ps, "Gmsh/MshFileName");
@@ -300,7 +300,7 @@ void onelab_cb(Fl_Widget *w, void *data)
         geometry_reload_cb(0, 0);
         if(FlGui::instance()->onelab->meshAuto()){
           mesh_3d_cb(0, 0);
-          save_mesh(it->second);
+          onelab_save_mesh(it->second);
         }
         onelab::server::instance()->setChanged(false, "Gmsh");
       }
@@ -369,6 +369,27 @@ static void onelab_input_choice_cb(Fl_Widget *w, void *data)
   }
 }
 
+static void onelab_choose_executable_cb(Fl_Widget *w, void *data)
+{
+  onelab::localNetworkClient *c = (onelab::localNetworkClient*)data;
+  std::string pattern = "*";
+#if defined(WIN32)
+  pattern += ".exe";
+#endif
+  if(fileChooser(FILE_CHOOSER_SINGLE, "Choose executable", pattern.c_str())){
+    std::string exe = fileChooserGetName(1);
+    c->setCommandLine(exe);
+    // FIXME hack
+    opt_solver_executable(0, GMSH_SET, exe);
+  }
+}
+
+static void onelab_remove_solver_cb(Fl_Widget *w, void *data)
+{
+  onelab::client *c = (onelab::client*)data;
+  FlGui::instance()->onelab->removeSolver(c->getName());
+}
+
 onelabWindow::onelabWindow(int deltaFontSize)
 {
   FL_NORMAL_SIZE -= deltaFontSize;
@@ -411,17 +432,6 @@ onelabWindow::onelabWindow(int deltaFontSize)
   _win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
-
-  // FIXME this should be called when we click on "GetDP" in the
-  // solver menu
-  onelab::server::instance()->registerClient
-    (new onelab::localNetworkClient("GetDP",
-                                    opt_solver_executable0(0, GMSH_GET, "")));
-  // onelab::server::citer it = onelab::server::instance()->findClient("GetDP");
-  // onelab::client *c = it->second;
-  // c->setCommandLine(newcommand);
-  // delete c;
-  //onelab::server::instance()->removeClient("GetDP");
 }
 
 static std::string getShortName(const std::string &name) 
@@ -518,5 +528,60 @@ void onelabWindow::rebuildTree()
   _tree->redraw();
 }
 
+void onelabWindow::rebuildSolverList()
+{
+  for(int i = _gear->menu()->size(); i >= 2; i--){
+    _gear->remove(i);
+  }
+  _title = "ONELAB";
+  for(onelab::server::citer it = onelab::server::instance()->firstClient();
+      it != onelab::server::instance()->lastClient(); it++){
+    onelab::client *c = it->second;
+    char tmp[256];
+    if(c->isNetworkClient()){
+      sprintf(tmp, "%s/Choose executable", c->getName().c_str());
+      _gear->add(tmp, 0, onelab_choose_executable_cb, (void*)c);
+    }
+    sprintf(tmp, "%s/Remove", c->getName().c_str());
+    _gear->add(tmp, 0, onelab_remove_solver_cb, (void*)c);
+    _title += " " + c->getName();
+  }
+  _win->label(_title.c_str());
+}
+
+void onelabWindow::addSolver(const std::string &name, const std::string &commandLine)
+{
+  onelab::server::citer it = onelab::server::instance()->findClient(name);
+  if(it == onelab::server::instance()->lastClient()){
+    onelab::client *c = new onelab::localNetworkClient(name, commandLine);
+    onelab::server::instance()->registerClient(c);
+  }
+  FlGui::instance()->onelab->rebuildSolverList();
+}
+
+void onelabWindow::removeSolver(const std::string &name)
+{
+  onelab::server::citer it = onelab::server::instance()->findClient(name);
+  if(it != onelab::server::instance()->lastClient()){
+    onelab::client *c = it->second;
+    onelab::server::instance()->removeClient(name);
+    if(c->isNetworkClient()) // cannot delete local gmsh client (allocated in Msg)
+      delete it->second;
+  }
+  FlGui::instance()->onelab->rebuildSolverList();
+}
+
+// new solver interface (onelab-based)
+void solver_cb(Fl_Widget *w, void *data)
+{
+  int num = (intptr_t)data;
+
+  std::string name = opt_solver_name(num, GMSH_GET, "");
+  std::string exe = opt_solver_executable(num, GMSH_GET, "");
+  FlGui::instance()->onelab->addSolver(name, exe);
+
+  onelab_cb(0, (void*)"initial check");
+}
+
 #endif
 
diff --git a/Fltk/onelabWindow.h b/Fltk/onelabWindow.h
index 64dc094af6588659ecaea5a4169afc5dc4b153e9..eb1f97febcc2996f1fe60d65de4dfb10395fdc85 100644
--- a/Fltk/onelabWindow.h
+++ b/Fltk/onelabWindow.h
@@ -23,8 +23,12 @@ class onelabWindow{
   Fl_Input *_model;
   Fl_Menu_Button *_gear;
   std::vector<Fl_Widget*> _treeWidgets;
+  std::string _title;
  public:
   onelabWindow(int deltaFontSize=0);
+  int x(){ return _win->x(); }
+  int y(){ return _win->y(); }
+  void rebuildSolverList();
   void rebuildTree();
   void redrawTree(){ _tree->redraw(); }
   void activate(){ _butt[0]->activate(); _butt[1]->activate(); }
@@ -39,6 +43,8 @@ class onelabWindow{
     _tree->item_pathname(path, 1024, item);
     return std::string(path);
   }
+  void addSolver(const std::string &name, const std::string &commandLine);
+  void removeSolver(const std::string &name);
 };
 
 void onelab_cb(Fl_Widget *w, void *data);
diff --git a/Fltk/solverWindow.cpp b/Fltk/solverWindow.cpp
index 4d34215d18e6802fb558cb8e4923cff3973b7c56..8f8a6dd24bea394fcac9fef71c15f88f2f89cd36 100644
--- a/Fltk/solverWindow.cpp
+++ b/Fltk/solverWindow.cpp
@@ -271,6 +271,8 @@ void ConnectionManager::run(std::string args)
   }
 }
 
+#if (FL_MAJOR_VERSION != 1) || (FL_MINOR_VERSION != 3)
+// old solver interface
 void solver_cb(Fl_Widget *w, void *data)
 {
   int num = (intptr_t)data;
@@ -303,6 +305,7 @@ void solver_cb(Fl_Widget *w, void *data)
 
   ConnectionManager::get(num)->runToGetOptions();
 }
+#endif
 
 static void solver_ok_cb(Fl_Widget *w, void *data)
 {