]> git.saurik.com Git - wxWidgets.git/commitdiff
fixed initial focus handling in the dialog and made SetFocus() send the focus
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 20 Apr 2002 13:53:11 +0000 (13:53 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 20 Apr 2002 13:53:11 +0000 (13:53 +0000)
events as under wxMSW

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15218 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/toplevel.h
include/wx/gtk1/toplevel.h
src/common/containr.cpp
src/gtk/notebook.cpp
src/gtk/toplevel.cpp
src/gtk/window.cpp
src/gtk1/notebook.cpp
src/gtk1/toplevel.cpp
src/gtk1/window.cpp

index a3b842add32c6674f8b4992a2ce06393de683261..1f4a35c268d6317557e6b7ba0f25cd27b2c1f38a 100644 (file)
@@ -92,13 +92,18 @@ public:
     long          m_fsSaveGdkFunc, m_fsSaveGdkDecor;
     long          m_fsSaveFlag;
     wxRect        m_fsSaveFrame;
-    
-    long          m_gdkFunc, m_gdkDecor; // m_windowStyle translated to GDK's terms
+
+    // m_windowStyle translated to GDK's terms
+    long          m_gdkFunc,
+                  m_gdkDecor;
 
 protected:
     // common part of all ctors
     void Init();
 
+    // focus event handler
+    void OnSetFocus(wxFocusEvent& event);
+
     // override wxWindow methods to take into account tool/menu/statusbars
     virtual void DoSetSize(int x, int y,
                            int width, int height,
@@ -109,6 +114,8 @@ protected:
 
     // is the frame currently iconized?
     bool m_isIconized;
+
+    DECLARE_EVENT_TABLE()
 };
 
 #endif // __GTKTOPLEVELH__
index a3b842add32c6674f8b4992a2ce06393de683261..1f4a35c268d6317557e6b7ba0f25cd27b2c1f38a 100644 (file)
@@ -92,13 +92,18 @@ public:
     long          m_fsSaveGdkFunc, m_fsSaveGdkDecor;
     long          m_fsSaveFlag;
     wxRect        m_fsSaveFrame;
-    
-    long          m_gdkFunc, m_gdkDecor; // m_windowStyle translated to GDK's terms
+
+    // m_windowStyle translated to GDK's terms
+    long          m_gdkFunc,
+                  m_gdkDecor;
 
 protected:
     // common part of all ctors
     void Init();
 
+    // focus event handler
+    void OnSetFocus(wxFocusEvent& event);
+
     // override wxWindow methods to take into account tool/menu/statusbars
     virtual void DoSetSize(int x, int y,
                            int width, int height,
@@ -109,6 +114,8 @@ protected:
 
     // is the frame currently iconized?
     bool m_isIconized;
+
+    DECLARE_EVENT_TABLE()
 };
 
 #endif // __GTKTOPLEVELH__
index b76ec648d6ba04a4e30f6f538c2ccc5db9d5291f..c387c5da204f16b21fa38dcd8d994ad9a702b2ca 100644 (file)
@@ -50,6 +50,12 @@ wxControlContainer::wxControlContainer(wxWindow *winParent)
 
 void wxControlContainer::SetLastFocus(wxWindow *win)
 {
+    // the panel itself should never get the focus at all but if it does happen
+    // temporarily (as it seems to do under wxGTK), at the very least don't
+    // forget our previous m_winLastFocused
+    if ( win == m_winParent )
+        return;
+
     // if we're setting the focus
     if ( win )
     {
@@ -70,6 +76,17 @@ void wxControlContainer::SetLastFocus(wxWindow *win)
     }
 
     m_winLastFocused = win;
+
+    if ( win )
+    {
+        wxLogTrace(_T("focus"), _T("Set last focus to %s(%s)"),
+                   win->GetClassInfo()->GetClassName(),
+                   win->GetLabel().c_str());
+    }
+    else
+    {
+        wxLogTrace(_T("focus"), _T("No more last focus"));
+    }
 }
 
 // ----------------------------------------------------------------------------
index 9d70d97f45a1fe19836d2cc507d2eae0b9f23418..08fc2ca89d0dee6c3b7d85d503188da3e71d0609 100644 (file)
@@ -46,16 +46,6 @@ extern bool g_isIdle;
 
 extern bool g_blockEventsOnDrag;
 
-//-----------------------------------------------------------------------------
-// debug
-//-----------------------------------------------------------------------------
-
-#ifdef __WXDEBUG__
-
-extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
-
-#endif
-
 //-----------------------------------------------------------------------------
 // wxGtkNotebookPage
 //-----------------------------------------------------------------------------
@@ -291,10 +281,6 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
 
     m_widget = gtk_notebook_new();
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_widget, wxT("wxNotebook::m_widget"), name );
-#endif
-
     gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
