]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/window.cpp
corrected warnings when compiling with -Wall -W
[wxWidgets.git] / src / gtk1 / window.cpp
index c823a1b56f4f10a9625f0f66bd6e8d125ab26a1a..bad1ac7648dc2979e3853ff25e6360699017729e 100644 (file)
@@ -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
@@ -266,43 +270,6 @@ 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
@@ -381,15 +348,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
@@ -534,8 +492,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,28 +503,6 @@ static int gtk_window_expose_callback( GtkWidget *widget,
                                          (int)gdk_event->area.width,
                                          (int)gdk_event->area.height );
     }
-*/
-
-#ifndef __WXUNIVERSAL__
-    GtkPizza *pizza = GTK_PIZZA (widget);
-
-    if (win->GetThemeEnabled())
-    {
-        wxWindow *parent = win->GetParent();
-        while (parent && !parent->IsTopLevel())
-            parent = parent->GetParent();
-        if (!parent)
-            parent = win;
-
-        gtk_paint_flat_box (parent->m_widget->style,
-                            pizza->bin_window,
-                            GTK_STATE_NORMAL,
-                            GTK_SHADOW_NONE,
-                            &gdk_event->area,
-                            parent->m_widget,
-                            (char *)"base",
-                            0, 0, -1, -1);
-    }
 #endif
 
     win->GetUpdateRegion().Union( gdk_event->area.x,
@@ -575,7 +511,7 @@ static int gtk_window_expose_callback( GtkWidget *widget,
                                   gdk_event->area.height );
 
     // Actual redrawing takes place in idle time.
-    win->Update();
+    win->GtkUpdate();
 
 #ifdef __WXGTK20__
 
@@ -635,8 +571,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 +582,7 @@ static void gtk_window_draw_callback( GtkWidget *widget,
                                          (int)rect->width,
                                          (int)rect->height );
     }
-*/
+#endif
 
 #ifndef __WXUNIVERSAL__
     GtkPizza *pizza = GTK_PIZZA (widget);
@@ -682,7 +618,7 @@ static void gtk_window_draw_callback( GtkWidget *widget,
 
     // Actual redrawing takes place in idle time.
 
-    win->Update();
+    win->GtkUpdate();
 
 #ifndef __WXUNIVERSAL__
     // Redraw child widgets
@@ -1767,6 +1703,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 )
@@ -1797,14 +1748,9 @@ 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
-    wxChildFocusEvent eventFocus(win);
-    (void)win->GetEventHandler()->ProcessEvent(eventFocus);
-
 #ifdef HAVE_XIM
     if (win->m_ic)
         gdk_im_begin(win->m_ic, win->m_wxwindow->window);
@@ -1819,6 +1765,8 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget,
     }
 #endif // wxUSE_CARET
 
+    g_activeFrameLostFocus = FALSE;
+    
     wxWindowGTK *active = wxGetTopLevelParent(win);
     if ( active != g_activeFrame )
     {
@@ -1835,20 +1783,18 @@ 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() );
-    event.SetEventObject( win );
 
-    if (win->GetEventHandler()->ProcessEvent( event ))
+    if ( DoSendFocusEvents(win) )
     {
        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
        return TRUE;
     }
 
-
     return FALSE;
 }
 
@@ -2029,7 +1975,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);
 
@@ -2057,7 +2004,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;
 
@@ -2164,10 +2112,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 );
@@ -2578,6 +2526,9 @@ wxWindowGTK::~wxWindowGTK()
     if (g_activeFrame == this)
         g_activeFrame = NULL;
 
+    if ( g_delayedFocus == this )
+        g_delayedFocus = NULL;
+
     m_isBeingDeleted = TRUE;
     m_hasVMT = FALSE;
 
@@ -2894,7 +2845,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
 void wxWindowGTK::OnInternalIdle()
 {
     // Update invalidated regions.
-    Update();
+    GtkUpdate();
 
     // Synthetize activate events.
     if ( g_sendActivateEvent != -1 )
@@ -2919,7 +2870,7 @@ void wxWindowGTK::OnInternalIdle()
         }
         g_activeFrameLostFocus = FALSE;
     }
-
+    
     wxCursor cursor = m_cursor;
     if (g_globalCursor.Ok()) cursor = g_globalCursor;
 
@@ -3274,13 +3225,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))
@@ -3292,7 +3236,22 @@ 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))
+            {
+                wxLogTrace(_T("focus"),
+                           _T("Delaying setting focus to %s(%s)\n"),
+                           GetClassInfo()->GetClassName(), GetLabel().c_str());
+
+                g_delayedFocus = this;
+            }
+            else
+            {
+                wxLogTrace(_T("focus"),
+                           _T("Setting focus to %s(%s)\n"),
+                           GetClassInfo()->GetClassName(), GetLabel().c_str());
+
+                gtk_widget_grab_focus (m_widget);
+            }
         }
         else if (GTK_IS_CONTAINER(m_widget))
         {
@@ -3303,6 +3262,8 @@ void wxWindowGTK::SetFocus()
            // ?
         }
     }
+
+    (void)DoSendFocusEvents((wxWindow*)this);
 }
 
 bool wxWindowGTK::AcceptsFocus() const
@@ -3418,6 +3379,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)
@@ -3484,6 +3448,11 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
 }
 
 void wxWindowGTK::Update()
+{
+    GtkUpdate();
+}
+
+void wxWindowGTK::GtkUpdate()
 {
 #ifdef __WXGTK20__
     if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window)
@@ -3503,8 +3472,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 );
@@ -3517,7 +3521,7 @@ 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() );
@@ -3525,8 +3529,8 @@ void wxWindowGTK::GtkSendPaintEvents()
             wxRegionIterator upd( m_clearRegion );
             while (upd)
             {
-                gdk_draw_rectangle( GTK_PIZZA(m_wxwindow)->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 ++;
             }
         }
@@ -3549,14 +3553,12 @@ 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)
     {
         GtkPizzaChild *child = (GtkPizzaChild*) children->data;
         children = children->next;
-
+        
         if (GTK_WIDGET_NO_WINDOW (child->widget) &&
             GTK_WIDGET_DRAWABLE (child->widget))
         {
@@ -3596,11 +3598,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?
+        GtkUpdate();
     }
 }
 
@@ -3619,16 +3624,34 @@ 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)
+    {
+        // wxMSW doesn't clear the window here, either.
+        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)
@@ -3642,27 +3665,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 )
@@ -3689,8 +3712,10 @@ bool wxWindowGTK::SetForegroundColour( const wxColour &colour )
         // widget hasn't been realized yet.
         m_delayedForegroundColour = TRUE;
     }
-
-    ApplyWidgetStyle();
+    else
+    {
+       GtkSetForegroundColour( colour );
+    }
 
     return TRUE;
 }
@@ -4305,3 +4330,4 @@ void wxWinModule::OnExit()
         gdk_gc_unref( g_eraseGC );
 }
 
+// vi:sts=4:sw=4:et