diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index f01e2a374540ef705c784eada8cfbef6f92b644b..0bed098df13cefa3751f4cb8e43fb8d0df7c763a 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.402 2004-12-31 04:04:50 geuzaine Exp $
+// $Id: GUI.cpp,v 1.403 2004-12-31 06:09:31 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -63,6 +63,7 @@
 #include "OpenFile.h"
 #include "CommandLine.h"
 #include "Solvers.h"
+#include "Shortcut_Window.h"
 
 #define NB_BUTT_SCROLL 25
 #define NB_HISTORY_MAX 1000
@@ -917,7 +918,7 @@ void GUI::create_menu_window(int argc, char **argv)
   }
 #endif
 
-  m_window = new Fl_Window(width, MH + NB_BUTT_SCROLL * BH, "Gmsh");
+  m_window = new Main_Window(width, MH + NB_BUTT_SCROLL * BH, "Gmsh");
   m_window->box(GMSH_WINDOW_BOX);
   m_window->callback(file_quit_cb);
 
@@ -1246,7 +1247,7 @@ void GUI::create_graphic_window(int argc, char **argv)
   int glheight = CTX.viewport[3] - CTX.viewport[1];
   int height = glheight + sh;
 
-  g_window = new Fl_Window(width, height);
+  g_window = new Main_Window(width, height);
   g_window->callback(file_quit_cb);
 
   // bottom button bar
@@ -1579,7 +1580,7 @@ void GUI::create_option_window()
     return;
   }
 
-  opt_window = new Fl_Window(width, height);
+  opt_window = new Dialog_Window(width, height);
   opt_window->box(GMSH_WINDOW_BOX);
 
   // Buttons
@@ -3079,7 +3080,7 @@ void GUI::create_statistics_window()
   int width = 26 * fontsize;
   int height = 5 * WB + 18 * BH;
 
