diff --git a/Common/Context.h b/Common/Context.h
index 91738ca637b1ff884355211103352dc482db7e76..d8ccc0bacd0fc8d34442fb2a832956941e1fd826 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -64,6 +64,9 @@ class CTX {
   std::string meshStatReportFileName;
   // the home directory
   std::string homeDir;
+  // file history
+  int history_size;
+  std::string recent_files[5];
   // create mesh statistics report (0: do nothing, 1: create, 2: append)
   int createAppendMeshStatReport;
   // save session/option file on exit?
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 55e38ad1eb7f4317e1784d296a0b059ecb0601ef..218d733ff6b2dcf0ce2ddb8c0912192cc7b27d61 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -60,6 +60,17 @@ StringXString GeneralOptions_String[] = {
   { F|S, "OptionsFileName" , opt_general_options_filename , ".gmsh-options" ,
     "Option file created with `Tools->Options->Save'; automatically read on startup" },
 
+  { F|S, "RecentFile1", opt_general_recent_file1 , "" ,
+    "Most recent opened file"},
+  { F|S, "RecentFile2", opt_general_recent_file2 , "" ,
+    "2nd most recent opened file"},
+  { F|S, "RecentFile3", opt_general_recent_file3 , "" ,
+    "3rd most recent opened file"},
+  { F|S, "RecentFile4", opt_general_recent_file4 , "" ,
+    "4th most recent opened file"},
+  { F|S, "RecentFile5", opt_general_recent_file5 , "" ,
+    "5th most recent opened file"},
+  
   { 0,   "SessionFileName" , opt_general_session_filename , ".gmshrc" ,
     "Option file into which session specific information is saved; automatically "
     "read on startup" },
@@ -598,6 +609,9 @@ StringXNumber GeneralOptions_Number[] = {
   { F|S, "GraphicsWidth" , opt_general_graphics_size0 , 600. , 
     "Width (in pixels) of the graphic window" }, 
 
+  { F|S, "HistorySize", opt_general_history_size , 0,
+    "Number of recently opened files in the menu"},
+
   { F|O, "InitialModule", opt_general_initial_context, 0. , 
     "Module launched on startup (0=automatic, 1=geometry, 2=mesh, 3=solver, "
     "4=post-processing) " },
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index fdb7b72b35e8533da1cdc27271578e1e366aeeff..6bafd14c690dbb48999f60f0acb41edbac829ee8 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -18,6 +18,7 @@
 #include "StringUtils.h"
 #include "GeomMeshMatcher.h"
 #include "LuaBindings.h"
+#include "menuWindow.h"
 
 #if defined(HAVE_PARSER)
 #include "Parser.h"
@@ -450,11 +451,18 @@ void OpenProject(std::string fileName)
 
   // temporary hack until we fill the current GModel on the fly during
   // parsing
-  ResetTemporaryBoundingBox();
+  ResetTemporaryBoundingBox(); 
 
   // merge the file
-  MergeFile(fileName);
-
+  if(MergeFile(fileName)) {
+    for (int i=4; i > 0; i--)
+      CTX::instance()->recent_files[i] = CTX::instance()->recent_files[i-1];
+    CTX::instance()->recent_files[0] = fileName;
+    if (CTX::instance()->history_size < 5)
+      CTX::instance()->history_size++;
+    FlGui::instance()->menu->fillRecentHistoryMenu();
+  }
+  
   CTX::instance()->lock = 0;
 
 #if defined(HAVE_FLTK)
diff --git a/Common/Options.cpp b/Common/Options.cpp
index e707c1cce4df7ff67b381f08c0a6e6b46950efe3..e2a318bfed9d0cd13d60f8f01771e191de0aacf0 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -987,6 +987,41 @@ std::string opt_general_options_filename(OPT_ARGS_STR)
   return CTX::instance()->optionsFileName;
 }
 
+std::string opt_general_recent_file1(OPT_ARGS_STR)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->recent_files[0] = val;
+  return CTX::instance()->recent_files[0];
+}
+
+std::string opt_general_recent_file2(OPT_ARGS_STR)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->recent_files[1] = val;
+  return CTX::instance()->recent_files[1];
+}
+
+std::string opt_general_recent_file3(OPT_ARGS_STR)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->recent_files[2] = val;
+  return CTX::instance()->recent_files[2];
+}
+
+std::string opt_general_recent_file4(OPT_ARGS_STR)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->recent_files[3] = val;
+  return CTX::instance()->recent_files[3];
+}
+
+std::string opt_general_recent_file5(OPT_ARGS_STR)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->recent_files[4] = val;
+  return CTX::instance()->recent_files[4];
+}
+
 std::string opt_general_editor(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
@@ -2495,6 +2530,14 @@ double opt_general_message_auto_scroll(OPT_ARGS_NUM)
   return CTX::instance()->msgAutoScroll;
 }
 
+double opt_general_history_size(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    if ((int)val >= 0 && (int)val < 6)
+      CTX::instance()->history_size = (int)val;
+  return CTX::instance()->history_size;
+}
+
 double opt_general_option_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index 7fd5c9bf3c66a52bb28e5acf651ac0404fe2811c..7414368ff4f5b6d52a1c5c74ab266d730482f9a7 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -39,6 +39,11 @@ std::string opt_general_tmp_filename(OPT_ARGS_STR);
 std::string opt_general_error_filename(OPT_ARGS_STR);
 std::string opt_general_session_filename(OPT_ARGS_STR);
 std::string opt_general_options_filename(OPT_ARGS_STR);
