[gtk+] GdkWindow: Track all native windows of native windows



commit 8306d26714514f001d49b1cefc182459a44d9724
Author: Alexander Larsson <alexl redhat com>
Date:   Wed May 15 10:23:14 2013 +0200

    GdkWindow: Track all native windows of native windows
    
    We keep a list of all native children of a native window. This means
    we don't have to recurse over the entire hierarchy to find any
    native children.

 gdk/gdkinternals.h          |    1 +
 gdk/gdkwindow.c             |   40 ++++++++++++++++++++++++++++++++++++----
 gdk/win32/gdkwindow-win32.c |    2 ++
 gdk/x11/gdkwindow-x11.c     |    2 ++
 4 files changed, 41 insertions(+), 4 deletions(-)
---
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 87d3fbc..3f2d1a4 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -189,6 +189,7 @@ struct _GdkWindow
 
   GList *filters;
   GList *children;
+  GList *native_children;
 
   cairo_pattern_t *background;
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index f4f1440..2c9a2a1 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -1375,6 +1375,9 @@ gdk_window_new (GdkWindow     *parent,
       _gdk_display_create_window_impl (display, window, real_parent, screen, event_mask, attributes, 
attributes_mask);
       window->impl_window = window;
 
+      if (parent)
+        parent->impl_window->native_children = g_list_prepend (parent->impl_window->native_children, window);
+
       /* This will put the native window topmost in the native parent, which may
        * be wrong wrt other native windows in the non-native hierarchy, so restack */
       if (!_gdk_window_has_impl (real_parent))
@@ -1444,6 +1447,14 @@ change_impl (GdkWindow *private,
 
       if (child->impl == old_impl)
        change_impl (child, impl_window, new);
+      else
+        {
+          /* The child is a native, update native_children */
+          old_impl_window->native_children =
+            g_list_remove (old_impl_window->native_children, child);
+          impl_window->native_children =
+            g_list_prepend (impl_window->native_children, child);
+        }
     }
 }
 
@@ -1570,7 +1581,13 @@ gdk_window_reparent (GdkWindow *window,
     }
 
   if (old_parent)
-    old_parent->children = g_list_remove (old_parent->children, window);
+    {
+      old_parent->children = g_list_remove (old_parent->children, window);
+
+      if (gdk_window_has_impl (window))
+        old_parent->impl_window->native_children =
+          g_list_remove (old_parent->impl_window->native_children, window);
+    }
 
   window->parent = new_parent;
   window->x = x;
@@ -1578,6 +1595,9 @@ gdk_window_reparent (GdkWindow *window,
 
   new_parent->children = g_list_prepend (new_parent->children, window);
 
+  if (gdk_window_has_impl (window))
+    new_parent->impl_window->native_children = g_list_prepend (new_parent->impl_window->native_children, 
window);
+
   /* Switch the window type as appropriate */
 
   switch (GDK_WINDOW_TYPE (new_parent))
@@ -1686,7 +1706,7 @@ gdk_window_ensure_native (GdkWindow *window)
   GdkWindowImpl *new_impl, *old_impl;
   GdkDisplay *display;
   GdkScreen *screen;
-  GdkWindow *above;
+  GdkWindow *above, *parent;
   GList listhead;
   GdkWindowImplClass *impl_class;
 
@@ -1711,15 +1731,20 @@ gdk_window_ensure_native (GdkWindow *window)
 
   screen = gdk_window_get_screen (window);
   display = gdk_screen_get_display (screen);
+  parent = window->parent;
 
   old_impl = window->impl;
   _gdk_display_create_window_impl (display,
-                                   window, window->parent,
+                                   window, parent,
                                    screen,
                                    get_native_event_mask (window),
                                    NULL, 0);
   new_impl = window->impl;
 
+  if (parent)
+    parent->impl_window->native_children =
+      g_list_prepend (parent->impl_window->native_children, window);
+
   window->impl = old_impl;
   change_impl (window, window, new_impl);
 
@@ -1729,7 +1754,7 @@ gdk_window_ensure_native (GdkWindow *window)
    * native parent, which may be wrong wrt the position of the previous
    * non-native window wrt to the other non-native children, so correct this.
    */
-  above = find_native_sibling_above (window->parent, window);
+  above = find_native_sibling_above (parent, window);
   if (above)
     {
       listhead.data = window;
@@ -1925,6 +1950,10 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
              if (window->parent->children)
                window->parent->children = g_list_remove (window->parent->children, window);
 
+              if (gdk_window_has_impl (window))
+                window->parent->impl_window->native_children =
+                  g_list_remove (window->parent->impl_window->native_children, window);
+
              if (!recursing &&
                  GDK_WINDOW_IS_MAPPED (window))
                {
@@ -1967,6 +1996,9 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
                }
 
              g_list_free (children);
+
+              if (gdk_window_has_impl (window))
+                g_assert (window->native_children == NULL);
            }
 
          _gdk_window_clear_update_area (window);
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 4ec80c1..29714b5 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -714,6 +714,8 @@ gdk_win32_window_foreign_new_for_display (GdkDisplay      *display,
     window->parent = _gdk_root;
   
   window->parent->children = g_list_prepend (window->parent->children, window);
+  window->parent->impl_window->native_children =
+    g_list_prepend (window->parent->impl_window->native_children, window);
 
   GetClientRect ((HWND) anid, &rect);
   point.x = rect.left;
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 6f3a8eb..1f1dbf1 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -1226,6 +1226,8 @@ gdk_x11_window_foreign_new_for_display (GdkDisplay *display,
     win->parent = gdk_screen_get_root_window (screen);
 
   win->parent->children = g_list_prepend (win->parent->children, win);
+  win->parent->impl_window->native_children =
+    g_list_prepend (win->parent->impl_window->native_children, win);
 
   impl->xid = window;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]