X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f6fca1f80e1a49807cc353b7709ac697b3066af4..7f8c0d74d7025b6c677fbd88890ea10d302ef3d5:/src/gtk1/window.cpp diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 62bc1f70d2..4e92f5a423 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -1111,29 +1111,27 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, return FALSE; if (g_blockEventsOnDrag) return FALSE; - + + + wxKeyEvent event( wxEVT_KEY_DOWN ); + bool ret = false; + bool return_after_IM = false; + + if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) + { + // Emit KEY_DOWN event + ret = win->GetEventHandler()->ProcessEvent( event ); + } + else + { + // Return after IM processing as we cannot do + // anything with it anyhow. + return_after_IM = true; + } + #ifdef __WXGTK20__ -#if 0 - // We have to pass key press events through GTK+'s Input Method context - // object in order to get correct characters. By doing so, we lose the - // ability to let other GTK+'s handlers (namely, widgets' default signal - // handlers) handle the signal by returning false from this callback. - // Because GTK+ sends the events to parent widgets as well, we can't - // afford losing it, otherwise native widgets inserted into wxPanel - // would break in subtle ways (e.g. spacebar would no longer toggle - // wxCheckButton's state). Therefore, we only pass the event to IM if it - // originated in this window's widget, which we detect by checking if we've - // seen the same event before (no events from children are lost this way, - // because gtk_window_key_press_callback is installed for native controls - // as well and the wxKeyEvent it creates propagates upwards). - static GdkEventKey s_lastEvent; - bool useIM = (win->m_imData != NULL) && - memcmp(gdk_event, &s_lastEvent, sizeof(GdkEventKey)) != 0; - s_lastEvent = *gdk_event; -#else - // 2005.01.26 modified by hzysoft@sina.com.tw: - // There is no need to store lastEvent. The original code makes GTK+ IM - // dysfunction. When we get a key_press event here, it could be originate + // 2005.01.26 modified by Hong Jen Yee (hzysoft@sina.com.tw): + // When we get a key_press event here, it could be originate // from the current widget or its child widgets. However, only the widget // with the INPUT FOCUS can generate the INITIAL key_press event. That is, // if the CURRENT widget doesn't have the FOCUS at all, this event definitely @@ -1143,50 +1141,83 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, // widgets has both IM context and input focus, the event should be filtered // by gtk_im_context_filter_keypress(). // Then, we should, according to GTK+ 2.0 API doc, return whatever it returns. - bool useIM = (win->m_imData != NULL) && ( wxWindow::FindFocus() == win ); -#endif - -#endif - -#ifdef __WXGTK20__ - // 2005.01.26 modified by hzysoft@sina.com.tw: - // We should let GTK+ IM filter key event first. According to GTK+ 2.0 API - // docs, if IM filter returns true, NO FURTHER PROCESSING SHOULD BE DONE for - // this keystroke. Making wxWidgets unable to receive EVT_KEY_DOWN in this - // situation is resonable. In reality, when IM is activated, wxWidgets should - // receive EVT_CHAR instead. - if (useIM) - { - // it may be useful for the input method, though: - bool ret = gtk_im_context_filter_keypress(win->m_imData->context, gdk_event); + if ((!ret) && (win->m_imData != NULL) && ( wxWindow::FindFocus() == win )) + { + // We should let GTK+ IM filter key event first. According to GTK+ 2.0 API + // docs, if IM filter returns true, no further processing should be done. + // we should send the key_down event anyway. + bool intercepted_by_IM = gtk_im_context_filter_keypress(win->m_imData->context, gdk_event); win->m_imData->lastKeyEvent = NULL; - if( ret ) + if (intercepted_by_IM) { wxLogTrace(TRACE_KEYS, _T("Key event intercepted by IM")); - return ret; + return true; } } #endif + if (return_after_IM) + return true; - wxKeyEvent event( wxEVT_KEY_DOWN ); - if ( !wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) - { - // unknown key pressed, ignore (the event would be useless anyhow) - // 2005.02.22 modified by PCMan. - // In GTK+ 1.2, strings sent by IMs are also regarded as key_press events whose - // keyCodes cannot be recognized by wxWidgets. These MBCS strings, however, are - // composed of more than one character, which means gdk_event->length will always - // greater than one. - // When gtk_event->length == 1, this may be an ASCII character and can be translated - // by WX. However, when MBCS characters are sent by IM, gdk_event->length will >= 2. - // So when gdk_event->length >= 2, this is not an invalid key but a part of a string - // sent by IM which contains user input and shouldn't be ignored. - if (gdk_event->length <= 1) // Only ignore those keys whose gdk_event->length <=1. - return FALSE; - } +#ifndef __WXGTK20__ + // This is for GTK+ 1.2 only. The char event generatation for GTK+ 2.0 is done + // in the "commit" handler. + + // 2005.02.02 modified by Hong Jen Yee (hzysoft@sina.com.tw). + // In GTK+ 1.2, strings sent by IMs are also regarded as key_press events whose + // keyCodes cannot be recognized by wxWidgets. These MBCS strings, however, are + // composed of more than one character, which means gdk_event->length will always + // greater than one. When gtk_event->length == 1, this may be an ASCII character + // and can be translated by wx. However, when MBCS characters are sent by IM, + // gdk_event->length will >= 2. So neither should we pass it to accelerator table, + // nor should we pass it to controls. The following explanation was excerpted + // from GDK documentation. + // gint length : the length of string. + // gchar *string : a null-terminated multi-byte string containing the composed + // characters resulting from the key press. When text is being input, in a GtkEntry + // for example, it is these characters which should be added to the input buffer. + // When using Input Methods to support internationalized text input, the composed + // characters appear here after the pre-editing has been completed. + + if ( (!ret) && (gdk_event->length > 1) ) // If this event contains a pre-edited string from IM. + { + // We should translate this key event into wxEVT_CHAR not wxEVT_KEY_DOWN. + #if wxUSE_UNICODE // GTK+ 1.2 is not UTF-8 based. + const wxWCharBuffer string = wxConvLocal.cMB2WC( gdk_event->string ); + if( !string ) + return false; + #else + const char* string = gdk_event->string; + #endif + + // Implement OnCharHook by checking ancesteror top level windows + wxWindow *parent = win; + while (parent && !parent->IsTopLevel()) + parent = parent->GetParent(); - // Emit KEY_DOWN event - bool ret = win->GetEventHandler()->ProcessEvent( event ); + for( const wxChar* pstr = string; *pstr; pstr++ ) + { + #if wxUSE_UNICODE + event.m_uniChar = *pstr; + // Backward compatible for ISO-8859-1 + event.m_keyCode = *pstr < 256 ? event.m_uniChar : 0; + #else + event.m_keyCode = *pstr; + #endif + if (parent) + { + event.SetEventType( wxEVT_CHAR_HOOK ); + ret = parent->GetEventHandler()->ProcessEvent( event ); + } + if (!ret) + { + event.SetEventType(wxEVT_CHAR); + win->GetEventHandler()->ProcessEvent( event ); + } + } + return true; + } + +#endif // #ifndef __WXGTK20__ #if wxUSE_ACCEL if (!ret) @@ -1254,6 +1285,10 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, } } + + + + // win is a control: tab can be propagated up if ( !ret && ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) && @@ -3723,18 +3758,28 @@ void wxWindowGTK::Raise() { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - if (!m_widget->window) return; - - gdk_window_raise( m_widget->window ); + if (m_wxwindow && m_wxwindow->window) + { + gdk_window_raise( m_wxwindow->window ); + } + else if (m_widget->window) + { + gdk_window_raise( m_widget->window ); + } } void wxWindowGTK::Lower() { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - if (!m_widget->window) return; - - gdk_window_lower( m_widget->window ); + if (m_wxwindow && m_wxwindow->window) + { + gdk_window_lower( m_wxwindow->window ); + } + else if (m_widget->window) + { + gdk_window_lower( m_widget->window ); + } } bool wxWindowGTK::SetCursor( const wxCursor &cursor )