+std::string opt_general_recent_file1(OPT_ARGS_STR);
+std::string opt_general_recent_file2(OPT_ARGS_STR);
+std::string opt_general_recent_file3(OPT_ARGS_STR);
+std::string opt_general_recent_file4(OPT_ARGS_STR);
+std::string opt_general_recent_file5(OPT_ARGS_STR);
 std::string opt_general_editor(OPT_ARGS_STR);
 std::string opt_general_web_browser(OPT_ARGS_STR);
 std::string opt_general_gui_theme(OPT_ARGS_STR);
@@ -243,6 +248,7 @@ double opt_general_message_position1(OPT_ARGS_NUM);
 double opt_general_message_size0(OPT_ARGS_NUM);
 double opt_general_message_size1(OPT_ARGS_NUM);
 double opt_general_message_auto_scroll(OPT_ARGS_NUM);
+double opt_general_history_size(OPT_ARGS_NUM);
 double opt_general_option_position0(OPT_ARGS_NUM);
 double opt_general_option_position1(OPT_ARGS_NUM);
 double opt_general_plugin_position0(OPT_ARGS_NUM);
diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index de9c4529e476b048adcfa7546664cdb6963469e7..378fe0c4a0e9d92287b5cf2b4b7f3a7ea5e6b3bf 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -231,7 +231,7 @@ FlGui::FlGui(int argc, char **argv)
                                         gmsh32x32, 32, 32));
   menu->win->icon
     ((const char*)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
-                                        gmsh32x32, 32, 32));
+    gmsh32x32, 32, 32));
 #endif
 
   // open graphic window first for correct non-modal behaviour on
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index 9754e96a353646df0980b645745684947b927015..f148b3bd1e1996310402dc28bebea7924c5b4ede 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -141,6 +141,17 @@ static void file_merge_cb(Fl_Widget *w, void *data)
     FlGui::instance()->menu->setContext(menu_post, 0);
 }
 
+void file_open_recent_cb(Fl_Widget *w, void *data)
+{  
+  std::string str((const char*)data);
+
+  int n = PView::list.size();
+  OpenProject(str);
+  drawContext::global()->draw();
+  if(n != (int)PView::list.size())
+    FlGui::instance()->menu->setContext(menu_post, 0);
+}
+
 static void file_clear_cb(Fl_Widget *w, void *data)
 {
   ClearProject();
@@ -2218,6 +2229,13 @@ static Fl_Menu_Item bar_table[] = {
     {"&New...",     FL_CTRL+'n', (Fl_Callback *)file_new_cb, 0},
     {"&Open...",    FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0},
     {"M&erge...",   FL_CTRL+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0},
+    {"Open recent", 0, 0, 0, FL_SUBMENU},
+      {"History1", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History2", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History3", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History4", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History5", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {0},
     {"&Clear",      0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER},
     {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
       {"Start...",  0, (Fl_Callback *)file_remote_cb, (void*)"start"},
@@ -2271,6 +2289,13 @@ static Fl_Menu_Item sysbar_table[] = {
     {"Open...",    FL_META+'o', (Fl_Callback *)file_open_cb, 0},
     {"Merge...",   FL_META+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0},
     {"Clear",      0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER},
+    {"Open recent", 0, 0, 0, FL_SUBMENU},
+      {"History1", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History2", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History3", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History4", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {"History5", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE},
+      {0},
     {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
       {"Start...",  0, (Fl_Callback *)file_remote_cb, (void*)"start"},
       {"Merge...",  0, (Fl_Callback *)file_remote_cb, (void*)"merge"},
@@ -2598,6 +2623,10 @@ menuWindow::menuWindow()
     bar->menu(bar_table);
     bar->box(FL_UP_BOX);
     bar->global();
+    
+    // create recent history menu
+    fillRecentHistoryMenu();
+    
     Fl_Box *o = new Fl_Box(0, BH, width, BH + 6);
     o->box(FL_UP_BOX);
     y = BH + 3;
@@ -2872,3 +2901,18 @@ void menuWindow::setContext(contextItem *menu_asked, int flag)
   else
     win->size(width, _MH + NB_BUTT_SCROLL * BH);
 }
+
+void menuWindow::fillRecentHistoryMenu() {
+  for (int i = 0; i < CTX::instance()->history_size; i++){
+#if defined(__APPLE__)
+    sysbar_table[i+5].text = (CTX::instance()->recent_files[i]).c_str();
+    sysbar_table[i+5].callback_ = (Fl_Callback *)file_open_recent_cb;
+    sysbar_table[i+5].user_data_ = (void*)(CTX::instance()->recent_files[i]).c_str();
+    sysbar_table[i+5].show();
+#endif
+    bar_table[i+5].text = (CTX::instance()->recent_files[i]).c_str();
+    bar_table[i+5].callback_ = (Fl_Callback *)file_open_recent_cb;
+    bar_table[i+5].user_data_ = (void*)(CTX::instance()->recent_files[i]).c_str();
+    bar_table[i+5].show();
+  }; 
+}
diff --git a/Fltk/menuWindow.h b/Fltk/menuWindow.h
index c7a7bf056f9fb6eaddd266abb14d4aa8a7e71f54..6b8ca7efc899d66876722991eea063a08a8422dd 100644
--- a/Fltk/menuWindow.h
+++ b/Fltk/menuWindow.h
@@ -72,9 +72,11 @@ class menuWindow{
   std::vector<popupButton*> popup;
   std::vector<popupButton*> popup2;
   std::vector<char*> label, label2;
+
  public:
   menuWindow();
   void setContext(contextItem *menu_asked, int flag);
+  void fillRecentHistoryMenu();
 };
 
 void file_quit_cb(Fl_Widget *w, void *data);
@@ -88,5 +90,6 @@ 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 file_open_recent_cb(Fl_Widget *w, void *data);
 
 #endif