diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index b4262049015e46dbc0f44fc7b8c3c261e419f527..1e1ad69661c6e03dc4369b9ca5170e11dcd31847 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -786,6 +786,7 @@ void Msg::ImportPhysicalsAsOnelabRegions()
         onelab::region p(name, num.str());
         p.setDimension(dim);
         p.setReadOnly(true);
+        p.setAttribute("Closed", "1");
         _onelabClient->set(p);
       }
     }
diff --git a/Common/onelab.h b/Common/onelab.h
index b3ec2a9d0122c1eeaffac6edb68d1bbf6bf927a3..532f74c42ac9fc6d4c5aff0bd981786b7112ce52 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -100,6 +100,11 @@ namespace onelab{
     const std::string &getName() const { return _name; }
     const std::string &getLabel() const { return _label; }
     const std::string &getHelp() const { return _help; }
+    std::string getPath() const
+    {
+      std::string::size_type last = _name.find_last_of('/');
+      return _name.substr(0, last);
+    }
     std::string getShortName() const
     {
       if(_label.size()) return _label;
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp
index 4eeca8854d963c49951fadb490c66afe737d863a..eb6e38468d7895a06499919a324b0061233bbbf7 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabWindow.cpp
@@ -599,6 +599,48 @@ static void onelab_add_solver_cb(Fl_Widget *w, void *data)
   }
 }
 
+template<class T>
+static void setClosed(const std::string &path, std::vector<T> &ps,
+                      const std::string &value)
+{
+  onelab::server::instance()->get(ps);
+  for(unsigned int i = 0; i < ps.size(); i++){
+    if(ps[i].getPath() == path){
+      ps[i].setAttribute("Closed", value);
+      onelab::server::instance()->set(ps[i]);
+    }
+  }
+}
+
+static void onelab_tree_cb(Fl_Widget *w, void *data)
+{
+  Fl_Tree *tree = (Fl_Tree*)w;
+  Fl_Tree_Item *item = (Fl_Tree_Item*)tree->callback_item();
+  std::string path = FlGui::instance()->onelab->getPath(item);
+  std::vector<onelab::number> numbers;
+  std::vector<onelab::string> strings;
+  std::vector<onelab::region> regions;
+  std::vector<onelab::function> functions;
+  switch(tree->callback_reason()){
+  case FL_TREE_REASON_SELECTED: break;
+  case FL_TREE_REASON_DESELECTED: break;
+  case FL_TREE_REASON_OPENED:
+    setClosed(path, numbers, "0");
+    setClosed(path, strings, "0");
+    setClosed(path, regions, "0");
+    setClosed(path, functions, "0");
+    break;
+  case FL_TREE_REASON_CLOSED:
+    setClosed(path, numbers, "1");
+    setClosed(path, strings, "1");
+    setClosed(path, regions, "1");
+    setClosed(path, functions, "1");
+    break;
+  default:
+    break;
+  }
+}
+
 onelabWindow::onelabWindow(int deltaFontSize)
   : _deltaFontSize(deltaFontSize), _stop(false)
 {
@@ -612,6 +654,7 @@ onelabWindow::onelabWindow(int deltaFontSize)
   _win->box(GMSH_WINDOW_BOX);
 
   _tree = new Fl_Tree(WB, WB, width - 2 * WB, height - 3 * WB - BH);
+  _tree->callback(onelab_tree_cb);
   _tree->connectorstyle(FL_TREE_CONNECTOR_SOLID);
   _tree->showroot(0);
 
@@ -980,14 +1023,7 @@ void onelabWindow::rebuildTree()
 
   _itemWidth = (int)(0.45 * _tree->w());
 
-  std::vector<std::string> closed;
-  for (Fl_Tree_Item *n = _tree->first(); n; n = n->next())
-    if(n->is_close()) closed.push_back(getPath(n));
-
-  if(_treeWidgets.empty()){ // first time we build the tree
-    closed.push_back("Gmsh");
-    closed.push_back("Gmsh/Physical groups");
-  }
+  std::set<std::string> closed;
 
   _tree->clear();
   _tree->sortorder(FL_TREE_SORT_ASCENDING);
@@ -1004,6 +1040,8 @@ void onelabWindow::rebuildTree()
   onelab::server::instance()->get(numbers);
   for(unsigned int i = 0; i < numbers.size(); i++){
     if(!numbers[i].getVisible()) continue;
+    if(numbers[i].getAttribute("Closed") == "1")
+      closed.insert(numbers[i].getPath());
     _addParameter(numbers[i]);
   }
 
@@ -1011,6 +1049,8 @@ void onelabWindow::rebuildTree()
   onelab::server::instance()->get(strings);
   for(unsigned int i = 0; i < strings.size(); i++){
     if(!strings[i].getVisible()) continue;
+    if(strings[i].getAttribute("Closed") == "1")
+      closed.insert(strings[i].getPath());
     _addParameter(strings[i]);
   }
 
@@ -1018,6 +1058,8 @@ void onelabWindow::rebuildTree()
   onelab::server::instance()->get(regions);
   for(unsigned int i = 0; i < regions.size(); i++){
     if(!regions[i].getVisible()) continue;
+    if(regions[i].getAttribute("Closed") == "1")
+      closed.insert(regions[i].getPath());
     _addParameter(regions[i]);
   }
 
@@ -1025,6 +1067,8 @@ void onelabWindow::rebuildTree()
   onelab::server::instance()->get(functions);
   for(unsigned int i = 0; i < functions.size(); i++){
     if(!functions[i].getVisible()) continue;
+    if(functions[i].getAttribute("Closed") == "1")
+      closed.insert(functions[i].getPath());
     _addParameter(functions[i]);
   }
 
@@ -1041,8 +1085,8 @@ void onelabWindow::rebuildTree()
     }
   }
 
-  for(unsigned int i = 0; i < closed.size(); i++)
-    _tree->close(closed[i].c_str());
+  for(std::set<std::string>::iterator it = closed.begin(); it != closed.end(); it++)
+    _tree->close(it->c_str(), 0);
 
   _tree->redraw();