fixed initial focus handling in the dialog and made SetFocus() send the focus

events as under wxMSW


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15218 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2002-04-20 13:53:11 +00:00
parent 33b494d643
commit 6aeb6f2a58
9 changed files with 159 additions and 318 deletions

View File

@@ -92,13 +92,18 @@ public:
long m_fsSaveGdkFunc, m_fsSaveGdkDecor; long m_fsSaveGdkFunc, m_fsSaveGdkDecor;
long m_fsSaveFlag; long m_fsSaveFlag;
wxRect m_fsSaveFrame; 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: protected:
// common part of all ctors // common part of all ctors
void Init(); void Init();
// focus event handler
void OnSetFocus(wxFocusEvent& event);
// override wxWindow methods to take into account tool/menu/statusbars // override wxWindow methods to take into account tool/menu/statusbars
virtual void DoSetSize(int x, int y, virtual void DoSetSize(int x, int y,
int width, int height, int width, int height,
@@ -109,6 +114,8 @@ protected:
// is the frame currently iconized? // is the frame currently iconized?
bool m_isIconized; bool m_isIconized;
DECLARE_EVENT_TABLE()
}; };
#endif // __GTKTOPLEVELH__ #endif // __GTKTOPLEVELH__

View File

@@ -92,13 +92,18 @@ public:
long m_fsSaveGdkFunc, m_fsSaveGdkDecor; long m_fsSaveGdkFunc, m_fsSaveGdkDecor;
long m_fsSaveFlag; long m_fsSaveFlag;
wxRect m_fsSaveFrame; 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: protected:
// common part of all ctors // common part of all ctors
void Init(); void Init();
// focus event handler
void OnSetFocus(wxFocusEvent& event);
// override wxWindow methods to take into account tool/menu/statusbars // override wxWindow methods to take into account tool/menu/statusbars
virtual void DoSetSize(int x, int y, virtual void DoSetSize(int x, int y,
int width, int height, int width, int height,
@@ -109,6 +114,8 @@ protected:
// is the frame currently iconized? // is the frame currently iconized?
bool m_isIconized; bool m_isIconized;
DECLARE_EVENT_TABLE()
}; };
#endif // __GTKTOPLEVELH__ #endif // __GTKTOPLEVELH__

View File

@@ -50,6 +50,12 @@ wxControlContainer::wxControlContainer(wxWindow *winParent)
void wxControlContainer::SetLastFocus(wxWindow *win) 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 we're setting the focus
if ( win ) if ( win )
{ {
@@ -70,6 +76,17 @@ void wxControlContainer::SetLastFocus(wxWindow *win)
} }
m_winLastFocused = 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"));
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -46,16 +46,6 @@ extern bool g_isIdle;
extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnDrag;
//-----------------------------------------------------------------------------
// debug
//-----------------------------------------------------------------------------
#ifdef __WXDEBUG__
extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxGtkNotebookPage // wxGtkNotebookPage
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -291,10 +281,6 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
m_widget = gtk_notebook_new(); 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_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page", gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",

View File

