simplified and cleaned up wxGTK's focus handling

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@52473 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík 2008-03-14 01:10:43 +00:00
parent fe828a03f4
commit bd2e08d065
9 changed files with 226 additions and 325 deletions

View File

@ -94,8 +94,6 @@ public:
// From wxComboBoxBase:
virtual int GetCurrentSelection() const;
virtual void SetFocus();
void OnChar( wxKeyEvent &event );
// Standard event handling

View File

@ -128,17 +128,12 @@ public:
// implementation
// --------------
void SetFocus();
void GtkDisableEvents();
void GtkEnableEvents();
#if wxUSE_TOOLTIPS
void ApplyToolTip( GtkTooltips *tips, const gchar *tip );
#endif // wxUSE_TOOLTIPS
virtual void OnInternalIdle();
bool m_hasFocus,
m_lostFocus;
wxRadioBoxButtonsInfoList m_buttonsInfo;
protected:
@ -151,12 +146,11 @@ protected:
virtual void DoApplyWidgetStyle(GtkRcStyle *style);
virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
virtual bool GTKNeedsToFilterSameWindowFocus() const { return true; }
virtual bool GTKWidgetNeedsMnemonic() const;
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
// common part of all ctors
void Init();
private:
DECLARE_DYNAMIC_CLASS(wxRadioBox)
};

View File

@ -186,7 +186,17 @@ public:
GdkWindow* GTKGetDrawingWindow() const;
bool GTKHandleFocusIn();
bool GTKHandleFocusOut();
void GTKHandleFocusOutNoDeferring();
static void GTKHandleDeferredFocusOut();
protected:
// for controls composed of multiple GTK widgets, return true to eliminate
// spurious focus events if the focus changes between GTK+ children within
// the same wxWindow
virtual bool GTKNeedsToFilterSameWindowFocus() const { return false; }
// Override GTKWidgetNeedsMnemonic and return true if your
// needs to set its mnemonic widget, such as for a
// GtkLabel for wxStaticText, then do the actual
@ -206,12 +216,6 @@ protected:
// Check if the given window makes part of this widget
bool GTKIsOwnWindow(GdkWindow *window) const;
// Set the focus to this window if its setting was delayed because the
// widget hadn't been realized when SetFocus() was called
//
// Return true if focus was set to us, false if nothing was done
bool GTKSetDelayedFocusIfNeeded();
public:
// Returns the default context which usually is anti-aliased
PangoContext *GtkGetPangoDefaultContext();
@ -287,7 +291,6 @@ public:
bool m_noExpose:1; // wxGLCanvas has its own redrawing
bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size"
bool m_hasVMT:1;
bool m_hasFocus:1; // true if == FindFocus()
bool m_isScrolling:1; // dragging scrollbar thumb?
bool m_clipPaintRegion:1; // true after ScrollWindow()
wxRegion m_nativeUpdateRegion; // not transformed for RTL

View File

@ -170,17 +170,6 @@ wxComboBox::~wxComboBox()
delete m_strings;
}
void wxComboBox::SetFocus()
{
if ( m_hasFocus )
{
// don't do anything if we already have focus
return;
}
gtk_widget_grab_focus( m_focusWidget );
}
int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items,
unsigned int pos,
void **clientData, wxClientDataType type)

View File

@ -295,8 +295,6 @@ void wxControl::OnInternalIdle()
if ( GTK_WIDGET_REALIZED(m_widget) )
{
GTKUpdateCursor();
GTKSetDelayedFocusIfNeeded();
}
if ( wxUpdateUIEvent::CanUpdate(this) )

View File

