]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/frame.cpp
fixed bug/assert failure when refreshing items in non report mode
[wxWidgets.git] / src / gtk1 / frame.cpp
index 23b5ea9c9f3d1e82c279fb61349fc6b0f0bb2ecd..b1987a0b8d5e7278edf11a6f74aaf02eeaf15c5a 100644 (file)
@@ -23,7 +23,8 @@
 #define XIconifyWindow XICONIFYWINDOW
 #endif
 
-#include "wx/frame.h"
+#include "wx/defs.h"
+
 #include "wx/dialog.h"
 #include "wx/control.h"
 #include "wx/app.h"
@@ -64,7 +65,9 @@ extern int g_openDialogs;
 // event tables
 // ----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow)
+#ifndef __WXUNIVERSAL__
+    IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
+#endif
 
 // ----------------------------------------------------------------------------
 // data
@@ -108,7 +111,7 @@ static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUS
 // "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();
@@ -139,7 +142,7 @@ 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();
@@ -150,11 +153,13 @@ static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WX
     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;
 
@@ -166,7 +171,7 @@ static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *
 // "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;
 
@@ -174,12 +179,14 @@ static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *
     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;
 
@@ -192,7 +199,7 @@ static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidge
 // "child_detached" of tool bar
 //-----------------------------------------------------------------------------
 
-static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(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();
@@ -210,9 +217,9 @@ static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidge
 
 static gint
 #if (GTK_MINOR_VERSION > 0)
-gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrame *win )
+gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrameGTK *win )
 #else
-gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrame *win )
+gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrameGTK *win )
 #endif
 {
     if (g_isIdle)
@@ -246,8 +253,8 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *ev
 /* 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 * WXUNUSED(widget), wxFrame *win )
+static void
+gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxFrameGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
@@ -321,31 +328,80 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(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;
+}
+
+//-----------------------------------------------------------------------------
+// "draw" of m_client
+//-----------------------------------------------------------------------------
+
+
+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);
 }
 
 // ----------------------------------------------------------------------------
-// wxFrame itself
+// wxFrameGTK itself
 // ----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
-// InsertChild for wxFrame
+// InsertChild for wxFrameGTK
 //-----------------------------------------------------------------------------
 
-/* Callback for wxFrame. This very strange beast has to be used because
+/* 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;
+        wxFrameGTK* frame = (wxFrameGTK*) parent;
         gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
                          GTK_WIDGET(child->m_widget),
                          child->m_x,
@@ -386,10 +442,10 @@ static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child )
 }
 
 // ----------------------------------------------------------------------------
-// wxFrame creation
+// wxFrameGTK creation
 // ----------------------------------------------------------------------------
 
-void wxFrame::Init()
+void wxFrameGTK::Init()
 {
     m_sizeSet = FALSE;
     m_miniEdge = 0;
@@ -398,25 +454,40 @@ void wxFrame::Init()
     m_menuBarDetached = FALSE;
     m_toolBarDetached = FALSE;
     m_insertInClientArea = TRUE;
+    m_isFrame = TRUE;
+    m_isIconized = FALSE;
+    m_fsIsShowing = FALSE;
+    m_themeEnabled = TRUE;
 }
 
-bool wxFrame::Create( wxWindow *parent,
+bool wxFrameGTK::Create( wxWindow *parent,
                       wxWindowID id,
-                      const wxString &title,
-                      const wxPoint &pos,
-                      const wxSize &size,
+                      const wxStringtitle,
+                      const wxPointpos,
+                      const wxSize& sizeOrig,
                       long style,
                       const wxString &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;
+    }
+
     wxTopLevelWindows.Append( this );
 
     m_needParent = FALSE;
-    m_fsIsShowing = FALSE;
 
     if (!PreCreation( parent, pos, size ) ||
         !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
     {
-        wxFAIL_MSG( wxT("wxFrame creation failed") );
+        wxFAIL_MSG( wxT("wxFrameGTK creation failed") );
         return FALSE;
     }
 
@@ -426,6 +497,9 @@ bool wxFrame::Create( wxWindow *parent,
 
     GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
 
+    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)))
@@ -435,7 +509,7 @@ bool wxFrame::Create( wxWindow *parent,
         gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
 
 #ifdef __WXDEBUG__
-    debug_focus_in( m_widget, wxT("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() );
@@ -450,8 +524,14 @@ bool wxFrame::Create( wxWindow *parent,
     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, wxT("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 */
@@ -460,11 +540,11 @@ bool wxFrame::Create( wxWindow *parent,
     gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
 
 #ifdef __WXDEBUG__
-    debug_focus_in( m_wxwindow, wxT("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 );
@@ -488,6 +568,16 @@ bool wxFrame::Create( wxWindow *parent,
     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 );
@@ -495,7 +585,7 @@ bool wxFrame::Create( wxWindow *parent,
     return TRUE;
 }
 
-wxFrame::~wxFrame()
+wxFrameGTK::~wxFrameGTK()
 {
     m_isBeingDeleted = TRUE;
 
@@ -513,29 +603,29 @@ wxFrame::~wxFrame()
     }
 }
 
-bool wxFrame::ShowFullScreen(bool show, long style )
+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 );
     }
@@ -543,15 +633,15 @@ bool wxFrame::ShowFullScreen(bool show, long style )
     {
         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;
 }
 
@@ -559,7 +649,7 @@ bool wxFrame::ShowFullScreen(bool show, long style )
 // overridden wxWindow methods
 // ----------------------------------------------------------------------------
 
-bool wxFrame::Show( bool show )
+bool wxFrameGTK::Show( bool show )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
@@ -576,16 +666,16 @@ bool wxFrame::Show( bool show )
     return wxWindow::Show( show );
 }
 