@@ -56,16 +56,6 @@ extern wxList wxPendingDelete;
extern int g_openDialogs; extern int g_openDialogs;
extern wxWindowGTK *g_delayedFocus; 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 // "focus" from m_window
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -154,18 +144,6 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WX
return FALSE; 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 // "realize" from m_widget
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -174,7 +152,8 @@ static wxWindow* wxGetTopLevelParent(wxWindow *win)
// so we do this directly after realization // so we do this directly after realization
static void static void
gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *win ) gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
wxTopLevelWindowGTK *win )
{ {
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
@@ -194,50 +173,11 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *
// reset the icon // reset the icon
wxIconBundle iconsOld = win->GetIcons(); wxIconBundle iconsOld = win->GetIcons();
wxIcon tmp = iconsOld.GetIcon( -1 ); // operator != is not-const if ( iconsOld.GetIcon(-1).Ok() )
if ( tmp != wxNullIcon )
{ {
// wxIconBundle icon( iconOld );
win->SetIcon( wxNullIcon ); win->SetIcon( wxNullIcon );
win->SetIcons( iconsOld ); 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 // wxTopLevelWindowGTK itself
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
EVT_SET_FOCUS(wxTopLevelWindowGTK::OnSetFocus)
END_EVENT_TABLE()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// InsertChild for wxTopLevelWindowGTK // InsertChild for wxTopLevelWindowGTK
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -388,7 +332,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
wxTopLevelWindows.Append( this ); wxTopLevelWindows.Append( this );
m_needParent = FALSE; m_needParent = FALSE;
if (!PreCreation( parent, pos, size ) || if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
{ {
@@ -426,10 +370,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
if (!name.IsEmpty()) if (!name.IsEmpty())
gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() ); 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_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); 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 ); GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
#endif #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 only represents the client area without toolbar and menubar
m_wxwindow = gtk_pizza_new(); m_wxwindow = gtk_pizza_new();
gtk_widget_show( m_wxwindow ); gtk_widget_show( m_wxwindow );
gtk_container_add( GTK_CONTAINER(m_mainWidget), 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 // we donm't allow the frame to get the focus as otherwise
// the frame will grab it at arbitrary focus changes // the frame will grab it at arbitrary focus changes
GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); 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)) if ((m_x != -1) || (m_y != -1))
gtk_widget_set_uposition( m_widget, m_x, m_y ); gtk_widget_set_uposition( m_widget, m_x, m_y );
gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height ); gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
// we cannot set MWM hints and icons before the widget has // we cannot set MWM hints and icons before the widget has
@@ -546,7 +478,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
wxTopLevelWindowGTK::~wxTopLevelWindowGTK() wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
{ {
m_isBeingDeleted = TRUE; m_isBeingDeleted = TRUE;
// it may also be GtkScrolledWindow in the case of an MDI child // it may also be GtkScrolledWindow in the case of an MDI child
if (GTK_IS_WINDOW(m_widget)) if (GTK_IS_WINDOW(m_widget))
{ {
@@ -830,9 +762,31 @@ void wxTopLevelWindowGTK::OnInternalIdle()
return; 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(); 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 // frame title/icon

View File

@@ -270,43 +270,6 @@ extern bool g_mainThreadLocked;
#else #else
# define DEBUG_MAIN_THREAD # define DEBUG_MAIN_THREAD
#endif #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 #else
#define DEBUG_MAIN_THREAD #define DEBUG_MAIN_THREAD
#endif // Debug #endif // Debug
@@ -385,15 +348,6 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win)
return (wxWindow *)NULL; 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 ) static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
{ {
// wxUniversal widgets draw the borders and scrollbars themselves // wxUniversal widgets draw the borders and scrollbars themselves
@@ -1749,6 +1703,21 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
// "focus_in_event" // "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, static gint gtk_window_focus_in_callback( GtkWidget *widget,
GdkEvent *WXUNUSED(event), GdkEvent *WXUNUSED(event),
wxWindow *win ) 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() ); printf( "OnSetFocus 2 from %s\n", win->GetName().c_str() );
#endif #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 #ifdef HAVE_XIM
if (win->m_ic) if (win->m_ic)
gdk_im_begin(win->m_ic, win->m_wxwindow->window); 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; // return TRUE;
} }
if ( DoSendFocusEvents(win) )
wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
event.SetEventObject( win );
if (win->GetEventHandler()->ProcessEvent( event ))
{ {
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" ); gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
return TRUE; return TRUE;
@@ -2906,15 +2866,6 @@ void wxWindowGTK::OnInternalIdle()
g_activeFrameLostFocus = FALSE; 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; wxCursor cursor = m_cursor;
if (g_globalCursor.Ok()) cursor = g_globalCursor; 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_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) )
{ {
if (!GTK_WIDGET_REALIZED(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; g_delayedFocus = this;
}
else else
{
wxLogTrace(_T("focus"),
_T("Setting focus to %s(%s)\n"),
GetClassInfo()->GetClassName(), GetLabel().c_str());
gtk_widget_grab_focus (m_widget); gtk_widget_grab_focus (m_widget);
}
} }
else if (GTK_IS_CONTAINER(m_widget)) else if (GTK_IS_CONTAINER(m_widget))
{ {
@@ -3294,6 +3257,8 @@ void wxWindowGTK::SetFocus()
// ? // ?
} }
} }
(void)DoSendFocusEvents(this);
} }
bool wxWindowGTK::AcceptsFocus() const bool wxWindowGTK::AcceptsFocus() const

View File

@@ -46,16 +46,6 @@ extern bool g_isIdle;
extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnDrag;
//-----------------------------------------------------------------------------
// debug
//-----------------------------------------------------------------------------
#ifdef __WXDEBUG__
extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxGtkNotebookPage // wxGtkNotebookPage
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -291,10 +281,6 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
m_widget = gtk_notebook_new(); 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_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page", gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",

View File