@ -258,7 +258,6 @@ IMPLEMENT_DYNAMIC_CLASS( wxGtkFileCtrl, wxControl )
void wxGtkFileCtrl::Init()
{
m_hasFocus = false;
m_checkNextSelEvent = false;
// ignore the first folder change event which is fired upon startup.

View File

@ -138,46 +138,33 @@ static gint gtk_radiobox_keypress_callback( GtkWidget *widget, GdkEventKey *gdk_
}
extern "C" {
static gint gtk_radiobutton_focus_in( GtkWidget * WXUNUSED(widget),
GdkEvent *WXUNUSED(event),
wxRadioBox *win )
static gint gtk_radiobutton_focus_out( GtkWidget * WXUNUSED(widget),
GdkEventFocus *WXUNUSED(event),
wxRadioBox *win )
{
if ( win->m_lostFocus )
{
// no, we didn't really lose it
win->m_lostFocus = FALSE;
}
else if ( !win->m_hasFocus )
{
win->m_hasFocus = true;
wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
event.SetEventObject( win );
// never stop the signal emission, it seems to break the kbd handling
// inside the radiobox
(void)win->HandleWindowEvent( event );
}
// NB: This control is composed of several GtkRadioButton widgets and
// when focus changes from one of them to another in the same
// wxRadioBox, we get a focus-out event followed by focus-in for
// another GtkRadioButton owned by the same control. We don't want
// to generate two spurious wxEVT_SET_FOCUS events in this case,
// so we defer sending wx events until idle time.
win->GTKHandleFocusOut();
// never stop the signal emission, it seems to break the kbd handling
// inside the radiobox
return FALSE;
}
}
extern "C" {
static gint gtk_radiobutton_focus_out( GtkWidget * WXUNUSED(widget),
GdkEvent *WXUNUSED(event),
wxRadioBox *win )
static gint gtk_radiobutton_focus_in( GtkWidget * WXUNUSED(widget),
GdkEventFocus *WXUNUSED(event),
wxRadioBox *win )
{
// wxASSERT_MSG( win->m_hasFocus, _T("got focus out without any focus in?") );
// Replace with a warning, else we dump core a lot!
// if (!win->m_hasFocus)
// wxLogWarning(_T("Radiobox got focus out without any focus in.") );
// we might have lost the focus, but may be not - it may have just gone to
// another button in the same radiobox, so we'll check for it in the next
// idle iteration (leave m_hasFocus == true for now)
win->m_lostFocus = true;
win->GTKHandleFocusIn();
// never stop the signal emission, it seems to break the kbd handling
// inside the radiobox
return FALSE;
}
}
@ -210,12 +197,6 @@ static void gtk_radiobutton_size_allocate( GtkWidget *widget,
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox,wxControl)
void wxRadioBox::Init()
{
m_hasFocus =
m_lostFocus = false;
}
bool wxRadioBox::Create( wxWindow *parent, wxWindowID id,
const wxString& title,
const wxPoint &pos, const wxSize &size,
@ -372,25 +353,6 @@ bool wxRadioBox::Show( bool show )
return true;
}
void wxRadioBox::SetFocus()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
if (m_buttonsInfo.GetCount() == 0) return;
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
while (node)
{
GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->GetData()->button );
if (button->active)
{
gtk_widget_grab_focus( GTK_WIDGET(button) );
return;
}
node = node->GetNext();
}
}
void wxRadioBox::SetSelection( int n )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
@ -646,22 +608,6 @@ GdkWindow *wxRadioBox::GTKGetWindow(wxArrayGdkWindows& windows) const
return NULL;
}
void wxRadioBox::OnInternalIdle()
{
wxControl::OnInternalIdle();
if ( m_lostFocus )
{
m_hasFocus = false;
m_lostFocus = false;
wxFocusEvent event( wxEVT_KILL_FOCUS, GetId() );
event.SetEventObject( this );
(void)HandleWindowEvent( event );
}
}
// static
wxVisualAttributes
wxRadioBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))

View File