-void wxFrame::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
+void wxFrameGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
 {
-    wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
+    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), wxT("invalid frame") );
 
-    /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
+    /* this shouldn't happen: wxFrameGTK, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
     /* avoid recursions */
@@ -652,13 +742,14 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
     m_resizing = FALSE;
 }
 
-void wxFrame::DoGetClientSize( int *width, int *height ) const
+void wxFrameGTK::DoGetClientSize( int *width, int *height ) const
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
     wxWindow::DoGetClientSize( width, height );
     if (height)
     {
+#if wxUSE_MENUS_NATIVE
         /* menu bar */
         if (m_frameMenuBar)
         {
@@ -667,6 +758,7 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const
             else
                 (*height) -= wxPLACE_HOLDER;
         }
+#endif // wxUSE_MENUS_NATIVE
 
 #if wxUSE_STATUSBAR
         /* status bar */
@@ -706,10 +798,11 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const
     }
 }
 
-void wxFrame::DoSetClientSize( int width, int height )
+void wxFrameGTK::DoSetClientSize( int width, int height )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
+#if wxUSE_MENUS_NATIVE
         /* menu bar */
         if (m_frameMenuBar)
         {
@@ -718,6 +811,7 @@ void wxFrame::DoSetClientSize( int width, int height )
             else
                 height += wxPLACE_HOLDER;
         }
+#endif // wxUSE_MENUS_NATIVE
 
 #if wxUSE_STATUSBAR
         /* status bar */
@@ -751,7 +845,7 @@ void wxFrame::DoSetClientSize( int width, int height )
     DoSetSize( -1, -1, width + m_miniEdge*2, height  + m_miniEdge*2 + m_miniTitle, 0 );
 }
 
-void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
+void wxFrameGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
                          int width, int height )
 {
     // due to a bug in gtk, x,y are always 0
@@ -762,7 +856,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
     if (m_resizing) return;
     m_resizing = TRUE;
 
-    /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
+    /* this shouldn't happen: wxFrameGTK, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
     m_width = width;
@@ -772,9 +866,9 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
     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 */
@@ -806,6 +900,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
          * 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_NATIVE
         if (m_frameMenuBar)
         {
             int xx = m_miniEdge;
@@ -822,6 +917,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
                                   xx, yy, ww, hh );
             client_area_y_offset += hh;
         }
+#endif // wxUSE_MENUS_NATIVE
 
 #if wxUSE_TOOLBAR
         if ((m_frameToolBar) && m_frameToolBar->IsShown() &&
@@ -829,6 +925,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
         {
             int xx = m_miniEdge;
             int yy = m_miniEdge + m_miniTitle;
+#if wxUSE_MENUS_NATIVE
             if (m_frameMenuBar)
             {
                 if (!m_menuBarDetached)
@@ -836,6 +933,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
                 else
                     yy += wxPLACE_HOLDER;
             }
+#endif // wxUSE_MENUS_NATIVE
 
             m_frameToolBar->m_x = xx;
             m_frameToolBar->m_y = yy;
@@ -895,7 +993,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
                             xx, yy, ww, hh );
         gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL );
     }
-#endif
+#endif // wxUSE_STATUSBAR
 
     m_sizeSet = TRUE;
 
@@ -904,6 +1002,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
     event.SetEventObject( this );
     GetEventHandler()->ProcessEvent( event );
 
+#if wxUSE_STATUSBAR
     // send size event to status bar
     if (m_frameStatusBar)
     {
@@ -911,11 +1010,12 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
         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 );
@@ -923,7 +1023,7 @@ void wxFrame::MakeModal( bool modal )
         gtk_grab_remove( m_widget );
 }
 
-void wxFrame::OnInternalIdle()
+void wxFrameGTK::OnInternalIdle()
 {
     if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow))
     {
@@ -935,7 +1035,9 @@ void wxFrame::OnInternalIdle()
         return;
     }
 
+#if wxUSE_MENUS_NATIVE
     if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
+#endif // wxUSE_MENUS_NATIVE
 #if wxUSE_TOOLBAR
     if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
 #endif
@@ -950,15 +1052,14 @@ void wxFrame::OnInternalIdle()
 // menu/tool/status bar stuff
 // ----------------------------------------------------------------------------
 
