mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 22:41:43 +00:00
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.
This commit is contained in:
parent
1ab425b132
commit
f96777ea02
@ -89,6 +89,11 @@
|
|||||||
* </example>
|
* </example>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CHILD1,
|
||||||
|
CHILD2
|
||||||
|
};
|
||||||
|
|
||||||
struct _GtkPanedPrivate
|
struct _GtkPanedPrivate
|
||||||
{
|
{
|
||||||
GtkPaned *first_paned;
|
GtkPaned *first_paned;
|
||||||
@ -978,6 +983,50 @@ flip_child (GtkWidget *widget,
|
|||||||
child_pos->x = 2 * x + width - child_pos->x - child_pos->width;
|
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
|
static void
|
||||||
gtk_paned_child_allocate (GtkWidget *child,
|
gtk_paned_child_allocate (GtkWidget *child,
|
||||||
GdkWindow *child_window, /* can be NULL */
|
GdkWindow *child_window, /* can be NULL */
|
||||||
@ -1182,10 +1231,6 @@ gtk_paned_size_allocate (GtkWidget *widget,
|
|||||||
&window2_allocation,
|
&window2_allocation,
|
||||||
&child2_allocation);
|
&child2_allocation);
|
||||||
}
|
}
|
||||||
if (priv->child1_window)
|
|
||||||
gdk_window_show (priv->child1_window);
|
|
||||||
if (priv->child2_window)
|
|
||||||
gdk_window_show (priv->child2_window);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1195,9 +1240,9 @@ gtk_paned_size_allocate (GtkWidget *widget,
|
|||||||
gdk_window_hide (priv->handle);
|
gdk_window_hide (priv->handle);
|
||||||
|
|
||||||
if (priv->child1)
|
if (priv->child1)
|
||||||
gtk_widget_set_child_visible (priv->child1, TRUE);
|
gtk_paned_set_child_visible (paned, 0, TRUE);
|
||||||
if (priv->child2)
|
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.x = allocation->x;
|
||||||
window_allocation.y = allocation->y;
|
window_allocation.y = allocation->y;
|
||||||
@ -1213,10 +1258,6 @@ gtk_paned_size_allocate (GtkWidget *widget,
|
|||||||
priv->child1_window,
|
priv->child1_window,
|
||||||
&window_allocation,
|
&window_allocation,
|
||||||
&child_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))
|
else if (priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||||
{
|
{
|
||||||
@ -1224,10 +1265,6 @@ gtk_paned_size_allocate (GtkWidget *widget,
|
|||||||
priv->child2_window,
|
priv->child2_window,
|
||||||
&window_allocation,
|
&window_allocation,
|
||||||
&child_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))
|
priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||||
gdk_window_show (priv->handle);
|
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);
|
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);
|
gdk_window_show (priv->child2_window);
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_paned_parent_class)->map (widget);
|
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->handle);
|
||||||
|
|
||||||
gdk_window_hide (priv->child1_window);
|
if (gdk_window_is_visible (priv->child1_window))
|
||||||
gdk_window_hide (priv->child2_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);
|
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 == widget)
|
||||||
{
|
{
|
||||||
|
if (priv->child1_window && gdk_window_is_visible (priv->child1_window))
|
||||||
|
gdk_window_hide (priv->child1_window);
|
||||||
|
|
||||||
gtk_widget_unparent (widget);
|
gtk_widget_unparent (widget);
|
||||||
|
|
||||||
priv->child1 = NULL;
|
priv->child1 = NULL;
|
||||||
|
|
||||||
if (priv->child1_window)
|
|
||||||
gdk_window_hide (priv->child1_window);
|
|
||||||
|
|
||||||
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
|
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
|
||||||
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (container));
|
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (container));
|
||||||
}
|
}
|
||||||
else if (priv->child2 == widget)
|
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);
|
gtk_widget_unparent (widget);
|
||||||
|
|
||||||
priv->child2 = NULL;
|
priv->child2 = NULL;
|
||||||
|
|
||||||
if (priv->child2_window)
|
|
||||||
gdk_window_hide (priv->child2_window);
|
|
||||||
|
|
||||||
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
|
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
|
||||||
gtk_widget_queue_resize_no_redraw (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);
|
priv->max_position);
|
||||||
|
|
||||||
if (priv->child1)
|
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)
|
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));
|
g_object_freeze_notify (G_OBJECT (paned));
|
||||||
if (priv->child1_size != old_position)
|
if (priv->child1_size != old_position)
|
||||||
|
Loading…
Reference in New Issue
Block a user