]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/frame.cpp
AddBook ignores wxMac paths (still won't work)
[wxWidgets.git] / src / gtk / frame.cpp
index eadb75575f9fb7c5943a2220eb839f31a15c56b7..fb364d258e6130ab0898cac62a7e347015a1c104 100644 (file)
@@ -7,49 +7,77 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
 #ifdef __GNUG__
     #pragma implementation "frame.h"
 #endif
 
-#include "wx/frame.h"
+#ifdef __VMS
+#define XIconifyWindow XICONIFYWINDOW
+#endif
+
+#include "wx/defs.h"
+
 #include "wx/dialog.h"
 #include "wx/control.h"
 #include "wx/app.h"
 #include "wx/menu.h"
-#include "wx/toolbar.h"
-#include "wx/statusbr.h"
+#if wxUSE_TOOLBAR
+    #include "wx/toolbar.h"
+#endif
+#if wxUSE_STATUSBAR
+    #include "wx/statusbr.h"
+#endif
 #include "wx/dcclient.h"
 
-#include "glib.h"
-#include "gdk/gdk.h"
-#include "gtk/gtk.h"
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
+
 #include "wx/gtk/win_gtk.h"
-#include "gdk/gdkkeysyms.h"
 
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 // constants
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 
 const int wxMENU_HEIGHT    = 27;
 const int wxSTATUS_HEIGHT  = 25;
 const int wxPLACE_HOLDER   = 0;
 
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 // idle system
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 
 extern void wxapp_install_idle_handler();
 extern bool g_isIdle;
+extern int g_openDialogs;
 
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// event tables
+// ----------------------------------------------------------------------------
+
+#ifndef __WXUNIVERSAL__
+    IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
+#endif
+
+// ----------------------------------------------------------------------------
 // data
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 
 extern wxList wxPendingDelete;
 
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 // debug
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 
 #ifdef __WXDEBUG__
 
@@ -57,22 +85,56 @@ extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar
 
 #endif
 
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// GTK callbacks
+// ----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// "focus" from m_window
+//-----------------------------------------------------------------------------
+
+static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    // This disables GTK's tab traversal
+    gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
+    return TRUE;
+}
+
 //-----------------------------------------------------------------------------
 // "size_allocate"
 //-----------------------------------------------------------------------------
 
-static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrame *win )
+static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrameGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    if (!win->m_hasVMT) return;
+    if (!win->m_hasVMT)
+        return;
 
     if ((win->m_width != alloc->width) || (win->m_height != alloc->height))
     {
+/*
+        wxPrintf( "OnSize from " );
+        if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+           wxPrintf( win->GetClassInfo()->GetClassName() );
+        wxPrintf( " %d %d %d %d\n", (int)alloc->x,
+                                (int)alloc->y,
+                                (int)alloc->width,
+                                (int)alloc->height );
+*/
+
         win->m_width = alloc->width;
         win->m_height = alloc->height;
-        win->UpdateSize();
+        win->m_queuedFullRedraw = TRUE;
+        win->GtkUpdateSize();
     }
 }
 
@@ -80,59 +142,64 @@ static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation*
 // "delete_event"
 //-----------------------------------------------------------------------------
 
-static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrame *win )
+static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrameGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    win->Close();
+    if ((g_openDialogs == 0) && (win->IsEnabled()))
+        win->Close();
 
     return TRUE;
 }
 
+#if wxUSE_MENUS_NATIVE
+
 //-----------------------------------------------------------------------------
 // "child_attached" of menu bar
 //-----------------------------------------------------------------------------
 
-static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
+static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrameGTK *win )
 {
     if (!win->m_hasVMT) return;
 
     win->m_menuBarDetached = FALSE;
-    win->UpdateSize();
+    win->GtkUpdateSize();
 }
 
 //-----------------------------------------------------------------------------
 // "child_detached" of menu bar
 //-----------------------------------------------------------------------------
 
-static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
+static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrameGTK *win )
 {
     if (!win->m_hasVMT) return;
 
     win->m_menuBarDetached = TRUE;
-    win->UpdateSize();
+    win->GtkUpdateSize();
 }
 
+#endif // wxUSE_MENUS_NATIVE
+
 #if wxUSE_TOOLBAR
 //-----------------------------------------------------------------------------
 // "child_attached" of tool bar
 //-----------------------------------------------------------------------------
 
-static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
+static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrameGTK *win )
 {
     if (!win->m_hasVMT) return;
 
     win->m_toolBarDetached = FALSE;
 
-    win->UpdateSize();
+    win->GtkUpdateSize();
 }
 
 //-----------------------------------------------------------------------------
 // "child_detached" of tool bar
 //-----------------------------------------------------------------------------
 
-static void gtk_toolbar_detached_callback( GtkWidget *widget, GtkWidget *WXUNUSED(child), wxFrame *win )
+static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrameGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
@@ -140,7 +207,7 @@ static void gtk_toolbar_detached_callback( GtkWidget *widget, GtkWidget *WXUNUSE
     if (!win->m_hasVMT) return;
 
     win->m_toolBarDetached = TRUE;
-    win->UpdateSize();
+    win->GtkUpdateSize();
 }
 #endif // wxUSE_TOOLBAR
 
@@ -148,19 +215,29 @@ static void gtk_toolbar_detached_callback( GtkWidget *widget, GtkWidget *WXUNUSE
 // "configure_event"
 //-----------------------------------------------------------------------------
 
-static gint gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrame *win )
+static gint
+#if (GTK_MINOR_VERSION > 0)
+gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrameGTK *win )
+#else
+gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrameGTK *win )
+#endif
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    if (!win->m_hasVMT) return FALSE;
+    if (!win->m_hasVMT)
+        return FALSE;
 
+#if (GTK_MINOR_VERSION > 0)
     int x = 0;
     int y = 0;
     gdk_window_get_root_origin( win->m_widget->window, &x, &y );
-
     win->m_x = x;
     win->m_y = y;