@@ -56,16 +56,6 @@ extern wxList wxPendingDelete;
extern int g_openDialogs; extern int g_openDialogs;
extern wxWindowGTK *g_delayedFocus; 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 // "focus" from m_window
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -154,18 +144,6 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WX
return FALSE; 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 // "realize" from m_widget
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -174,7 +152,8 @@ static wxWindow* wxGetTopLevelParent(wxWindow *win)
// so we do this directly after realization // so we do this directly after realization
static void static void
gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *win ) gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
wxTopLevelWindowGTK *win )
{ {
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
@@ -194,50 +173,11 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *
// reset the icon // reset the icon
wxIconBundle iconsOld = win->GetIcons(); wxIconBundle iconsOld = win->GetIcons();
wxIcon tmp = iconsOld.GetIcon( -1 ); // operator != is not-const if ( iconsOld.GetIcon(-1).Ok() )
if ( tmp != wxNullIcon )
{ {
// wxIconBundle icon( iconOld );
win->SetIcon( wxNullIcon ); win->SetIcon( wxNullIcon );
win->SetIcons( iconsOld ); 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 // wxTopLevelWindowGTK itself
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
EVT_SET_FOCUS(wxTopLevelWindowGTK::OnSetFocus)
END_EVENT_TABLE()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// InsertChild for wxTopLevelWindowGTK // InsertChild for wxTopLevelWindowGTK
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -388,7 +332,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
wxTopLevelWindows.Append( this ); wxTopLevelWindows.Append( this );
m_needParent = FALSE; m_needParent = FALSE;
if (!PreCreation( parent, pos, size ) || if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
{ {
@@ -426,10 +370,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
if (!name.IsEmpty()) if (!name.IsEmpty())
gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() ); 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_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); 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 ); GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
#endif #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 only represents the client area without toolbar and menubar
m_wxwindow = gtk_pizza_new(); m_wxwindow = gtk_pizza_new();
gtk_widget_show( m_wxwindow ); gtk_widget_show( m_wxwindow );
gtk_container_add( GTK_CONTAINER(m_mainWidget), 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 // we donm't allow the frame to get the focus as otherwise
// the frame will grab it at arbitrary focus changes // the frame will grab it at arbitrary focus changes
GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); 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)) if ((m_x != -1) || (m_y != -1))
gtk_widget_set_uposition( m_widget, m_x, m_y ); gtk_widget_set_uposition( m_widget, m_x, m_y );
gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height ); gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
// we cannot set MWM hints and icons before the widget has // we cannot set MWM hints and icons before the widget has
@@ -546,7 +478,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
wxTopLevelWindowGTK::~wxTopLevelWindowGTK() wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
{ {
m_isBeingDeleted = TRUE; m_isBeingDeleted = TRUE;
// it may also be GtkScrolledWindow in the case of an MDI child // it may also be GtkScrolledWindow in the case of an MDI child
if (GTK_IS_WINDOW(m_widget)) if (GTK_IS_WINDOW(m_widget))
{ {
@@ -830,9 +762,31 @@ void wxTopLevelWindowGTK::OnInternalIdle()
return; 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(); 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 // frame title/icon

View File

@@ -270,43 +270,6 @@ extern bool g_mainThreadLocked;
#else #else
# define DEBUG_MAIN_THREAD # define DEBUG_MAIN_THREAD
#endif #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 #else
#define DEBUG_MAIN_THREAD #define DEBUG_MAIN_THREAD
#endif // Debug #endif // Debug
@@ -385,15 +348,6 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win)
return (wxWindow *)NULL; 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 ) static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
{ {
// wxUniversal widgets draw the borders and scrollbars themselves // wxUniversal widgets draw the borders and scrollbars themselves
@@ -1749,6 +1703,21 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
// "focus_in_event" // "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, static gint gtk_window_focus_in_callback( GtkWidget *widget,
GdkEvent *WXUNUSED(event), GdkEvent *WXUNUSED(event),
wxWindow *win ) 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() ); printf( "OnSetFocus 2 from %s\n", win->GetName().c_str() );
#endif #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 #ifdef HAVE_XIM
if (win->m_ic) if (win->m_ic)
gdk_im_begin(win->m_ic, win->m_wxwindow->window); 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; // return TRUE;
} }
if ( DoSendFocusEvents(win) )
wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
event.SetEventObject( win );
if (win->GetEventHandler()->ProcessEvent( event ))
{ {
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" ); gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
return TRUE; return TRUE;
@@ -2906,15 +2866,6 @@ void wxWindowGTK::OnInternalIdle()
g_activeFrameLostFocus = FALSE; 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; wxCursor cursor = m_cursor;
if (g_globalCursor.Ok()) cursor = g_globalCursor; 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_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) )
{ {
if (!GTK_WIDGET_REALIZED(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; g_delayedFocus = this;
}
else else
{
wxLogTrace(_T("focus"),
_T("Setting focus to %s(%s)\n"),
GetClassInfo()->GetClassName(), GetLabel().c_str());
gtk_widget_grab_focus (m_widget); gtk_widget_grab_focus (m_widget);
}
} }
else if (GTK_IS_CONTAINER(m_widget)) else if (GTK_IS_CONTAINER(m_widget))
{ {
@@ -3294,6 +3257,8 @@ void wxWindowGTK::SetFocus()
// ? // ?
} }
} }
(void)DoSendFocusEvents(this);
} }
bool wxWindowGTK::AcceptsFocus() const bool wxWindowGTK::AcceptsFocus() const