[gtk+] GtkMenu: Properly detach menu when the window is detached
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkMenu: Properly detach menu when the window is detached
- Date: Sun, 26 Jul 2015 05:57:38 +0000 (UTC)
commit 955c1c7734507bd5ef9b9aa36469948405cf2b81
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Thu Jul 23 14:34:12 2015 +0800
GtkMenu: Properly detach menu when the window is detached
Without properly cleaning up GtkMenu private attach state
(GtkMenuAttachData) when the attached widget is freed, we would end up
with an invalid pointer to a freed widget. Trying to detach from that
widget would cause a segmentation fault.
https://bugzilla.gnome.org/show_bug.cgi?id=752761
gtk/gtkmenu.c | 22 +++++++++++++++++++++-
1 files changed, 21 insertions(+), 1 deletions(-)
---
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 2b4203f..b39de7d 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -1194,6 +1194,18 @@ attach_widget_screen_changed (GtkWidget *attach_widget,
menu_change_screen (menu, gtk_widget_get_screen (attach_widget));
}
+static void
+menu_toplevel_attached_to (GtkWindow *toplevel, GParamSpec *pspec, GtkMenu *menu)
+{
+ GtkMenuAttachData *data;
+
+ data = g_object_get_data (G_OBJECT (menu), attach_data_key);
+
+ g_return_if_fail (data);
+
+ gtk_menu_detach (menu);
+}
+
/**
* gtk_menu_attach_to_widget:
* @menu: a #GtkMenu
@@ -1250,6 +1262,8 @@ gtk_menu_attach_to_widget (GtkMenu *menu,
/* Attach the widget to the toplevel window. */
gtk_window_set_attached_to (GTK_WINDOW (menu->priv->toplevel), attach_widget);
+ g_signal_connect (GTK_WINDOW (menu->priv->toplevel), "notify::attached-to",
+ G_CALLBACK (menu_toplevel_attached_to), menu);
_gtk_widget_update_parent_muxer (GTK_WIDGET (menu));
@@ -1291,10 +1305,12 @@ gtk_menu_get_attach_widget (GtkMenu *menu)
void
gtk_menu_detach (GtkMenu *menu)
{
+ GtkWindow *toplevel;
GtkMenuAttachData *data;
GList *list;
g_return_if_fail (GTK_IS_MENU (menu));
+ toplevel = GTK_WINDOW (menu->priv->toplevel);
/* keep this function in sync with gtk_widget_unparent() */
data = g_object_get_data (G_OBJECT (menu), attach_data_key);
@@ -1306,7 +1322,11 @@ gtk_menu_detach (GtkMenu *menu)
g_object_set_data (G_OBJECT (menu), I_(attach_data_key), NULL);
/* Detach the toplevel window. */
- gtk_window_set_attached_to (GTK_WINDOW (menu->priv->toplevel), NULL);
+ g_signal_handlers_disconnect_by_func (toplevel,
+ (gpointer) menu_toplevel_attached_to,
+ menu);
+ if (gtk_window_get_attached_to (toplevel) == data->attach_widget)
+ gtk_window_set_attached_to (toplevel, NULL);
g_signal_handlers_disconnect_by_func (data->attach_widget,
(gpointer) attach_widget_screen_changed,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]