@ -57,8 +57,6 @@
// this is incremented while a modal dialog is shown
int wxOpenModalDialogsCount = 0;
extern wxWindowGTK *g_delayedFocus;
// the frame that is currently active (i.e. its child has focus). It is
// used to generate wxActivateEvents
static wxTopLevelWindowGTK *g_activeFrame = (wxTopLevelWindowGTK*) NULL;
@ -1032,22 +1030,6 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
void wxTopLevelWindowGTK::OnInternalIdle()
{
// set the focus if not done yet and if we can already do it
if ( GTK_WIDGET_REALIZED(m_wxwindow) )
{
if ( g_delayedFocus &&
wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this )
{
wxLogTrace(_T("focus"),
_T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
g_delayedFocus->GetClassInfo()->GetClassName(),
g_delayedFocus->GetLabel().c_str());
g_delayedFocus->SetFocus();
g_delayedFocus = NULL;
}
}
wxWindow::OnInternalIdle();
// Synthetize activate events.

View File

@ -185,11 +185,13 @@ extern wxCursor g_globalCursor;
static wxWindowGTK *g_captureWindow = (wxWindowGTK*) NULL;
static bool g_captureWindowHasMouse = false;
wxWindowGTK *g_focusWindow = (wxWindowGTK*) NULL;
// The window that currently has focus or is scheduled to get it in the next
// event loop iteration
static wxWindowGTK *gs_focusWindow = NULL;
// If a window get the focus set but has not been realized
// yet, defer setting the focus to idle time.
wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL;
// the window that has deferred focus-out event pending, if any (see
// GTKAddDeferredFocusOut() for details)
static wxWindowGTK *gs_deferredFocusOut = NULL;
// global variables because GTK+ DnD want to have the
// mouse event that caused it
@ -225,31 +227,6 @@ gdk_window_warp_pointer (GdkWindow *window,
}
}
//-----------------------------------------------------------------------------
// local code (see below)
//-----------------------------------------------------------------------------
// returns the child of win which currently has focus or NULL if not found
static wxWindow *wxFindFocusedChild(wxWindowGTK *win)
{
wxWindow *winFocus = wxWindowGTK::FindFocus();
if ( !winFocus )
return (wxWindow *)NULL;
if ( winFocus == win )
return (wxWindow *)win;
for ( wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
node;
node = node->GetNext() )
{
wxWindow *child = wxFindFocusedChild(node->GetData());
if ( child )
return child;
}
return (wxWindow *)NULL;
}
//-----------------------------------------------------------------------------
// "size_request" of m_widget
@ -1251,21 +1228,6 @@ wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventCrossing)
if ( rc != -1 ) \
return rc
// 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->HandleWindowEvent(eventChildFocus);
wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
eventFocus.SetEventObject(win);
return win->HandleWindowEvent(eventFocus);
}
// all event handlers must have C linkage as they're called from GTK+ C code
extern "C"
{
@ -1410,7 +1372,7 @@ gtk_window_button_press_callback( GtkWidget *widget,
return TRUE;
if ((event_type == wxEVT_LEFT_DOWN) && !win->IsOfStandardClass() &&
(g_focusWindow != win) /* && win->IsFocusable() */)
(gs_focusWindow != win) /* && win->IsFocusable() */)
{
win->SetFocus();
}
@ -1610,44 +1572,9 @@ static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win)
static gboolean
gtk_window_focus_in_callback( GtkWidget * WXUNUSED(widget),
GdkEventFocus *WXUNUSED(event),
wxWindow *win )
wxWindowGTK *win )
{
if (win->m_imData)
gtk_im_context_focus_in(win->m_imData->context);
g_focusWindow = win;
wxLogTrace(TRACE_FOCUS,
_T("%s: focus in"), win->GetName().c_str());
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = win->GetCaret();
if ( caret )
{
caret->OnSetFocus();
}
#endif // wxUSE_CARET
gboolean ret = FALSE;
// does the window itself think that it has the focus?
if ( !win->m_hasFocus )
{
// not yet, notify it
win->m_hasFocus = true;
(void)DoSendFocusEvents(win);
ret = TRUE;
}
// Disable default focus handling for custom windows
// since the default GTK+ handler issues a repaint
if (win->m_wxwindow)
return ret;
return FALSE;
return win->GTKHandleFocusIn();
}
//-----------------------------------------------------------------------------
@ -1659,53 +1586,13 @@ gtk_window_focus_out_callback( GtkWidget * WXUNUSED(widget),
GdkEventFocus * WXUNUSED(gdk_event),
wxWindowGTK *win )
{
if (win->m_imData)
gtk_im_context_focus_out(win->m_imData->context);
wxLogTrace( TRACE_FOCUS,
_T("%s: focus out"), win->GetName().c_str() );
wxWindowGTK *winFocus = wxFindFocusedChild(win);
if ( winFocus )
win = winFocus;
g_focusWindow = (wxWindowGTK *)NULL;
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = win->GetCaret();
if ( caret )
{
caret->OnKillFocus();
}
#endif // wxUSE_CARET
// don't send the window a kill focus event if it thinks that it doesn't
// have focus already
if ( win->m_hasFocus )
{
// the event handler might delete the window when it loses focus, so
// check whether this is a custom window before calling it
const bool has_wxwindow = win->m_wxwindow != NULL;
win->m_hasFocus = false;
wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
event.SetEventObject( win );
(void)win->GTKProcessEvent( event );
// Disable default focus handling for custom windows
// since the default GTK+ handler issues a repaint
if ( has_wxwindow )
return TRUE;
}
// continue with normal processing
return FALSE;
return win->GTKHandleFocusOut();
}
//-----------------------------------------------------------------------------
// "focus"
//-----------------------------------------------------------------------------
static gboolean
wx_window_focus_callback(GtkWidget *widget,
GtkDirectionType WXUNUSED(direction),
@ -2005,7 +1892,7 @@ public:
wxWindow *wxWindowBase::DoFindFocus()
{
// the cast is necessary when we compile in wxUniversal mode
return (wxWindow *)g_focusWindow;
return wx_static_cast(wxWindow*, gs_focusWindow);
}
//-----------------------------------------------------------------------------
@ -2117,8 +2004,6 @@ void wxWindowGTK::Init()
m_insertCallback = wxInsertChildInWindow;
m_hasFocus = false;
m_clipPaintRegion = false;
m_needsStyleChange = false;
@ -2251,11 +2136,11 @@ wxWindowGTK::~wxWindowGTK()
{
SendDestroyEvent();
if (g_focusWindow == this)
g_focusWindow = NULL;
if (gs_focusWindow == this)
gs_focusWindow = NULL;
if ( g_delayedFocus == this )
g_delayedFocus = NULL;
if ( gs_deferredFocusOut == this )
gs_deferredFocusOut = NULL;
m_isBeingDeleted = true;
m_hasVMT = false;
@ -2614,6 +2499,9 @@ bool wxWindowGTK::GtkShowFromOnIdle()
void wxWindowGTK::OnInternalIdle()
{
if ( gs_deferredFocusOut )
GTKHandleDeferredFocusOut();
// Check if we have to show window now
if (GtkShowFromOnIdle()) return;
@ -2979,90 +2867,194 @@ void wxWindowGTK::GetTextExtent( const wxString& string,
g_object_unref (layout);
}
bool wxWindowGTK::GTKSetDelayedFocusIfNeeded()
{
if ( g_delayedFocus == this )
{
if ( GTK_WIDGET_REALIZED(m_widget) )
{
gtk_widget_grab_focus(m_widget);
g_delayedFocus = NULL;
return true;
bool wxWindowGTK::GTKHandleFocusIn()
{
// Disable default focus handling for custom windows since the default GTK+
// handler issues a repaint
const bool retval = m_wxwindow ? true : false;
// NB: if there's still unprocessed deferred focus-out event (see
// GTKHandleFocusOut() for explanation), we need to process it first so
// that the order of focus events -- focus-out first, then focus-in
// elsewhere -- is preserved
if ( gs_deferredFocusOut )
{
if ( GTKNeedsToFilterSameWindowFocus() &&
gs_deferredFocusOut == this )
{
// GTK+ focus changed from this wxWindow back to itself, so don't
// emit any events at all
wxLogTrace(TRACE_FOCUS,
"filtered out spurious focus change within %s(%p, %s)",
GetClassInfo()->GetClassName(), this, GetLabel());
gs_deferredFocusOut = NULL;
return retval;
}
// otherwise we need to send focus-out first
wxASSERT_MSG ( gs_deferredFocusOut != this,
"GTKHandleFocusIn(GTKFocus_Normal) called even though focus changed back to itself - derived class should handle this" );
GTKHandleDeferredFocusOut();
}
return false;
wxLogTrace(TRACE_FOCUS,
"handling focus_in event for %s(%p, %s)",
GetClassInfo()->GetClassName(), this, GetLabel());
if (m_imData)
gtk_im_context_focus_in(m_imData->context);
// NB: SetFocus() does this assignment too, but not all focus changes
// originate from SetFocus() call
gs_focusWindow = this;
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = GetCaret();
if ( caret )
{
caret->OnSetFocus();
}
#endif // wxUSE_CARET
// Notify the parent keeping track of focus for the kbd navigation
// purposes that we got it.
wxChildFocusEvent eventChildFocus(this);
GTKProcessEvent(eventChildFocus);
wxFocusEvent eventFocus(wxEVT_SET_FOCUS, GetId());
eventFocus.SetEventObject(this);
GTKProcessEvent(eventFocus);
return retval;
}
bool wxWindowGTK::GTKHandleFocusOut()
{
// Disable default focus handling for custom windows since the default GTK+
// handler issues a repaint
const bool retval = m_wxwindow ? true : false;
// NB: If a control is composed of several GtkWidgets and when focus
// changes from one of them to another within the same wxWindow, we get
// a focus-out event followed by focus-in for another GtkWidget owned
// by the same wx control. We don't want to generate two spurious
// wxEVT_SET_FOCUS events in this case, so we defer sending wx events
// from GTKHandleFocusOut() until we know for sure it's not coming back
// (i.e. in GTKHandleFocusIn() or at idle time).
if ( GTKNeedsToFilterSameWindowFocus() )
{
wxASSERT_MSG( gs_deferredFocusOut == NULL,
"deferred focus out event already pending" );
wxLogTrace(TRACE_FOCUS,
"deferring focus_out event for %s(%p, %s)",
GetClassInfo()->GetClassName(), this, GetLabel());
gs_deferredFocusOut = this;
return retval;
}
GTKHandleFocusOutNoDeferring();
return retval;
}
void wxWindowGTK::GTKHandleFocusOutNoDeferring()
{
wxLogTrace(TRACE_FOCUS,
"handling focus_out event for %s(%p, %s)",
GetClassInfo()->GetClassName(), this, GetLabel());
if (m_imData)
gtk_im_context_focus_out(m_imData->context);
if ( gs_focusWindow != this )
{
// Something is terribly wrong, gs_focusWindow is out of sync with the
// real focus. We will reset it to NULL anyway, because after this
// focus-out event is handled, one of the following with happen:
//
// * either focus will go out of the app altogether, in which case
// gs_focusWindow _should_ be NULL
//
// * or it goes to another control, in which case focus-in event will
// follow immediately and it will set gs_focusWindow to the right
// value
wxLogDebug("window %s(%p, %s) lost focus even though it didn't have it",
GetClassInfo()->GetClassName(), this, GetLabel());
}
gs_focusWindow = NULL;
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = GetCaret();
if ( caret )
{
caret->OnKillFocus();
}
#endif // wxUSE_CARET
wxFocusEvent event( wxEVT_KILL_FOCUS, GetId() );
event.SetEventObject( this );
GTKProcessEvent( event );
}
/*static*/
void wxWindowGTK::GTKHandleDeferredFocusOut()
{
// NB: See GTKHandleFocusOut() for explanation. This function is called
// from either GTKHandleFocusIn() or OnInternalIdle() to process
// deferred event.
if ( gs_deferredFocusOut )
{
wxWindowGTK *win = gs_deferredFocusOut;
gs_deferredFocusOut = NULL;
wxLogTrace(TRACE_FOCUS,
"processing deferred focus_out event for %s(%p, %s)",
win->GetClassInfo()->GetClassName(), win, win->GetLabel());
win->GTKHandleFocusOutNoDeferring();
}
}
void wxWindowGTK::SetFocus()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
if ( m_hasFocus )
{
// don't do anything if we already have focus
return;
}
if (m_wxwindow)
{
// wxWindow::SetFocus() should really set the focus to
// this control, whatever the flags are
if (!GTK_WIDGET_CAN_FOCUS(m_wxwindow))
GTK_WIDGET_SET_FLAGS(m_wxwindow, GTK_CAN_FOCUS);
// Setting "physical" focus is not immediate in GTK+ and while
// gtk_widget_is_focus ("determines if the widget is the focus widget
// within its toplevel", i.e. returns true for one widget per TLW, not
// globally) returns true immediately after grabbing focus,
// GTK_WIDGET_HAS_FOCUS (which returns true only for the one widget that
// has focus at the moment) takes affect only after the window is shown
// (if it was hidden at the moment of the call) or at the next event loop
// iteration.
//
// Because we want to FindFocus() call immediately following
// foo->SetFocus() to return foo, we have to keep track of "pending" focus
// ourselves.
gs_focusWindow = this;
if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow))
{
gtk_widget_grab_focus (m_wxwindow);
}
GtkWidget *widget = m_wxwindow ? m_wxwindow : m_focusWidget;
if ( GTK_IS_CONTAINER(widget) &&
!GTK_WIDGET_CAN_FOCUS(widget) )
{
wxLogTrace(TRACE_FOCUS,
_T("Setting focus to a child of %s(%p, %s)"),
GetClassInfo()->GetClassName(), this, GetLabel().c_str());
gtk_widget_child_focus(widget, GTK_DIR_TAB_FORWARD);
}
else
{
// wxWindow::SetFocus() should really set the focus to
// this control, whatever the flags are
if (!GTK_WIDGET_CAN_FOCUS(m_widget))
GTK_WIDGET_SET_FLAGS(m_widget, GTK_CAN_FOCUS);
if (GTK_IS_CONTAINER(m_widget))
{
if (GTK_IS_RADIO_BUTTON(m_widget))
{
gtk_widget_grab_focus (m_widget);
return;
}
gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD );
}
else
if (GTK_WIDGET_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) )
{
if (!GTK_WIDGET_REALIZED(m_widget))
{
// we can't set the focus to the widget now so we remember that
// it should be focused and will do it later, during the idle
// time, as soon as we can
wxLogTrace(TRACE_FOCUS,
_T("Delaying setting focus to %s(%s)"),
GetClassInfo()->GetClassName(), GetLabel().c_str());
g_delayedFocus = this;
}
else
{
wxLogTrace(TRACE_FOCUS,
_T("Setting focus to %s(%s)"),
GetClassInfo()->GetClassName(), GetLabel().c_str());
gtk_widget_grab_focus (m_widget);
}
}
else
{
wxLogTrace(TRACE_FOCUS,
_T("Can't set focus to %s(%s)"),
GetClassInfo()->GetClassName(), GetLabel().c_str());
}
wxLogTrace(TRACE_FOCUS,
_T("Setting focus to %s(%p, %s)"),
GetClassInfo()->GetClassName(), this, GetLabel().c_str());
gtk_widget_grab_focus(widget);
}
}