]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
Fix Tab navigation when focused control is disabled.
[wxWidgets.git] / src / gtk / window.cpp
index 2f9a0edfe45ceed64c5c3cc8ff73d2d6a763e723..eb4d2df8cd2fab92486794d3225a6edbff796de1 100644 (file)
@@ -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;
@@ -819,6 +822,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 +969,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 +1001,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 +1028,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 +1848,8 @@ gtk_window_realized_callback(GtkWidget* widget, wxWindow* win)
     wxWindowCreateEvent event( win );
     event.SetEventObject( win );
     win->GTKProcessEvent( event );
+
+    win->GTKUpdateCursor(true, false);
 }
 
 //-----------------------------------------------------------------------------
@@ -2638,10 +2643,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 +2657,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 +3417,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() );
             }
         }
     }