index b2045d79d473ba41fffc7e8b92c4972dbb2743f9..9f5beeea7c234aaac0c55790d7dcd81a6b83d37f 100644 (file)
@@ -56,16 +56,6 @@ extern wxList         wxPendingDelete;
 extern int            g_openDialogs;
 extern wxWindowGTK   *g_delayedFocus;
 
-// ----------------------------------------------------------------------------
-// debug
-// ----------------------------------------------------------------------------
-
-#ifdef __WXDEBUG__
-
-extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
-
-#endif
-
 //-----------------------------------------------------------------------------
 // "focus" from m_window
 //-----------------------------------------------------------------------------
@@ -154,18 +144,6 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WX
     return FALSE;
 }
 
-//-----------------------------------------------------------------------------
-// local code
-//-----------------------------------------------------------------------------
-
-static wxWindow* wxGetTopLevelParent(wxWindow *win)
-{
-    wxWindow *p = win;
-    while (p && !p->IsTopLevel())
-         p = p->GetParent();
-    return p;
-}
-
 //-----------------------------------------------------------------------------
 // "realize" from m_widget
 //-----------------------------------------------------------------------------
@@ -174,7 +152,8 @@ static wxWindow* wxGetTopLevelParent(wxWindow *win)
 // so we do this directly after realization
 
 static void
-gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *win )
+gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
+                             wxTopLevelWindowGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
@@ -194,50 +173,11 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *
 
     // reset the icon
     wxIconBundle iconsOld = win->GetIcons();
-    wxIcon tmp = iconsOld.GetIcon( -1 ); // operator != is not-const
-    if ( tmp != wxNullIcon )
+    if ( iconsOld.GetIcon(-1).Ok() )
     {
-        // wxIconBundle icon( iconOld );
         win->SetIcon( wxNullIcon );
         win->SetIcons( iconsOld );
     }
-
-    // We need to set the focus to some child. Either, this
-    // has been done already or will be done in the next
-    // idle cycle, or we will set it ourselves.
-
-    if (g_delayedFocus)
-    {
-        if (wxGetTopLevelParent(g_delayedFocus))
-            return;
-        else
-            g_delayedFocus = NULL;
-    }
-        
-    wxWindow *currentFocus = wxWindow::FindFocus();
-    if (currentFocus)
-    {
-        // I am not sure if this ever can happen,
-        // since the TLW is just about to get
-        // created and its children probably don't
-        // have any focus.
-        if (wxGetTopLevelParent(currentFocus) == win)
-            return;
-    }
-
-    // We set the focus to the child that accepts the focus.
-    wxWindowList::Node *node = win->GetChildren().GetFirst();
-    while (node)
-    {
-        wxWindow *child = node->GetData();
-        if (child->AcceptsFocus())
-        {
-            child->SetFocus();
-            break;
-        }
-        
-        node = node->GetNext();
-    }
 }
 
 //-----------------------------------------------------------------------------
@@ -308,6 +248,10 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxW
 // wxTopLevelWindowGTK itself
 // ----------------------------------------------------------------------------
 
+BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
+    EVT_SET_FOCUS(wxTopLevelWindowGTK::OnSetFocus)
+END_EVENT_TABLE()
+
 //-----------------------------------------------------------------------------
 // InsertChild for wxTopLevelWindowGTK
 //-----------------------------------------------------------------------------
@@ -388,7 +332,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
     wxTopLevelWindows.Append( this );
 
     m_needParent = FALSE;
-    
+
     if (!PreCreation( parent, pos, size ) ||
         !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
     {
@@ -426,10 +370,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
     if (!name.IsEmpty())
         gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_widget, wxT("wxTopLevelWindowGTK::m_widget"), name );
-#endif
-
     gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
     GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
 
@@ -450,19 +390,11 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
                 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
 #endif
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_mainWidget, wxT("wxTopLevelWindowGTK::m_mainWidget"), name );
-#endif
-
     // m_wxwindow only represents the client area without toolbar and menubar
     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, wxT("wxTopLevelWindowGTK::m_wxwindow"), name );
