[gtk+] paned: Be careful about showing windows
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] paned: Be careful about showing windows
- Date: Tue, 10 May 2011 22:48:00 +0000 (UTC)
commit f96777ea02e58ec4641d55a68e8b136ff4e79bae
Author: Benjamin Otte <otte redhat com>
Date: Wed May 11 00:46:08 2011 +0200
paned: Be careful about showing windows
The previous code failed to account for all child visibility and paned
mapedness invariants which could cause stray GDK windows to appear.
Not good.
Credit goes to Xan for triggering it.
gtk/gtkpaned.c | 91 ++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 65 insertions(+), 26 deletions(-)
---
diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c
index 62c66bb..0fe290e 100644
--- a/gtk/gtkpaned.c
+++ b/gtk/gtkpaned.c
@@ -89,6 +89,11 @@
* </example>
*/
+enum {
+ CHILD1,
+ CHILD2
+};
+
struct _GtkPanedPrivate
{
GtkPaned *first_paned;
@@ -978,6 +983,50 @@ flip_child (GtkWidget *widget,
child_pos->x = 2 * x + width - child_pos->x - child_pos->width;
}
+static gboolean
+gtk_paned_get_child_visible (GtkPaned *paned,
+ guint id)
+{
+ GtkPanedPrivate *priv = paned->priv;
+ GtkWidget *child;
+
+ child = id == CHILD1 ? priv->child1 : priv->child2;
+
+ return (child != NULL && gtk_widget_get_child_visible (child));
+}
+
+static void
+gtk_paned_set_child_visible (GtkPaned *paned,
+ guint id,
+ gboolean visible)
+{
+ GtkPanedPrivate *priv = paned->priv;
+ GtkWidget *child;
+ gboolean was_visible;
+
+ was_visible = gtk_paned_get_child_visible (paned, id);
+
+ child = id == CHILD1 ? priv->child1 : priv->child2;
+
+ if (child == NULL)
+ return;
+
+ if (was_visible == visible)
+ return;
+
+ gtk_widget_set_child_visible (child, visible);
+
+ if (gtk_widget_get_mapped (GTK_WIDGET (paned)))
+ {
+ GdkWindow *window = id == CHILD1 ? priv->child1_window : priv->child2_window;
+
+ if (visible)
+ gdk_window_show (window);
+ else
+ gdk_window_hide (window);
+ }
+}
+
static void
gtk_paned_child_allocate (GtkWidget *child,
GdkWindow *child_window, /* can be NULL */
@@ -1182,10 +1231,6 @@ gtk_paned_size_allocate (GtkWidget *widget,
&window2_allocation,
&child2_allocation);
}
- if (priv->child1_window)
- gdk_window_show (priv->child1_window);
- if (priv->child2_window)
- gdk_window_show (priv->child2_window);
}
else
{
@@ -1195,9 +1240,9 @@ gtk_paned_size_allocate (GtkWidget *widget,
gdk_window_hide (priv->handle);
if (priv->child1)
- gtk_widget_set_child_visible (priv->child1, TRUE);
+ gtk_paned_set_child_visible (paned, 0, TRUE);
if (priv->child2)
- gtk_widget_set_child_visible (priv->child2, TRUE);
+ gtk_paned_set_child_visible (paned, 1, TRUE);
window_allocation.x = allocation->x;
window_allocation.y = allocation->y;
@@ -1213,10 +1258,6 @@ gtk_paned_size_allocate (GtkWidget *widget,
priv->child1_window,
&window_allocation,
&child_allocation);
- if (priv->child1_window)
- gdk_window_show (priv->child1_window);
- if (priv->child2_window)
- gdk_window_hide (priv->child2_window);
}
else if (priv->child2 && gtk_widget_get_visible (priv->child2))
{
@@ -1224,10 +1265,6 @@ gtk_paned_size_allocate (GtkWidget *widget,
priv->child2_window,
&window_allocation,
&child_allocation);
- if (priv->child2_window)
- gdk_window_show (priv->child2_window);
- if (priv->child1_window)
- gdk_window_hide (priv->child1_window);
}
}
}
@@ -1376,9 +1413,9 @@ gtk_paned_map (GtkWidget *widget)
priv->child2 && gtk_widget_get_visible (priv->child2))
gdk_window_show (priv->handle);
- if (priv->child1 && gtk_widget_get_visible (priv->child1))
+ if (priv->child1 && gtk_widget_get_visible (priv->child1) && gtk_widget_get_child_visible (priv->child1))
gdk_window_show (priv->child1_window);
- if (priv->child2 && gtk_widget_get_visible (priv->child2))
+ if (priv->child2 && gtk_widget_get_visible (priv->child2) && gtk_widget_get_child_visible (priv->child2))
gdk_window_show (priv->child2_window);
GTK_WIDGET_CLASS (gtk_paned_parent_class)->map (widget);
@@ -1392,8 +1429,10 @@ gtk_paned_unmap (GtkWidget *widget)
gdk_window_hide (priv->handle);
- gdk_window_hide (priv->child1_window);
- gdk_window_hide (priv->child2_window);
+ if (gdk_window_is_visible (priv->child1_window))
+ gdk_window_hide (priv->child1_window);
+ if (gdk_window_is_visible (priv->child2_window))
+ gdk_window_hide (priv->child2_window);
GTK_WIDGET_CLASS (gtk_paned_parent_class)->unmap (widget);
}
@@ -1863,25 +1902,25 @@ gtk_paned_remove (GtkContainer *container,
if (priv->child1 == widget)
{
+ if (priv->child1_window && gdk_window_is_visible (priv->child1_window))
+ gdk_window_hide (priv->child1_window);
+
gtk_widget_unparent (widget);
priv->child1 = NULL;
- if (priv->child1_window)
- gdk_window_hide (priv->child1_window);
-
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (container));
}
else if (priv->child2 == widget)
{
+ if (priv->child2_window && gdk_window_is_visible (priv->child2_window))
+ gdk_window_hide (priv->child2_window);
+
gtk_widget_unparent (widget);
priv->child2 = NULL;
- if (priv->child2_window)
- gdk_window_hide (priv->child2_window);
-
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (container));
}
@@ -2068,10 +2107,10 @@ gtk_paned_calc_position (GtkPaned *paned,
priv->max_position);
if (priv->child1)
- gtk_widget_set_child_visible (priv->child1, priv->child1_size != 0);
+ gtk_paned_set_child_visible (paned, 0, priv->child1_size != 0);
if (priv->child2)
- gtk_widget_set_child_visible (priv->child2, priv->child1_size != allocation);
+ gtk_paned_set_child_visible (paned, 1, priv->child1_size != allocation);
g_object_freeze_notify (G_OBJECT (paned));
if (priv->child1_size != old_position)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]