+#else
+    win->m_x = event->x;
+    win->m_y = event->y;
+#endif
 
     wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
     mevent.SetEventObject( win );
@@ -176,43 +253,51 @@ static gint gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventC
 /* we cannot MWM hints and icons before the widget has been realized,
    so we do this directly after realization */
 
-static gint
-gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win )
+static void
+gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxFrameGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    /* all this is for Motif Window Manager "hints" and is supposed to be
-       recognized by other WM as well. not tested. */
-    long decor = (long) GDK_DECOR_BORDER;
-    long func = (long) GDK_FUNC_MOVE;
-
-    if ((win->GetWindowStyle() & wxCAPTION) != 0)
-        decor |= GDK_DECOR_TITLE;
-    if ((win->GetWindowStyle() & wxSYSTEM_MENU) != 0)
-    {
-       decor |= GDK_DECOR_MENU;
-       func |= GDK_FUNC_CLOSE;
-    }
-    if ((win->GetWindowStyle() & wxMINIMIZE_BOX) != 0)
-    {
-        func |= GDK_FUNC_MINIMIZE;
-        decor |= GDK_DECOR_MINIMIZE;
-    }
-    if ((win->GetWindowStyle() & wxMAXIMIZE_BOX) != 0)
+    if ((win->m_miniEdge > 0) || (win->HasFlag(wxSIMPLE_BORDER)) || (win->HasFlag(wxNO_BORDER)))
     {
-        func |= GDK_FUNC_MAXIMIZE;
-        decor |= GDK_DECOR_MAXIMIZE;
+        /* This is a mini-frame or a borderless frame. */
+        gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)0 );
+        gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)0 );
     }
-    if ((win->GetWindowStyle() & wxRESIZE_BORDER) != 0)
+    else
     {
-       func |= GDK_FUNC_RESIZE;
-       decor |= GDK_DECOR_RESIZEH;
-    }
-
+        /* All this is for Motif Window Manager "hints" and is supposed to be
+           recognized by other WM as well. Not tested. */
+        long decor = (long) GDK_DECOR_BORDER;
+        long func = (long) GDK_FUNC_MOVE;
+
+        if ((win->GetWindowStyle() & wxCAPTION) != 0)
+            decor |= GDK_DECOR_TITLE;
+        if ((win->GetWindowStyle() & wxSYSTEM_MENU) != 0)
+        {
+            decor |= GDK_DECOR_MENU;
+            func |= GDK_FUNC_CLOSE;
+        }
+        if ((win->GetWindowStyle() & wxMINIMIZE_BOX) != 0)
+        {
+            func |= GDK_FUNC_MINIMIZE;
+            decor |= GDK_DECOR_MINIMIZE;
+        }
+        if ((win->GetWindowStyle() & wxMAXIMIZE_BOX) != 0)
+        {
+            func |= GDK_FUNC_MAXIMIZE;
+            decor |= GDK_DECOR_MAXIMIZE;
+        }
+        if ((win->GetWindowStyle() & wxRESIZE_BORDER) != 0)
+        {
+           func |= GDK_FUNC_RESIZE;
+           decor |= GDK_DECOR_RESIZEH;
+        }
 
-    gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)decor);
-    gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
+        gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)decor);
+        gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
+    }
 
     /* GTK's shrinking/growing policy */
     if ((win->GetWindowStyle() & wxRESIZE_BORDER) == 0)
@@ -221,10 +306,11 @@ gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win )
         gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1);
 
     /* reset the icon */
-    if (win->m_icon != wxNullIcon)
+    wxIcon iconOld = win->GetIcon();
+    if ( iconOld != wxNullIcon )
     {
-        wxIcon icon( win->m_icon );
-        win->m_icon = wxNullIcon;
+        wxIcon icon( iconOld );
+        win->SetIcon( wxNullIcon );
         win->SetIcon( icon );
     }
 
@@ -242,33 +328,88 @@ gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win )
 
         node = node->GetNext();
     }
+}
 
-    return FALSE;
+//-----------------------------------------------------------------------------
+// "map_event" from m_widget
+//-----------------------------------------------------------------------------
+
+static void
+gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
+                        GdkEvent * WXUNUSED(event),
+                        wxFrame *win )
+{
+    win->SetIconizeState(FALSE);
+}
+
+//-----------------------------------------------------------------------------
+// "unmap_event" from m_widget
+//-----------------------------------------------------------------------------
+
+static void
+gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
+                          GdkEvent * WXUNUSED(event),
+                          wxFrame *win )
+{
+    win->SetIconizeState(TRUE);
+}
+
+//-----------------------------------------------------------------------------
+// "expose_event" of m_client
+//-----------------------------------------------------------------------------
+
+static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
+{
+    GtkPizza *pizza = GTK_PIZZA(widget);
+
+    gtk_paint_flat_box (win->m_widget->style, pizza->bin_window, GTK_STATE_NORMAL,
+                GTK_SHADOW_NONE, &gdk_event->area, win->m_widget, "base", 0, 0, -1, -1);
+
+    return TRUE;
 }
 
 //-----------------------------------------------------------------------------
-// InsertChild for wxFrame
+// "draw" of m_client
 //-----------------------------------------------------------------------------
 
-/* Callback for wxFrame. This very strange beast has to be used because
+
+static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
+{
+    GtkPizza *pizza = GTK_PIZZA(widget);
+
+    gtk_paint_flat_box (win->m_widget->style, pizza->bin_window, GTK_STATE_NORMAL,
+                GTK_SHADOW_NONE, rect, win->m_widget, "base", 0, 0, -1, -1);
+}
+
+// ----------------------------------------------------------------------------
+// wxFrameGTK itself
+// ----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// InsertChild for wxFrameGTK
+//-----------------------------------------------------------------------------
+
+/* Callback for wxFrameGTK. This very strange beast has to be used because
  * C++ has no virtual methods in a constructor. We have to emulate a
  * virtual function here as wxWindows requires different ways to insert
  * a child in container classes. */
 