-#endif
-
     // we donm't allow the frame to get the focus as otherwise
     // the frame will grab it at arbitrary focus changes
     GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
@@ -477,7 +409,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 
     if ((m_x != -1) || (m_y != -1))
         gtk_widget_set_uposition( m_widget, m_x, m_y );
-        
+
     gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
 
     //  we cannot set MWM hints and icons before the widget has
@@ -546,7 +478,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
 {
     m_isBeingDeleted = TRUE;
-    
+
     // it may also be GtkScrolledWindow in the case of an MDI child
     if (GTK_IS_WINDOW(m_widget))
     {
@@ -830,9 +762,31 @@ void wxTopLevelWindowGTK::OnInternalIdle()
         return;
     }
 
+    // set the focus if not done yet and if we can already do it
+    if ( GTK_WIDGET_REALIZED(m_wxwindow) )
+    {
+        if ( g_delayedFocus && wxGetTopLevelParent(g_delayedFocus) == this )
+        {
+            g_delayedFocus->SetFocus();
+            g_delayedFocus = NULL;
+        }
+    }
+
     wxWindow::OnInternalIdle();
 }
 
+void wxTopLevelWindowGTK::OnSetFocus(wxFocusEvent& event)
+{
+#if 0
+    if ( !g_delayedFocus || wxGetTopLevelParent(g_delayedFocus) != this )
+    {
+        // let the base class version set the focus to the first child which
+        // accepts it
+        event.Skip();
+    }
+    //else: the focus will be really set from OnInternalIdle() later
+#endif
+}
 
 // ----------------------------------------------------------------------------
 // frame title/icon
index c15e735d2b18ed4a83e5eb0871d394ffd3ba1e23..7460101617e7d90783b1e0dc290eb176878cdd4d 100644 (file)
@@ -270,43 +270,6 @@ extern bool g_mainThreadLocked;
 #else
 #   define DEBUG_MAIN_THREAD
 #endif
-
-static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
-                                         GdkEvent *WXUNUSED(event),
-                                         const wxChar *WXUNUSED(name) )
-{
-/*
-    static bool s_done = FALSE;
-    if ( !s_done )
-    {
-        wxLog::AddTraceMask("focus");
-        s_done = TRUE;
-    }
-    wxLogTrace(wxT("FOCUS NOW AT: %s"), name);
-*/
-
-    return FALSE;
-}
-
-void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window )
-{
-    // suppress warnings about gtk_debug_focus_in_callback being unused with
-    // this "if ( 0 )"
-    if ( 0 )
-    {
-        wxString tmp = name;
-        tmp += wxT(" FROM ");
-        tmp += window;
-
-        wxChar *s = new wxChar[tmp.Length()+1];
-
-        wxStrcpy( s, tmp );
-
-        gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
-          GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
-    }
-}
-
 #else
 #define DEBUG_MAIN_THREAD
 #endif // Debug
@@ -385,15 +348,6 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win)
     return (wxWindow *)NULL;
 }
 
