diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index 4ef053ac4ed2e7a4adf22cd5197a0187ce9486e9..10376dcfaca601a305ff3bbb925b62895737e1cd 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -49,6 +49,7 @@ int Msg::_progressMeterCurrent = 0;
 std::map<std::string, double> Msg::_timers;
 int Msg::_warningCount = 0;
 int Msg::_errorCount = 0;
+std::string Msg::_firstError;
 GmshMessage *Msg::_callback = 0;
 std::string Msg::_commandLine;
 std::string Msg::_launchDate;
@@ -222,7 +223,8 @@ void Msg::Fatal(const char *fmt, ...)
     FlGui::instance()->check();
     std::string tmp = std::string("@C1@.") + "Fatal   : " + str;
     FlGui::instance()->addMessage(tmp.c_str());
-    FlGui::instance()->showMessages();
+    if(_firstError.empty()) _firstError = str;
+    FlGui::instance()->setLastStatus(FL_DARK_RED);
     FlGui::instance()->saveMessages
       ((CTX::instance()->homeDir + CTX::instance()->errorFileName).c_str());
     fl_alert("A fatal error has occurred which will force Gmsh to abort.\n"
@@ -267,7 +269,8 @@ void Msg::Error(const char *fmt, ...)
     FlGui::instance()->check();
     std::string tmp = std::string("@C1@.") + "Error   : " + str;
     FlGui::instance()->addMessage(tmp.c_str());
-    FlGui::instance()->showMessages();
+    if(_firstError.empty()) _firstError = str;
+    FlGui::instance()->setLastStatus(FL_DARK_RED);
   }
 #endif
 
@@ -357,19 +360,6 @@ void Msg::Direct(const char *fmt, ...)
   vsnprintf(str, sizeof(str), fmt, args);
   va_end(args);
 
-  Direct(3, str);
-}
-
-void Msg::Direct(int level, const char *fmt, ...)
-{
-  if(_commRank || _verbosity < level) return;
-
-  char str[5000];
-  va_list args;
-  va_start(args, fmt);
-  vsnprintf(str, sizeof(str), fmt, args);
-  va_end(args);
-
   if(_callback) (*_callback)("Direct", str);
   if(_client) _client->Info(str);
 
@@ -378,16 +368,8 @@ void Msg::Direct(int level, const char *fmt, ...)
   {
     if(FlGui::available()){
       FlGui::instance()->check();
-      std::string tmp;
-      if(level < 2)
-	tmp = std::string("@C1@.") + str;
-      else if(level < 3)
-	tmp = std::string("@C5@.") + str;
-      else
-	tmp = std::string("@C4@.") + str;
+      std::string tmp = std::string("@C4@.") + str;
       FlGui::instance()->addMessage(tmp.c_str());
-      if(level == 1)
-	FlGui::instance()->showMessages();
     }
   }
 #endif
@@ -536,6 +518,17 @@ void Msg::PrintTimers()
   }
 }
 
+void Msg::ResetErrorCounter()
+{
+  _warningCount = 0; _errorCount = 0;
+  _firstError.clear();
+#if defined(HAVE_FLTK)
+  if(FlGui::available()){
+    FlGui::instance()->setLastStatus();
+  }
+#endif
+}
+
 void Msg::PrintErrorCounter(const char *title)
 {
   if(_commRank || _verbosity < 1) return;
@@ -557,10 +550,7 @@ void Msg::PrintErrorCounter(const char *title)
     FlGui::instance()->addMessage((red + prefix + err).c_str());
     FlGui::instance()->addMessage((red + prefix + help).c_str());
     FlGui::instance()->addMessage((red + prefix + line).c_str());
-    if(_errorCount){
-      FlGui::instance()->showMessages();
-      fl_beep();
-    }
+    if(_errorCount) fl_beep();
   }
 #endif
 
