Changes allowing for proper KEY_DOWN and CHAR events for wxGTK2

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20627 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2003-05-14 19:25:18 +00:00
parent 44d511ad4d
commit 7c5e6fc68e
2 changed files with 132 additions and 344 deletions

View File

@@ -1065,7 +1065,7 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event,
return TRUE; return TRUE;
} }
#ifndef __WXGTK20__
static gint gtk_window_key_press_callback( GtkWidget *widget, static gint gtk_window_key_press_callback( GtkWidget *widget,
GdkEventKey *gdk_event, GdkEventKey *gdk_event,
wxWindow *win ) wxWindow *win )
@@ -1115,9 +1115,24 @@ static gint gtk_window_key_press_callback( GtkWidget *widget,
// will only be sent if it is not in an accelerator table. // will only be sent if it is not in an accelerator table.
if (!ret) if (!ret)
{ {
// Find key code for EVT_CHAR and EVT_CHAR_HOOK events long key_code;
KeySym keysym = gdk_event->keyval; KeySym keysym = gdk_event->keyval;
long key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */); #ifdef __WXGTK20__
// In GTK 2.0, we need to hand over the key event to an input method
// and the IM will emit a "commit" event containing the actual utf8
// character. In that case the EVT_CHAR events will be sent from
// there. But only do it this way for non-KeySym keys.
key_code = wxTranslateKeySymToWXKey(gdk_event->keyval, FALSE /* isChar */);
if ( !key_code && win->m_imContext )
{
gtk_im_context_filter_keypress ( (GtkIMContext*) win->m_imContext, gdk_event );
ret = TRUE;
}
else
#endif
{
// Find key code for EVT_CHAR and EVT_CHAR_HOOK events
key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */);
if ( !key_code ) if ( !key_code )
{ {
if ( gdk_event->length == 1 ) if ( gdk_event->length == 1 )
@@ -1154,6 +1169,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget,
} }
} }
} }
}
// win is a control: tab can be propagated up // win is a control: tab can be propagated up
if ( !ret && if ( !ret &&
@@ -1221,132 +1237,8 @@ static gint gtk_window_key_press_callback( GtkWidget *widget,
return FALSE; return FALSE;
} }
#endif
#ifdef __WXGTK20__ #ifdef __WXGTK20__
static gint gtk_window_key_press_callback( GtkWidget *widget,
GdkEventKey *gdk_event,
wxWindow *win )
{
if (g_isIdle)
wxapp_install_idle_handler();
if (!win->m_hasVMT)
return FALSE;
if (g_blockEventsOnDrag)
return FALSE;
bool ret = FALSE;
bool dont_use_IM = FALSE;
wxKeyEvent event( wxEVT_KEY_DOWN );
long keycode = wxTranslateKeySymToWXKey( gdk_event->keyval, FALSE );
if (keycode)
{
// We were able to decode the key press without
// any input method, so don't use it.
dont_use_IM = TRUE;
// now fill all the other fields
int x = 0;
int y = 0;
GdkModifierType state;
if (gdk_event->window)
gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
event.SetTimestamp( gdk_event->time );
event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0;
event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0;
event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0;
event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK) != 0;
event.m_keyCode = keycode;
event.m_scanCode = gdk_event->keyval;
event.m_rawCode = (wxUint32) gdk_event->keyval;
event.m_rawFlags = 0;
event.m_x = x;
event.m_y = y;
event.SetEventObject( win );
// send key down event
ret = win->GetEventHandler()->ProcessEvent( event );
if (!ret)
{
// Implement OnCharHook by checking ancesteror top level windows
wxWindow *parent = win;
while (parent && !parent->IsTopLevel())
parent = parent->GetParent();
if (parent)
{
event.SetEventType( wxEVT_CHAR_HOOK );
ret = parent->GetEventHandler()->ProcessEvent( event );
}
if (!ret)
{
event.SetEventType(wxEVT_CHAR);
ret = win->GetEventHandler()->ProcessEvent( event );
}
}
// win is a control: tab can be propagated up
if ( !ret &&
((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
win->GetParent() && (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
{
wxNavigationKeyEvent new_event;
new_event.SetEventObject( win->GetParent() );
// GDK reports GDK_ISO_Left_Tab for SHIFT-TAB
new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
// CTRL-TAB changes the (parent) window, i.e. switch notebook page
new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
new_event.SetCurrentFocus( win );
ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
}
if ( !ret &&
(gdk_event->keyval == GDK_Escape) )
{
wxWindow *winForCancel = win, *btnCancel = NULL;
while ( winForCancel )
{
btnCancel = winForCancel->FindWindow(wxID_CANCEL);
if ( btnCancel ) break;
if ( winForCancel->IsTopLevel() ) break;
winForCancel = winForCancel->GetParent();
}
if ( btnCancel )
{
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
event.SetEventObject(btnCancel);
ret = btnCancel->GetEventHandler()->ProcessEvent(event);
}
}
}
if (ret)
{
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
return TRUE;
}
if (!dont_use_IM && win->m_imContext)
{
// In GTK 2.0, we need to hand over the key
// event to an input method and the IM will
// emit a "commit" event containing the
// actual utf8 character.
gtk_im_context_filter_keypress ( (GtkIMContext*) win->m_imContext, gdk_event );
return TRUE;
}
return FALSE;
}
static void gtk_wxwindow_commit_cb (GtkIMContext *context, static void gtk_wxwindow_commit_cb (GtkIMContext *context,
const gchar *str, const gchar *str,
wxWindow *window) wxWindow *window)
@@ -1369,9 +1261,12 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context,
event.m_keyCode = uniChar; event.m_keyCode = uniChar;
#endif #endif
if (!ret)
{ // TODO: We still need to set all the extra attributes of the
// Implement OnCharHook by checking ancesteror top level windows // event, modifiers and such...
// Implement OnCharHook by checking ancestor top level windows
wxWindow *parent = window; wxWindow *parent = window;
while (parent && !parent->IsTopLevel()) while (parent && !parent->IsTopLevel())
parent = parent->GetParent(); parent = parent->GetParent();
@@ -1386,7 +1281,6 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context,
event.SetEventType(wxEVT_CHAR); event.SetEventType(wxEVT_CHAR);
ret = window->GetEventHandler()->ProcessEvent( event ); ret = window->GetEventHandler()->ProcessEvent( event );
} }
}
} }
#endif #endif

View File

@@ -1065,7 +1065,7 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event,
return TRUE; return TRUE;
} }
#ifndef __WXGTK20__
static gint gtk_window_key_press_callback( GtkWidget *widget, static gint gtk_window_key_press_callback( GtkWidget *widget,
GdkEventKey *gdk_event, GdkEventKey *gdk_event,
wxWindow *win ) wxWindow *win )
@@ -1115,9 +1115,24 @@ static gint gtk_window_key_press_callback( GtkWidget *widget,
// will only be sent if it is not in an accelerator table. // will only be sent if it is not in an accelerator table.
if (!ret) if (!ret)
{ {
// Find key code for EVT_CHAR and EVT_CHAR_HOOK events long key_code;
KeySym keysym = gdk_event->keyval; KeySym keysym = gdk_event->keyval;
long key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */); #ifdef __WXGTK20__
// In GTK 2.0, we need to hand over the key event to an input method
// and the IM will emit a "commit" event containing the actual utf8
// character. In that case the EVT_CHAR events will be sent from
// there. But only do it this way for non-KeySym keys.
key_code = wxTranslateKeySymToWXKey(gdk_event->keyval, FALSE /* isChar */);
if ( !key_code && win->m_imContext )
{
gtk_im_context_filter_keypress ( (GtkIMContext*) win->m_imContext, gdk_event );
ret = TRUE;
}
else
#endif
{
// Find key code for EVT_CHAR and EVT_CHAR_HOOK events
key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */);
if ( !key_code ) if ( !key_code )
{ {
if ( gdk_event->length == 1 ) if ( gdk_event->length == 1 )
@@ -1154,6 +1169,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget,
} }
} }
} }
}
// win is a control: tab can be propagated up // win is a control: tab can be propagated up
if ( !ret && if ( !ret &&
@@ -1221,132 +1237,8 @@ static gint gtk_window_key_press_callback( GtkWidget *widget,
return FALSE; return FALSE;
} }
#endif
#ifdef __WXGTK20__ #ifdef __WXGTK20__
static gint gtk_window_key_press_callback( GtkWidget *widget,
GdkEventKey *gdk_event,
wxWindow *win )
{
if (g_isIdle)
wxapp_install_idle_handler();
if (!win->m_hasVMT)
return FALSE;
if (g_blockEventsOnDrag)
return FALSE;
bool ret = FALSE;
bool dont_use_IM = FALSE;
wxKeyEvent event( wxEVT_KEY_DOWN );
long keycode = wxTranslateKeySymToWXKey( gdk_event->keyval, FALSE );
if (keycode)
{
// We were able to decode the key press without
// any input method, so don't use it.
dont_use_IM = TRUE;
// now fill all the other fields
int x = 0;
int y = 0;
GdkModifierType state;
if (gdk_event->window)
gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
event.SetTimestamp( gdk_event->time );
event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0;
event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0;
event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0;
event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK) != 0;
event.m_keyCode = keycode;
event.m_scanCode = gdk_event->keyval;
event.m_rawCode = (wxUint32) gdk_event->keyval;
event.m_rawFlags = 0;
event.m_x = x;
event.m_y = y;
event.SetEventObject( win );
// send key down event
ret = win->GetEventHandler()->ProcessEvent( event );
if (!ret)
{
// Implement OnCharHook by checking ancesteror top level windows
wxWindow *parent = win;
while (parent && !parent->IsTopLevel())
parent = parent->GetParent();
if (parent)
{
event.SetEventType( wxEVT_CHAR_HOOK );
ret = parent->GetEventHandler()->ProcessEvent( event );
}
if (!ret)
{
event.SetEventType(wxEVT_CHAR);
ret = win->GetEventHandler()->ProcessEvent( event );
}
}
// win is a control: tab can be propagated up
if ( !ret &&
((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
win->GetParent() && (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
{
wxNavigationKeyEvent new_event;
new_event.SetEventObject( win->GetParent() );
// GDK reports GDK_ISO_Left_Tab for SHIFT-TAB
new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
// CTRL-TAB changes the (parent) window, i.e. switch notebook page
new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
new_event.SetCurrentFocus( win );
ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
}
if ( !ret &&
(gdk_event->keyval == GDK_Escape) )
{
wxWindow *winForCancel = win, *btnCancel = NULL;
while ( winForCancel )
{
btnCancel = winForCancel->FindWindow(wxID_CANCEL);
if ( btnCancel ) break;
if ( winForCancel->IsTopLevel() ) break;
winForCancel = winForCancel->GetParent();
}
if ( btnCancel )
{
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
event.SetEventObject(btnCancel);
ret = btnCancel->GetEventHandler()->ProcessEvent(event);
}
}
}
if (ret)
{
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
return TRUE;
}
if (!dont_use_IM && win->m_imContext)
{
// In GTK 2.0, we need to hand over the key
// event to an input method and the IM will
// emit a "commit" event containing the
// actual utf8 character.
gtk_im_context_filter_keypress ( (GtkIMContext*) win->m_imContext, gdk_event );
return TRUE;
}
return FALSE;
}
static void gtk_wxwindow_commit_cb (GtkIMContext *context, static void gtk_wxwindow_commit_cb (GtkIMContext *context,
const gchar *str, const gchar *str,
wxWindow *window) wxWindow *window)
@@ -1369,9 +1261,12 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context,
event.m_keyCode = uniChar; event.m_keyCode = uniChar;
#endif #endif
if (!ret)
{ // TODO: We still need to set all the extra attributes of the
// Implement OnCharHook by checking ancesteror top level windows // event, modifiers and such...
// Implement OnCharHook by checking ancestor top level windows
wxWindow *parent = window; wxWindow *parent = window;
while (parent && !parent->IsTopLevel()) while (parent && !parent->IsTopLevel())
parent = parent->GetParent(); parent = parent->GetParent();
@@ -1386,7 +1281,6 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context,
event.SetEventType(wxEVT_CHAR); event.SetEventType(wxEVT_CHAR);
ret = window->GetEventHandler()->ProcessEvent( event ); ret = window->GetEventHandler()->ProcessEvent( event );
} }
}
} }
#endif #endif