diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 2e809b2..15e3ab5 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -77,6 +77,8 @@ struct _GtkMenuPrivate
   gint y;
   gboolean initially_pushed_in;
 
+  GDestroyNotify position_func_data_destroy;
+
   /* info used for the table */
   guint *heights;
   gint heights_length;
@@ -1136,6 +1138,13 @@ gtk_menu_destroy (GtkObject *object)
       priv->title = NULL;
     }
 
+  if (priv->position_func_data_destroy)
+    {
+      priv->position_func_data_destroy (menu->position_func_data);
+      menu->position_func_data = NULL;
+      priv->position_func_data_destroy = NULL;
+    }
+
   GTK_OBJECT_CLASS (gtk_menu_parent_class)->destroy (object);
 }
 
@@ -1413,6 +1422,7 @@ popup_grab_on_window (GdkWindow *window,
  * @parent_menu_item: (allow-none): the menu item whose activation triggered the popup, or %NULL
  * @func: (allow-none): a user supplied function used to position the menu, or %NULL
  * @data: (allow-none): user supplied data to be passed to @func.
+ * @destroy: (allow-none): destroy notify for @data.
  * @button: the mouse button which was pressed to initiate the event.
  * @activate_time: the time at which the activation event occurred.
  *
@@ -1443,6 +1453,7 @@ gtk_menu_popup_for_device (GtkMenu             *menu,
                            GtkWidget           *parent_menu_item,
                            GtkMenuPositionFunc  func,
                            gpointer             data,
+                           GDestroyNotify       destroy,
                            guint                button,
                            guint32              activate_time)
 {
@@ -1457,7 +1468,25 @@ gtk_menu_popup_for_device (GtkMenu             *menu,
   GdkDevice *keyboard, *pointer;
 
   g_return_if_fail (GTK_IS_MENU (menu));
-  g_return_if_fail (GDK_IS_DEVICE (device));
+  g_return_if_fail (device == NULL || GDK_IS_DEVICE (device));
+
+  if (device == NULL)
+    device = gtk_get_current_event_device ();
+
+  if (device == NULL)
+    {
+      GdkDisplay *display;
+      GdkDeviceManager *device_manager;
+      GList *devices;
+
+      display = gtk_widget_get_display (GTK_WIDGET (menu));
+      device_manager = gdk_display_get_device_manager (display);
+      devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+      device = devices->data;
+
+      g_list_free (devices);
+    }
 
   widget = GTK_WIDGET (menu);
   menu_shell = GTK_MENU_SHELL (menu);
@@ -1602,6 +1631,7 @@ gtk_menu_popup_for_device (GtkMenu             *menu,
   menu->parent_menu_item = parent_menu_item;
   menu->position_func = func;
   menu->position_func_data = data;
+  priv->position_func_data_destroy = destroy;
   menu_shell->activate_time = activate_time;
 
   /* We need to show the menu here rather in the init function because
@@ -1713,27 +1743,11 @@ gtk_menu_popup (GtkMenu		    *menu,
 
   g_return_if_fail (GTK_IS_MENU (menu));
 
-  device = gtk_get_current_event_device ();
-
-  if (!device)
-    {
-      GdkDisplay *display;
-      GdkDeviceManager *device_manager;
-      GList *devices;
-
-      display = gtk_widget_get_display (GTK_WIDGET (menu));
-      device_manager = gdk_display_get_device_manager (display);
-      devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
-
-      device = devices->data;
-
-      g_list_free (devices);
-    }
-
-  gtk_menu_popup_for_device (menu, device,
+  gtk_menu_popup_for_device (menu,
+                             NULL,
                              parent_menu_shell,
                              parent_menu_item,
-                             func, data,
+                             func, data, NULL,
                              button, activate_time);
 }
 
diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h
index 5274b09..fbb887b 100644
--- a/gtk/gtkmenu.h
+++ b/gtk/gtkmenu.h
@@ -139,10 +139,10 @@ void       gtk_menu_popup_for_device      (GtkMenu             *menu,
                                            GtkWidget           *parent_menu_item,
                                            GtkMenuPositionFunc  func,
                                            gpointer             data,
+                                           GDestroyNotify       destroy,
                                            guint                button,
                                            guint32              activate_time);
 
-
 /* Position the menu according to its position function. Called
  * from gtkmenuitem.c when a menu-item changes its allocation
  */