-static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child )
+static void wxInsertChildInFrame( wxFrameGTK* parent, wxWindow* child )
 {
+    wxASSERT( GTK_IS_WIDGET(child->m_widget) );
+
     if (!parent->m_insertInClientArea)
     {
         /* these are outside the client area */
-        wxFrame* frame = (wxFrame*) parent;
-        gtk_myfixed_put( GTK_MYFIXED(frame->m_mainWidget),
+        wxFrameGTK* frame = (wxFrameGTK*) parent;
+        gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
                          GTK_WIDGET(child->m_widget),
                          child->m_x,
                          child->m_y,
                          child->m_width,
                          child->m_height );
 
-#if wxUSE_TOOLBAR
+#if wxUSE_TOOLBAR_NATIVE
         /* we connect to these events for recalculating the client area
            space when the toolbar is floating */
         if (wxIS_KIND_OF(child,wxToolBar))
@@ -288,7 +429,7 @@ static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child )
     else
     {
         /* these are inside the client area */
-        gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
+        gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
                          GTK_WIDGET(child->m_widget),
                          child->m_x,
                          child->m_y,
@@ -297,30 +438,15 @@ static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child )
     }
 
     /* resize on OnInternalIdle */
-    parent->UpdateSize();
+    parent->GtkUpdateSize();
 }
 
-//-----------------------------------------------------------------------------
-// wxFrame
-//-----------------------------------------------------------------------------
-
-BEGIN_EVENT_TABLE(wxFrame, wxWindow)
-    EVT_SIZE(wxFrame::OnSize)
-    EVT_CLOSE(wxFrame::OnCloseWindow)
-    EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
-END_EVENT_TABLE()
-
-IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow)
+// ----------------------------------------------------------------------------
+// wxFrameGTK creation
+// ----------------------------------------------------------------------------
 
-void wxFrame::Init()
+void wxFrameGTK::Init()
 {
-    m_frameMenuBar = (wxMenuBar *) NULL;
-#if wxUSE_STATUSBAR
-    m_frameStatusBar = (wxStatusBar *) NULL;
-#endif // wxUSE_STATUSBAR
-#if wxUSE_TOOLBAR
-    m_frameToolBar = (wxToolBar *) NULL;
-#endif // wxUSE_TOOLBAR
     m_sizeSet = FALSE;
     m_miniEdge = 0;
     m_miniTitle = 0;
@@ -328,41 +454,62 @@ void wxFrame::Init()
     m_menuBarDetached = FALSE;
     m_toolBarDetached = FALSE;
     m_insertInClientArea = TRUE;
+    m_isFrame = TRUE;
+    m_isIconized = FALSE;
+    m_fsIsShowing = FALSE;
+    m_themeEnabled = TRUE;
 }
 
-wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title,
-      const wxPoint &pos, const wxSize &size,
-      long style, const wxString &name )
+bool wxFrameGTK::Create( wxWindow *parent,
+                      wxWindowID id,
+                      const wxString& title,
+                      const wxPoint& pos,
+                      const wxSize& sizeOrig,
+                      long style,
+                      const wxString &name )
 {
-    Init();
-
-    Create( parent, id, title, pos, size, style, name );
-}
+    // always create a frame of some reasonable, even if arbitrary, size (at
+    // least for MSW compatibility)
+    wxSize size = sizeOrig;
+    if ( size.x == -1 || size.y == -1 )
+    {
+        wxSize sizeDpy = wxGetDisplaySize();
+        if ( size.x == -1 )
+            size.x = sizeDpy.x / 3;
+        if ( size.y == -1 )
+            size.y = sizeDpy.y / 5;
+    }
 
-bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
-      const wxPoint &pos, const wxSize &size,
-      long style, const wxString &name )
-{
     wxTopLevelWindows.Append( this );
 
     m_needParent = FALSE;
 
-    PreCreation( parent, id, pos, size, style, name );
+    if (!PreCreation( parent, pos, size ) ||
+        !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
+    {
+        wxFAIL_MSG( wxT("wxFrameGTK creation failed") );
+        return FALSE;
+    }
 
     m_title = title;
 
     m_insertCallback = (wxInsertChildFunction) wxInsertChildInFrame;
 
     GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
-    if (style & wxSIMPLE_BORDER) win_type = GTK_WINDOW_POPUP;
+
+    if (style & wxFRAME_TOOL_WINDOW)
+        win_type = GTK_WINDOW_POPUP;
 
     m_widget = gtk_window_new( win_type );
 
+    if ((m_parent) && (HasFlag(wxFRAME_FLOAT_ON_PARENT)) && (GTK_IS_WINDOW(m_parent->m_widget)))
+        gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
+
     if (!name.IsEmpty())
         gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
 
 #ifdef __WXDEBUG__
-    debug_focus_in( m_widget, _T("wxFrame::m_widget"), name );
+    debug_focus_in( m_widget, wxT("wxFrameGTK::m_widget"), name );
 #endif
 
     gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
@@ -372,77 +519,139 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
         GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
 
     /* m_mainWidget holds the toolbar, the menubar and the client area */
-    m_mainWidget = gtk_myfixed_new();
+    m_mainWidget = gtk_pizza_new();
     gtk_widget_show( m_mainWidget );
     GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
     gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
 
+    /* for m_mainWidget themes */
+    gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
+                GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
+    gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
+                GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
+
 #ifdef __WXDEBUG__
-    debug_focus_in( m_mainWidget, _T("wxFrame::m_mainWidget"), name );
+    debug_focus_in( m_mainWidget, wxT("wxFrameGTK::m_mainWidget"), name );
 #endif
 
     /* m_wxwindow only represents the client area without toolbar and menubar */
-    m_wxwindow = gtk_myfixed_new();
+    m_wxwindow = gtk_pizza_new();
     gtk_widget_show( m_wxwindow );
     gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
 
 #ifdef __WXDEBUG__
-    debug_focus_in( m_wxwindow, _T("wxFrame::m_wxwindow"), name );
+    debug_focus_in( m_wxwindow, wxT("wxFrameGTK::m_wxwindow"), name );
 #endif
 
     /* we donm't allow the frame to get the focus as otherwise
-       the frame will grabit at arbitrary fcous changes. */
+       the frame will grab it at arbitrary focus changes. */
     GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
 
     if (m_parent) m_parent->AddChild( this );
 
+    /* the user resized the frame by dragging etc. */
+    gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
+        GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
+
     PostCreation();
 
+    if ((m_x != -1) || (m_y != -1))
+        gtk_widget_set_uposition( m_widget, m_x, m_y );
+    gtk_widget_set_usize( m_widget, m_width, m_height );
+
     /*  we cannot set MWM hints and icons before the widget has
         been realized, so we do this directly after realization */
     gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
 
-    /* the user resized the frame by dragging etc. */
-    gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
-        GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
+    /* the only way to get the window size is to connect to this event */
+    gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
+        GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
+
+    /* map and unmap for iconized state */
+    gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
+        GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
+    gtk_signal_connect( GTK_OBJECT(m_widget), "unmap_event",
+        GTK_SIGNAL_FUNC(gtk_frame_unmap_callback), (gpointer)this );
 
     /* the only way to get the window size is to connect to this event */
     gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
         GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
 
+    /* disable native tab traversal */
+    gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
+        GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
+
     return TRUE;
 }
 
-wxFrame::~wxFrame()
+wxFrameGTK::~wxFrameGTK()
 {
     m_isBeingDeleted = TRUE;
 
-    if (m_frameMenuBar) delete m_frameMenuBar;
-    m_frameMenuBar = (wxMenuBar *) NULL;
-
-#if wxUSE_STATUSBAR
-    if (m_frameStatusBar) delete m_frameStatusBar;
-    m_frameStatusBar = (wxStatusBar *) NULL;
-#endif // wxUSE_STATUSBAR
-
-#if wxUSE_TOOLBAR
-    if (m_frameToolBar) delete m_frameToolBar;
-    m_frameToolBar = (wxToolBar *) NULL;
-#endif // wxUSE_TOOLBAR
+    DeleteAllBars();
 
     wxTopLevelWindows.DeleteObject( this );
 
     if (wxTheApp->GetTopWindow() == this)
         wxTheApp->SetTopWindow( (wxWindow*) NULL );
 
-    if (wxTopLevelWindows.Number() == 0)
+    if ((wxTopLevelWindows.Number() == 0) &&
+        (wxTheApp->GetExitOnFrameDelete()))
+    {
         wxTheApp->ExitMainLoop();
+    }
+}
+
+bool wxFrameGTK::ShowFullScreen(bool show, long style )
+{
+    if (show == m_fsIsShowing) return FALSE; // return what?
+
+    m_fsIsShowing = show;
+
+    if (show)
+    {
+        m_fsSaveStyle = m_windowStyle;
+        m_fsSaveFlag = style;
+        GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
+        GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
+
+        gtk_widget_hide( m_widget );
+        gtk_widget_unrealize( m_widget );
+
+        m_windowStyle = wxSIMPLE_BORDER;
+
+        int x;
+        int y;
+        wxDisplaySize( &x, &y );
+        SetSize( 0, 0, x, y );
+
+        gtk_widget_realize( m_widget );
+        gtk_widget_show( m_widget );
+    }
+    else
+    {
+        gtk_widget_hide( m_widget );
+        gtk_widget_unrealize( m_widget );
+
+        m_windowStyle = m_fsSaveStyle;
+
+        SetSize( m_fsSaveFrame.x, m_fsSaveFrame.y, m_fsSaveFrame.width, m_fsSaveFrame.height );
+
+        gtk_widget_realize( m_widget );
+        gtk_widget_show( m_widget );
+    }
+
+    return TRUE;
 }
 
-bool wxFrame::Show( bool show )
+// ----------------------------------------------------------------------------
+// overridden wxWindow methods
+// ----------------------------------------------------------------------------
+
+bool wxFrameGTK::Show( bool show )
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
     if (show && !m_sizeSet)
     {
@@ -457,28 +666,26 @@ bool wxFrame::Show( bool show )
     return wxWindow::Show( show );
 }
 
-bool wxFrame::Destroy()
+void wxFrameGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
-
-    if (!wxPendingDelete.Member(this)) wxPendingDelete.Append(this);
-
-    return TRUE;
+    wxFAIL_MSG( wxT("DoMoveWindow called for wxFrameGTK") );
 }
 
-void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
+void wxFrameGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
-    /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
-    wxASSERT_MSG( (m_wxwindow != NULL), _T("invalid frame") );
+    /* this shouldn't happen: wxFrameGTK, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
+    wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
     /* avoid recursions */
-    if (m_resizing) return;
+    if (m_resizing)
+        return;
     m_resizing = TRUE;
 
     int old_x = m_x;
     int old_y = m_y;
+
     int old_width = m_width;
     int old_height = m_height;
 
@@ -497,6 +704,7 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
         m_height = height;
     }
 
+/*
     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
     {
         if (width == -1) m_width = 80;
@@ -506,6 +714,7 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
     {
        if (height == -1) m_height = 26;
     }
+*/
 
     if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
     if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
@@ -522,6 +731,8 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
 
     if ((m_width != old_width) || (m_height != old_height))
     {
+        gtk_widget_set_usize( m_widget, m_width, m_height );
+
         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
            done either directly before the frame is shown or in idle time
            so that different calls to SetSize() don't lead to flicker. */
@@ -531,26 +742,14 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
     m_resizing = FALSE;
 }
 
-void wxFrame::Centre( int direction )
-{
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
-
-    int x = 0;
-    int y = 0;
-
-    if ((direction & wxHORIZONTAL) == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
-    if ((direction & wxVERTICAL) == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
-
-    Move( x, y );
-}
-
-void wxFrame::DoGetClientSize( int *width, int *height ) const
+void wxFrameGTK::DoGetClientSize( int *width, int *height ) const
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
     wxWindow::DoGetClientSize( width, height );
     if (height)
     {
+#if wxUSE_MENUS
         /* menu bar */
         if (m_frameMenuBar)
         {
@@ -559,36 +758,51 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const
             else
                 (*height) -= wxPLACE_HOLDER;
         }
+#endif // wxUSE_MENUS
 
+#if wxUSE_STATUSBAR
         /* status bar */
-        if (m_frameStatusBar) (*height) -= wxSTATUS_HEIGHT;
+        if (m_frameStatusBar && m_frameStatusBar->IsShown()) (*height) -= wxSTATUS_HEIGHT;
+#endif // wxUSE_STATUSBAR
 
+#if wxUSE_TOOLBAR
         /* tool bar */
-        if (m_frameToolBar)
+        if (m_frameToolBar && m_frameToolBar->IsShown())
         {
-            if (!m_toolBarDetached)
+            if (m_toolBarDetached)
             {
-                int y = 0;
-                m_frameToolBar->GetSize( (int *) NULL, &y );
-                (*height) -= y;
+                *height -= wxPLACE_HOLDER;
             }
             else
-                (*height) -= wxPLACE_HOLDER;
+            {
+                int x, y;
+                m_frameToolBar->GetSize( &x, &y );
+                if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL )
+                {
+                    *width -= x;
+                }
+                else
+                {
+                    *height -= y;
+                }
+            }
         }
+#endif // wxUSE_TOOLBAR
 
         /* mini edge */
-        (*height) -= m_miniEdge*2 + m_miniTitle;
+        *height -= m_miniEdge*2 + m_miniTitle;
     }
     if (width)
     {
-        (*width) -= m_miniEdge*2;
+        *width -= m_miniEdge*2;
     }
 }
 
-void wxFrame::DoSetClientSize( int width, int height )
+void wxFrameGTK::DoSetClientSize( int width, int height )
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
+#if wxUSE_MENUS
         /* menu bar */
         if (m_frameMenuBar)
         {
@@ -597,27 +811,42 @@ void wxFrame::DoSetClientSize( int width, int height )
             else
                 height += wxPLACE_HOLDER;
         }
+#endif // wxUSE_MENUS
 
+#if wxUSE_STATUSBAR
         /* status bar */
-        if (m_frameStatusBar) height += wxSTATUS_HEIGHT;
+        if (m_frameStatusBar && m_frameStatusBar->IsShown()) height += wxSTATUS_HEIGHT;
+#endif
 
+#if wxUSE_TOOLBAR
         /* tool bar */
-        if (m_frameToolBar)
+        if (m_frameToolBar && m_frameToolBar->IsShown())
         {
-            if (!m_toolBarDetached)
+            if (m_toolBarDetached)
             {
-                int y = 0;
-                m_frameToolBar->GetSize( (int *) NULL, &y );
-                height += y;
+                height += wxPLACE_HOLDER;
             }
             else
-                height += wxPLACE_HOLDER;
+            {
+                int x, y;
+                m_frameToolBar->GetSize( &x, &y );
+                if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL )
+                {
+                    width += x;
+                }
+                else
+                {
+                    height += y;
+                }
+            }
         }
+#endif
 
-    wxWindow::DoSetClientSize( width + m_miniEdge*2, height  + m_miniEdge*2 + m_miniTitle );
+    DoSetSize( -1, -1, width + m_miniEdge*2, height  + m_miniEdge*2 + m_miniTitle, 0 );
 }
 
-void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height )
+void wxFrameGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
+                         int width, int height )
 {
     // due to a bug in gtk, x,y are always 0
     // m_x = x;
@@ -627,29 +856,43 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
     if (m_resizing) return;
     m_resizing = TRUE;
 
-    /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
-    wxASSERT_MSG( (m_wxwindow != NULL), _T("invalid frame") );
+    /* this shouldn't happen: wxFrameGTK, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
+    wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
     m_width = width;
     m_height = height;
 
     /* space occupied by m_frameToolBar and m_frameMenuBar */
-    int client_area_y_offset = 0;
+    int client_area_x_offset = 0,
+        client_area_y_offset = 0;
 
-    /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
+    /* wxMDIChildFrame derives from wxFrameGTK but it _is_ a wxWindow as it uses
        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
-       set in wxFrame::Create so it is used to check what kind of frame we
+       set in wxFrameGTK::Create so it is used to check what kind of frame we
        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
        skip the part which handles m_frameMenuBar, m_frameToolBar and (most
        importantly) m_mainWidget */
 
+    if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
+    if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
+    if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
+    if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
+
     if (m_mainWidget)
     {
-        /* check if size is in legal range */
-        if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
-        if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
-        if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
-        if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
+        /* set size hints */
+        gint flag = 0; // GDK_HINT_POS;
+        if ((m_minWidth != -1) || (m_minHeight != -1)) flag |= GDK_HINT_MIN_SIZE;
+        if ((m_maxWidth != -1) || (m_maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE;
+        GdkGeometry geom;
+        geom.min_width = m_minWidth;
+        geom.min_height = m_minHeight;
+        geom.max_width = m_maxWidth;
+        geom.max_height = m_maxHeight;
+        gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
+                                       (GtkWidget*) NULL,
+                                       &geom,
+                                       (GdkWindowHints) flag );
 
         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
          * menubar, the toolbar and the client area, which is represented by
@@ -657,6 +900,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
          * this hurts in the eye, but I don't want to call SetSize()
          * because I don't want to call any non-native functions here. */
 
+#if wxUSE_MENUS
         if (m_frameMenuBar)
         {
             int xx = m_miniEdge;
@@ -668,16 +912,20 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
             m_frameMenuBar->m_y = yy;
             m_frameMenuBar->m_width = ww;
             m_frameMenuBar->m_height = hh;
-            gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget),
+            gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
                                   m_frameMenuBar->m_widget,
                                   xx, yy, ww, hh );
             client_area_y_offset += hh;
         }
+#endif // wxUSE_MENUS
 
-        if (m_frameToolBar)
+#if wxUSE_TOOLBAR
+        if ((m_frameToolBar) && m_frameToolBar->IsShown() &&
+            (m_frameToolBar->m_widget->parent == m_mainWidget))
         {
             int xx = m_miniEdge;
             int yy = m_miniEdge + m_miniTitle;
+#if wxUSE_MENUS
             if (m_frameMenuBar)
             {
                 if (!m_menuBarDetached)
@@ -685,24 +933,41 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
                 else
                     yy += wxPLACE_HOLDER;
             }
-            int ww = m_width - 2*m_miniEdge;
-            int hh = m_frameToolBar->m_height;
-           if (m_toolBarDetached) hh = wxPLACE_HOLDER;
+#endif // wxUSE_MENUS
+
             m_frameToolBar->m_x = xx;
             m_frameToolBar->m_y = yy;
-            /* m_frameToolBar->m_height = hh;   don't change the toolbar's height */
-            m_frameToolBar->m_width = ww;
-            gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget),
+
+            /* don't change the toolbar's reported height/width */
+            int ww, hh;
+            if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL )
+            {
+                ww = m_toolBarDetached ? wxPLACE_HOLDER
+                                       : m_frameToolBar->m_width;
+                hh = m_height - 2*m_miniEdge;
+
+                client_area_x_offset += ww;
+            }
+            else
+            {
+                ww = m_width - 2*m_miniEdge;
+                hh = m_toolBarDetached ? wxPLACE_HOLDER
+                                       : m_frameToolBar->m_height;
+
+                client_area_y_offset += hh;
+            }
+
+            gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
                                   m_frameToolBar->m_widget,
                                   xx, yy, ww, hh );