-// Returns toplevel grandparent of given window:
-static wxWindowGTK* wxGetTopLevelParent(wxWindowGTK *win)
-{
-    wxWindowGTK *p = win;
-    while (p && !p->IsTopLevel())
-         p = p->GetParent();
-    return p;
-}
-
 static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
 {
     // wxUniversal widgets draw the borders and scrollbars themselves
@@ -1749,6 +1703,21 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
 // "focus_in_event"
 //-----------------------------------------------------------------------------
 
+// send the wxChildFocusEvent and wxFocusEvent, common code of
+// gtk_window_focus_in_callback() and SetFocus()
+static bool DoSendFocusEvents(wxWindow *win)
+{
+    // Notify the parent keeping track of focus for the kbd navigation
+    // purposes that we got it.
+    wxChildFocusEvent eventChildFocus(win);
+    (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
+
+    wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
+    eventFocus.SetEventObject(win);
+
+    return win->GetEventHandler()->ProcessEvent(eventFocus);
+}
+
 static gint gtk_window_focus_in_callback( GtkWidget *widget,
                                           GdkEvent *WXUNUSED(event),
                                           wxWindow *win )
@@ -1782,11 +1751,6 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
     printf( "OnSetFocus 2 from %s\n", win->GetName().c_str() );
 #endif
 
-    // Notify the parent keeping track of focus for the kbd navigation
-    // purposes that we got it.
-    wxChildFocusEvent eventFocus(win);
-    (void)win->GetEventHandler()->ProcessEvent(eventFocus);
-
 #ifdef HAVE_XIM
     if (win->m_ic)
         gdk_im_begin(win->m_ic, win->m_wxwindow->window);
@@ -1825,11 +1789,7 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
         //    return TRUE;
     }
 
-
-    wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
-    event.SetEventObject( win );
-
-    if (win->GetEventHandler()->ProcessEvent( event ))
+    if ( DoSendFocusEvents(win) )
     {
        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
        return TRUE;
@@ -2906,15 +2866,6 @@ void wxWindowGTK::OnInternalIdle()
         g_activeFrameLostFocus = FALSE;
     }
     
-    if (g_delayedFocus == this)
-    {
-        if (GTK_WIDGET_REALIZED(m_widget))
-        {
-            gtk_widget_grab_focus( m_widget );
-            g_delayedFocus = NULL;
-        }
-    }
-
     wxCursor cursor = m_cursor;
     if (g_globalCursor.Ok()) cursor = g_globalCursor;
 
@@ -3281,9 +3232,21 @@ void wxWindowGTK::SetFocus()
         if (GTK_WIDGET_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) )
         {
             if (!GTK_WIDGET_REALIZED(m_widget))
+            {
+                wxLogTrace(_T("focus"),
+                           _T("Delaying setting focus to %s(%s)\n"),
+                           GetClassInfo()->GetClassName(), GetLabel().c_str());
+
                 g_delayedFocus = this;
+            }
             else
+            {
+                wxLogTrace(_T("focus"),
+                           _T("Setting focus to %s(%s)\n"),
+                           GetClassInfo()->GetClassName(), GetLabel().c_str());
+
                 gtk_widget_grab_focus (m_widget);
+            }
         }
         else if (GTK_IS_CONTAINER(m_widget))
         {
@@ -3294,6 +3257,8 @@ void wxWindowGTK::SetFocus()
            // ?
         }
     }
+
+    (void)DoSendFocusEvents(this);
 }
 
 bool wxWindowGTK::AcceptsFocus() const
index 9d70d97f45a1fe19836d2cc507d2eae0b9f23418..08fc2ca89d0dee6c3b7d85d503188da3e71d0609 100644 (file)
@@ -46,16 +46,6 @@ extern bool g_isIdle;
 
 extern bool g_blockEventsOnDrag;
 
-//-----------------------------------------------------------------------------
-// debug
-//-----------------------------------------------------------------------------
-
-#ifdef __WXDEBUG__
-
-extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
-
-#endif
-
 //-----------------------------------------------------------------------------
 // wxGtkNotebookPage
 //-----------------------------------------------------------------------------
@@ -291,10 +281,6 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
 
     m_widget = gtk_notebook_new();
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_widget, wxT("wxNotebook::m_widget"), name );
-#endif
-
     gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
index b2045d79d473ba41fffc7e8b92c4972dbb2743f9..9f5beeea7c234aaac0c55790d7dcd81a6b83d37f 100644 (file)
@@ -56,16 +56,6 @@ extern wxList         wxPendingDelete;
 extern int            g_openDialogs;
 extern wxWindowGTK   *g_delayedFocus;
 
-// ----------------------------------------------------------------------------
-// debug
-// ----------------------------------------------------------------------------
-
-#ifdef __WXDEBUG__
-
-extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
-
-#endif
-
 //-----------------------------------------------------------------------------
 // "focus" from m_window
 //-----------------------------------------------------------------------------
@@ -154,18 +144,6 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WX
     return FALSE;
 }
 
-//-----------------------------------------------------------------------------
-// local code
-//-----------------------------------------------------------------------------
-
-static wxWindow* wxGetTopLevelParent(wxWindow *win)
-{
-    wxWindow *p = win;
-    while (p && !p->IsTopLevel())
-         p = p->GetParent();
-    return p;
-}
-
 //-----------------------------------------------------------------------------
 // "realize" from m_widget
 //-----------------------------------------------------------------------------
@@ -174,7 +152,8 @@ static wxWindow* wxGetTopLevelParent(wxWindow *win)
 // so we do this directly after realization
 
 static void
-gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *win )
+gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
+                             wxTopLevelWindowGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
@@ -194,50 +173,11 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *
 
     // reset the icon
     wxIconBundle iconsOld = win->GetIcons();
