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:
@@ -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();
|
||||||
@@ -1387,7 +1282,6 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context,
|
|||||||
ret = window->GetEventHandler()->ProcessEvent( event );
|
ret = window->GetEventHandler()->ProcessEvent( event );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
@@ -1387,7 +1282,6 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context,
|
|||||||
ret = window->GetEventHandler()->ProcessEvent( event );
|
ret = window->GetEventHandler()->ProcessEvent( event );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user