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,
// is the frame currently iconized?
bool m_isIconized;
+
+ DECLARE_EVENT_TABLE()
};
#endif // __GTKTOPLEVELH__
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,
// is the frame currently iconized?
bool m_isIconized;
+
+ DECLARE_EVENT_TABLE()
};
#endif // __GTKTOPLEVELH__
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 )
{
}
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"));
+ }
}
// ----------------------------------------------------------------------------
extern bool g_blockEventsOnDrag;
-//-----------------------------------------------------------------------------
-// debug
-//-----------------------------------------------------------------------------
-
-#ifdef __WXDEBUG__
-
-extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
-
-#endif
-
//-----------------------------------------------------------------------------
// wxGtkNotebookPage
//-----------------------------------------------------------------------------
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",
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
//-----------------------------------------------------------------------------
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
//-----------------------------------------------------------------------------
// 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();
// 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();
- }
}
//-----------------------------------------------------------------------------
// wxTopLevelWindowGTK itself
// ----------------------------------------------------------------------------
+BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
+ EVT_SET_FOCUS(wxTopLevelWindowGTK::OnSetFocus)
+END_EVENT_TABLE()
+
//-----------------------------------------------------------------------------
// InsertChild for wxTopLevelWindowGTK
//-----------------------------------------------------------------------------
wxTopLevelWindows.Append( this );
m_needParent = FALSE;
-
+
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
{
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 );
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 );
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
wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
{
m_isBeingDeleted = TRUE;
-
+
// it may also be GtkScrolledWindow in the case of an MDI child
if (GTK_IS_WINDOW(m_widget))
{
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
#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
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
// "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 )
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);
// 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;
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;
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))
{
// ?
}
}
+
+ (void)DoSendFocusEvents(this);
}
bool wxWindowGTK::AcceptsFocus() const
extern bool g_blockEventsOnDrag;
-//-----------------------------------------------------------------------------
-// debug
-//-----------------------------------------------------------------------------
-
-#ifdef __WXDEBUG__
-
-extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
-
-#endif
-
//-----------------------------------------------------------------------------
// wxGtkNotebookPage
//-----------------------------------------------------------------------------
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",
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
//-----------------------------------------------------------------------------
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
//-----------------------------------------------------------------------------
// 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();
// 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();
- }
}
//-----------------------------------------------------------------------------
// wxTopLevelWindowGTK itself
// ----------------------------------------------------------------------------
+BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
+ EVT_SET_FOCUS(wxTopLevelWindowGTK::OnSetFocus)
+END_EVENT_TABLE()
+
//-----------------------------------------------------------------------------
// InsertChild for wxTopLevelWindowGTK
//-----------------------------------------------------------------------------
wxTopLevelWindows.Append( this );
m_needParent = FALSE;
-
+
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
{
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 );
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 );
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
wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
{
m_isBeingDeleted = TRUE;
-
+
// it may also be GtkScrolledWindow in the case of an MDI child
if (GTK_IS_WINDOW(m_widget))
{
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
#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
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
// "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 )
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);
// 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;
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;
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))
{
// ?
}
}
+
+ (void)DoSendFocusEvents(this);
}
bool wxWindowGTK::AcceptsFocus() const