-            client_area_y_offset += hh;
         }
+#endif // wxUSE_TOOLBAR
 
-        int client_x = m_miniEdge;
+        int client_x = client_area_x_offset + m_miniEdge;
         int client_y = client_area_y_offset + m_miniEdge + m_miniTitle;
-        int client_w = m_width - 2*m_miniEdge;
+        int client_w = m_width - client_area_x_offset - 2*m_miniEdge;
         int client_h = m_height - client_area_y_offset- 2*m_miniEdge - m_miniTitle;
-        gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget),
+        gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
                               m_wxwindow,
                               client_x, client_y, client_w, client_h );
     }
@@ -712,7 +977,8 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
            is no need to set the size or position of m_wxwindow. */
     }
 
-    if (m_frameStatusBar)
+#if wxUSE_STATUSBAR
+    if (m_frameStatusBar && m_frameStatusBar->IsShown())
     {
         int xx = 0 + m_miniEdge;
         int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset;
@@ -722,33 +988,34 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
         m_frameStatusBar->m_y = yy;
         m_frameStatusBar->m_width = ww;
         m_frameStatusBar->m_height = hh;
-        gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow),
-                              m_frameStatusBar->m_widget,
-                              xx, yy, ww, hh );
+        gtk_pizza_set_size( GTK_PIZZA(m_wxwindow),
+                            m_frameStatusBar->m_widget,
+                            xx, yy, ww, hh );
+        gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL );
     }
-
-    /* we actually set the size of a frame here and no-where else */
-    gtk_widget_set_usize( m_widget, m_width, m_height );
+#endif // wxUSE_STATUSBAR
 
     m_sizeSet = TRUE;
 
-    /* send size event to frame */
+    // send size event to frame
     wxSizeEvent event( wxSize(m_width,m_height), GetId() );
     event.SetEventObject( this );
     GetEventHandler()->ProcessEvent( event );
 
-    /* send size event to status bar */
+#if wxUSE_STATUSBAR
+    // send size event to status bar
     if (m_frameStatusBar)
     {
         wxSizeEvent event2( wxSize(m_frameStatusBar->m_width,m_frameStatusBar->m_height), m_frameStatusBar->GetId() );
         event2.SetEventObject( m_frameStatusBar );
         m_frameStatusBar->GetEventHandler()->ProcessEvent( event2 );
     }
+#endif // wxUSE_STATUSBAR
 
     m_resizing = FALSE;
 }
 
-void wxFrame::MakeModal( bool modal )
+void wxFrameGTK::MakeModal( bool modal )
 {
     if (modal)
         gtk_grab_add( m_widget );
@@ -756,169 +1023,106 @@ void wxFrame::MakeModal( bool modal )
         gtk_grab_remove( m_widget );
 }
 
-void wxFrame::OnInternalIdle()
+void wxFrameGTK::OnInternalIdle()
 {
     if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow))
+    {
         GtkOnSize( m_x, m_y, m_width, m_height );
 
-    DoMenuUpdates();
+        // we'll come back later
+        if (g_isIdle)
+            wxapp_install_idle_handler();
+        return;
+    }
 
+#if wxUSE_MENUS
     if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
+#endif // wxUSE_MENUS
+#if wxUSE_TOOLBAR
     if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
+#endif
+#if wxUSE_STATUSBAR
     if (m_frameStatusBar) m_frameStatusBar->OnInternalIdle();
-}
+#endif
 
-void wxFrame::OnCloseWindow( wxCloseEvent& WXUNUSED(event) )
-{
-    Destroy();
+    wxWindow::OnInternalIdle();
 }
 
