diff --git a/Common/onelab.h b/Common/onelab.h
index 4b847745d733f7c67340964956fc6be713c187b0..2e9dfaf53ebb21163cdb89be3e89d72d82087f92 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -48,13 +48,20 @@ namespace onelab{
     std::string _shortHelp, _help;
     // client code(s) that use this parameter
     std::set<std::string> _clients;
+    // flag to check if the parameter has been changed since the last run
+    bool _changed;
+    // should the parameter be visible in the interface
+    bool _visible;
   public:
     parameter(const std::string &name="", const std::string &shortHelp="", 
               const std::string &help="")
-      : _name(name), _shortHelp(shortHelp), _help(help){}
+      : _name(name), _shortHelp(shortHelp), _help(help), _changed(true),
+        _visible(true) {}
     void setName(const std::string &name){ _name = name; }
     void setShortHelp(const std::string &shortHelp){ _shortHelp = shortHelp; }
     void setHelp(const std::string &help){ _help = help; }
+    void setChanged(bool changed){ _changed = changed; }
+    void setVisible(bool visible){ _visible = visible; }
     void setClients(std::set<std::string> &clients){ _clients = clients; }
     void addClient(const std::string &client){ _clients.insert(client); }
     void addClients(std::set<std::string> &clients)
@@ -69,6 +76,8 @@ namespace onelab{
     const std::string &getName() const { return _name; }
     const std::string &getShortHelp() const { return _shortHelp; }
     const std::string &getHelp() const { return _help; }
+    bool getChanged() const { return _changed; }
+    bool getVisible() const { return _visible; }
     const std::set<std::string> &getClients() const { return _clients; }
     static char charSep(){ return '|' /* '\0' */; }
     std::string sanitize(const std::string &in)
@@ -82,7 +91,8 @@ namespace onelab{
     {
       std::ostringstream sstream;
       sstream << getType() << charSep() << sanitize(getName()) << charSep() 
-              << sanitize(getShortHelp()) << charSep() << sanitize(getHelp());
+              << sanitize(getShortHelp()) << charSep() << sanitize(getHelp())
+              << charSep() << getVisible() ? 1 : 0;
       return sstream.str();
     }
     virtual void fromChar(const std::string &msg){}
@@ -159,6 +169,7 @@ namespace onelab{
       setName(getNextToken(msg, pos));
       setShortHelp(getNextToken(msg, pos));
       setHelp(getNextToken(msg, pos));
+      setVisible(atoi(getNextToken(msg, pos).c_str()));
       setValue(atof(getNextToken(msg, pos).c_str()));
       setDefaultValue(atof(getNextToken(msg, pos).c_str()));
       setMin(atof(getNextToken(msg, pos).c_str()));
@@ -208,6 +219,7 @@ namespace onelab{
       setName(getNextToken(msg, pos));
       setShortHelp(getNextToken(msg, pos));
       setHelp(getNextToken(msg, pos));
+      setVisible(atoi(getNextToken(msg, pos).c_str()));
       setValue(getNextToken(msg, pos));
       setDefaultValue(getNextToken(msg, pos));
       _choices.resize(atoi(getNextToken(msg, pos).c_str()));
@@ -322,7 +334,10 @@ namespace onelab{
       if(it != ps.end()){
         std::set<std::string> clients = p.getClients();
         (*it)->addClients(clients);
-        if(value) (*it)->setValue(p.getValue());
+        if(value && p.getValue() != (*it)->getValue()){
+          (*it)->setValue(p.getValue());
+          (*it)->setChanged(true);
+        }
       }
       else{
         ps.insert(new T(p));
@@ -390,6 +405,28 @@ namespace onelab{
         if((*it)->hasClient(client)) return true;
       return false;
     }
+    // check if some parameters have changed (optionnally only check
+    // the parameters that depend on a given client)
+    bool getChanged(const std::string &client="")
+    {
+      std::set<parameter*> ps;
+      _getAllParameters(ps);
+      for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++){
+        if((client.empty() || (*it)->hasClient(client)) && (*it)->getChanged())
+          return true;
+      }
+      return false;
+    }
+    // set all parameters as unchanged (optionnally only affect those
+    // parameters that depend on a given client)
+    bool setChanged(bool changed, const std::string &client="")
+    {
+      std::set<parameter*> ps;
+      _getAllParameters(ps);
+      for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++)
+        if(client.empty() || (*it)->hasClient(client))
+          (*it)->setChanged(changed);
+    }
     std::string toChar()
     {
       std::string s;
@@ -470,9 +507,13 @@ namespace onelab{
     citer lastClient(){ return _clients.end(); }
     citer findClient(const std::string &name){ return _clients.find(name); }
     int getNumClients(){ return _clients.size(); }
-    bool dependsOnClient(const std::string &client)
+    void setChanged(bool changed, const std::string &client="")
+    {
+      _parameterSpace.setChanged(changed, client);
+    }
+    bool getChanged(const std::string &client="")
     {
-      return _parameterSpace.hasClient(client);
+      return _parameterSpace.getChanged(client);
     }
     std::string toChar(){ return _parameterSpace.toChar(); }
   };
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index c8a7d82ea563ecbd1f39897ca454c33f9c2ac2a9..5970d81012b3c8ca7b26807633bea6c22bd4b000 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -1593,8 +1593,10 @@ static void geometry_physical_add_cb(Fl_Widget *w, void *data)
   action_point_line_surface_volume(7, 0, str.c_str());
 }
 
-static void mesh_save_cb(Fl_Widget *w, void *data)
+void mesh_save_cb(Fl_Widget *w, void *data)
 {
+  bool force = data ? true : false;
+
   std::string name = CTX::instance()->outputFileName;
   if(name.empty()){
     if(CTX::instance()->mesh.fileFormat == FORMAT_AUTO)
@@ -1602,7 +1604,7 @@ static void mesh_save_cb(Fl_Widget *w, void *data)
     else
       name = GetDefaultFileName(CTX::instance()->mesh.fileFormat);
   }
-  if(CTX::instance()->confirmOverwrite) {
+  if(!force && CTX::instance()->confirmOverwrite) {
     if(!StatFile(name))
       if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
                     "Cancel", "Replace", 0, name.c_str()))
diff --git a/Fltk/menuWindow.h b/Fltk/menuWindow.h
index 94d982c7f4dfde0f51e81aa3b2c09247105af3de..18c1ed86d9a357229286bcb678130a276fdc1cb8 100644
--- a/Fltk/menuWindow.h
+++ b/Fltk/menuWindow.h
@@ -91,6 +91,7 @@ void geometry_reload_cb(Fl_Widget *w, void *data);
 void mesh_1d_cb(Fl_Widget *w, void *data);
 void mesh_2d_cb(Fl_Widget *w, void *data);
 void mesh_3d_cb(Fl_Widget *w, void *data);
+void mesh_save_cb(Fl_Widget *w, void *data);
 void help_about_cb(Fl_Widget *w, void *data);
 
 #endif
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp
index dec0a3d726e1c5817bacab9cf7dc8ef326f94e5a..8c671ca101381b57d53676b90b99c49b1545b953 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabWindow.cpp
@@ -239,22 +239,42 @@ void onelab_cb(Fl_Widget *w, void *data)
   }
 
   FlGui::instance()->onelab->deactivate();
+  
+  // Gmsh client is special (always gets executed first). The
+  // meta-model will allow more flexibility: but in the simple GUI we
+  // can assume this
+  if(onelab::server::instance()->findClient("Gmsh") != 
+     onelab::server::instance()->lastClient()){
+    // reload geometry if Gmsh parameters have been modified
+    if(onelab::server::instance()->getChanged("Gmsh")){
+      if(action == "check"){
+        geometry_reload_cb(0, 0);
+      }
+      else if(action == "compute"){
+        mesh_3d_cb(0, 0);
+        mesh_save_cb(0, (void*)"force");
+        onelab::server::instance()->setChanged(false, "Gmsh");
+      }
+    }
+  }
+
+  // Iterate over all other clients
   for(onelab::server::citer it = onelab::server::instance()->firstClient();
       it != onelab::server::instance()->lastClient(); it++){
     onelab::client *c = it->second;
+    if(c->getName() == "Gmsh") continue;
     std::string what = FlGui::instance()->onelab->getModelName();
-    // FIXME should be more intelligent, and only perform check if we changed
-    // some parameters which depend on the client
     if(action == "check"){
-      if(c->getName() == "Gmsh" && onelab::server::instance()->dependsOnClient("Gmsh"))
-        geometry_reload_cb(0, 0);
       c->run(what);
     }
     else if(action == "compute"){
+      // FIXME we should define a string (invisible param) in the db
+      // that stores this information
       if(c->getName() == "GetDP") what += " -solve -pos";
       c->run(what);
     }
   }
+
   FlGui::instance()->onelab->activate();
 
   printf("Gmsh ONELAB db:\n%s\n", onelab::server::instance()->toChar().c_str());