X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c2246a3881e5c3293b70560dde099ee772c86d73..a5655d37db9baabce654849fd66173f95f74e230:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index a8b4ad1e46..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); } } } @@ -1845,6 +1849,8 @@ gtk_window_realized_callback(GtkWidget* widget, wxWindow* win) wxWindowCreateEvent event( win ); event.SetEventObject( win ); win->GTKProcessEvent( event ); + + win->GTKUpdateCursor(true, false); } //----------------------------------------------------------------------------- @@ -2638,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; @@ -2653,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") ); @@ -3402,37 +3418,22 @@ void wxWindowGTK::GTKUpdateCursor(bool update_self /*=true*/, bool recurse /*=tr wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor()); if ( cursor.Ok() ) { - if (m_wxwindow && (m_wxwindow != m_widget)) + wxArrayGdkWindows windowsThis; + GdkWindow* window = GTKGetWindow(windowsThis); + if (window) + gdk_window_set_cursor( window, cursor.GetCursor() ); + else { - wxArrayGdkWindows windowsThis; - GdkWindow* window = GTKGetDrawingWindow(); - if (window) - gdk_window_set_cursor( window, cursor.GetCursor() ); - else + const size_t count = windowsThis.size(); + for ( size_t n = 0; n < count; n++ ) { - const size_t count = windowsThis.size(); - for ( size_t n = 0; n < count; n++ ) + GdkWindow *win = windowsThis[n]; + // It can be zero if the window has not been realized yet. + if ( win ) { - GdkWindow *win = windowsThis[n]; - if ( !win ) - { - wxFAIL_MSG(wxT("NULL window returned by GTKGetWindow()?")); - continue; - } gdk_window_set_cursor(win, cursor.GetCursor()); } } - - window = m_widget->window; - if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget))) - gdk_window_set_cursor( window, cursor.GetCursor() ); - - } - else if ( m_widget ) - { - GdkWindow *window = m_widget->window; - if ( window && !GTK_WIDGET_NO_WINDOW(m_widget) ) - gdk_window_set_cursor( window, cursor.GetCursor() ); } } } @@ -4388,7 +4389,7 @@ GdkWindow* wxWindowGTK::GTKGetDrawingWindow() const { GdkWindow* window = NULL; if (m_wxwindow) - window = WX_PIZZA(m_wxwindow)->m_draw_window; + window = m_wxwindow->window; return window; }