-void wxFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
+// ----------------------------------------------------------------------------
+// menu/tool/status bar stuff
+// ----------------------------------------------------------------------------
+
+#if wxUSE_MENUS_NATIVE
+
+void wxFrameGTK::DetachMenuBar()
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
+    wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
-#if wxUSE_CONSTRAINTS
-    if (GetAutoLayout())
+    if ( m_frameMenuBar )
     {
-        Layout();
-    }
-    else
-#endif // wxUSE_CONSTRAINTS
-    {
-        /* do we have exactly one child? */
-        wxWindow *child = (wxWindow *)NULL;
-        for ( wxNode *node = GetChildren().First(); node; node = node->Next() )
+        m_frameMenuBar->UnsetInvokingWindow( this );
+
+        if (m_frameMenuBar->GetWindowStyle() & wxMB_DOCKABLE)
         {
-            wxWindow *win = (wxWindow *)node->Data();
-            if ( !wxIS_KIND_OF(win,wxFrame) && !wxIS_KIND_OF(win,wxDialog) )
-            {
-                if (child)
-                {
-                    /* it's the second one: do nothing */
-                    return;
-                }
+            gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar->m_widget),
+                GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this );
 
-                child = win;
-            }
+            gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar->m_widget),
+                GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this );
         }
 
-        /* no children at all? */
-        if (child)
-        {
-            /* yes: set it's size to fill all the frame */
-            int client_x, client_y;
-            DoGetClientSize( &client_x, &client_y );
-            child->SetSize( 1, 1, client_x-2, client_y-2 );
-        }
+        gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
+        gtk_widget_ref( m_frameMenuBar->m_widget );
+        gtk_widget_unparent( m_frameMenuBar->m_widget );
     }
-}
-
-static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
-{
-    menu->SetInvokingWindow( win );
-
-#if (GTK_MINOR_VERSION > 0)
-    /* support for native hot keys  */
-    gtk_accel_group_attach( menu->m_accel, GTK_OBJECT(win->m_widget));
-#endif
 
-    wxNode *node = menu->GetItems().First();
-    while (node)
-    {
-        wxMenuItem *menuitem = (wxMenuItem*)node->Data();
-        if (menuitem->IsSubMenu())
-            SetInvokingWindow( menuitem->GetSubMenu(), win );
-        node = node->Next();
-    }
+    wxFrameBase::DetachMenuBar();
 }
 
-void wxFrame::SetMenuBar( wxMenuBar *menuBar )
+void wxFrameGTK::AttachMenuBar( wxMenuBar *menuBar )
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
-    wxASSERT_MSG( (m_wxwindow != NULL), _T("invalid frame") );
-
-    m_frameMenuBar = menuBar;
+    wxFrameBase::AttachMenuBar(menuBar);
 
     if (m_frameMenuBar)
     {
-#if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
-        /* support for native key accelerators indicated by underscroes */
-         gtk_accel_group_attach( m_frameMenuBar->m_accel, GTK_OBJECT(m_widget));
-#endif
+        m_frameMenuBar->SetInvokingWindow( this );
 
-        wxNode *node = m_frameMenuBar->GetMenus().First();
-        while (node)
-        {
-            wxMenu *menu = (wxMenu*)node->Data();
-            SetInvokingWindow( menu, this );
-            node = node->Next();
-        }
-
-        if (m_frameMenuBar->GetParent() != this)
-        {
-            m_frameMenuBar->SetParent(this);
-            gtk_myfixed_put( GTK_MYFIXED(m_mainWidget),
+        m_frameMenuBar->SetParent(this);
+        gtk_pizza_put( GTK_PIZZA(m_mainWidget),
                 m_frameMenuBar->m_widget,
                 m_frameMenuBar->m_x,
                 m_frameMenuBar->m_y,
                 m_frameMenuBar->m_width,
                 m_frameMenuBar->m_height );
 
-            if (menuBar->GetWindowStyle() & wxMB_DOCKABLE)
-            {
-                gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_attached",
-                    GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this );
+        if (menuBar->GetWindowStyle() & wxMB_DOCKABLE)
+        {
+            gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_attached",
+                GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this );
 
-                gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_detached",
-                    GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this );
-            }
+            gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_detached",
+                GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this );
         }
+
+        m_frameMenuBar->Show( TRUE );
     }
 
     /* resize window in OnInternalIdle */
     m_sizeSet = FALSE;
 }
 
-wxMenuBar *wxFrame::GetMenuBar() const
-{
-    return m_frameMenuBar;
-}
-
-void wxFrame::OnMenuHighlight(wxMenuEvent& event)
-{
-#if wxUSE_STATUSBAR
-    if (GetStatusBar())
-    {
-        // if no help string found, we will clear the status bar text
-        wxString helpString;
-
-        int menuId = event.GetMenuId();
-        if ( menuId != -1 )
-        {
-            wxMenuBar *menuBar = GetMenuBar();
-            if (menuBar)
-            {
-                helpString = menuBar->GetHelpString(menuId);
-            }
-        }
-
-        SetStatusText(helpString);
-    }
-#endif // wxUSE_STATUSBAR
-}
+#endif // wxUSE_MENUS_NATIVE
 
 #if wxUSE_TOOLBAR
-wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& name )
-{
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
 
-    wxCHECK_MSG( m_frameToolBar == NULL, FALSE, _T("recreating toolbar in wxFrame") );
+wxToolBar* wxFrameGTK::CreateToolBar( long style, wxWindowID id, const wxString& name )
+{
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
     m_insertInClientArea = FALSE;
 
-    m_frameToolBar = OnCreateToolBar( style, id, name );
-
-    if (m_frameToolBar) GetChildren().DeleteObject( m_frameToolBar );
+    m_frameToolBar = wxFrameBase::CreateToolBar( style, id, name );
 
     m_insertInClientArea = TRUE;
 
@@ -927,118 +1131,129 @@ wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& na
     return m_frameToolBar;
 }
 
-wxToolBar* wxFrame::OnCreateToolBar( long style, wxWindowID id, const wxString& name )
+void wxFrameGTK::SetToolBar(wxToolBar *toolbar)
 {
-    return new wxToolBar( this, id, wxDefaultPosition, wxDefaultSize, style, name );
-}
+    wxFrameBase::SetToolBar(toolbar);
 
-wxToolBar *wxFrame::GetToolBar() const
-{
-    return m_frameToolBar;
+    if (m_frameToolBar)
+    {
+        /* insert into toolbar area if not already there */
+        if ((m_frameToolBar->m_widget->parent) &&
+            (m_frameToolBar->m_widget->parent != m_mainWidget))
+        {
+            GetChildren().DeleteObject( m_frameToolBar );
+
+            gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget );
+            GtkUpdateSize();
+        }
+    }
 }
