X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/010afced511d74f4f1c10390da96c6ccf687d574..12447831a8ebc506f730cafac6f6ef13f243b7d2:/src/gtk1/window.cpp diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index c15e735d2b..ed792dcc17 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -270,47 +270,13 @@ extern bool g_mainThreadLocked; #else # define DEBUG_MAIN_THREAD #endif - -static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget), - GdkEvent *WXUNUSED(event), - const wxChar *WXUNUSED(name) ) -{ -/* - static bool s_done = FALSE; - if ( !s_done ) - { - wxLog::AddTraceMask("focus"); - s_done = TRUE; - } - wxLogTrace(wxT("FOCUS NOW AT: %s"), name); -*/ - - return FALSE; -} - -void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window ) -{ - // suppress warnings about gtk_debug_focus_in_callback being unused with - // this "if ( 0 )" - if ( 0 ) - { - wxString tmp = name; - tmp += wxT(" FROM "); - tmp += window; - - wxChar *s = new wxChar[tmp.Length()+1]; - - wxStrcpy( s, tmp ); - - gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event", - GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s ); - } -} - #else #define DEBUG_MAIN_THREAD #endif // Debug +// the trace mask used for the focus debugging messages +#define TRACE_FOCUS _T("focus") + //----------------------------------------------------------------------------- // missing gdk functions //----------------------------------------------------------------------------- @@ -385,15 +351,6 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win) return (wxWindow *)NULL; } -// Returns toplevel grandparent of given window: -static wxWindowGTK* wxGetTopLevelParent(wxWindowGTK *win) -{ - wxWindowGTK *p = win; - while (p && !p->IsTopLevel()) - p = p->GetParent(); - return p; -} - static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) { // wxUniversal widgets draw the borders and scrollbars themselves @@ -555,6 +512,10 @@ static int gtk_window_expose_callback( GtkWidget *widget, gdk_event->area.y, gdk_event->area.width, gdk_event->area.height ); + win->m_clearRegion.Union( gdk_event->area.x, + gdk_event->area.y, + gdk_event->area.width, + gdk_event->area.height ); // Actual redrawing takes place in idle time. win->GtkUpdate(); @@ -1105,6 +1066,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (g_blockEventsOnDrag) return FALSE; + wxKeyEvent event( wxEVT_KEY_DOWN ); if ( !wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) { @@ -1112,6 +1074,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, return FALSE; } + // Emit KEY_DOWN event bool ret = win->GetEventHandler()->ProcessEvent( event ); #if wxUSE_ACCEL @@ -1134,10 +1097,11 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, } #endif // wxUSE_ACCEL - /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x - will only be sent if it is not in an accelerator table. */ - if ( !ret ) + // Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x + // will only be sent if it is not in an accelerator table. + if (!ret) { + // Find key code for EVT_CHAR and EVT_CHAR_HOOK events KeySym keysym = gdk_event->keyval; long key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */); if ( !key_code ) @@ -1157,16 +1121,27 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, { wxLogTrace(TRACE_KEYS, _T("Char event: %ld"), key_code); - // reuse the same event object, just change its type and use the - // translated keycode instead of the raw one - event.SetEventType(wxEVT_CHAR); event.m_keyCode = key_code; + + // Implement OnCharHook by checking ancesteror top level windows + wxWindow *parent = win; + while (parent && !parent->IsTopLevel()) + parent = parent->GetParent(); + if (parent) + { + event.SetEventType( wxEVT_CHAR_HOOK ); + ret = parent->GetEventHandler()->ProcessEvent( event ); + } - ret = win->GetEventHandler()->ProcessEvent( event ); + if (!ret) + { + event.SetEventType(wxEVT_CHAR); + ret = win->GetEventHandler()->ProcessEvent( event ); + } } } - /* win is a control: tab can be propagated up */ + // win is a control: tab can be propagated up if ( !ret && ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) && // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may @@ -1179,15 +1154,15 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, { wxNavigationKeyEvent new_event; new_event.SetEventObject( win->GetParent() ); - /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ + // GDK reports GDK_ISO_Left_Tab for SHIFT-TAB new_event.SetDirection( (gdk_event->keyval == GDK_Tab) ); - /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ + // CTRL-TAB changes the (parent) window, i.e. switch notebook page new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) ); new_event.SetCurrentFocus( win ); ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event ); } - /* generate wxID_CANCEL if has been pressed (typically in dialogs) */ + // generate wxID_CANCEL if has been pressed (typically in dialogs) if ( !ret && (gdk_event->keyval == GDK_Escape) ) { @@ -1196,9 +1171,9 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, ret = win->GetEventHandler()->ProcessEvent( new_event ); } - /* Doesn't work. */ -#if 0 // (GTK_MINOR_VERSION > 0) - /* Pressing F10 will activate the menu bar of the top frame. */ + // Doesn't work. +#if 0 + // Pressing F10 will activate the menu bar of the top frame if ( (!ret) && (gdk_event->keyval == GDK_F10) ) { @@ -1231,7 +1206,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); return TRUE; } - + return FALSE; } @@ -1272,6 +1247,10 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, // the mouse events // ============================================================================ +// ---------------------------------------------------------------------------- +// mouse event processing helpers +// ---------------------------------------------------------------------------- + // init wxMouseEvent with the info from gdk_event #define InitMouseEvent(win, event, gdk_event) \ { \ @@ -1289,10 +1268,6 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, event.m_y = (wxCoord)gdk_event->y - pt.y; \ } -// ---------------------------------------------------------------------------- -// mouse event processing helper -// ---------------------------------------------------------------------------- - static void AdjustEventButtonState(wxMouseEvent& event) { // GDK reports the old state of the button for a button press event, but @@ -1325,11 +1300,79 @@ static void AdjustEventButtonState(wxMouseEvent& event) } } +// find the window to send the mouse event too +static +wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y) +{ + wxCoord xx = x; + wxCoord yy = y; + + if (win->m_wxwindow) + { + GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow); + xx += pizza->xoffset; + yy += pizza->yoffset; + } + + wxNode *node = win->GetChildren().First(); + while (node) + { + wxWindowGTK *child = (wxWindowGTK*)node->Data(); + + node = node->Next(); + if (!child->IsShown()) + continue; + + if (child->IsTransparentForMouse()) + { + // wxStaticBox is transparent in the box itself + int xx1 = child->m_x; + int yy1 = child->m_y; + int xx2 = child->m_x + child->m_width; + int yy2 = child->m_x + child->m_height; + + // left + if (((xx >= xx1) && (xx <= xx1+10) && (yy >= yy1) && (yy <= yy2)) || + // right + ((xx >= xx2-10) && (xx <= xx2) && (yy >= yy1) && (yy <= yy2)) || + // top + ((xx >= xx1) && (xx <= xx2) && (yy >= yy1) && (yy <= yy1+10)) || + // bottom + ((xx >= xx1) && (xx <= xx2) && (yy >= yy2-1) && (yy <= yy2))) + { + win = child; + x -= child->m_x; + y -= child->m_y; + break; + } + + } + else + { + if ((child->m_wxwindow == (GtkWidget*) NULL) && + (child->m_x <= xx) && + (child->m_y <= yy) && + (child->m_x+child->m_width >= xx) && + (child->m_y+child->m_height >= yy)) + { + win = child; + x -= child->m_x; + y -= child->m_y; + break; + } + } + } + + return win; +} + //----------------------------------------------------------------------------- // "button_press_event" //----------------------------------------------------------------------------- -static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindowGTK *win ) +static gint gtk_window_button_press_callback( GtkWidget *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1400,77 +1443,15 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton AdjustEventButtonState(event); - // wxListBox actually get mouse events from the item - - if (win->m_isListBox) - { - event.m_x += widget->allocation.x; - event.m_y += widget->allocation.y; - } + // wxListBox actually get mouse events from the item, so we need to give it + // a chance to correct this + win->FixUpMouseEvent(widget, event.m_x, event.m_y); - // Some control don't have their own X window and thus cannot get - // any events. - - if (!g_captureWindow) - { - wxCoord x = event.m_x; - wxCoord y = event.m_y; - if (win->m_wxwindow) - { - GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow); - x += pizza->xoffset; - y += pizza->yoffset; - } - - wxNode *node = win->GetChildren().First(); - while (node) - { - wxWindowGTK *child = (wxWindowGTK*)node->Data(); - - node = node->Next(); - if (!child->IsShown()) - continue; - - if (child->m_isStaticBox) - { - // wxStaticBox is transparent in the box itself - int xx1 = child->m_x; - int yy1 = child->m_y; - int xx2 = child->m_x + child->m_width; - int yy2 = child->m_x + child->m_height; - - // left - if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) || - // right - ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) || - // top - ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) || - // bottom - ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2))) - { - win = child; - event.m_x -= child->m_x; - event.m_y -= child->m_y; - break; - } - - } - else - { - if ((child->m_wxwindow == (GtkWidget*) NULL) && - (child->m_x <= x) && - (child->m_y <= y) && - (child->m_x+child->m_width >= x) && - (child->m_y+child->m_height >= y)) - { - win = child; - event.m_x -= child->m_x; - event.m_y -= child->m_y; - break; - } - } - } - } + // find the correct window to send the event too: it may be a different one + // from the one which got it at GTK+ level because some control don't have + // their own X window and thus cannot get any events. + if ( !g_captureWindow ) + win = FindWindowForMouseEvent(win, event.m_x, event.m_y); event.SetEventObject( win ); @@ -1531,77 +1512,11 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto AdjustEventButtonState(event); - // wxListBox actually get mouse events from the item - - if (win->m_isListBox) - { - event.m_x += widget->allocation.x; - event.m_y += widget->allocation.y; - } + // same wxListBox hack as above + win->FixUpMouseEvent(widget, event.m_x, event.m_y); - // Some control don't have their own X window and thus cannot get - // any events. - - if (!g_captureWindow) - { - wxCoord x = event.m_x; - wxCoord y = event.m_y; - if (win->m_wxwindow) - { - GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow); - x += pizza->xoffset; - y += pizza->yoffset; - } - - wxNode *node = win->GetChildren().First(); - while (node) - { - wxWindowGTK *child = (wxWindowGTK*)node->Data(); - - node = node->Next(); - if (!child->IsShown()) - continue; - - if (child->m_isStaticBox) - { - // wxStaticBox is transparent in the box itself - int xx1 = child->m_x; - int yy1 = child->m_y; - int xx2 = child->m_x + child->m_width; - int yy2 = child->m_x + child->m_height; - - // left - if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) || - // right - ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) || - // top - ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) || - // bottom - ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2))) - { - win = child; - event.m_x -= child->m_x; - event.m_y -= child->m_y; - break; - } - - } - else - { - if ((child->m_wxwindow == (GtkWidget*) NULL) && - (child->m_x <= x) && - (child->m_y <= y) && - (child->m_x+child->m_width >= x) && - (child->m_y+child->m_height >= y)) - { - win = child; - event.m_x -= child->m_x; - event.m_y -= child->m_y; - break; - } - } - } - } + if ( !g_captureWindow ) + win = FindWindowForMouseEvent(win, event.m_x, event.m_y); event.SetEventObject( win ); @@ -1672,66 +1587,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, } else // no capture { - // Some control don't have their own X window and thus cannot get - // any events. - - wxCoord x = event.m_x; - wxCoord y = event.m_y; - if (win->m_wxwindow) - { - GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow); - x += pizza->xoffset; - y += pizza->yoffset; - } - - wxNode *node = win->GetChildren().First(); - while (node) - { - wxWindowGTK *child = (wxWindowGTK*)node->Data(); - - node = node->Next(); - if (!child->IsShown()) - continue; - - if (child->m_isStaticBox) - { - // wxStaticBox is transparent in the box itself - int xx1 = child->m_x; - int yy1 = child->m_y; - int xx2 = child->m_x + child->m_width; - int yy2 = child->m_x + child->m_height; - - // left - if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) || - // right - ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) || - // top - ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) || - // bottom - ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2))) - { - win = child; - event.m_x -= child->m_x; - event.m_y -= child->m_y; - break; - } - - } - else - { - if ((child->m_wxwindow == (GtkWidget*) NULL) && - (child->m_x <= x) && - (child->m_y <= y) && - (child->m_x+child->m_width >= x) && - (child->m_y+child->m_height >= y)) - { - win = child; - event.m_x -= child->m_x; - event.m_y -= child->m_y; - break; - } - } - } + win = FindWindowForMouseEvent(win, event.m_x, event.m_y); } event.SetEventObject( win ); @@ -1749,6 +1605,21 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, // "focus_in_event" //----------------------------------------------------------------------------- +// send the wxChildFocusEvent and wxFocusEvent, common code of +// gtk_window_focus_in_callback() and SetFocus() +static bool DoSendFocusEvents(wxWindow *win) +{ + // Notify the parent keeping track of focus for the kbd navigation + // purposes that we got it. + wxChildFocusEvent eventChildFocus(win); + (void)win->GetEventHandler()->ProcessEvent(eventChildFocus); + + wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId()); + eventFocus.SetEventObject(win); + + return win->GetEventHandler()->ProcessEvent(eventFocus); +} + static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win ) @@ -1778,14 +1649,8 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, g_focusWindowLast = g_focusWindow = win; -#if 0 - 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. - wxChildFocusEvent eventFocus(win); - (void)win->GetEventHandler()->ProcessEvent(eventFocus); + wxLogTrace(TRACE_FOCUS, + _T("%s: focus in"), win->GetName().c_str()); #ifdef HAVE_XIM if (win->m_ic) @@ -1825,14 +1690,17 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, // return TRUE; } - - wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() ); - event.SetEventObject( win ); - - if (win->GetEventHandler()->ProcessEvent( event )) + // does the window itself think that it has the focus? + if ( !win->m_hasFocus ) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" ); - return TRUE; + // not yet, notify it + win->m_hasFocus = TRUE; + + if ( DoSendFocusEvents(win) ) + { + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" ); + return TRUE; + } } return FALSE; @@ -1852,9 +1720,8 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk if (!win->m_hasVMT) return FALSE; if (g_blockEventsOnDrag) return FALSE; -#if 0 - wxLogDebug( wxT("OnKillFocus from %s"), win->GetName().c_str() ); -#endif + wxLogTrace( TRACE_FOCUS, + _T("%s: focus out"), win->GetName().c_str() ); if ( !g_activeFrameLostFocus && g_activeFrame ) { @@ -1863,7 +1730,7 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk // always) and makes using Mahogany quite annoying #if 0 wxASSERT_MSG( wxGetTopLevelParent(win) == g_activeFrame, - wxT("unfocusing window that hasn't gained focus properly") ) + wxT("unfocusing window that hasn't gained focus properly") ); #endif // 0 g_activeFrameLostFocus = TRUE; @@ -1894,13 +1761,20 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk } #endif // wxUSE_CARET - wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); - event.SetEventObject( win ); - - if (win->GetEventHandler()->ProcessEvent( event )) + // don't send the window a kill focus event if it thinks that it doesn't + // have focus already + if ( win->m_hasFocus ) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" ); - return TRUE; + win->m_hasFocus = FALSE; + + wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); + event.SetEventObject( win ); + + if (win->GetEventHandler()->ProcessEvent( event )) + { + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" ); + return TRUE; + } } return FALSE; @@ -2015,7 +1889,8 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, win->m_oldVerticalPos = adjust->value; - wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(win->m_widget)); + GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW(win->m_widget); + wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(sw->vscrollbar)); int value = (int)(adjust->value+0.5); @@ -2043,7 +1918,8 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, float diff = adjust->value - win->m_oldHorizontalPos; if (fabs(diff) < 0.2) return; - wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(win->m_widget)); + GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW(win->m_widget); + wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(sw->hscrollbar)); win->m_oldHorizontalPos = adjust->value; @@ -2134,6 +2010,22 @@ wxWindow *wxWindowBase::FindFocus() return (wxWindow *)g_focusWindow; } +//----------------------------------------------------------------------------- +// "destroy" event +//----------------------------------------------------------------------------- + +// VZ: Robert commented the code using out so it generates warnings: should +// be either fixed or removed completely +#if 0 + +static void gtk_window_destroy_callback( GtkWidget* widget, wxWindow *win ) +{ + wxWindowDestroyEvent event(win); + win->GetEventHandler()->ProcessEvent(event); +} + +#endif // 0 + //----------------------------------------------------------------------------- // "realize" from m_widget //----------------------------------------------------------------------------- @@ -2352,8 +2244,7 @@ static void wxInsertChildInWindow( wxWindowGTK* parent, wxWindowGTK* child ) wxWindow *wxGetActiveWindow() { - // the cast is necessary when we compile in wxUniversal mode - return (wxWindow *)g_focusWindow; + return wxWindow::FindFocus(); } //----------------------------------------------------------------------------- @@ -2405,11 +2296,8 @@ void wxWindowGTK::Init() m_insertCallback = (wxInsertChildFunction) NULL; - m_isStaticBox = FALSE; - m_isRadioButton = FALSE; - m_isListBox = FALSE; - m_isFrame = FALSE; m_acceptsFocus = FALSE; + m_hasFocus = FALSE; m_clipPaintRegion = FALSE; @@ -2564,6 +2452,9 @@ wxWindowGTK::~wxWindowGTK() if (g_activeFrame == this) g_activeFrame = NULL; + if ( g_delayedFocus == this ) + g_delayedFocus = NULL; + m_isBeingDeleted = TRUE; m_hasVMT = FALSE; @@ -2749,6 +2640,11 @@ void wxWindowGTK::ConnectWidget( GtkWidget *widget ) gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event", GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this ); + + // This keeps crashing on me. RR. + // + // gtk_signal_connect( GTK_OBJECT(widget), "destroy", + // GTK_SIGNAL_FUNC(gtk_window_destroy_callback), (gpointer)this ); } bool wxWindowGTK::Destroy() @@ -2906,15 +2802,6 @@ 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; @@ -3267,7 +3154,13 @@ void wxWindowGTK::GetTextExtent( const wxString& string, void wxWindowGTK::SetFocus() { - wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); + wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); + + if ( m_hasFocus ) + { + // don't do anything if we already have focus + return; + } if (m_wxwindow) { @@ -3281,9 +3174,24 @@ void wxWindowGTK::SetFocus() if (GTK_WIDGET_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) ) { if (!GTK_WIDGET_REALIZED(m_widget)) + { + // we can't set the focus to the widget now so we remember that + // it should be focused and will do it later, during the idle + // time, as soon as we can + wxLogTrace(TRACE_FOCUS, + _T("Delaying setting focus to %s(%s)"), + GetClassInfo()->GetClassName(), GetLabel().c_str()); + g_delayedFocus = this; + } else + { + wxLogTrace(TRACE_FOCUS, + _T("Setting focus to %s(%s)"), + GetClassInfo()->GetClassName(), GetLabel().c_str()); + gtk_widget_grab_focus (m_widget); + } } else if (GTK_IS_CONTAINER(m_widget)) { @@ -3291,7 +3199,9 @@ void wxWindowGTK::SetFocus() } else { - // ? + wxLogTrace(TRACE_FOCUS, + _T("Can't set focus to %s(%s)"), + GetClassInfo()->GetClassName(), GetLabel().c_str()); } } } @@ -3502,8 +3412,43 @@ void wxWindowGTK::GtkSendPaintEvents() return; } + // widget to draw on + GtkPizza *pizza = GTK_PIZZA (m_wxwindow); + + // Clip to paint region in wxClientDC m_clipPaintRegion = TRUE; + if (GetThemeEnabled()) + { + // find ancestor from which to steal background + wxWindow *parent = GetParent(); + while (parent && !parent->IsTopLevel()) + parent = parent->GetParent(); + if (!parent) + parent = (wxWindow*)this; + + wxRegionIterator upd( m_updateRegion ); + while (upd) + { + GdkRectangle rect; + rect.x = upd.GetX(); + rect.y = upd.GetY(); + rect.width = upd.GetWidth(); + rect.height = upd.GetHeight(); + + gtk_paint_flat_box( parent->m_widget->style, + pizza->bin_window, + GTK_STATE_NORMAL, + GTK_SHADOW_NONE, + &rect, + parent->m_widget, + (char *)"base", + 0, 0, -1, -1 ); + + upd ++; + } + } + else // if (!m_clearRegion.IsEmpty()) // always send an erase event { wxWindowDC dc( (wxWindow*)this ); @@ -3516,46 +3461,16 @@ void wxWindowGTK::GtkSendPaintEvents() { if (!g_eraseGC) { - g_eraseGC = gdk_gc_new( GTK_PIZZA(m_wxwindow)->bin_window ); + g_eraseGC = gdk_gc_new( pizza->bin_window ); gdk_gc_set_fill( g_eraseGC, GDK_SOLID ); } gdk_gc_set_foreground( g_eraseGC, m_backgroundColour.GetColor() ); - // widget to draw on - GtkPizza *pizza = GTK_PIZZA (m_wxwindow); - - // find ancestor from which to steal background - wxWindow *parent = GetParent(); - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); - if (!parent) - parent = this; - wxRegionIterator upd( m_clearRegion ); while (upd) { - if (GetThemeEnabled()) - { - GdkRectangle rect; - rect.x = upd.GetX(); - rect.y = upd.GetY(); - rect.width = upd.GetWidth(); - rect.height = upd.GetHeight(); - - gtk_paint_flat_box( parent->m_widget->style, - pizza->bin_window, - GTK_STATE_NORMAL, - GTK_SHADOW_NONE, - &rect, - parent->m_widget, - (char *)"base", - 0, 0, -1, -1 ); - } - else - { - gdk_draw_rectangle( pizza->bin_window, g_eraseGC, 1, - upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); - } + gdk_draw_rectangle( pizza->bin_window, g_eraseGC, 1, + upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); upd ++; } } @@ -3578,8 +3493,6 @@ void wxWindowGTK::GtkSendPaintEvents() // being redrawn because the wxWindows class is allowed to // paint over the window-less widgets. - GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - GList *children = pizza->children; while (children) { @@ -3664,12 +3577,9 @@ void wxWindowGTK::GtkSetBackgroundColour( const wxColour &colour ) // 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))) + if (m_wxwindow) { - /* wxMSW doesn't clear the window here. I don't do that either to - provide compatibility. call Clear() to do the job. */ - + // wxMSW doesn't clear the window here, either. gdk_window_set_background( window, m_backgroundColour.GetColor() ); } @@ -4247,7 +4157,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") ); - + // No scrolling requested. if ((dx == 0) && (dy == 0)) return; @@ -4271,7 +4181,6 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) GetClientSize( &cw, &ch ); m_clearRegion.Intersect( 0, 0, cw, ch ); } - m_clipPaintRegion = TRUE; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); @@ -4360,3 +4269,4 @@ void wxWinModule::OnExit() gdk_gc_unref( g_eraseGC ); } +// vi:sts=4:sw=4:et