diff --git a/Common/GmshMessage.h b/Common/GmshMessage.h
index a5b8f7a33764cbf1d3a98e5e4b401ec5dabf5896..b9fee7d6d89da09cbdcee4a26c3275fa33023e72 100644
--- a/Common/GmshMessage.h
+++ b/Common/GmshMessage.h
@@ -36,6 +36,7 @@ class Msg {
   static std::map<std::string, double> _timers;
   // counters
   static int _warningCount, _errorCount;
+  static std::string _firstError;
   // callback
   static GmshMessage *_callback;
   // command-line and startup time
@@ -68,7 +69,6 @@ class Msg {
   static void Warning(const char *fmt, ...);
   static void Info(const char *fmt, ...);
   static void Direct(const char *fmt, ...);
-  static void Direct(int level, const char *fmt, ...);
   static void StatusBar(bool log, const char *fmt, ...);
   static void StatusGl(const char *fmt, ...);
   static void Debug(const char *fmt, ...);
@@ -78,8 +78,9 @@ class Msg {
   static void ResetProgressMeter(){ if(!_commRank) _progressMeterCurrent = 0; }
   static double &Timer(std::string str){ return _timers[str]; }
   static void PrintTimers();
-  static void ResetErrorCounter(){ _warningCount = 0; _errorCount = 0; }
+  static void ResetErrorCounter();
   static int GetErrorCount(){ return _errorCount; }
+  static std::string GetFirstError(){ return _firstError; }
   static void PrintErrorCounter(const char *title);
   static double GetValue(const char *text, double defaultval);
   static std::string GetString(const char *text, std::string defaultval);
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 431ed9ff488af92816b8f0f892429f0a44e2e89d..bbfd091acbac739af4a191efcaeb40ba53522e0e 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -583,6 +583,7 @@ void ClearProject()
     GModel::current()->setSelection(0);
   }
 #endif
+  Msg::ResetErrorCounter();
 }
 
 void OpenProject(const std::string &fileName)
@@ -593,6 +594,8 @@ void OpenProject(const std::string &fileName)
   }
   CTX::instance()->lock = 1;
 
+  Msg::ResetErrorCounter();
+
   if(GModel::current()->empty()){
     // if the current model is empty, make sure it's reaaally
     // cleaned-up, and reuse it (don't clear the parser variables: if
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 5d2b22ecb9315ba0fe164c0669fd90ed73897d7b..5b3028919a13e1d73eb1b379e1fe871814846106 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -129,12 +129,10 @@ static void PrintStringOptions(int num, int level, int diff, int help,
           // remove \n, \t, \r
           for(unsigned int i = 0; i < strlen(tmp); i++)
             if(tmp[i] == '\n' || tmp[i] == '\t' || tmp[i] == '\r') tmp[i] = ' ';
-          // Warning: must call Msg::Direct(level, ...) here, because
-          // we cannot use tmp as a format string (it can contain %s!)
           if(vec)
             vec->push_back(std::string(tmp) + '\0' + "string");
           else
-            Msg::Direct(3, "%s", tmp);
+            Msg::Direct("%s", tmp);
         }
       }
     }
diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index b369ea6a8dc408f62c4f8927c008b3871740f356..e01f8c4764d6fbe43f0c6e031136d2818ba05d2d 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -793,8 +793,11 @@ char FlGui::selectEntity(int type)
 void FlGui::setStatus(const std::string &msg, bool opengl)
 {
   if(!opengl){
+    _lastStatus = msg;
     static char buff[1024];
     std::string tmp = std::string(" ") + msg;
+    if(Msg::GetFirstError().size() && graph[0]->getMessageHeight() < FL_NORMAL_SIZE)
+      tmp += " - Click to show messages [ ... " + Msg::GetFirstError() + " ... ]";
     strncpy(buff, tmp.c_str(), sizeof(buff) - 1);
     buff[sizeof(buff) - 1] = '\0';
     for(unsigned int i = 0; i < graph.size(); i++){
@@ -818,6 +821,17 @@ void FlGui::setStatus(const std::string &msg, bool opengl)
   }
 }
 
+void FlGui::setLastStatus(int col)
+{
+  for(unsigned int i = 0; i < graph.size(); i++){
+    if(col >= 0)
+      graph[i]->getProgress()->labelcolor(col);
+    else
+      graph[i]->getProgress()->labelcolor(FL_FOREGROUND_COLOR);
+  }
+  setStatus(_lastStatus);
+}
+
 void FlGui::setProgress(const std::string &msg, double val, double min, double max)
 {
   for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++){
@@ -982,12 +996,6 @@ void FlGui::addMessage(const char *msg)
     FlGui::instance()->graph[i]->addMessage(msg);
 }
 
-void FlGui::showMessages()
-{
-  for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
-    FlGui::instance()->graph[i]->showMessages();
-}
-
 void FlGui::saveMessages(const char *fileName)
 {
   FlGui::instance()->graph[0]->saveMessages(fileName);
diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h
index 20d3bd2aa7f21be7d6f2841bc2e09e4c3be8b22e..b397dbdd851c7b49bfaac2ef720eb32147780299 100644
--- a/Fltk/FlGui.h
+++ b/Fltk/FlGui.h
@@ -44,6 +44,7 @@ class FlGui{
  private:
   static FlGui *_instance;
   static std::string _openedThroughMacFinder;
+  std::string _lastStatus;
  public:
   std::vector<GVertex*> selectedVertices;
   std::vector<GEdge*> selectedEdges;
@@ -109,17 +110,17 @@ class FlGui{
   char selectEntity(int type);
   // display status message
   void setStatus(const std::string &msg, bool opengl=false);
+  // redisplay last status message
+  void setLastStatus(int col=-1);
   // display status message and update progress bar
   void setProgress(const std::string &msg, double val, double min, double max);
   // set color of progress message
   void setProgressColor(int col);
   // create the window for physical context dependant definitions
   void callForSolverPlugin(int dim);
-  // add line in message console(s)
+  // add line in message console
   void addMessage(const char *msg);
-  // show the message console
-  void showMessages();
-  // add line in message console(s)
+  // save messages to file
   void saveMessages(const char *fileName);
   // rebuild the tree
   void rebuildTree();
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index f4ff9c4df52be2c11e1138cc2618f5191c7e74c2..750aeb4b910deb85c714f48299413729248a6a66 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -1643,8 +1643,6 @@ static void mesh_inspect_cb(Fl_Widget *w, void *data)
             str += info[i] + "\n";
           FlGui::instance()->getCurrentOpenglWindow()->drawTooltip(str);
         }
-        else
-          FlGui::instance()->showMessages();
       }
     }
     if(ib == 'q') {
@@ -2444,6 +2442,24 @@ class mainWindowSpecialResize : public mainWindow {
   }
 };
 
+class mainWindowProgress : public Fl_Progress{
+public:
+  mainWindowProgress(int x, int y, int w, int h, const char *l=0) :
+    Fl_Progress(x, y, w, h, l){}
+  int handle(int event)
+  {
+    if(event == FL_PUSH){
+      if(FlGui::available()){
+        for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
+          FlGui::instance()->graph[i]->showHideMessages();
+        Msg::ResetErrorCounter();
+      }
+      return 1;
+    }
+    return Fl_Progress::handle(event);
+  }
+};
+
 graphicWindow::graphicWindow(bool main, int numTiles, bool detachedMenu)
   : _autoScrollMessages(true)
 {
@@ -2585,7 +2601,7 @@ graphicWindow::graphicWindow(bool main, int numTiles, bool detachedMenu)
   }
 
   x += 4;
-  _label = new Fl_Progress(x, mh + glheight + mheight + 2, width - x, sht);
+  _label = new mainWindowProgress(x, mh + glheight + mheight + 2, width - x, sht);
   _label->box(FL_FLAT_BOX);
   _label->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
   _label->color(FL_BACKGROUND_COLOR, FL_DARK2); // FL_DARK_GREEN
@@ -2998,7 +3014,7 @@ void graphicWindow::showMessages()
   if(!_browser || !_win->shown()) return;
   if(_browser->h() < FL_NORMAL_SIZE){
     int height = CTX::instance()->msgSize;
-    if(height < FL_NORMAL_SIZE) height = 5 * FL_NORMAL_SIZE;
+    if(height < FL_NORMAL_SIZE) height = 10 * FL_NORMAL_SIZE;
     int maxh = _win->h() - _bottom->h();
     if(height > maxh) height = maxh / 2;
     setMessageHeight(height);
@@ -3031,7 +3047,7 @@ void graphicWindow::addMessage(const char *msg)
 {
   if(!_browser) return;
   _browser->add(msg, 0);
-  if(_autoScrollMessages && _win->shown() && _browser->h() >= 10)
+  if(_autoScrollMessages && _win->shown() && _browser->h() >= FL_NORMAL_SIZE)
     _browser->bottomline(_browser->size());
 }
 
diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index 7bbf0de59e665f1f6254be4f46dd74eb4e4039cb..eb9e5153f57a123ab5f72042fcb74304751807af 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -291,13 +291,13 @@ bool onelab::localNetworkClient::run()
       Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str());
       break;
     case GmshSocket::GMSH_INFO:
-      Msg::Direct("%-8.8s: %s", _name.c_str(), message.c_str());
+      Msg::Direct("Info    : %s - %s", _name.c_str(), message.c_str());
       break;
     case GmshSocket::GMSH_WARNING:
-      Msg::Direct(2, "%-8.8s: %s", _name.c_str(), message.c_str());
+      Msg::Warning("%s - %s", _name.c_str(), message.c_str());
       break;
     case GmshSocket::GMSH_ERROR:
-      Msg::Direct(1, "%-8.8s: %s", _name.c_str(), message.c_str());
+      Msg::Error("%s - %s", _name.c_str(), message.c_str());
       break;
     case GmshSocket::GMSH_MERGE_FILE:
       if(CTX::instance()->solver.autoMergeFile){
@@ -473,7 +473,10 @@ static void loadDb(const std::string &name)
 
 void onelab_cb(Fl_Widget *w, void *data)
 {
+  Msg::ResetErrorCounter();
+
   if(!data) return;
+
   std::string action((const char*)data);
 
   if(action == "refresh"){
@@ -579,7 +582,6 @@ void onelab_cb(Fl_Widget *w, void *data)
         OpenProject(GModel::current()->getFileName());
         drawContext::global()->draw();
       }
-      Msg::ResetErrorCounter();
 #endif
     }
     else{
@@ -1363,7 +1365,6 @@ void onelabGroup::openTreeItem(const std::string &name)
 void onelabGroup::checkForErrors(const std::string &client)
 {
   if(Msg::GetErrorCount() > 0 && !CTX::instance()->expertMode){
-    Msg::ResetErrorCounter();
     std::string msg
       (client + " reported an error: do you really want to continue?\n\n"
        "(To disable this warning in the future, select `Enable expert mode'\n"
@@ -1565,8 +1566,6 @@ void onelabGroup::removeSolver(const std::string &name)
 
 void solver_cb(Fl_Widget *w, void *data)
 {
-  Msg::ResetErrorCounter();
-
   int num = (intptr_t)data;
   if(num >= 0){
     std::string name = opt_solver_name(num, GMSH_GET, "");
@@ -1653,7 +1652,6 @@ void flgui_wait_cb(double time)
 int metamodel_cb(const std::string &name, const std::string &action)
 {
 #if defined(HAVE_ONELAB_METAMODEL)
-  Msg::ResetErrorCounter();
   if(FlGui::instance()->onelab->isBusy())
     FlGui::instance()->onelab->show();
   else{
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 578336e76604e8b68858af233726e2a1bd4e4cc6..deb8dd037e0707420c956e5680a98de9664834ab 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -13,6 +13,7 @@ typedef unsigned long intptr_t;
 #include <FL/Fl_Tabs.H>
 #include <FL/Fl_Scroll.H>
 #include <FL/Fl_Color_Chooser.H>
+#include <FL/fl_ask.H>
 #include "GmshDefines.h"
 #include "GmshMessage.h"
 #include "FlGui.h"
@@ -176,8 +177,7 @@ static void options_show_file_cb(Fl_Widget *w, void *data)
     file += CTX::instance()->sessionFileName;
   else
     file += CTX::instance()->optionsFileName;
-  Msg::Direct("%s", file.c_str());
-  FlGui::instance()->showMessages();
+  fl_message("File path: %s", file.c_str());
 }
 
 static void options_restore_defaults_cb(Fl_Widget *w, void *data)