fixes for the focus handling: don't set back to back set/kill focus events
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15714 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -210,10 +210,11 @@ public:
|
|||||||
bool m_isRadioButton:1; // faster than IS_KIND_OF
|
bool m_isRadioButton:1; // faster than IS_KIND_OF
|
||||||
bool m_isListBox:1; // faster than IS_KIND_OF
|
bool m_isListBox:1; // faster than IS_KIND_OF
|
||||||
bool m_isFrame:1; // faster than IS_KIND_OF
|
bool m_isFrame:1; // faster than IS_KIND_OF
|
||||||
bool m_acceptsFocus:1; // not wxStaticBox, not wxStaticBitmap etc.
|
bool m_acceptsFocus:1; // true if not static
|
||||||
bool m_isScrolling;
|
bool m_hasFocus:1; // true if == FindFocus()
|
||||||
bool m_clipPaintRegion; // TRUE after ScrollWindow()
|
bool m_isScrolling:1; // dragging scrollbar thumb?
|
||||||
bool m_queuedFullRedraw; // TRUE after DoMoveWindow
|
bool m_clipPaintRegion:1; // TRUE after ScrollWindow()
|
||||||
|
bool m_queuedFullRedraw:1; // TRUE after DoMoveWindow
|
||||||
|
|
||||||
// These are true if the style were set before the widget was realized
|
// These are true if the style were set before the widget was realized
|
||||||
// (typcally in the constructor) but the actual GTK style must not be set
|
// (typcally in the constructor) but the actual GTK style must not be set
|
||||||
|
@@ -210,10 +210,11 @@ public:
|
|||||||
bool m_isRadioButton:1; // faster than IS_KIND_OF
|
bool m_isRadioButton:1; // faster than IS_KIND_OF
|
||||||
bool m_isListBox:1; // faster than IS_KIND_OF
|
bool m_isListBox:1; // faster than IS_KIND_OF
|
||||||
bool m_isFrame:1; // faster than IS_KIND_OF
|
bool m_isFrame:1; // faster than IS_KIND_OF
|
||||||
bool m_acceptsFocus:1; // not wxStaticBox, not wxStaticBitmap etc.
|
bool m_acceptsFocus:1; // true if not static
|
||||||
bool m_isScrolling;
|
bool m_hasFocus:1; // true if == FindFocus()
|
||||||
bool m_clipPaintRegion; // TRUE after ScrollWindow()
|
bool m_isScrolling:1; // dragging scrollbar thumb?
|
||||||
bool m_queuedFullRedraw; // TRUE after DoMoveWindow
|
bool m_clipPaintRegion:1; // TRUE after ScrollWindow()
|
||||||
|
bool m_queuedFullRedraw:1; // TRUE after DoMoveWindow
|
||||||
|
|
||||||
// These are true if the style were set before the widget was realized
|
// These are true if the style were set before the widget was realized
|
||||||
// (typcally in the constructor) but the actual GTK style must not be set
|
// (typcally in the constructor) but the actual GTK style must not be set
|
||||||
|
@@ -274,6 +274,9 @@ extern bool g_mainThreadLocked;
|
|||||||
#define DEBUG_MAIN_THREAD
|
#define DEBUG_MAIN_THREAD
|
||||||
#endif // Debug
|
#endif // Debug
|
||||||
|
|
||||||
|
// the trace mask used for the focus debugging messages
|
||||||
|
#define TRACE_FOCUS _T("focus")
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// missing gdk functions
|
// missing gdk functions
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -1751,9 +1754,8 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
|
|||||||
g_focusWindowLast =
|
g_focusWindowLast =
|
||||||
g_focusWindow = win;
|
g_focusWindow = win;
|
||||||
|
|
||||||
#if 0
|
wxLogTrace(TRACE_FOCUS,
|
||||||
printf( "OnSetFocus 2 from %s\n", win->GetName().c_str() );
|
_T("%s: focus in"), win->GetName().c_str());
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_XIM
|
#ifdef HAVE_XIM
|
||||||
if (win->m_ic)
|
if (win->m_ic)
|
||||||
@@ -1793,11 +1795,18 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
|
|||||||
// return TRUE;
|
// return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// does the window itself think that it has the focus?
|
||||||
|
if ( !win->m_hasFocus )
|
||||||
|
{
|
||||||
|
// not yet, notify it
|
||||||
|
win->m_hasFocus = TRUE;
|
||||||
|
|
||||||
if ( DoSendFocusEvents(win) )
|
if ( DoSendFocusEvents(win) )
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1816,9 +1825,8 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk
|
|||||||
if (!win->m_hasVMT) return FALSE;
|
if (!win->m_hasVMT) return FALSE;
|
||||||
if (g_blockEventsOnDrag) return FALSE;
|
if (g_blockEventsOnDrag) return FALSE;
|
||||||
|
|
||||||
#if 0
|
wxLogTrace( TRACE_FOCUS,
|
||||||
wxLogDebug( wxT("OnKillFocus from %s"), win->GetName().c_str() );
|
_T("%s: focus out"), win->GetName().c_str() );
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( !g_activeFrameLostFocus && g_activeFrame )
|
if ( !g_activeFrameLostFocus && g_activeFrame )
|
||||||
{
|
{
|
||||||
@@ -1858,6 +1866,12 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk
|
|||||||
}
|
}
|
||||||
#endif // wxUSE_CARET
|
#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 )
|
||||||
|
{
|
||||||
|
win->m_hasFocus = FALSE;
|
||||||
|
|
||||||
wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
|
wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
|
||||||
event.SetEventObject( win );
|
event.SetEventObject( win );
|
||||||
|
|
||||||
@@ -1866,6 +1880,7 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk
|
|||||||
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
|
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -2318,8 +2333,7 @@ static void wxInsertChildInWindow( wxWindowGTK* parent, wxWindowGTK* child )
|
|||||||
|
|
||||||
wxWindow *wxGetActiveWindow()
|
wxWindow *wxGetActiveWindow()
|
||||||
{
|
{
|
||||||
// the cast is necessary when we compile in wxUniversal mode
|
return wxWindow::FindFocus();
|
||||||
return (wxWindow *)g_focusWindow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -2376,6 +2390,7 @@ void wxWindowGTK::Init()
|
|||||||
m_isListBox = FALSE;
|
m_isListBox = FALSE;
|
||||||
m_isFrame = FALSE;
|
m_isFrame = FALSE;
|
||||||
m_acceptsFocus = FALSE;
|
m_acceptsFocus = FALSE;
|
||||||
|
m_hasFocus = FALSE;
|
||||||
|
|
||||||
m_clipPaintRegion = FALSE;
|
m_clipPaintRegion = FALSE;
|
||||||
|
|
||||||
@@ -3227,7 +3242,13 @@ void wxWindowGTK::GetTextExtent( const wxString& string,
|
|||||||
|
|
||||||
void wxWindowGTK::SetFocus()
|
void wxWindowGTK::SetFocus()
|
||||||
{
|
{
|
||||||
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
|
||||||
|
|
||||||
|
if ( m_hasFocus )
|
||||||
|
{
|
||||||
|
// don't do anything if we already have focus
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_wxwindow)
|
if (m_wxwindow)
|
||||||
{
|
{
|
||||||
@@ -3242,16 +3263,19 @@ void wxWindowGTK::SetFocus()
|
|||||||
{
|
{
|
||||||
if (!GTK_WIDGET_REALIZED(m_widget))
|
if (!GTK_WIDGET_REALIZED(m_widget))
|
||||||
{
|
{
|
||||||
wxLogTrace(_T("focus"),
|
// we can't set the focus to the widget now so we remember that
|
||||||
_T("Delaying setting focus to %s(%s)\n"),
|
// 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());
|
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
||||||
|
|
||||||
g_delayedFocus = this;
|
g_delayedFocus = this;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxLogTrace(_T("focus"),
|
wxLogTrace(TRACE_FOCUS,
|
||||||
_T("Setting focus to %s(%s)\n"),
|
_T("Setting focus to %s(%s)"),
|
||||||
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
||||||
|
|
||||||
gtk_widget_grab_focus (m_widget);
|
gtk_widget_grab_focus (m_widget);
|
||||||
@@ -3263,11 +3287,11 @@ void wxWindowGTK::SetFocus()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ?
|
wxLogTrace(TRACE_FOCUS,
|
||||||
|
_T("Can't set focus to %s(%s)"),
|
||||||
|
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)DoSendFocusEvents((wxWindow*)this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWindowGTK::AcceptsFocus() const
|
bool wxWindowGTK::AcceptsFocus() const
|
||||||
|
@@ -274,6 +274,9 @@ extern bool g_mainThreadLocked;
|
|||||||
#define DEBUG_MAIN_THREAD
|
#define DEBUG_MAIN_THREAD
|
||||||
#endif // Debug
|
#endif // Debug
|
||||||
|
|
||||||
|
// the trace mask used for the focus debugging messages
|
||||||
|
#define TRACE_FOCUS _T("focus")
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// missing gdk functions
|
// missing gdk functions
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -1751,9 +1754,8 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
|
|||||||
g_focusWindowLast =
|
g_focusWindowLast =
|
||||||
g_focusWindow = win;
|
g_focusWindow = win;
|
||||||
|
|
||||||
#if 0
|
wxLogTrace(TRACE_FOCUS,
|
||||||
printf( "OnSetFocus 2 from %s\n", win->GetName().c_str() );
|
_T("%s: focus in"), win->GetName().c_str());
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_XIM
|
#ifdef HAVE_XIM
|
||||||
if (win->m_ic)
|
if (win->m_ic)
|
||||||
@@ -1793,11 +1795,18 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
|
|||||||
// return TRUE;
|
// return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// does the window itself think that it has the focus?
|
||||||
|
if ( !win->m_hasFocus )
|
||||||
|
{
|
||||||
|
// not yet, notify it
|
||||||
|
win->m_hasFocus = TRUE;
|
||||||
|
|
||||||
if ( DoSendFocusEvents(win) )
|
if ( DoSendFocusEvents(win) )
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1816,9 +1825,8 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk
|
|||||||
if (!win->m_hasVMT) return FALSE;
|
if (!win->m_hasVMT) return FALSE;
|
||||||
if (g_blockEventsOnDrag) return FALSE;
|
if (g_blockEventsOnDrag) return FALSE;
|
||||||
|
|
||||||
#if 0
|
wxLogTrace( TRACE_FOCUS,
|
||||||
wxLogDebug( wxT("OnKillFocus from %s"), win->GetName().c_str() );
|
_T("%s: focus out"), win->GetName().c_str() );
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( !g_activeFrameLostFocus && g_activeFrame )
|
if ( !g_activeFrameLostFocus && g_activeFrame )
|
||||||
{
|
{
|
||||||
@@ -1858,6 +1866,12 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk
|
|||||||
}
|
}
|
||||||
#endif // wxUSE_CARET
|
#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 )
|
||||||
|
{
|
||||||
|
win->m_hasFocus = FALSE;
|
||||||
|
|
||||||
wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
|
wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
|
||||||
event.SetEventObject( win );
|
event.SetEventObject( win );
|
||||||
|
|
||||||
@@ -1866,6 +1880,7 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk
|
|||||||
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
|
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -2318,8 +2333,7 @@ static void wxInsertChildInWindow( wxWindowGTK* parent, wxWindowGTK* child )
|
|||||||
|
|
||||||
wxWindow *wxGetActiveWindow()
|
wxWindow *wxGetActiveWindow()
|
||||||
{
|
{
|
||||||
// the cast is necessary when we compile in wxUniversal mode
|
return wxWindow::FindFocus();
|
||||||
return (wxWindow *)g_focusWindow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -2376,6 +2390,7 @@ void wxWindowGTK::Init()
|
|||||||
m_isListBox = FALSE;
|
m_isListBox = FALSE;
|
||||||
m_isFrame = FALSE;
|
m_isFrame = FALSE;
|
||||||
m_acceptsFocus = FALSE;
|
m_acceptsFocus = FALSE;
|
||||||
|
m_hasFocus = FALSE;
|
||||||
|
|
||||||
m_clipPaintRegion = FALSE;
|
m_clipPaintRegion = FALSE;
|
||||||
|
|
||||||
@@ -3227,7 +3242,13 @@ void wxWindowGTK::GetTextExtent( const wxString& string,
|
|||||||
|
|
||||||
void wxWindowGTK::SetFocus()
|
void wxWindowGTK::SetFocus()
|
||||||
{
|
{
|
||||||
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
|
||||||
|
|
||||||
|
if ( m_hasFocus )
|
||||||
|
{
|
||||||
|
// don't do anything if we already have focus
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_wxwindow)
|
if (m_wxwindow)
|
||||||
{
|
{
|
||||||
@@ -3242,16 +3263,19 @@ void wxWindowGTK::SetFocus()
|
|||||||
{
|
{
|
||||||
if (!GTK_WIDGET_REALIZED(m_widget))
|
if (!GTK_WIDGET_REALIZED(m_widget))
|
||||||
{
|
{
|
||||||
wxLogTrace(_T("focus"),
|
// we can't set the focus to the widget now so we remember that
|
||||||
_T("Delaying setting focus to %s(%s)\n"),
|
// 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());
|
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
||||||
|
|
||||||
g_delayedFocus = this;
|
g_delayedFocus = this;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxLogTrace(_T("focus"),
|
wxLogTrace(TRACE_FOCUS,
|
||||||
_T("Setting focus to %s(%s)\n"),
|
_T("Setting focus to %s(%s)"),
|
||||||
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
||||||
|
|
||||||
gtk_widget_grab_focus (m_widget);
|
gtk_widget_grab_focus (m_widget);
|
||||||
@@ -3263,11 +3287,11 @@ void wxWindowGTK::SetFocus()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ?
|
wxLogTrace(TRACE_FOCUS,
|
||||||
|
_T("Can't set focus to %s(%s)"),
|
||||||
|
GetClassInfo()->GetClassName(), GetLabel().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)DoSendFocusEvents((wxWindow*)this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWindowGTK::AcceptsFocus() const
|
bool wxWindowGTK::AcceptsFocus() const
|
||||||
|
Reference in New Issue
Block a user