-    wxIcon tmp = iconsOld.GetIcon( -1 ); // operator != is not-const
-    if ( tmp != wxNullIcon )
+    if ( iconsOld.GetIcon(-1).Ok() )
     {
-        // wxIconBundle icon( iconOld );
         win->SetIcon( wxNullIcon );
         win->SetIcons( iconsOld );
     }
-
-    // We need to set the focus to some child. Either, this
-    // has been done already or will be done in the next
-    // idle cycle, or we will set it ourselves.
-
-    if (g_delayedFocus)
-    {
-        if (wxGetTopLevelParent(g_delayedFocus))
-            return;
-        else
-            g_delayedFocus = NULL;
-    }
-        
-    wxWindow *currentFocus = wxWindow::FindFocus();
-    if (currentFocus)
-    {
-        // I am not sure if this ever can happen,
-        // since the TLW is just about to get
-        // created and its children probably don't
-        // have any focus.
-        if (wxGetTopLevelParent(currentFocus) == win)
-            return;
-    }
-
-    // We set the focus to the child that accepts the focus.
-    wxWindowList::Node *node = win->GetChildren().GetFirst();
-    while (node)
-    {
-        wxWindow *child = node->GetData();
-        if (child->AcceptsFocus())
-        {
-            child->SetFocus();
-            break;
-        }
-        
-        node = node->GetNext();
-    }
 }
 
 //-----------------------------------------------------------------------------
@@ -308,6 +248,10 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxW
 // wxTopLevelWindowGTK itself
 // ----------------------------------------------------------------------------
 
+BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
+    EVT_SET_FOCUS(wxTopLevelWindowGTK::OnSetFocus)
+END_EVENT_TABLE()
+
 //-----------------------------------------------------------------------------
 // InsertChild for wxTopLevelWindowGTK
 //-----------------------------------------------------------------------------
@@ -388,7 +332,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
     wxTopLevelWindows.Append( this );
 
     m_needParent = FALSE;
-    
+
     if (!PreCreation( parent, pos, size ) ||
         !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
     {
@@ -426,10 +370,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
     if (!name.IsEmpty())
         gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_widget, wxT("wxTopLevelWindowGTK::m_widget"), name );
-#endif
-
     gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
     GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
 
@@ -450,19 +390,11 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
                 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
 #endif
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_mainWidget, wxT("wxTopLevelWindowGTK::m_mainWidget"), name );
-#endif
-
     // m_wxwindow only represents the client area without toolbar and menubar
     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, wxT("wxTopLevelWindowGTK::m_wxwindow"), name );
-#endif
-
     // we donm't allow the frame to get the focus as otherwise
     // the frame will grab it at arbitrary focus changes
     GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
@@ -477,7 +409,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 
     if ((m_x != -1) || (m_y != -1))
         gtk_widget_set_uposition( m_widget, m_x, m_y );
-        
+
     gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
 
     //  we cannot set MWM hints and icons before the widget has
@@ -546,7 +478,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
 {
     m_isBeingDeleted = TRUE;
-    
+
     // it may also be GtkScrolledWindow in the case of an MDI child
     if (GTK_IS_WINDOW(m_widget))
     {
@@ -830,9 +762,31 @@ void wxTopLevelWindowGTK::OnInternalIdle()
         return;
     }
 
+    // set the focus if not done yet and if we can already do it
+    if ( GTK_WIDGET_REALIZED(m_wxwindow) )
+    {
+        if ( g_delayedFocus && wxGetTopLevelParent(g_delayedFocus) == this )
+        {
+            g_delayedFocus->SetFocus();
+            g_delayedFocus = NULL;
+        }
+    }
+
     wxWindow::OnInternalIdle();
 }
 
+void wxTopLevelWindowGTK::OnSetFocus(wxFocusEvent& event)
+{
+#if 0
+    if ( !g_delayedFocus || wxGetTopLevelParent(g_delayedFocus) != this )
+    {
+        // let the base class version set the focus to the first child which
+        // accepts it
+        event.Skip();
+    }
+    //else: the focus will be really set from OnInternalIdle() later
+#endif
+}
 
 // ----------------------------------------------------------------------------
 // frame title/icon
index c15e735d2b18ed4a83e5eb0871d394ffd3ba1e23..7460101617e7d90783b1e0dc290eb176878cdd4d 100644 (file)
@@ -270,43 +270,6 @@ extern bool g_mainThreadLocked;
 #else
 #   define DEBUG_MAIN_THREAD
 #endif
