diff --git a/Common/Options.cpp b/Common/Options.cpp
index 3c15f566e43b876a877535ffc45cfcda534f8b33..1331c4cf24c099f0209c34d9e66ea7eb80b51984 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.182 2004-09-12 17:02:13 geuzaine Exp $
+// $Id: Options.cpp,v 1.183 2004-09-16 19:15:26 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1723,7 +1723,7 @@ char *opt_solver_fifth_button_command4(OPT_ARGS_STR)
 int _gui_action_valid(int action, int num)
 {
   return ((WID) &&
-	  (num < NB_BUTT_MAX) &&
+	  (num < (int)WID->m_toggle_butt.size()) &&
 	  (action & GMSH_GUI) && 
 	  (num == WID->view_number));
 }
@@ -1735,7 +1735,7 @@ char *opt_view_name(OPT_ARGS_STR)
   if(action & GMSH_SET) {
     strcpy(v->Name, val);
 #if defined(HAVE_FLTK)
-    if(WID && (num < NB_BUTT_MAX)) {
+    if(WID && (num < (int)WID->m_toggle_butt.size())) {
       // this is OK even if v->Name is not static or allocated, since
       // we reset it correctly in the main GUI routines when the view
       // associated with the button changes (i.e., when views are
@@ -4424,7 +4424,7 @@ double opt_view_visible(OPT_ARGS_NUM)
     v->Visible = (int)val;
   }
 #if defined(HAVE_FLTK)
-  if(WID && (action & GMSH_GUI) && (num < NB_BUTT_MAX))
+  if(WID && (action & GMSH_GUI) && (num < (int)WID->m_toggle_butt.size()))
     WID->m_toggle_butt[num]->value(v->Visible);
 #endif
   Msg(DEBUG1, "View %d", v->Num);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index f530ba82f1750877bf70e87d09a95e8ad415d9c9..0ec48818444f2f7ced48659df798e3084c745d23 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.268 2004-09-11 06:38:22 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.269 2004-09-16 19:15:26 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -3112,6 +3112,21 @@ void view_remove_invisible_cb(CALLBACK_ARGS)
   Draw();
 }
 
+void view_remove_empty_cb(CALLBACK_ARGS)
+{
+  int i;
+  if(!CTX.post.list)
+    return;
+  REMOVE_ALL_VIEWS = 1;
+  for(i = List_Nbr(CTX.post.list) - 1; i >= 0; i--){
+    Post_View *v = (Post_View*) List_Pointer(CTX.post.list, i);
+    if(v->empty())
+      view_remove_cb(NULL, (void *)i);
+  }
+  REMOVE_ALL_VIEWS = 0;
+  Draw();
+}
+
 void view_remove_cb(CALLBACK_ARGS)
 {
   RemoveViewByIndex((long int)data);
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 90d4c7c83adc874b407708cc41036399bcda4874..a01c68706e3dce8acf9440a7ee48ee65652d414c 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -107,6 +107,7 @@ void view_remove_cb(CALLBACK_ARGS) ;
 void view_remove_all_cb(CALLBACK_ARGS) ;
 void view_remove_visible_cb(CALLBACK_ARGS) ;
 void view_remove_invisible_cb(CALLBACK_ARGS) ;
+void view_remove_empty_cb(CALLBACK_ARGS) ;
 void view_save_ascii_cb(CALLBACK_ARGS) ;
 void view_save_binary_cb(CALLBACK_ARGS) ;
 void view_duplicate_cb(CALLBACK_ARGS) ;
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index e805a44c6ca26fab55868461e68810a3cd38603f..b6d3045570c4c1d10517b16c1bd7d91b1c31e051 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.341 2004-09-14 17:43:40 geuzaine Exp $
+// $Id: GUI.cpp,v 1.342 2004-09-16 19:15:27 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -55,11 +55,14 @@
 #include "CommandLine.h"
 #include "Solvers.h"
 
-#define WINDOW_BOX FL_FLAT_BOX
-#define TOGGLE_BOX FL_DOWN_BOX
+#define NB_BUTT_SCROLL 25
+#define NB_HISTORY_MAX 1000
+
+#define WINDOW_BOX   FL_FLAT_BOX
+#define TOGGLE_BOX   FL_DOWN_BOX
 #define TOGGLE_COLOR FL_BLACK
-#define RADIO_BOX  FL_ROUND_DOWN_BOX
-#define RADIO_COLOR FL_BLACK
+#define RADIO_BOX    FL_ROUND_DOWN_BOX
+#define RADIO_COLOR  FL_BLACK
 
 #define IW (10*fontsize)  // input field width
 #define BB (7*fontsize)   // width of a button with internal label
@@ -812,7 +815,6 @@ void GUI::wait()
 
 // Create the menu window
 
-
 void GUI::add_post_plugins(Fl_Menu_Button * button, int iView)
 {
   char name[256], menuname[256];
@@ -831,14 +833,14 @@ void GUI::add_post_plugins(Fl_Menu_Button * button, int iView)
 
 void GUI::create_menu_window(int argc, char **argv)
 {
-  int i, y;
+  int y;
 
   if(m_window) {
     m_window->show(1, argv);
     return;
   }
 
-  int width = 13 * fontsize - fontsize / 2 - 2;
+  int width = 14 * fontsize;
 
   // this is the initial height: no dynamic button is shown!
 #if defined(__APPLE__) && defined(HAVE_FL_SYS_MENU_BAR)
@@ -852,7 +854,7 @@ void GUI::create_menu_window(int argc, char **argv)
   }
 #endif
 
-  m_window = new Fl_Window(width, MH, "Gmsh");
+  m_window = new Fl_Window(width, MH + NB_BUTT_SCROLL * BH, "Gmsh");
   m_window->box(WINDOW_BOX);
   m_window->callback(file_quit_cb);
 
@@ -883,17 +885,15 @@ void GUI::create_menu_window(int argc, char **argv)
   }
 #endif
 
-  m_navig_butt[0] = new Fl_Button(1, y, 18, BH / 2, "@#<");
+  m_navig_butt[0] = new Fl_Button(1, y, 18, BH / 2, "@#-1<");
   m_navig_butt[0]->labeltype(FL_SYMBOL_LABEL);
-  m_navig_butt[0]->labelsize(11);
   m_navig_butt[0]->box(FL_FLAT_BOX);
   m_navig_butt[0]->selection_color(FL_WHITE);
   m_navig_butt[0]->callback(mod_back_cb);
   m_navig_butt[0]->tooltip("Go back one in the menu history (<)");
 
-  m_navig_butt[1] = new Fl_Button(1, y + BH / 2, 18, BH / 2, "@#>");
+  m_navig_butt[1] = new Fl_Button(1, y + BH / 2, 18, BH / 2, "@#-1>");
   m_navig_butt[1]->labeltype(FL_SYMBOL_LABEL);
-  m_navig_butt[1]->labelsize(11);
   m_navig_butt[1]->box(FL_FLAT_BOX);
   m_navig_butt[1]->selection_color(FL_WHITE);
   m_navig_butt[1]->callback(mod_forward_cb);
@@ -907,78 +907,16 @@ void GUI::create_menu_window(int argc, char **argv)
   // time we select one of the categories, even if the category is not
   // changed):
   m_module_butt->when(FL_WHEN_RELEASE_ALWAYS);
-  y = MH;
-
-  for(i = 0; i < NB_BUTT_MAX; i++) {
-    m_push_butt[i] = new Fl_Button(0, y + i * BH, width, BH);
-    m_push_butt[i]->hide();
-
-    m_toggle_butt[i] = new Fl_Light_Button(0, y + i * BH, width - (fontsize + 4), BH);
-    m_toggle_butt[i]->callback(view_toggle_cb, (void *)i);
-    m_toggle_butt[i]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
-    m_toggle_butt[i]->hide();
-
-    m_toggle2_butt[i] = new Fl_Button(width - (fontsize + 4), y + i * BH, (fontsize + 4), BH, "@#>");
-    m_toggle2_butt[i]->labeltype(FL_SYMBOL_LABEL);
-    m_toggle2_butt[i]->labelsize(11);
-    m_toggle2_butt[i]->align(FL_ALIGN_CENTER);
-    m_toggle2_butt[i]->hide();
-    m_toggle2_butt[i]->tooltip("Show view option menu (Shift+w)");
-
-    m_popup_butt[i] = new Fl_Menu_Button(width - (fontsize + 4), y + i * BH, (fontsize + 4), BH);
-    m_popup_butt[i]->type(Fl_Menu_Button::POPUP123);
-
-    m_popup2_butt[i] = new Fl_Menu_Button(0, y + i * BH, width - (fontsize + 4), BH);
-    m_popup2_butt[i]->type(Fl_Menu_Button::POPUP3);
-
-    for(int j = 0; j < 2; j++) {
-      Fl_Menu_Button *pop = j ? m_popup2_butt[i] : m_popup_butt[i];
-      pop->add("Reload/View", 0, (Fl_Callback *) view_reload_cb, (void *)i, 0);
-      pop->add("Reload/All views", 0, (Fl_Callback *) view_reload_all_cb, (void *)i, 0);
-      pop->add("Reload/All visible views", 0, (Fl_Callback *) view_reload_visible_cb, (void *)i, 0);
-      pop->add("Remove/View", FL_Delete, (Fl_Callback *) view_remove_cb, (void *)i, 0);
-      pop->add("Remove/All views", 0, (Fl_Callback *) view_remove_all_cb, (void *)i, 0);
-      pop->add("Remove/All visible views", 0, (Fl_Callback *) view_remove_visible_cb, (void *)i, 0);
-      pop->add("Remove/All invisible views", 0, (Fl_Callback *) view_remove_invisible_cb, (void *)i, 0);
-      pop->add("Duplicate/View without options", 0, (Fl_Callback *) view_duplicate_cb, (void *)i, 0);
-      pop->add("Duplicate/View with options", 0, (Fl_Callback *) view_duplicate_with_options_cb, (void *)i, 0);
-      pop->add("Combine/Elements/From all views", 0, 
-	       (Fl_Callback *) view_combine_all_cb, (void *)i, 0);
-      pop->add("Combine/Elements/From all views (and remove originals)", 0, 
-	       (Fl_Callback *) view_combine_all_and_remove_cb, (void *)i, 0);
-      pop->add("Combine/Elements/From visible views", 0, 
-	       (Fl_Callback *) view_combine_visible_cb, (void *)i, 0);
-      pop->add("Combine/Elements/From visible views (and remove originals)", 0, 
-	       (Fl_Callback *) view_combine_visible_and_remove_cb, (void *)i, 0);
-      pop->add("Combine/Time steps/From all views", 0, 
-	       (Fl_Callback *) view_combine_time_all_cb, (void *)i, 0);
-      pop->add("Combine/Time steps/From all views (and remove originals)", 0, 
-	       (Fl_Callback *) view_combine_time_all_and_remove_cb, (void *)i, 0);
-      pop->add("Combine/Time steps/From visible views", 0, 
-	       (Fl_Callback *) view_combine_time_visible_cb, (void *)i, 0);
-      pop->add("Combine/Time steps/From visible views (and remove originals)", 0, 
-	       (Fl_Callback *) view_combine_time_visible_and_remove_cb, (void *)i, 0);
-      pop->add("Combine/Time steps/By view name", 0, 
-	       (Fl_Callback *) view_combine_time_by_name_cb, (void *)i, 0);
-      pop->add("Combine/Time steps/By view name (and remove originals)", 0, 
-	       (Fl_Callback *) view_combine_time_by_name_and_remove_cb, (void *)i, 0);
-      pop->add("Save as/ASCII view...", 0, (Fl_Callback *) view_save_ascii_cb, (void *)i, 0);
-      pop->add("Save as/Binary view...", 0, (Fl_Callback *) view_save_binary_cb, (void *)i, 0);
-      add_post_plugins(pop, i);
-      pop->add("Apply as background mesh", 0, (Fl_Callback *) view_applybgmesh_cb, (void *)i, FL_MENU_DIVIDER);
-      pop->add("Options...", 'o', (Fl_Callback *) view_options_cb, (void *)i, 0);
-      pop->hide();
-    }
-  }
-  m_window->position(CTX.position[0], CTX.position[1]);
-  m_window->end();
-}
 
-// Dynamically set the height of the menu window
+  // create an empty scroll area that will get populated dynamically
+  // in set_context()
+  m_scroll = new Fl_Scroll(0, MH, width, NB_BUTT_SCROLL * BH); 
+  m_scroll->type(Fl_Scroll::VERTICAL);
+  m_scroll->end();
 
-void GUI::set_menu_size(int nb_butt)
-{
-  m_window->size(m_window->w(), MH + nb_butt * BH);
+  m_window->size(width, MH);
+  m_window->position(CTX.position[0], CTX.position[1]);
+  m_window->end();
 }
 
 // Dynamically set the context
@@ -988,18 +926,16 @@ void GUI::set_context(Context_Item * menu_asked, int flag)
   static int nb_back = 0, nb_forward = 0, init_context = 0;
   static Context_Item *menu_history[NB_HISTORY_MAX];
   Context_Item *menu;
-  Post_View *v;
-  int i;
 
   if(!init_context) {
     init_context = 1;
-    for(i = 0; i < NB_HISTORY_MAX; i++) {
+    for(int i = 0; i < NB_HISTORY_MAX; i++) {
       menu_history[i] = NULL;
     }
   }
 
   if(nb_back > NB_HISTORY_MAX - 2)
-    nb_back = 1;        // we should do a circular list
+    nb_back = 1; // we should do a circular list
 
   if(flag == -1) {
     if(nb_back > 1) {
@@ -1027,16 +963,27 @@ void GUI::set_context(Context_Item * menu_asked, int flag)
     nb_forward = 0;
   }
 
-  int nb = 0;
-
-  if(menu[0].label[0] == '0')
+  if(menu[0].label[0] == '0'){
     m_module_butt->value(0);
-  else if(menu[0].label[0] == '1')
+  }
+  else if(menu[0].label[0] == '1'){
     m_module_butt->value(1);
-  else if(menu[0].label[0] == '2')
+  }
+  else if(menu[0].label[0] == '2'){
     m_module_butt->value(2);
-  else if(menu[0].label[0] == '3')
+    menu[1].label = opt_solver_name0(0, GMSH_GET, 0);
+    menu[2].label = opt_solver_name1(0, GMSH_GET, 0);
+    menu[3].label = opt_solver_name2(0, GMSH_GET, 0);
+    menu[4].label = opt_solver_name3(0, GMSH_GET, 0);
+    menu[5].label = opt_solver_name4(0, GMSH_GET, 0);
+    for(int i = 0; i < MAXSOLVERS; i++) {
+      if(!strlen(menu[i + 1].label))
+	menu[i + 1].label = NULL;
+    }
+  }
+  else if(menu[0].label[0] == '3'){
     m_module_butt->value(3);
+  }
   else {
     Msg(WARNING, "Something is wrong in your dynamic context definition");
     return;
@@ -1044,70 +991,127 @@ void GUI::set_context(Context_Item * menu_asked, int flag)
 
   Msg(STATUS2N, menu[0].label + 1);
 
-  switch (m_module_butt->value()) {
-  case 3:      // post-processing contexts
-    for(i = 0; i < List_Nbr(CTX.post.list); i++) {
-      if(i == NB_BUTT_MAX)
-        break;
-      nb++;
-      v = (Post_View *) List_Pointer(CTX.post.list, i);
-      m_push_butt[i]->hide();
-      m_toggle_butt[i]->show();
-      m_toggle_butt[i]->value(v->Visible);
-      m_toggle_butt[i]->label(v->Name);
-      m_toggle_butt[i]->tooltip(v->FileName);
-      m_toggle2_butt[i]->show();
-      m_popup_butt[i]->show();
-      m_popup2_butt[i]->show();
-    }
-    for(i = List_Nbr(CTX.post.list); i < NB_BUTT_MAX; i++) {
-      m_push_butt[i]->hide();
-      m_toggle_butt[i]->hide();
-      m_toggle2_butt[i]->hide();
-      m_popup_butt[i]->hide();
-      m_popup2_butt[i]->hide();
-    }
-    break;
-  default:     // geometry, mesh, solver contexts
-    if(m_module_butt->value() == 2) {   //solver
-      // should handle MAXSOLVERS
-      menu[1].label = opt_solver_name0(0, GMSH_GET, 0);
-      menu[2].label = opt_solver_name1(0, GMSH_GET, 0);
-      menu[3].label = opt_solver_name2(0, GMSH_GET, 0);
-      menu[4].label = opt_solver_name3(0, GMSH_GET, 0);
-      menu[5].label = opt_solver_name4(0, GMSH_GET, 0);
-      for(i = 0; i < MAXSOLVERS; i++) {
-        if(!strlen(menu[i + 1].label))
-          menu[i + 1].label = NULL;
-      }
-    }
-    for(i = 0; i < NB_BUTT_MAX; i++) {
-      m_toggle_butt[i]->hide();
-      m_toggle2_butt[i]->hide();
-      m_popup_butt[i]->hide();
-      m_popup2_butt[i]->hide();
-      if(menu[i + 1].label) {
-        m_push_butt[i]->label(menu[i + 1].label);
-        m_push_butt[i]->callback(menu[i + 1].callback, menu[i + 1].arg);
-        m_push_butt[i]->redraw();
-        m_push_butt[i]->show();
-        nb++;
+  // free all the children (m_push*, m_toggle*, m_pop*)
+  m_scroll->clear();
+  // reset the vectors
+  m_push_butt.clear();
+  m_toggle_butt.clear();
+  m_toggle2_butt.clear();
+  m_popup_butt.clear();
+  m_popup2_butt.clear();
+  for(unsigned int i = 0; i < m_pop_label.size(); i++)
+    delete [] m_pop_label[i];
+  m_pop_label.clear();
+
+  int width = m_window->w();
+  int right_pop_width = 4 * fontsize + 3;
+
+  // construct the dynamic menu
+  int nb = 0;
+  if(m_module_butt->value() == 3){ // post-processing context
+    for(nb = 0; nb < List_Nbr(CTX.post.list); nb++) {
+      Post_View *v = (Post_View *) List_Pointer(CTX.post.list, nb);
+      
+      Fl_Light_Button *b1 = new Fl_Light_Button(0, MH + nb * BH, width - right_pop_width, BH);
+      b1->callback(view_toggle_cb, (void *)nb);
+      b1->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+      b1->value(v->Visible);
+      b1->label(v->Name);
+      b1->tooltip(v->FileName);
+      
+      char *tmp = new char[32];
+      sprintf(tmp, "[%d]@#-1>", nb);
+      Fl_Button *b2 = new Fl_Button(width - right_pop_width, MH + nb * BH, right_pop_width, BH, tmp);
+      m_pop_label.push_back(tmp);
+      b2->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+      b2->tooltip("Show view option menu (Shift+w)");
+  
+      Fl_Menu_Button *p[2];
+      p[0] = new Fl_Menu_Button(width - right_pop_width, MH + nb * BH, right_pop_width, BH);
+      p[0]->type(Fl_Menu_Button::POPUP123);
+  
+      p[1] = new Fl_Menu_Button(0, MH + nb * BH, width - right_pop_width, BH);
+      p[1]->type(Fl_Menu_Button::POPUP3);
+  
+      for(int j = 0; j < 2; j++) {
+	p[j]->add("Reload/View", 0, 
+		  (Fl_Callback *) view_reload_cb, (void *)nb, 0);
+	p[j]->add("Reload/All views", 0, 
+		  (Fl_Callback *) view_reload_all_cb, (void *)nb, 0);
+	p[j]->add("Reload/All visible views", 0, 
+		  (Fl_Callback *) view_reload_visible_cb, (void *)nb, 0);
+	p[j]->add("Remove/View", FL_Delete, 
+		  (Fl_Callback *) view_remove_cb, (void *)nb, 0);
+	p[j]->add("Remove/All views", 0, 
+		  (Fl_Callback *) view_remove_all_cb, (void *)nb, 0);
+	p[j]->add("Remove/All visible views", 0, 
+		  (Fl_Callback *) view_remove_visible_cb, (void *)nb, 0);
+	p[j]->add("Remove/All invisible views", 0, 
+		  (Fl_Callback *) view_remove_invisible_cb, (void *)nb, 0);
+	p[j]->add("Remove/All empty views", 0, 
+		  (Fl_Callback *) view_remove_empty_cb, (void *)nb, 0);
+	p[j]->add("Duplicate/View without options", 0, 
+		  (Fl_Callback *) view_duplicate_cb, (void *)nb, 0);
+	p[j]->add("Duplicate/View with options", 0, 
+		  (Fl_Callback *) view_duplicate_with_options_cb, (void *)nb, 0);
+	p[j]->add("Combine/Elements/From all views", 0, 
+		  (Fl_Callback *) view_combine_all_cb, (void *)nb, 0);
+	p[j]->add("Combine/Elements/From all views (and remove originals)", 0, 
+		  (Fl_Callback *) view_combine_all_and_remove_cb, (void *)nb, 0);
+	p[j]->add("Combine/Elements/From visible views", 0, 
+		  (Fl_Callback *) view_combine_visible_cb, (void *)nb, 0);
+	p[j]->add("Combine/Elements/From visible views (and remove originals)", 0, 
+		  (Fl_Callback *) view_combine_visible_and_remove_cb, (void *)nb, 0);
+	p[j]->add("Combine/Time steps/From all views", 0, 
+		  (Fl_Callback *) view_combine_time_all_cb, (void *)nb, 0);
+	p[j]->add("Combine/Time steps/From all views (and remove originals)", 0, 
+		  (Fl_Callback *) view_combine_time_all_and_remove_cb, (void *)nb, 0);
+	p[j]->add("Combine/Time steps/From visible views", 0, 
+		  (Fl_Callback *) view_combine_time_visible_cb, (void *)nb, 0);
+	p[j]->add("Combine/Time steps/From visible views (and remove originals)", 0, 
+		  (Fl_Callback *) view_combine_time_visible_and_remove_cb, (void *)nb, 0);
+	p[j]->add("Combine/Time steps/By view name", 0, 
+		 (Fl_Callback *) view_combine_time_by_name_cb, (void *)nb, 0);
+	p[j]->add("Combine/Time steps/By view name (and remove originals)", 0, 
+		  (Fl_Callback *) view_combine_time_by_name_and_remove_cb, (void *)nb, 0);
+	p[j]->add("Save as/ASCII view...", 0, 
+		  (Fl_Callback *) view_save_ascii_cb, (void *)nb, 0);
+	p[j]->add("Save as/Binary view...", 0, 
+		  (Fl_Callback *) view_save_binary_cb, (void *)nb, 0);
+	add_post_plugins(p[j], nb);
+	p[j]->add("Apply as background mesh", 0, 
+		  (Fl_Callback *) view_applybgmesh_cb, (void *)nb, FL_MENU_DIVIDER);
+	p[j]->add("Options...", 'o', 
+		  (Fl_Callback *) view_options_cb, (void *)nb, 0);
       }
-      else
-        break;
+
+      m_toggle_butt.push_back(b1);
+      m_toggle2_butt.push_back(b2);
+      m_popup_butt.push_back(p[0]);
+      m_popup2_butt.push_back(p[1]);
+      m_scroll->add(b1);
+      m_scroll->add(b2);
+      m_scroll->add(p[0]);
+      m_scroll->add(p[1]);
     }
-    for(i = nb; i < NB_BUTT_MAX; i++) {
-      m_toggle_butt[i]->hide();
-      m_toggle2_butt[i]->hide();
-      m_popup_butt[i]->hide();
-      m_popup2_butt[i]->hide();
-      m_push_butt[i]->hide();
+  }
+  else{ // geometry, mesh and solver contexts
+    while(menu[nb + 1].label) {
+      Fl_Button *b = new Fl_Button(0, MH + nb * BH, width, BH);
+      b->label(menu[nb + 1].label);
+      b->callback(menu[nb + 1].callback, menu[nb + 1].arg);
+      m_push_butt.push_back(b);
+      m_scroll->add(b);
+      nb++;
     }
-    break;
   }
 
-  set_menu_size(nb);
+  m_scroll->redraw();
 
+  if(nb <= NB_BUTT_SCROLL)
+    m_window->size(width, MH + nb * BH);
+  else
+    m_window->size(width, MH + NB_BUTT_SCROLL * BH);
 }
 
 int GUI::get_context()
@@ -1115,7 +1119,6 @@ int GUI::get_context()
   return m_module_butt->value();
 }
 
-
 // Create the graphic window
 
 void GUI::create_graphic_window(int argc, char **argv)
@@ -1402,8 +1405,6 @@ void GUI::reset_option_browser()
   opt_browser->add("Solver");
   opt_browser->add("Post-processing");
   for(i = 0; i < List_Nbr(CTX.post.list); i++) {
-    if(i == NB_BUTT_MAX)
-      break;
     sprintf(str, "View [%d]", i);
     opt_browser->add(str);
   }
@@ -1459,6 +1460,7 @@ void GUI::create_option_window()
   // Selection browser
 
   opt_browser = new Fl_Hold_Browser(WB, WB, BROWSERW - WB, height - 3 * WB - BH);
+  opt_browser->has_scrollbar(Fl_Browser_::VERTICAL);
   reset_option_browser();
   opt_browser->callback(options_browser_cb);
   opt_browser->value(1);
@@ -3276,8 +3278,6 @@ void GUI::reset_clip_browser()
   clip_browser->add("Geometry");
   clip_browser->add("Mesh");
   for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
-    if(i == NB_BUTT_MAX)
-      break;
     sprintf(str, "View [%d]", i);
     clip_browser->add(str);
   }
@@ -3792,4 +3792,3 @@ void GUI::create_solver_window(int num)
   solver[num].window->position(CTX.solver_position[0], CTX.solver_position[1]);
   solver[num].window->end();
 }
-
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index 81089f5d1299377f50bbf8f109eef3def6588d6b..8a6c13e1f21a663e0d370d6031856a1ca40ccba0 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -47,12 +47,11 @@
 #include <FL/fl_ask.H>
 #include <FL/Fl_Tooltip.H>
 
+#include <vector>
+
 #include "Opengl_Window.h"
 #include "Colorbar_Window.h"
 
-#define NB_BUTT_MAX    100
-#define NB_HISTORY_MAX 1000
-
 #if defined(__APPLE__) && defined(HAVE_FL_SYS_MENU_BAR)
 #include <FL/Fl_Sys_Menu_Bar.H>
 #endif
@@ -119,6 +118,7 @@ struct SolverDialogBox
 class GUI{
 
   int MH, fontsize ;
+  Fl_Scroll *m_scroll;
 
   // Bitmaps
   Fl_Bitmap  *abort_bmp, *start_bmp, *stop_bmp, *rewind_bmp, *about_bmp ;
@@ -137,11 +137,12 @@ public:
   Fl_Menu_Bar      *m_menu_bar ;
   Fl_Choice        *m_module_butt ;
   Fl_Button        *m_navig_butt  [2] ;
-  Fl_Button        *m_push_butt   [NB_BUTT_MAX] ;
-  Fl_Light_Button  *m_toggle_butt [NB_BUTT_MAX] ;
-  Fl_Button        *m_toggle2_butt[NB_BUTT_MAX] ;
-  Fl_Menu_Button   *m_popup_butt  [NB_BUTT_MAX] ;
-  Fl_Menu_Button   *m_popup2_butt [NB_BUTT_MAX] ;
+  std::vector<Fl_Button*>       m_push_butt ;
+  std::vector<Fl_Light_Button*> m_toggle_butt ;
+  std::vector<Fl_Button*>       m_toggle2_butt ;
+  std::vector<Fl_Menu_Button*>  m_popup_butt ;
+  std::vector<Fl_Menu_Button*>  m_popup2_butt ;
+  std::vector<char*>            m_pop_label ;
 
   // graphic window
   Fl_Window        *g_window ;
@@ -273,7 +274,6 @@ public:
   void make_opengl_current();
   void redraw_opengl();
   void set_size(int w, int h);
-  void set_menu_size(int nb_butt);
   void set_context(Context_Item menu[], int flag);
   int  get_context();
   void set_anim_buttons(int mode);
diff --git a/Makefile b/Makefile
index 741998e5703c28c7cd0a6d7e8cc7cf2664740a58..fe25877d344dd03eb9515da9846b17305b08fa63 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.368 2004-09-12 04:13:59 geuzaine Exp $
+# $Id: Makefile,v 1.369 2004-09-16 19:15:26 geuzaine Exp $
 #
 # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 #
@@ -23,7 +23,7 @@ include variables
 
 GMSH_MAJOR_VERSION = 1
 GMSH_MINOR_VERSION = 55
-GMSH_PATCH_VERSION = 1
+GMSH_PATCH_VERSION = 2
 GMSH_EXTRA_VERSION = "-cvs"
 
 GMSH_VERSION = ${GMSH_MAJOR_VERSION}.${GMSH_MINOR_VERSION}.${GMSH_PATCH_VERSION}${GMSH_EXTRA_VERSION}
diff --git a/Plugin/CutMap.cpp b/Plugin/CutMap.cpp
index c3da508e12536c4499d8ccf8a72cb0f82fffbdb6..f855fe514271b6419600df4d9f1e4ffbadb93b9e 100644
--- a/Plugin/CutMap.cpp
+++ b/Plugin/CutMap.cpp
@@ -1,4 +1,4 @@
-// $Id: CutMap.cpp,v 1.37 2004-05-16 20:04:43 geuzaine Exp $
+// $Id: CutMap.cpp,v 1.38 2004-09-16 19:15:27 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -65,8 +65,8 @@ void GMSH_CutMapPlugin::getInfos(char *author, char *copyright,
 	 "corresponding time step in `dView'. If `dView'\n"
 	 "< 0, the plugin uses `iView' as the value source.\n"
 	 "\n"
-	 "Plugin(CutMap) creates (at most) as many views\n"
-	 "as there are time steps in `iView'.\n");
+	 "Plugin(CutMap) creates as many views as there are\n"
+	 "time steps in `iView'.\n");
 }
 
 int GMSH_CutMapPlugin::getNbOptions() const
diff --git a/Plugin/Extract.cpp b/Plugin/Extract.cpp
index 0cdcb06f1d70ae536c909a527e4c246b080b62fe..de62b443cfb2cddafee1e567e1a398bbd71cfa7b 100644
--- a/Plugin/Extract.cpp
+++ b/Plugin/Extract.cpp
@@ -1,4 +1,4 @@
-// $Id: Extract.cpp,v 1.11 2004-05-16 20:04:43 geuzaine Exp $
+// $Id: Extract.cpp,v 1.12 2004-09-16 19:15:27 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -244,19 +244,13 @@ Post_View *GMSH_ExtractPlugin::execute(Post_View * v)
   extract(expr, v1->VY, v1->NbVY, v2->SY, &v2->NbSY, v2->VY, &v2->NbVY, v1->NbTimeStep, 5, 3);
   extract(expr, v1->TY, v1->NbTY, v2->SY, &v2->NbSY, v2->VY, &v2->NbVY, v1->NbTimeStep, 5, 9);
 
-  if(v2->empty()) {
-    RemoveViewByNumber(v2->Num);
-    return v1;
-  }
-  else{
-    // copy time data
-    for(int i = 0; i < List_Nbr(v1->Time); i++)
-      List_Add(v2->Time, List_Pointer(v1->Time, i));
-    // finalize
-    char name[1024], filename[1024];
-    sprintf(name, "%s_Extract", v1->Name);
-    sprintf(filename, "%s_Extract.pos", v1->Name);
-    EndView(v2, 1, filename, name);
-    return v2;
-  }
+  // copy time data
+  for(int i = 0; i < List_Nbr(v1->Time); i++)
+    List_Add(v2->Time, List_Pointer(v1->Time, i));
+  // finalize
+  char name[1024], filename[1024];
+  sprintf(name, "%s_Extract", v1->Name);
+  sprintf(filename, "%s_Extract.pos", v1->Name);
+  EndView(v2, 1, filename, name);
+  return v2;
 }
diff --git a/Plugin/Levelset.cpp b/Plugin/Levelset.cpp
index d6df1e5d004510869dcb0ee97be917ca7ba782ec..3af76c07398fa78a19933d3675767ebdde6394e0 100644
--- a/Plugin/Levelset.cpp
+++ b/Plugin/Levelset.cpp
@@ -1,4 +1,4 @@
-// $Id: Levelset.cpp,v 1.14 2004-05-13 17:48:56 geuzaine Exp $
+// $Id: Levelset.cpp,v 1.15 2004-09-16 19:15:27 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -521,8 +521,7 @@ Post_View *GMSH_LevelsetPlugin::execute(Post_View * v)
   executeList(v, v->TY, v->NbTY, 9, w, w->TY, w->NbTY, 9, 5, 8, exnPyr, out);
 
   for(unsigned int i = 0; i < out.size(); i++) {
-    // create time data
-    // FIXME: todo
+    // FIXME: create time data
     // finalize
     char name[1024], filename[1024];
     sprintf(name, "%s_Levelset_%d", v->Name, i);
@@ -530,19 +529,5 @@ Post_View *GMSH_LevelsetPlugin::execute(Post_View * v)
     EndView(out[i], 1, filename, name);
   }
 
-  // remove empty views
-  List_T *to_remove = List_Create(10, 10, sizeof(int));
-  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
-    w = (Post_View*) List_Pointer(CTX.post.list, i);
-    if(w->empty())
-      List_Insert(to_remove, &w->Num, fcmp_int);
-  }
-  for(int i = 0; i < List_Nbr(to_remove); i++) {
-    int num;
-    List_Read(to_remove, i, &num);
-    RemoveViewByNumber(num);
-  }
-  List_Delete(to_remove);
-
   return 0;
 }