-void wxFrame::SetMenuBar( wxMenuBar *menuBar )
+#if wxUSE_MENUS_NATIVE
+
+void wxFrameGTK::DetachMenuBar()
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
-    if (menuBar == m_frameMenuBar)
-        return;
-
-    if (m_frameMenuBar)
+    if ( m_frameMenuBar )
     {
         m_frameMenuBar->UnsetInvokingWindow( this );
 
@@ -976,7 +1077,12 @@ void wxFrame::SetMenuBar( wxMenuBar *menuBar )
         gtk_widget_unparent( m_frameMenuBar->m_widget );
     }
 
-    m_frameMenuBar = menuBar;
+    wxFrameBase::DetachMenuBar();
+}
+
+void wxFrameGTK::AttachMenuBar( wxMenuBar *menuBar )
+{
+    wxFrameBase::AttachMenuBar(menuBar);
 
     if (m_frameMenuBar)
     {
@@ -1006,8 +1112,11 @@ void wxFrame::SetMenuBar( wxMenuBar *menuBar )
     m_sizeSet = FALSE;
 }
 
+#endif // wxUSE_MENUS_NATIVE
+
 #if wxUSE_TOOLBAR
-wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& name )
+
+wxToolBar* wxFrameGTK::CreateToolBar( long style, wxWindowID id, const wxString& name )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
@@ -1022,7 +1131,7 @@ wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& na
     return m_frameToolBar;
 }
 
-void wxFrame::SetToolBar(wxToolBar *toolbar)
+void wxFrameGTK::SetToolBar(wxToolBar *toolbar)
 {
     wxFrameBase::SetToolBar(toolbar);
 
@@ -1044,7 +1153,7 @@ void wxFrame::SetToolBar(wxToolBar *toolbar)
 
 #if wxUSE_STATUSBAR
 
-wxStatusBar* wxFrame::CreateStatusBar(int number,
+wxStatusBar* wxFrameGTK::CreateStatusBar(int number,
                                       long style,
                                       wxWindowID id,
                                       const wxString& name)
@@ -1057,7 +1166,7 @@ wxStatusBar* wxFrame::CreateStatusBar(int number,
     return wxFrameBase::CreateStatusBar( number, style, id, name );
 }
 
-void wxFrame::PositionStatusBar()
+void wxFrameGTK::PositionStatusBar()
 {
     if ( !m_frameStatusBar )
         return;
@@ -1070,7 +1179,7 @@ void wxFrame::PositionStatusBar()
 // frame title/icon
 // ----------------------------------------------------------------------------
 
-void wxFrame::SetTitle( const wxString &title )
+void wxFrameGTK::SetTitle( const wxString &title )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
@@ -1078,7 +1187,7 @@ void wxFrame::SetTitle( const wxString &title )
     gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
 }
 
-void wxFrame::SetIcon( const wxIcon &icon )
+void wxFrameGTK::SetIcon( const wxIcon &icon )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
@@ -1098,33 +1207,53 @@ void wxFrame::SetIcon( const wxIcon &icon )
 }
 
 // ----------------------------------------------------------------------------
-// frame state: maximized/iconized/normal (TODO)
+// frame state: maximized/iconized/normal
 // ----------------------------------------------------------------------------
 
-void wxFrame::Maximize(bool WXUNUSED(maximize))
+void wxFrameGTK::Maximize(bool WXUNUSED(maximize))
 {
+    wxFAIL_MSG( _T("not implemented") );
 }
 
-bool wxFrame::IsMaximized() const
+bool wxFrameGTK::IsMaximized() const
 {
+  //    wxFAIL_MSG( _T("not implemented") );
+
+    // This is an approximation
     return FALSE;
 }
 
-void wxFrame::Restore()
+void wxFrameGTK::Restore()
 {
+    wxFAIL_MSG( _T("not implemented") );
 }
 
-void wxFrame::Iconize( bool iconize )
+void wxFrameGTK::Iconize( bool iconize )
 {
    if (iconize)
    {
-        XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget->window ),
-                        GDK_WINDOW_XWINDOW( m_widget->window ),
-                        DefaultScreen( GDK_DISPLAY() ) );
+       GdkWindow *window = m_widget->window;
+
+       // you should do it later, for example from OnCreate() handler
+       wxCHECK_RET( window, _T("frame not created yet - can't iconize") );
+
+       XIconifyWindow( GDK_WINDOW_XDISPLAY( window ),
+                       GDK_WINDOW_XWINDOW( window ),
+                       DefaultScreen( GDK_DISPLAY() ) );
    }
 }
 
-bool wxFrame::IsIconized() const
+bool wxFrameGTK::IsIconized() const
 {
-    return FALSE;
+    return m_isIconized;
 }
+
+void wxFrameGTK::SetIconizeState(bool iconize)
+{
+    if ( iconize != m_isIconized )
+    {
+        m_isIconized = iconize;
+        (void)SendIconizeEvent(iconize);
+    }
+}
+