-
-static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
-                                         GdkEvent *WXUNUSED(event),
-                                         const wxChar *WXUNUSED(name) )
-{
-/*
-    static bool s_done = FALSE;
-    if ( !s_done )
-    {
-        wxLog::AddTraceMask("focus");
-        s_done = TRUE;
-    }
-    wxLogTrace(wxT("FOCUS NOW AT: %s"), name);
-*/
-
-    return FALSE;
-}
-
-void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window )
-{
-    // suppress warnings about gtk_debug_focus_in_callback being unused with
-    // this "if ( 0 )"
-    if ( 0 )
-    {
-        wxString tmp = name;
-        tmp += wxT(" FROM ");
-        tmp += window;
-
-        wxChar *s = new wxChar[tmp.Length()+1];
-
-        wxStrcpy( s, tmp );
-
-        gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
-          GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
-    }
-}
-
 #else
 #define DEBUG_MAIN_THREAD
 #endif // Debug
@@ -385,15 +348,6 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win)
     return (wxWindow *)NULL;
 }
 
-// Returns toplevel grandparent of given window:
-static wxWindowGTK* wxGetTopLevelParent(wxWindowGTK *win)
-{
-    wxWindowGTK *p = win;
-    while (p && !p->IsTopLevel())
-         p = p->GetParent();
-    return p;
-}
-
 static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
 {
     // wxUniversal widgets draw the borders and scrollbars themselves
@@ -1749,6 +1703,21 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
 // "focus_in_event"
 //-----------------------------------------------------------------------------
 
+// send the wxChildFocusEvent and wxFocusEvent, common code of
+// gtk_window_focus_in_callback() and SetFocus()
+static bool DoSendFocusEvents(wxWindow *win)
+{
+    // Notify the parent keeping track of focus for the kbd navigation
+    // purposes that we got it.
+    wxChildFocusEvent eventChildFocus(win);
+    (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
+
+    wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
+    eventFocus.SetEventObject(win);
+
+    return win->GetEventHandler()->ProcessEvent(eventFocus);
+}
+
 static gint gtk_window_focus_in_callback( GtkWidget *widget,
                                           GdkEvent *WXUNUSED(event),
                                           wxWindow *win )
@@ -1782,11 +1751,6 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
     printf( "OnSetFocus 2 from %s\n", win->GetName().c_str() );
 #endif
 
-    // Notify the parent keeping track of focus for the kbd navigation
-    // purposes that we got it.
-    wxChildFocusEvent eventFocus(win);
-    (void)win->GetEventHandler()->ProcessEvent(eventFocus);
-
 #ifdef HAVE_XIM
     if (win->m_ic)
         gdk_im_begin(win->m_ic, win->m_wxwindow->window);
@@ -1825,11 +1789,7 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
         //    return TRUE;
     }
 
-
-    wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
-    event.SetEventObject( win );
-
-    if (win->GetEventHandler()->ProcessEvent( event ))
+    if ( DoSendFocusEvents(win) )
     {
        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
        return TRUE;
@@ -2906,15 +2866,6 @@ void wxWindowGTK::OnInternalIdle()
         g_activeFrameLostFocus = FALSE;
     }
     
-    if (g_delayedFocus == this)
-    {
-        if (GTK_WIDGET_REALIZED(m_widget))
-        {
-            gtk_widget_grab_focus( m_widget );
-            g_delayedFocus = NULL;
-        }
-    }
-
     wxCursor cursor = m_cursor;
     if (g_globalCursor.Ok()) cursor = g_globalCursor;
 
@@ -3281,9 +3232,21 @@ void wxWindowGTK::SetFocus()
         if (GTK_WIDGET_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) )
         {
             if (!GTK_WIDGET_REALIZED(m_widget))
+            {
+                wxLogTrace(_T("focus"),
+                           _T("Delaying setting focus to %s(%s)\n"),
+                           GetClassInfo()->GetClassName(), GetLabel().c_str());
+
                 g_delayedFocus = this;
+            }
             else
+            {
+                wxLogTrace(_T("focus"),
+                           _T("Setting focus to %s(%s)\n"),
+                           GetClassInfo()->GetClassName(), GetLabel().c_str());
+
                 gtk_widget_grab_focus (m_widget);
+            }
         }
         else if (GTK_IS_CONTAINER(m_widget))
         {
@@ -3294,6 +3257,8 @@ void wxWindowGTK::SetFocus()
            // ?
         }
     }
+
+    (void)DoSendFocusEvents(this);
 }
 
 bool wxWindowGTK::AcceptsFocus() const