+ return g_object_new (GTK_TYPE_EVENT_BOX, NULL);
+}
+
+static void
+gtk_event_box_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkEventBox *event_box;
+
+ event_box = GTK_EVENT_BOX (object);
+
+ switch (prop_id)
+ {
+ case PROP_VISIBLE_WINDOW:
+ gtk_event_box_set_visible_window (event_box, g_value_get_boolean (value));
+ break;
+
+ case PROP_ABOVE_CHILD:
+ gtk_event_box_set_above_child (event_box, g_value_get_boolean (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_event_box_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkEventBox *event_box;
+
+ event_box = GTK_EVENT_BOX (object);
+
+ switch (prop_id)
+ {
+ case PROP_VISIBLE_WINDOW:
+ g_value_set_boolean (value, gtk_event_box_get_visible_window (event_box));
+ break;
+
+ case PROP_ABOVE_CHILD:
+ g_value_set_boolean (value, gtk_event_box_get_above_child (event_box));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * gtk_event_box_get_visible_window:
+ * @event_box: a #GtkEventBox
+ *
+ * Returns whether the event box has a visible window.
+ * See gtk_event_box_set_visible_window() for details.
+ *
+ * Return value: %TRUE if the event box window is visible
+ *
+ * Since: 2.4
+ */
+gboolean
+gtk_event_box_get_visible_window (GtkEventBox *event_box)
+{
+ g_return_val_if_fail (GTK_IS_EVENT_BOX (event_box), FALSE);
+
+ return gtk_widget_get_has_window (GTK_WIDGET (event_box));
+}
+
+/**
+ * gtk_event_box_set_visible_window:
+ * @event_box: a #GtkEventBox
+ * @visible_window: %TRUE to make the event box have a visible window
+ *
+ * Set whether the event box uses a visible or invisible child
+ * window. The default is to use visible windows.
+ *
+ * In an invisible window event box, the window that the
+ * event box creates is a %GDK_INPUT_ONLY window, which
+ * means that it is invisible and only serves to receive
+ * events.
+ *
+ * A visible window event box creates a visible (%GDK_INPUT_OUTPUT)
+ * window that acts as the parent window for all the widgets
+ * contained in the event box.
+ *
+ * You should generally make your event box invisible if
+ * you just want to trap events. Creating a visible window
+ * may cause artifacts that are visible to the user, especially
+ * if the user is using a theme with gradients or pixmaps.
+ *
+ * The main reason to create a non input-only event box is if
+ * you want to set the background to a different color or
+ * draw on it.
+ *
+ * <note><para>
+ * There is one unexpected issue for an invisible event box that has its
+ * window below the child. (See gtk_event_box_set_above_child().)
+ * Since the input-only window is not an ancestor window of any windows
+ * that descendent widgets of the event box create, events on these
+ * windows aren't propagated up by the windowing system, but only by GTK+.
+ * The practical effect of this is if an event isn't in the event
+ * mask for the descendant window (see gtk_widget_add_events()),
+ * it won't be received by the event box.
+ * </para><para>
+ * This problem doesn't occur for visible event boxes, because in
+ * that case, the event box window is actually the ancestor of the
+ * descendant windows, not just at the same place on the screen.
+ * </para></note>
+ *
+ * Since: 2.4
+ */
+void
+gtk_event_box_set_visible_window (GtkEventBox *event_box,
+ gboolean visible_window)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_EVENT_BOX (event_box));
+
+ widget = GTK_WIDGET (event_box);
+
+ visible_window = visible_window != FALSE;
+
+ if (visible_window != gtk_widget_get_has_window (widget))
+ {
+ if (gtk_widget_get_realized (widget))
+ {
+ gboolean visible = gtk_widget_get_visible (widget);
+
+ if (visible)
+ gtk_widget_hide (widget);
+
+ gtk_widget_unrealize (widget);
+
+ gtk_widget_set_has_window (widget, visible_window);
+
+ gtk_widget_realize (widget);
+
+ if (visible)
+ gtk_widget_show (widget);
+ }
+ else
+ {
+ gtk_widget_set_has_window (widget, visible_window);
+ }
+
+ if (gtk_widget_get_visible (widget))
+ gtk_widget_queue_resize (widget);
+
+ g_object_notify (G_OBJECT (event_box), "visible-window");
+ }
+}
+
+/**
+ * gtk_event_box_get_above_child:
+ * @event_box: a #GtkEventBox
+ *
+ * Returns whether the event box window is above or below the
+ * windows of its child. See gtk_event_box_set_above_child()
+ * for details.
+ *
+ * Return value: %TRUE if the event box window is above the
+ * window of its child
+ *
+ * Since: 2.4
+ */
+gboolean
+gtk_event_box_get_above_child (GtkEventBox *event_box)
+{
+ GtkEventBoxPrivate *priv = event_box->priv;
+
+ g_return_val_if_fail (GTK_IS_EVENT_BOX (event_box), FALSE);
+
+ return priv->above_child;
+}
+
+/**
+ * gtk_event_box_set_above_child:
+ * @event_box: a #GtkEventBox
+ * @above_child: %TRUE if the event box window is above its child
+ *
+ * Set whether the event box window is positioned above the windows
+ * of its child, as opposed to below it. If the window is above, all
+ * events inside the event box will go to the event box. If the window
+ * is below, events in windows of child widgets will first got to that
+ * widget, and then to its parents.
+ *
+ * The default is to keep the window below the child.
+ *
+ * Since: 2.4
+ */
+void
+gtk_event_box_set_above_child (GtkEventBox *event_box,
+ gboolean above_child)
+{
+ GtkEventBoxPrivate *priv = event_box->priv;
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_EVENT_BOX (event_box));
+
+ widget = GTK_WIDGET (event_box);
+
+ above_child = above_child != FALSE;
+
+ if (priv->above_child != above_child)
+ {
+ priv->above_child = above_child;
+
+ if (gtk_widget_get_realized (widget))
+ {
+ if (!gtk_widget_get_has_window (widget))
+ {
+ if (above_child)
+ gdk_window_raise (priv->event_window);
+ else
+ gdk_window_lower (priv->event_window);
+ }
+ else
+ {
+ gboolean visible = gtk_widget_get_visible (widget);
+
+ if (visible)
+ gtk_widget_hide (widget);
+
+ gtk_widget_unrealize (widget);
+ gtk_widget_realize (widget);
+
+ if (visible)
+ gtk_widget_show (widget);
+ }
+ }
+
+ if (gtk_widget_get_visible (widget))
+ gtk_widget_queue_resize (widget);
+
+ g_object_notify (G_OBJECT (event_box), "above-child");
+ }