[gtk+/layered-windows: 3/10] gdk: Add gdk_window_get/set_layered



commit 705ba65b335156b67059e8ff2dc28631ab23d896
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Dec 1 13:57:27 2011 +0100

    gdk: Add gdk_window_get/set_layered

 gdk/gdkinternals.h |    2 +
 gdk/gdkwindow.c    |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 103 insertions(+), 1 deletions(-)
---
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 27afe02..62a58ed 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -204,6 +204,8 @@ struct _GdkWindow
   guint input_only : 1;
   guint modal_hint : 1;
   guint composited : 1;
+  guint layered : 1;
+  guint effective_layered : 1;
 
   guint destroyed : 2;
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index dba0897..ef39150 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -787,6 +787,31 @@ gdk_window_update_visibility_recursively (GdkWindow *window,
     }
 }
 
+static void
+gdk_window_propagate_effective_layered (GdkWindow *window)
+{
+  GdkWindow *child;
+  GList *l;
+  gboolean child_effective;
+
+  /* Assumes window->effective_layered is correct */
+
+  for (l = window->children; l != NULL; l = l->next)
+    {
+      child = l->data;
+
+      if (child->impl != window->impl)
+	continue;
+
+      child_effective = window->effective_layered || child->layered;
+      if (child->effective_layered != child_effective)
+	{
+	  child->effective_layered = child_effective;
+	  gdk_window_propagate_effective_layered (child);
+	}
+    }
+}
+
 static gboolean
 should_apply_clip_as_shape (GdkWindow *window)
 {
@@ -1389,6 +1414,8 @@ gdk_window_new (GdkWindow     *parent,
       window->impl = g_object_ref (window->impl_window->impl);
     }
 
+  if (window->impl_window != window)
+    window->effective_layered = parent->effective_layered;
   recompute_visible_regions (window, TRUE, FALSE);
 
   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
@@ -1619,7 +1646,12 @@ gdk_window_reparent (GdkWindow *window,
 
   _gdk_window_update_viewable (window);
 
-  recompute_visible_regions (window, TRUE, FALSE);
+  window->effective_layered = window->layered;
+  if (window->impl_window != window)
+    window->effective_layered |= new_parent->effective_layered;
+  gdk_window_propagate_effective_layered (window);
+
+  recompute_visible_regions (window, TRUE, TRUE);
   if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
     recompute_visible_regions (old_parent, FALSE, TRUE);
 
@@ -7404,6 +7436,74 @@ gdk_window_set_composited (GdkWindow *window,
 }
 
 /**
+ * gdk_window_get_layered:
+ * @window: a #GdkWindow
+ *
+ * Determines whether @window is layered.
+ *
+ * See gdk_window_set_layered().
+ *
+ * Returns: %TRUE if the window is layered.
+ *
+ * Since: 3.4
+ **/
+gboolean
+gdk_window_get_layered (GdkWindow *window)
+{
+  g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+  return window->layered;
+}
+
+/**
+ * gdk_window_set_layered:
+ * @window: a #GdkWindow
+ * @layered: %TRUE to set the window as layered
+ *
+ * Sets a #GdkWindow as layered, or unsets it. Layered
+ * windows are non-opaque, and if you don't draw to them
+ * or draw transparently, then the window below the window
+ * is (partially) visible. If a window is layered, then all
+ * its children are also automatically layered.
+ *
+ * It only makes sense for child windows to be layered, ad
+ * you can't make native windows layered.
+ *
+ * An additional effect of this call is that the area of this
+ * window is no longer clipped from regions marked for
+ * invalidation on its parent. Draws done on the parent
+ * window are also no longer clipped by the child.
+ *
+ * Since: 3.4
+ */
+void
+gdk_window_set_layered (GdkWindow *window,
+			gboolean   layered)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  layered = layered != FALSE;
+
+  if (window->layered == layered)
+    return;
+
+  window->layered = layered;
+  window->effective_layered = layered;
+  if (window->impl_window != window &&
+      window->parent && window->parent->effective_layered)
+    window->effective_layered = TRUE;
+
+  gdk_window_propagate_effective_layered (window);
+
+  recompute_visible_regions (window, TRUE, TRUE);
+  if (!gdk_window_is_toplevel (window))
+    recompute_visible_regions (window->parent, FALSE, FALSE);
+
+  if (GDK_WINDOW_IS_MAPPED (window))
+    gdk_window_invalidate_in_parent (window);
+}
+
+/**
  * gdk_window_get_modal_hint:
  * @window: A toplevel #GdkWindow.
  *



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