-  stat_window = new Fl_Window(width, height, "Statistics");
+  stat_window = new Dialog_Window(width, height, "Statistics");
   stat_window->box(GMSH_WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
@@ -3255,7 +3256,7 @@ PluginDialogBox *GUI::create_plugin_window(GMSH_Plugin * p)
 
   PluginDialogBox *pdb = new PluginDialogBox;
   pdb->current_view_index = 0;
-  pdb->main_window = new Fl_Window(width, height);
+  pdb->main_window = new Dialog_Window(width, height);
   pdb->main_window->box(GMSH_WINDOW_BOX);
   sprintf(buffer, "%s Plugin", namep);
   char *nbuffer = new char[strlen(buffer) + 1];
@@ -3337,7 +3338,7 @@ void GUI::create_message_window()
   int width = CTX.msg_size[0];
   int height = CTX.msg_size[1];
 
-  msg_window = new Fl_Window(width, height, "Message Console");
+  msg_window = new Dialog_Window(width, height, "Message Console");
   msg_window->box(GMSH_WINDOW_BOX);
 
   msg_browser = new Fl_Browser(WB, WB, width - 2 * WB, height - 3 * WB - BH);
@@ -3449,7 +3450,7 @@ void GUI::create_visibility_window()
   int width = cols[0] + cols[1] + cols[2] + cols[3] + 2 * WB;
   int height = 15 * BH;
 
-  vis_window = new Fl_Window(width, height, "Visibility");
+  vis_window = new Dialog_Window(width, height, "Visibility");
   vis_window->box(GMSH_WINDOW_BOX);
 
   int brw = width - 2 * WB;
@@ -3574,7 +3575,7 @@ void GUI::create_clip_window()
   int brw = 105;
   int BW = width - brw - 3 * WB - 2 * fontsize;
 
-  clip_window = new Fl_Window(width, height, "Clipping Planes");
+  clip_window = new Dialog_Window(width, height, "Clipping Planes");
   clip_window->box(GMSH_WINDOW_BOX);
 
   clip_browser = new Fl_Multi_Browser(1 * WB, 1 * WB, brw, 5 * BH);
@@ -3626,6 +3627,7 @@ void GUI::create_about_window()
   int width = 33 * fontsize;
   int height = 15 * BH;
 
+  // not a "Dialog_Window" since it is modal 
   about_window = new Fl_Window(width, height, "About Gmsh");
   about_window->box(GMSH_WINDOW_BOX);
 
@@ -3709,7 +3711,7 @@ void GUI::create_geometry_context_window(int num)
   int width = 31 * fontsize;
   int height = 5 * WB + 9 * BH;
 
-  context_geometry_window = new Fl_Window(width, height, "Contextual Geometry Definitions");
+  context_geometry_window = new Dialog_Window(width, height, "Contextual Geometry Definitions");
   context_geometry_window->box(GMSH_WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
@@ -3857,7 +3859,7 @@ void GUI::create_mesh_context_window(int num)
   int width = 31 * fontsize;
   int height = 5 * WB + 5 * BH;
 
-  context_mesh_window = new Fl_Window(width, height, "Contextual Mesh Definitions");
+  context_mesh_window = new Dialog_Window(width, height, "Contextual Mesh Definitions");
   context_mesh_window->box(GMSH_WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
@@ -3940,7 +3942,7 @@ void GUI::create_solver_window(int num)
   if(height < 8 * WB + 8 * BH)
     height = 8 * WB + 8 * BH;   //minimum height required by Options tab
 
-  solver[num].window = new Fl_Window(width, height);
+  solver[num].window = new Dialog_Window(width, height);
   solver[num].window->box(GMSH_WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - (3 + newrow) * WB - (1 + newrow) * BH);
diff --git a/Fltk/GUI_Extras.cpp b/Fltk/GUI_Extras.cpp
index 30aae059da2912fc1190728a99948748239c7d9c..f23ca586ffdb036b1d3bacdca2e37dbf2fc0e56f 100644
--- a/Fltk/GUI_Extras.cpp
+++ b/Fltk/GUI_Extras.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI_Extras.cpp,v 1.3 2004-12-31 04:04:51 geuzaine Exp $
+// $Id: GUI_Extras.cpp,v 1.4 2004-12-31 06:09:31 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -19,20 +19,20 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include <FL/Fl_Window.H>
-#include <FL/Fl_Button.H>
-#include <FL/Fl_Return_Button.H>
-#include <FL/Fl_Value_Slider.H>
-#include <errno.h>
-
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "Mesh.h"
 #include "File_Picker.h"
+#include "Shortcut_Window.h"
 #include "CreateFile.h"
 #include "Options.h"
 #include "Context.h"
 
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Value_Slider.H>
+#include <errno.h>
+
 extern Context_T CTX;
 
 // File chooser
@@ -118,7 +118,7 @@ int arrow_editor(char *title, double &a, double &b, double &c)
 
   if(!editor){
     editor = new _editor;
-    editor->window = new Fl_Window(200, 140);
+    editor->window = new Dialog_Window(200, 140);
     editor->sa = new Fl_Value_Slider(10, 10, 100, 25, "Head radius");
     editor->sa->type(FL_HOR_SLIDER);
     editor->sa->align(FL_ALIGN_RIGHT);
@@ -174,6 +174,7 @@ int jpeg_dialog(char *name, int TeX)
   if(!dialog){
     dialog = new _jpeg_dialog;
     int h = 3*10 + 25 + 2*25, y = 0;
+    // not a "Dialog_Window" since it is modal 
     dialog->window = new Fl_Window(200, h, "JPEG Options"); y = 10;
     dialog->window->box(GMSH_WINDOW_BOX);
     dialog->s[0] = new Fl_Value_Slider(10, y, 100, 25, "Quality"); y += 25;
@@ -234,6 +235,7 @@ int gif_dialog(char *name)
   if(!dialog){
     dialog = new _gif_dialog;
     int h = 3*10 + 25 + 4*25, y = 0;
+    // not a "Dialog_Window" since it is modal 
     dialog->window = new Fl_Window(200, h, "GIF Options"); y = 10;
     dialog->window->box(GMSH_WINDOW_BOX);
     dialog->b[0] = new Fl_Check_Button(10, y, 180, 25, "Dither"); y += 25;
@@ -326,6 +328,7 @@ int gl2ps_dialog(char *name, char *title, int format, int TeX)
   if(!dialog){
     dialog = new _gl2ps_dialog;
     int h = 3*10 + 25 + 6*25, y = 0;
+    // not a "Dialog_Window" since it is modal 
     dialog->window = new Fl_Window(200, h); y = 10;
     dialog->window->box(GMSH_WINDOW_BOX);
     dialog->c = new Fl_Choice(10, y, 145, 25, "Type"); y+= 25;
@@ -404,6 +407,7 @@ int options_dialog(char *name)
   if(!dialog){
     dialog = new _options_dialog;
     int h = 3*10 + 25 + 1*25, y = 0;
+    // not a "Dialog_Window" since it is modal 
     dialog->window = new Fl_Window(200, h, "Options"); y = 10;
     dialog->window->box(GMSH_WINDOW_BOX);
     dialog->b = new Fl_Check_Button(10, y, 180, 25, "Save only modified options"); y += 25;
@@ -460,6 +464,7 @@ int msh_dialog(char *name)
   if(!dialog){
     dialog = new _msh_dialog;
     int h = 3*10 + 25 + 2*25, y = 0;
+    // not a "Dialog_Window" since it is modal 
     dialog->window = new Fl_Window(200, h, "MSH Options"); y = 10;
     dialog->window->box(GMSH_WINDOW_BOX);
     dialog->c = new Fl_Choice(10, y, 130, 25, "Format"); y+= 25;
diff --git a/Fltk/Makefile b/Fltk/Makefile
index 6925b99fcd04e027f7d0f3aaacaf9fd13cd859a9..ba23ee9a198cf09e6fcf69c19f0f94784cc4c4b4 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.63 2004-12-30 22:43:22 geuzaine Exp $
+# $Id: Makefile,v 1.64 2004-12-31 06:09:31 geuzaine Exp $
 #
 # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 #
@@ -96,15 +96,16 @@ GUI.o: GUI.cpp ../Plugin/PluginManager.h ../Plugin/Plugin.h \
   ../Mesh/Edge.h ../Geo/ExtrudeParams.h ../Mesh/STL.h ../Mesh/Metric.h \
   ../Mesh/Matrix.h ../Graphics/Draw.h GUI.h Opengl_Window.h \
   Colorbar_Window.h Callbacks.h Bitmaps.h Win32Icon.h \
-  ../Parser/OpenFile.h ../Common/CommandLine.h Solvers.h
+  ../Parser/OpenFile.h ../Common/CommandLine.h Solvers.h \
+  Shortcut_Window.h
 GUI_Extras.o: GUI_Extras.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../Common/GmshUI.h ../Mesh/Mesh.h \
   ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Simplex.h ../Mesh/Face.h \
   ../Mesh/Edge.h ../Geo/ExtrudeParams.h ../Mesh/STL.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h ../Mesh/Metric.h \
-  ../Mesh/Matrix.h File_Picker.h ../Graphics/CreateFile.h \
-  ../Common/Options.h ../Common/Context.h
+  ../Mesh/Matrix.h File_Picker.h Shortcut_Window.h \
+  ../Graphics/CreateFile.h ../Common/Options.h ../Common/Context.h
 Callbacks.o: Callbacks.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../Common/GmshUI.h ../Geo/Geo.h \
diff --git a/Fltk/Shortcut_Window.h b/Fltk/Shortcut_Window.h
new file mode 100644
index 0000000000000000000000000000000000000000..97257608e32f0a8ba493652c662e77140dc4b7e0
--- /dev/null
+++ b/Fltk/Shortcut_Window.h
@@ -0,0 +1,87 @@
+#ifndef _SHORTCUT_WINDOW_H
+#define _SHORTCUT_WINDOW_H
+
+// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "GmshUI.h"
+
+#include <FL/Fl_Window.H>
+#include <FL/fl_ask.H>
+
+// Derive special windows from Fl_Window to correctly process the
+// OS-specific shorcuts (Cmd-w on Mac, Alt+F4 on Windows)
+
+class Dialog_Window : public Fl_Window {
+  int  handle(int event){
+    switch (event) {
+    case FL_SHORTCUT:
+    case FL_KEYBOARD:
+#if defined(__APPLE__)
+      if(Fl::test_shortcut(FL_META+'w')){
+	do_callback();
+	return 1;
+      }
+#elif defined(WIN32)
+      if(Fl::test_shortcut(FL_ALT+FL_F+4)){
+	do_callback();
+	return 1;
+      }
+#endif
+      break;
+    }
+    return Fl_Window::handle(event);
+  }
+ public:
+  Dialog_Window(int x,int y,int w,int h,const char *l=0) :
+    Fl_Window(x, y, w, h, l) {}
+  Dialog_Window(int w,int h,const char *l=0) :
+    Fl_Window(w, h, l) {}
+};
+
+class Main_Window : public Fl_Window {
+  int  handle(int event){
+    switch (event) {
+    case FL_SHORTCUT:
+    case FL_KEYBOARD:
+#if defined(__APPLE__)
+      if(Fl::test_shortcut(FL_META+'w')){
+	if(fl_ask("Do you really want to quit?"))
+	  do_callback();
+	return 1;
+      }
+#elif defined(WIN32)
+      if(Fl::test_shortcut(FL_ALT+FL_F+4)){
+	if(fl_ask("Do you really want to quit?"))
+	  do_callback();
+	return 1;
+      }
+#endif
+      break;
+    }
+    return Fl_Window::handle(event);
+  }
+ public:
+  Main_Window(int x,int y,int w,int h,const char *l=0) :
+    Fl_Window(x, y, w, h, l) {}
+  Main_Window(int w,int h,const char *l=0) :
+    Fl_Window(w, h, l) {}
+};
+
+#endif
diff --git a/Plugin/Makefile b/Plugin/Makefile
index ccda2d1e0dca375779a51cec74473e1c25975d7d..402ac791cda38d050a4538feeed816713cd08590 100644
--- a/Plugin/Makefile
+++ b/Plugin/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.73 2004-12-30 22:43:22 geuzaine Exp $
+# $Id: Makefile,v 1.74 2004-12-31 06:09:31 geuzaine Exp $
 #
 # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 #
@@ -193,7 +193,7 @@ StructuralSolver.o: StructuralSolver.cpp StructuralSolver.h ../Geo/Geo.h \
   ../Common/Views.h ../Common/ColorTable.h ../Common/GmshMatrix.h \
   ../Common/AdaptiveViews.h ../Common/GmshUI.h ../Common/Context.h \
   ../DataStr/Tools.h ../Graphics/Draw.h ../Mesh/Utils.h \
-  ../Numeric/Numeric.h
+  ../Numeric/Numeric.h ../Fltk/Shortcut_Window.h
 Skin.o: Skin.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Common/Views.h ../Common/ColorTable.h ../DataStr/List.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h \
diff --git a/Plugin/StructuralSolver.cpp b/Plugin/StructuralSolver.cpp
index ff415b0331d29fd11322a6c7c00014472578eea0..92b976139b77fe41ad6b6bb848e997a0bcfb336c 100644
--- a/Plugin/StructuralSolver.cpp
+++ b/Plugin/StructuralSolver.cpp
@@ -4,6 +4,7 @@
 #include "Draw.h"
 #include "Utils.h"
 #include "Numeric.h"
+#include "Shortcut_Window.h"
 
 extern Mesh *THEM;
 extern Context_T CTX;
@@ -466,7 +467,7 @@ void StructuralSolver ::popupPropertiesForPhysicalEntity (int dim)
   int width = 31 * fontsize;
   int height = 5 * WB + 9 * BH;
 
-  _window = new Fl_Window(width, height, "Structural Solver");
+  _window = new Dialog_Window(width, height, "Structural Solver");
   _window->box(WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);