X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/486ac2444d3d7d3ae6fde5337d906654218069ab..2d956b58023a4955313a1c1531bc70a0deb0b831:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 0628df2a04..efc124ac8d 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -232,13 +232,17 @@ static bool g_captureWindowHasMouse = FALSE; // the last window which had the focus - this is normally never NULL (except // if we never had focus at all) as even when g_focusWindow is NULL it still // keeps its previous value -static wxWindowGTK *g_focusWindowLast = (wxWindowGTK *)NULL; +static wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL; // the frame that is currently active (i.e. its child has focus). It is // used to generate wxActivateEvents -static wxWindowGTK *g_activeFrame = (wxWindowGTK *)NULL; +static wxWindowGTK *g_activeFrame = (wxWindowGTK*) NULL; static bool g_activeFrameLostFocus = FALSE; +// If a window get the focus set but has not been realized +// yet, defer setting the focus to idle time. +wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL; + // if we detect that the app has got/lost the focus, we set this variable to // either TRUE or FALSE and an activate event will be sent during the next // OnIdle() call and it is reset to -1: this value means that we shouldn't @@ -534,8 +538,8 @@ static int gtk_window_expose_callback( GtkWidget *widget, if (g_isIdle) wxapp_install_idle_handler(); -/* - if (win->GetName() == wxT("panel")) +#if 0 + if (win->GetName()) { wxPrintf( wxT("OnExpose from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -545,7 +549,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, (int)gdk_event->area.width, (int)gdk_event->area.height ); } -*/ +#endif #ifndef __WXUNIVERSAL__ GtkPizza *pizza = GTK_PIZZA (widget); @@ -635,8 +639,8 @@ static void gtk_window_draw_callback( GtkWidget *widget, return; } -/* - if (win->GetName() == wxT("panel")) +#if 0 + if (win->GetName()) { wxPrintf( wxT("OnDraw from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -646,7 +650,7 @@ static void gtk_window_draw_callback( GtkWidget *widget, (int)rect->width, (int)rect->height ); } -*/ +#endif #ifndef __WXUNIVERSAL__ GtkPizza *pizza = GTK_PIZZA (widget); @@ -1009,6 +1013,12 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, } s_lastKeyPress = { 0, 0 }; KeySym keysym = gdk_event->keyval; + + wxLogTrace(TRACE_KEYS, _T("Key %s event: keysym = %d"), + event.GetEventType() == wxEVT_KEY_UP ? _T("release") + : _T("press"), + keysym); + long key_code = wxTranslateKeySymToWXKey(keysym, FALSE /* !isChar */); if ( !key_code ) @@ -1034,6 +1044,9 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, // and then back but always using the lower register Display *dpy = (Display *)wxGetDisplay(); KeyCode keycode = XKeysymToKeycode(dpy, keysym); + + wxLogTrace(TRACE_KEYS, _T("\t-> keycode %d"), keycode); + KeySym keysymNormalized = XKeycodeToKeysym(dpy, keycode, 0); // use the normalized, i.e. lower register, keysym if we've @@ -1071,10 +1084,7 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, } } - wxLogTrace(TRACE_KEYS, _T("Key %s event: keysym = %d => keycode = %ld"), - event.GetEventType() == wxEVT_KEY_UP ? _T("release") - : _T("press"), - gdk_event->keyval, key_code); + wxLogTrace(TRACE_KEYS, _T("\t-> wxKeyCode %d"), key_code); // sending unknown key events doesn't really make sense if ( !key_code ) @@ -1791,11 +1801,11 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, g_focusWindow = win; #if 0 - wxLogDebug( wxT("OnSetFocus from %s\n"), win->GetName().c_str() ); + printf( "OnSetFocus 2 from %s\n", win->GetName().c_str() ); #endif - // notify the parent keeping track of focus for the kbd navigation - // purposes that we got it + // Notify the parent keeping track of focus for the kbd navigation + // purposes that we got it. wxChildFocusEvent eventFocus(win); (void)win->GetEventHandler()->ProcessEvent(eventFocus); @@ -1813,6 +1823,8 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, } #endif // wxUSE_CARET + g_activeFrameLostFocus = FALSE; + wxWindowGTK *active = wxGetTopLevelParent(win); if ( active != g_activeFrame ) { @@ -1829,8 +1841,11 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, wxActivateEvent event(wxEVT_ACTIVATE, TRUE, g_activeFrame->GetId()); event.SetEventObject(g_activeFrame); g_activeFrame->GetEventHandler()->ProcessEvent(event); + + // Don't send focus events in addition to activate + // if (win == g_activeFrame) + // return TRUE; } - g_activeFrameLostFocus = FALSE; wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() ); @@ -1842,7 +1857,6 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, return TRUE; } - return FALSE; } @@ -2158,10 +2172,10 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win ) wxapp_install_idle_handler(); if (win->m_delayedBackgroundColour) - win->SetBackgroundColour( win->GetBackgroundColour() ); + win->GtkSetBackgroundColour( win->GetBackgroundColour() ); if (win->m_delayedForegroundColour) - win->SetForegroundColour( win->GetForegroundColour() ); + win->GtkSetForegroundColour( win->GetForegroundColour() ); wxWindowCreateEvent event( win ); event.SetEventObject( win ); @@ -2913,6 +2927,15 @@ void wxWindowGTK::OnInternalIdle() } g_activeFrameLostFocus = FALSE; } + + if (g_delayedFocus == this) + { + if (GTK_WIDGET_REALIZED(m_widget)) + { + gtk_widget_grab_focus( m_widget ); + g_delayedFocus = NULL; + } + } wxCursor cursor = m_cursor; if (g_globalCursor.Ok()) cursor = g_globalCursor; @@ -3268,13 +3291,6 @@ void wxWindowGTK::SetFocus() { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); -#if 0 - wxPrintf( "SetFocus from " ); - if (GetClassInfo() && GetClassInfo()->GetClassName()) - wxPrintf( GetClassInfo()->GetClassName() ); - wxPrintf( ".\n" ); -#endif - if (m_wxwindow) { if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow)) @@ -3286,7 +3302,10 @@ void wxWindowGTK::SetFocus() { if (GTK_WIDGET_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) ) { - gtk_widget_grab_focus (m_widget); + if (!GTK_WIDGET_REALIZED(m_widget)) + g_delayedFocus = this; + else + gtk_widget_grab_focus (m_widget); } else if (GTK_IS_CONTAINER(m_widget)) { @@ -3412,6 +3431,9 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) if (!m_widget->window) return; #ifndef __WXGTK20__ + if (g_isIdle) + wxapp_install_idle_handler(); + if (eraseBackground && m_wxwindow && m_wxwindow->window) { if (rect) @@ -3498,7 +3520,7 @@ void wxWindowGTK::GtkSendPaintEvents() } m_clipPaintRegion = TRUE; - + // if (!m_clearRegion.IsEmpty()) // always send an erase event { wxWindowDC dc( (wxWindow*)this ); @@ -3550,7 +3572,7 @@ void wxWindowGTK::GtkSendPaintEvents() { GtkPizzaChild *child = (GtkPizzaChild*) children->data; children = children->next; - + if (GTK_WIDGET_NO_WINDOW (child->widget) && GTK_WIDGET_DRAWABLE (child->widget)) { @@ -3590,11 +3612,14 @@ void wxWindowGTK::Clear() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); - if (!m_widget->window) return; - if (m_wxwindow && m_wxwindow->window) { - gdk_window_clear( m_wxwindow->window ); + m_clearRegion.Clear(); + wxSize size( GetClientSize() ); + m_clearRegion.Union( 0,0,size.x,size.y ); + + // Better do this in idle? + Update(); } } @@ -3613,16 +3638,37 @@ void wxWindowGTK::ApplyToolTip( GtkTooltips *tips, const wxChar *tip ) } #endif // wxUSE_TOOLTIPS +void wxWindowGTK::GtkSetBackgroundColour( const wxColour &colour ) +{ + GdkWindow *window = (GdkWindow*) NULL; + if (m_wxwindow) + window = GTK_PIZZA(m_wxwindow)->bin_window; + else + window = GetConnectWidget()->window; + + wxASSERT( window ); + + // We need the pixel value e.g. for background clearing. + m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) ); + + if ((m_wxwindow) && + (m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE))) + { + /* wxMSW doesn't clear the window here. I don't do that either to + provide compatibility. call Clear() to do the job. */ + + gdk_window_set_background( window, m_backgroundColour.GetColor() ); + } + + ApplyWidgetStyle(); +} + bool wxWindowGTK::SetBackgroundColour( const wxColour &colour ) { wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") ); if (!wxWindowBase::SetBackgroundColour(colour)) - { - // don't leave if the GTK widget has just - // been realized - if (!m_delayedBackgroundColour) return FALSE; - } + return FALSE; GdkWindow *window = (GdkWindow*) NULL; if (m_wxwindow) @@ -3636,27 +3682,27 @@ bool wxWindowGTK::SetBackgroundColour( const wxColour &colour ) // but it couldn't get applied as the // widget hasn't been realized yet. m_delayedBackgroundColour = TRUE; + return TRUE; } - - if (window) + else { - // We need the pixel value e.g. for background clearing. - m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) ); + GtkSetBackgroundColour( colour ); } - - if ((m_wxwindow) && - (m_wxwindow->window) && - (m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE))) - { - /* wxMSW doesn't clear the window here. I don't do that either to - provide compatibility. call Clear() to do the job. */ - gdk_window_set_background( window, m_backgroundColour.GetColor() ); - } + return TRUE; +} - ApplyWidgetStyle(); +void wxWindowGTK::GtkSetForegroundColour( const wxColour &colour ) +{ + GdkWindow *window = (GdkWindow*) NULL; + if (m_wxwindow) + window = GTK_PIZZA(m_wxwindow)->bin_window; + else + window = GetConnectWidget()->window; - return TRUE; + wxASSERT( window ); + + ApplyWidgetStyle(); } bool wxWindowGTK::SetForegroundColour( const wxColour &colour ) @@ -3683,8 +3729,10 @@ bool wxWindowGTK::SetForegroundColour( const wxColour &colour ) // widget hasn't been realized yet. m_delayedForegroundColour = TRUE; } - - ApplyWidgetStyle(); + else + { + GtkSetForegroundColour( colour ); + } return TRUE; }