X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f17393f19902b4fd15ad20068af37aa6bbefd952..b53e38fed51f88117e571676b3d12d7da86310f0:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 16d1c58200..5792525800 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -486,10 +486,21 @@ static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNU static long map_to_unmodified_wx_keysym( GdkEventKey *event ) { + // VZ: it seems that GDK_KEY_RELEASE event doesn't set event->string + // but only event->keyval which is quite useless to us, so remember + // the last character from GDK_KEY_PRESS and resue it as last resort + // + // NB: should be MT-neutral as always called from main thread only + static struct + { + KeySym keysym; + long keycode; + } s_lastKeyPress = { 0, 0 }; + KeySym keysym = event->keyval; long key_code; - switch (keysym) + switch ( keysym ) { case GDK_Shift_L: case GDK_Shift_R: key_code = WXK_SHIFT; break; @@ -581,16 +592,43 @@ static long map_to_unmodified_wx_keysym( GdkEventKey *event ) case GDK_F11: key_code = WXK_F11; break; case GDK_F12: key_code = WXK_F12; break; default: - if ( (keysym & 0xFF) == keysym ) + { + // do we have the translation? + if ( event->length == 1 ) { - guint upper = gdk_keyval_to_upper( (guint)keysym ); - key_code = upper ? upper : keysym; + keysym = (KeySym)event->string[0]; } - else + else if ( (keysym & 0xFF) != keysym ) { - // unknown key code - key_code = 0; + // non ASCII key, what to do? + + if ( event->type == GDK_KEY_RELEASE ) + { + // reuse the one from the last keypress if any + if ( keysym == s_lastKeyPress.keysym ) + { + key_code = s_lastKeyPress.keycode; + + // skip "return 0" + break; + } + } + + // ignore this one, we don't know it + return 0; } + //else: ASCII key, ok + + guint upper = gdk_keyval_to_upper( (guint)keysym ); + key_code = upper ? upper : keysym; + + if ( event->type == GDK_KEY_PRESS ) + { + // remember it to be reused below later + s_lastKeyPress.keysym = keysym; + s_lastKeyPress.keycode = key_code; + } + } } return key_code; @@ -683,7 +721,6 @@ static long map_to_wx_keysym( GdkEventKey *event ) case GDK_F11: key_code = WXK_F11; break; case GDK_F12: key_code = WXK_F12; break; default: - { if (event->length == 1) { key_code = (unsigned char)*event->string; @@ -692,7 +729,6 @@ static long map_to_wx_keysym( GdkEventKey *event ) { key_code = (guint)keysym; } - } } return key_code; @@ -1713,17 +1749,18 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, } #endif // wxUSE_CARET - wxWindowGTK *active = wxGetTopLevelParent(win); if ( active != g_activeFrame ) { if ( g_activeFrame ) { + wxLogTrace(wxT("activate"), wxT("Deactivating frame %p (from focus_in)"), g_activeFrame); wxActivateEvent event(wxEVT_ACTIVATE, FALSE, g_activeFrame->GetId()); event.SetEventObject(g_activeFrame); g_activeFrame->GetEventHandler()->ProcessEvent(event); } + wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), active); g_activeFrame = active; wxActivateEvent event(wxEVT_ACTIVATE, TRUE, g_activeFrame->GetId()); event.SetEventObject(g_activeFrame); @@ -1761,9 +1798,6 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED if (!win->m_hasVMT) return FALSE; if (g_blockEventsOnDrag) return FALSE; - //wxASSERT_MSG( wxGetTopLevelParent(win) == g_activeFrame, wxT("unfocusing window that haven't gained focus properly") ) - g_activeFrameLostFocus = TRUE; - // VZ: this is really weird but GTK+ seems to call us from inside // gtk_widget_grab_focus(), i.e. it first sends "focus_out" signal to // this widget and then "focus_in". This is totally unexpected and @@ -1776,6 +1810,12 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED return FALSE; } + if ( !g_activeFrameLostFocus && g_activeFrame ) + { + wxASSERT_MSG( wxGetTopLevelParent(win) == g_activeFrame, wxT("unfocusing window that haven't gained focus properly") ) + g_activeFrameLostFocus = TRUE; + } + // if the focus goes out of our app alltogether, OnIdle() will send // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset // g_sendActivateEvent to -1 @@ -2825,6 +2865,7 @@ void wxWindowGTK::OnInternalIdle() { if ( g_activeFrame ) { + wxLogTrace(wxT("activate"), wxT("Deactivating frame %p (from idle)"), g_activeFrame); wxActivateEvent event(wxEVT_ACTIVATE, FALSE, g_activeFrame->GetId()); event.SetEventObject(g_activeFrame); g_activeFrame->GetEventHandler()->ProcessEvent(event);