diff --git a/Plugin/Skin.cpp b/Plugin/Skin.cpp
index 26c1794f9621c8054ebcce31b10e4743c8fdc955..a503c1ae1165ba732572fc4cf43ab570aba675be 100644
--- a/Plugin/Skin.cpp
+++ b/Plugin/Skin.cpp
@@ -1,4 +1,4 @@
-// $Id: Skin.cpp,v 1.27 2004-05-16 20:04:43 geuzaine Exp $
+// $Id: Skin.cpp,v 1.28 2004-09-16 19:15:27 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -274,19 +274,13 @@ Post_View *GMSH_SkinPlugin::execute(Post_View * v)
   Tree_Action(_skin, addInView);
   Tree_Delete(_skin);
 
-  if(v2->empty()) {
-    RemoveViewByNumber(v2->Num);
-    return v1;
-  }
-  else{
-    // copy time data
-    for(int i = 0; i < List_Nbr(v1->Time); i++)
-      List_Add(v2->Time, List_Pointer(v1->Time, i));
-    // finalize
-    char name[1024], filename[1024];
-    sprintf(name, "%s_Skin", v1->Name);
-    sprintf(filename, "%s_Skin.pos", v1->Name);
-    EndView(v2, 1, filename, name);
-    return v2;
-  }
+  // copy time data
+  for(int i = 0; i < List_Nbr(v1->Time); i++)
+    List_Add(v2->Time, List_Pointer(v1->Time, i));
+  // finalize
+  char name[1024], filename[1024];
+  sprintf(name, "%s_Skin", v1->Name);
+  sprintf(filename, "%s_Skin.pos", v1->Name);
+  EndView(v2, 1, filename, name);
+  return v2;
 }
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 8194e7e0b9245b6c6fc6911c4d9615751231d69a..95c0f142557a959154434f7055b812eba5bf2910 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,9 +1,10 @@
-$Id: VERSIONS,v 1.244 2004-09-01 20:23:50 geuzaine Exp $
+$Id: VERSIONS,v 1.245 2004-09-16 19:15:27 geuzaine Exp $
 
 New since 1.55: new post-processing option to draw a scalar view
 raised by a displacement view without using Plugin(DisplacementRaise)
 (makes drawing arbitrary scalar fields on deformed meshes much
-easier); small bug fixes.
+easier); better post-processing menu (arbitrary number of
+views+scrollable+show view number); small bug fixes.
 
 New in 1.55: added background mesh support for Triangle; meshes can
 now be displayed using "smoothed" normals (like post-processing
diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi
index f349a5142310cdfe1ceea7bcde5681aed7367ec1..46ff1079bdfba7682dc11cb6b2a38a9df56bd726 100644
--- a/doc/texinfo/opt_general.texi
+++ b/doc/texinfo/opt_general.texi
@@ -36,7 +36,7 @@ Saved in: @code{General.SessionFileName}
 
 @item General.TextEditor
 System command to launch a text editor@*
-Default value: @code{"emacs %s &"}@*
+Default value: @code{"open -e %s"}@*
 Saved in: @code{General.OptionsFileName}
 
 @item General.TmpFileName
@@ -46,7 +46,7 @@ Saved in: @code{General.SessionFileName}
 
 @item General.WebBrowser
 System command to launch a web browser@*
-Default value: @code{"if [[ $(ps -e|grep mozilla|grep -v grep) ]]; then mozilla -remote 'openurl(%s)' ; else mozilla %s ; fi &"}@*
+Default value: @code{"open %s"}@*
 Saved in: @code{General.OptionsFileName}
 
 @item General.AlphaBlending
@@ -329,6 +329,11 @@ Z position of light source 0@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.Light0W
+Divisor of the X, Y and Z coordinates of light source 0 (W=0 means infinitely far source)@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.Light1
 Enable light source 1@*
 Default value: @code{0}@*
@@ -349,6 +354,11 @@ Z position of light source 1@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.Light1W
+Divisor of the X, Y and Z coordinates of light source 1 (W=0 means infinitely far source)@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.Light2
 Enable light source 2@*
 Default value: @code{0}@*
@@ -369,6 +379,11 @@ Z position of light source 2@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.Light2W
+Divisor of the X, Y and Z coordinates of light source 2 (W=0 means infinitely far source)@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.Light3
 Enable light source 3@*
 Default value: @code{0}@*
@@ -389,6 +404,11 @@ Z position of light source 3@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.Light3W
+Divisor of the X, Y and Z coordinates of light source 3 (W=0 means infinitely far source)@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.Light4
 Enable light source 4@*
 Default value: @code{0}@*
@@ -409,6 +429,11 @@ Z position of light source 4@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.Light4W
+Divisor of the X, Y and Z coordinates of light source 4 (W=0 means infinitely far source)@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.Light5
 Enable light source 5@*
 Default value: @code{0}@*
@@ -429,6 +454,11 @@ Z position of light source 5@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.Light5W
+Divisor of the X, Y and Z coordinates of light source 5 (W=0 means infinitely far source)@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.LineWidth
 Display width of lines (in pixels)@*
 Default value: @code{1}@*
diff --git a/doc/texinfo/opt_plugin.texi b/doc/texinfo/opt_plugin.texi
index 1e36dd642ec8b7cb571d4f8ca4c9b87af76d52e2..6507b084377982d2950324adce9be8bfba8489cc 100644
--- a/doc/texinfo/opt_plugin.texi
+++ b/doc/texinfo/opt_plugin.texi
@@ -47,8 +47,8 @@ plugin uses, for each time step in `iView', the
 corresponding time step in `dView'. If `dView'
 < 0, the plugin uses `iView' as the value source.
 
-Plugin(CutMap) creates (at most) as many views
-as there are time steps in `iView'.
+Plugin(CutMap) creates as many views as there are
+time steps in `iView'.
 
 Numeric options:
 @table @code
diff --git a/doc/texinfo/opt_view.texi b/doc/texinfo/opt_view.texi
index 36bb7d77f9f48ff203d91fc23599a8413f472349..a3a47d858036fc9b8a87ed6eb55372828850d503 100644
--- a/doc/texinfo/opt_view.texi
+++ b/doc/texinfo/opt_view.texi
@@ -244,6 +244,11 @@ Vertical position (in pixels) of the upper left corner of the scale or 2D graph@
 Default value: @code{50}@*
 Saved in: @code{General.OptionsFileName}
 
+@item View.RaisedScalarView
+Index of the scalar view raised by the displacement field@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item View.RaiseX
 Elevation of the view along X-axis (in model coordinates)@*
 Default value: @code{0}@*
@@ -315,7 +320,7 @@ Default value: @code{1}@*
 Saved in: @code{-}
 
 @item View.VectorType
-Vector display type (1=segment, 2=arrow, 3=pyramid, 4=3D arrow, 5=displacement)@*
+Vector display type (1=segment, 2=arrow, 3=pyramid, 4=3D arrow, 5=displacement, 6=raised scalar view)@*
 Default value: @code{4}@*
 Saved in: @code{General.OptionsFileName}