summaryrefslogtreecommitdiff
path: root/gtk/gtkpaned.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2011-05-11 00:46:08 +0200
committerBenjamin Otte <otte@redhat.com>2011-05-11 00:47:23 +0200
commitf96777ea02e58ec4641d55a68e8b136ff4e79bae (patch)
tree3c0d3b193b7d3cd7059157af33b228d6d14228d4 /gtk/gtkpaned.c
parent1ab425b1326ce09604d5570bb48465210f19e501 (diff)
downloadgtk+-f96777ea02e58ec4641d55a68e8b136ff4e79bae.tar.gz
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.
Diffstat (limited to 'gtk/gtkpaned.c')
-rw-r--r--gtk/gtkpaned.c91
1 files changed, 65 insertions, 26 deletions
diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c
index 62c66bbfa6..0fe290e7cc 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)