+
 #endif // wxUSE_TOOLBAR
 
 #if wxUSE_STATUSBAR
-wxStatusBar* wxFrame::CreateStatusBar( int number, long style, wxWindowID id, const wxString& name )
+
+wxStatusBar* wxFrameGTK::CreateStatusBar(int number,
+                                      long style,
+                                      wxWindowID id,
+                                      const wxString& name)
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
-    wxCHECK_MSG( m_frameStatusBar == NULL, FALSE, _T("recreating status bar in wxFrame") );
+    // because it will change when toolbar is added
+    m_sizeSet = FALSE;
 
-    m_frameStatusBar = OnCreateStatusBar( number, style, id, name );
+    return wxFrameBase::CreateStatusBar( number, style, id, name );
+}
 
-    m_sizeSet = FALSE;
+void wxFrameGTK::PositionStatusBar()
+{
+    if ( !m_frameStatusBar )
+        return;
 
-    return m_frameStatusBar;
+    m_sizeSet = FALSE;
 }
+#endif // wxUSE_STATUSBAR
+
+// ----------------------------------------------------------------------------
+// frame title/icon
+// ----------------------------------------------------------------------------
 
-wxStatusBar *wxFrame::OnCreateStatusBar( int number, long style, wxWindowID id, const wxString& name )
+void wxFrameGTK::SetTitle( const wxString &title )
 {
-    wxStatusBar *statusBar = (wxStatusBar *) NULL;
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
+
+    m_title = title;
+    gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
+}
 
-    statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20), style, name);
+void wxFrameGTK::SetIcon( const wxIcon &icon )
+{
+    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
-    // Set the height according to the font and the border size
-    wxClientDC dc(statusBar);
-    dc.SetFont( statusBar->GetFont() );
+    wxFrameBase::SetIcon(icon);
 
-    long x, y;
-    dc.GetTextExtent( "X", &x, &y );
+    if ( !m_icon.Ok() )
+        return;
 
-    int height = (int)( (y  * 1.1) + 2* statusBar->GetBorderY());
+    if (!m_widget->window)
+        return;
 
-    statusBar->SetSize( -1, -1, 100, height );
+    wxMask *mask = icon.GetMask();
+    GdkBitmap *bm = (GdkBitmap *) NULL;
+    if (mask) bm = mask->GetBitmap();
 
-    statusBar->SetFieldsCount( number );
-    return statusBar;
+    gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
 }
 
-wxStatusBar *wxFrame::GetStatusBar() const
+// ----------------------------------------------------------------------------
+// frame state: maximized/iconized/normal
+// ----------------------------------------------------------------------------
+
+void wxFrameGTK::Maximize(bool WXUNUSED(maximize))
 {
-    return m_frameStatusBar;
+    wxFAIL_MSG( _T("not implemented") );
 }
 
-void wxFrame::SetStatusText(const wxString& text, int number)
+bool wxFrameGTK::IsMaximized() const
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
+  //    wxFAIL_MSG( _T("not implemented") );
 
-    wxCHECK_RET( m_frameStatusBar != NULL, _T("no statusbar to set text for") );
-
-    m_frameStatusBar->SetStatusText(text, number);
+    // This is an approximation
+    return FALSE;
 }
 
-void wxFrame::SetStatusWidths(int n, const int widths_field[] )
+void wxFrameGTK::Restore()
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
-
-    wxCHECK_RET( m_frameStatusBar != NULL, _T("no statusbar to set widths for") );
-
-    m_frameStatusBar->SetStatusWidths(n, widths_field);
+    wxFAIL_MSG( _T("not implemented") );
 }
-#endif // wxUSE_STATUSBAR
 
-void wxFrame::Command( int id )
+void wxFrameGTK::Iconize( bool iconize )
 {
-    wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
-    commandEvent.SetInt( id );
-    commandEvent.SetEventObject( this );
-
-    wxMenuBar *bar = GetMenuBar();
-    if (!bar) return;
-
-    wxMenuItem *item = bar->FindItemForId(id) ;
-    if (item && item->IsCheckable())
-    {
-        bar->Check(id,!bar->Checked(id)) ;
-    }
+   if (iconize)
+   {
+       GdkWindow *window = m_widget->window;
 
-    wxEvtHandler* evtHandler = GetEventHandler();
+       // you should do it later, for example from OnCreate() handler
+       wxCHECK_RET( window, _T("frame not created yet - can't iconize") );
 
-    evtHandler->ProcessEvent(commandEvent);
+       XIconifyWindow( GDK_WINDOW_XDISPLAY( window ),
+                       GDK_WINDOW_XWINDOW( window ),
+                       DefaultScreen( GDK_DISPLAY() ) );
+   }
 }
 
-void wxFrame::SetTitle( const wxString &title )
+bool wxFrameGTK::IsIconized() const
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
-
-    m_title = title;
-    if (m_title.IsNull()) m_title = _T("");
-    gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
+    return m_isIconized;
 }
 
-void wxFrame::SetIcon( const wxIcon &icon )
+void wxFrameGTK::SetIconizeState(bool iconize)
 {
-    wxASSERT_MSG( (m_widget != NULL), _T("invalid frame") );
-
-    m_icon = icon;
-    if (!icon.Ok()) return;
-
-    if (!m_widget->window) return;
-
-    wxMask *mask = icon.GetMask();
-    GdkBitmap *bm = (GdkBitmap *) NULL;
-    if (mask) bm = mask->GetBitmap();
-
-    gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
+    if ( iconize != m_isIconized )
+    {
+        m_isIconized = iconize;
+        (void)SendIconizeEvent(iconize);
+    }
 }