X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9c76b9afa91300a88d8e82b4eee320c7629a5058..a5655d37db9baabce654849fd66173f95f74e230:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index a23f303794..30985280bd 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -305,6 +305,9 @@ expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win) if (gdk_event->window != gtk_widget_get_parent_window(win->m_wxwindow)) return false; + if (!win->IsShown()) + return false; + const GtkAllocation& alloc = win->m_wxwindow->allocation; const int x = alloc.x; const int y = alloc.y; @@ -685,7 +688,14 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event, event.m_rawFlags = 0; #if wxUSE_UNICODE event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval); -#endif + if ( !event.m_uniChar && event.m_keyCode <= WXK_DELETE ) + { + // Set Unicode key code to the ASCII equivalent for compatibility. E.g. + // let RETURN generate the key event with both key and Unicode key + // codes of 13. + event.m_uniChar = event.m_keyCode; + } +#endif // wxUSE_UNICODE wxGetMousePosition( &x, &y ); win->ScreenToClient( &x, &y ); event.m_x = x; @@ -788,17 +798,11 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, if ( !key_code ) return false; + event.m_keyCode = key_code; + // now fill all the other fields wxFillOtherKeyEventFields(event, win, gdk_event); - event.m_keyCode = key_code; -#if wxUSE_UNICODE - if ( gdk_event->type == GDK_KEY_PRESS || gdk_event->type == GDK_KEY_RELEASE ) - { - event.m_uniChar = key_code; - } -#endif - return true; } @@ -819,6 +823,37 @@ struct wxGtkIMData } }; +namespace +{ + +// Send wxEVT_CHAR_HOOK event to the parent of the window and if it wasn't +// processed, send wxEVT_CHAR to the window itself. Return true if either of +// them was handled. +bool +SendCharHookAndCharEvents(const wxKeyEvent& event, wxWindow *win) +{ + // wxEVT_CHAR_HOOK must be sent to the top level parent window to allow it + // to handle key events in all of its children. + wxWindow * const parent = wxGetTopLevelParent(win); + if ( parent ) + { + // We need to make a copy of the event object because it is + // modified while it's handled, notably its WasProcessed() flag + // is set after it had been processed once. + wxKeyEvent eventCharHook(event); + eventCharHook.SetEventType(wxEVT_CHAR_HOOK); + if ( parent->HandleWindowEvent(eventCharHook) ) + return true; + } + + // As above, make a copy of the event first. + wxKeyEvent eventChar(event); + eventChar.SetEventType(wxEVT_CHAR); + return win->HandleWindowEvent(eventChar); +} + +} // anonymous namespace + extern "C" { static gboolean gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), @@ -935,21 +970,7 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), #endif } - // Implement OnCharHook by checking ancestor top level windows - wxWindow *parent = win; - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); - if (parent) - { - event.SetEventType( wxEVT_CHAR_HOOK ); - ret = parent->HandleWindowEvent( event ); - } - - if (!ret) - { - event.SetEventType(wxEVT_CHAR); - ret = win->HandleWindowEvent( event ); - } + ret = SendCharHookAndCharEvents(event, win); } } @@ -981,13 +1002,6 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context), if( data.empty() ) return; - bool ret = false; - - // Implement OnCharHook by checking ancestor top level windows - wxWindow *parent = window; - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); - for( wxString::const_iterator pstr = data.begin(); pstr != data.end(); ++pstr ) { #if wxUSE_UNICODE @@ -1015,17 +1029,7 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context), #endif } - if (parent) - { - event.SetEventType( wxEVT_CHAR_HOOK ); - ret = parent->HandleWindowEvent( event ); - } - - if (!ret) - { - event.SetEventType(wxEVT_CHAR); - ret = window->HandleWindowEvent( event ); - } + SendCharHookAndCharEvents(event, window); } } } @@ -2640,10 +2644,9 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const } } - int border_x, border_y; - WX_PIZZA(m_wxwindow)->get_border_widths(border_x, border_y); - w -= 2 * border_x; - h -= 2 * border_y; + const wxSize sizeBorders = DoGetBorderSize(); + w -= sizeBorders.x; + h -= sizeBorders.y; if (w < 0) w = 0; @@ -2655,6 +2658,17 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const if (height) *height = h; } +wxSize wxWindowGTK::DoGetBorderSize() const +{ + if ( !m_wxwindow ) + return wxWindowBase::DoGetBorderSize(); + + int x, y; + WX_PIZZA(m_wxwindow)->get_border_widths(x, y); + + return 2*wxSize(x, y); +} + void wxWindowGTK::DoGetPosition( int *x, int *y ) const { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );